/* Perform either case-sensitive or case-insensitive field lookup. */ func (this *Field) Apply(context Context, first, second value.Value) (value.Value, error) { switch second.Type() { case value.STRING: s := second.Actual().(string) v, ok := first.Field(s) if !ok && this.caseInsensitive { s = strings.ToLower(s) fields := first.Fields() for f, val := range fields { if s == strings.ToLower(f) { return value.NewValue(val), nil } } } return v, nil case value.MISSING: return value.MISSING_VALUE, nil default: if first.Type() == value.MISSING { return value.MISSING_VALUE, nil } else { return value.NULL_VALUE, nil } } }
/* This method takes in an object, a name and a value and returns a new object that contains the name / attribute pair. If the type of input is missing then return a missing value, and if not an object return a null value. If the key is found, an error is thrown */ func (this *ObjectAdd) Apply(context Context, first, second, third value.Value) (value.Value, error) { // First must be an object, or we're out if first.Type() == value.MISSING { return value.MISSING_VALUE, nil } else if first.Type() != value.OBJECT { return value.NULL_VALUE, nil } // second must be a non empty string if second.Type() != value.STRING || second.Actual().(string) == "" { return first, nil } field := second.Actual().(string) // we don't overwrite _, exists := first.Field(field) if exists { return value.NULL_VALUE, nil } // SetField will remove if the attribute is missing, but we don't // overwrite anyway, so we might just skip now if third.Type() != value.MISSING { rv := first.CopyForUpdate() rv.SetField(field, third) return rv, nil } return first, nil }
/* Compute the Final. Compute the sum and the count. If these arent numbers throw an error. Compute the avg as sum/count. Check for divide by zero, and return a NULL value if true. */ func (this *Avg) ComputeFinal(cumulative value.Value, context Context) (value.Value, error) { if cumulative == value.NULL_VALUE { return cumulative, nil } sum, _ := cumulative.Field("sum") count, _ := cumulative.Field("count") if sum.Type() != value.NUMBER || count.Type() != value.NUMBER { return nil, fmt.Errorf("Missing or invalid sum or count in AVG: %v, %v.", sum.Actual(), count.Actual()) } if count.Actual().(float64) > 0.0 { return value.NewValue(sum.Actual().(float64) / count.Actual().(float64)), nil } else { return value.NULL_VALUE, nil } }
func doGetPrepared(prepared_stmt value.Value, track bool) (*Prepared, errors.Error) { switch prepared_stmt.Type() { case value.STRING: prepared := cache.get(prepared_stmt, track) if prepared == nil { return nil, errors.NewNoSuchPreparedError(prepared_stmt.Actual().(string)) } return prepared, nil case value.OBJECT: name_value, has_name := prepared_stmt.Field("name") if has_name { if prepared := cache.get(name_value, track); prepared != nil { return prepared, nil } } prepared_bytes, err := prepared_stmt.MarshalJSON() if err != nil { return nil, errors.NewUnrecognizedPreparedError(err) } return unmarshalPrepared(prepared_bytes) default: return nil, errors.NewUnrecognizedPreparedError(fmt.Errorf("Invalid prepared stmt %v", prepared_stmt)) } }
/* Aggregate input partial values into cumulative result number value for sum and count. If the partial results are not numbers, then return an error. */ func (this *Avg) cumulatePart(part, cumulative value.Value, context Context) (value.Value, error) { if part == value.NULL_VALUE { return cumulative, nil } else if cumulative == value.NULL_VALUE { return part, nil } psum, _ := part.Field("sum") pcount, _ := part.Field("count") csum, _ := cumulative.Field("sum") ccount, _ := cumulative.Field("count") if psum.Type() != value.NUMBER || pcount.Type() != value.NUMBER || csum.Type() != value.NUMBER || ccount.Type() != value.NUMBER { return nil, fmt.Errorf("Missing or invalid partial sum or count in AVG: %v, %v, %v, v.", psum.Actual(), pcount.Actual(), csum.Actual(), ccount.Actual()) } cumulative.SetField("sum", psum.Actual().(float64)+csum.Actual().(float64)) cumulative.SetField("count", pcount.Actual().(float64)+ccount.Actual().(float64)) return cumulative, nil }
/* Evaluate this as a top-level identifier. */ func (this *Identifier) Evaluate(item value.Value, context Context) (value.Value, error) { rv, _ := item.Field(this.identifier) return rv, nil }