/* This method returns an array that contains the values as arg 1, replaced by the 2nd argument value. If a third input argument is given (n) then at most n replacements are performed. Return this value. */ func (this *ArrayReplace) Apply(context Context, args ...value.Value) (value.Value, error) { av := args[0] v1 := args[1] v2 := args[2] if av.Type() == value.MISSING { return value.MISSING_VALUE, nil } else if av.Type() != value.ARRAY { return value.NULL_VALUE, nil } else if v1.Type() == value.MISSING { return av, nil } aa := av.Actual().([]interface{}) ra := make([]interface{}, 0, len(aa)) for _, a := range aa { v := value.NewValue(a) if v1.Equals(v) { if v2.Type() != value.MISSING { ra = append(ra, v2) } } else { ra = append(ra, v) } } return value.NewValue(ra), nil }
/* Returns the shape of the union result. If the two sub results are equal return the first value. If either of the inputs to the union setop are not objects then return the _JSON_SIGNATURE. Range through the two objects and check for equality and return object value. */ func (this *unionSubresult) Signature() value.Value { first := this.first.Signature() second := this.second.Signature() if first.Equals(second) { return first } if first.Type() != value.OBJECT || second.Type() != value.OBJECT { return _JSON_SIGNATURE } rv := first.Copy() sa := second.Actual().(map[string]interface{}) for k, v := range sa { cv, ok := rv.Field(k) if ok { if !value.NewValue(cv).Equals(value.NewValue(v)) { rv.SetField(k, _JSON_SIGNATURE) } } else { rv.SetField(k, v) } } return rv }
func Test2iScanRange(t *testing.T) { c.LogIgnore() //c.SetLogLevel(c.LogLevelDebug) low, high := value.NewValue("aaaa"), value.NewValue("zzzz") span := &datastore.Span{ Range: &datastore.Range{ Low: value.Values{low}, High: value.Values{high}, Inclusion: datastore.BOTH, }, } conn := datastore.NewIndexConnection(nil) entrych := conn.EntryChannel() quitch := conn.StopChannel() go index.Scan(span, false, 10000, conn) count := 0 loop: for { select { case _, ok := <-entrych: if !ok { break loop } count++ case <-quitch: break loop } } if count != 20000 { t.Fatal("failed ScanRange() - ", count) } }
/* This method takes in two values and returns a value that corresponds to the first position of the regular expression pattern (already set or populated using the second value) in the first string value, or -1 if it isnt found. If the input type is missing return missing, and if it isnt string then return null value. Use the FindStringIndex method in the regexp package to return a two-element slice of integers defining the location of the leftmost match in the string of the regular expression as per the Go Docs. Return the first element of this slice as a value. If a FindStringIndex returns nil, then the regexp pattern isnt found. Hence return -1. */ func (this *RegexpPosition) Apply(context Context, first, second value.Value) (value.Value, error) { if first.Type() == value.MISSING || second.Type() == value.MISSING { return value.MISSING_VALUE, nil } else if first.Type() != value.STRING || second.Type() != value.STRING { return value.NULL_VALUE, nil } f := first.Actual().(string) s := second.Actual().(string) re := this.re if re == nil { var err error re, err = regexp.Compile(s) if err != nil { return nil, err } } loc := re.FindStringIndex(f) if loc == nil { return value.NewValue(-1.0), nil } return value.NewValue(float64(loc[0])), nil }
/* This method evaluates the EVERY range predicate and returns a boolean value representing the result. The first step is to accumulate the elements or attributes of a collection/object. This is done by ranging over the bindings, evaluating the expressions and populating a slice of descendants if present. If any of these binding values are mising or null then, return a missing/null. The next step is to get the number of elements/attributes by ranging over the bindings slice. In order to evaluate the every clause, evaluate the satisfies condition with respect to the collection. If this returns false for any condition, then return false (as every condition needs to evaluate to true). If the condition over all elements/attributes have been satisfied, return true. */ func (this *Every) Evaluate(item value.Value, context Context) (value.Value, error) { missing := false null := false barr := make([][]interface{}, len(this.bindings)) for i, b := range this.bindings { bv, err := b.Expression().Evaluate(item, context) if err != nil { return nil, err } if b.Descend() { buffer := make([]interface{}, 0, 256) bv = value.NewValue(bv.Descendants(buffer)) } switch bv.Type() { case value.ARRAY: barr[i] = bv.Actual().([]interface{}) case value.MISSING: missing = true default: null = true } } if missing { return value.MISSING_VALUE, nil } if null { return value.NULL_VALUE, nil } n := -1 for _, b := range barr { if n < 0 || len(b) < n { n = len(b) } } for i := 0; i < n; i++ { cv := value.NewScopeValue(make(map[string]interface{}, len(this.bindings)), item) for j, b := range this.bindings { cv.SetField(b.Variable(), barr[j][i]) } sv, e := this.satisfies.Evaluate(cv, context) if e != nil { return nil, e } if !sv.Truth() { return value.NewValue(false), nil } } return value.NewValue(true), nil }
/* For Regexp Replace there can be either 3 or 4 input arguments. It searches for occurences of the regular expression pattern (representing the substring already set or populated using the second value) in the first arg (the expr) and replaces it with the third arg (the repacer). If there are only 3 args then use the ReplaceAllLiteralString method in the Regexp package to return a string after replacing matches of the Regexp with the replacement string. If the fourth arg exists it contains the replacements to a maximum number. Make sure its an integer value, and call ReplaceAllString. Keep track of the count. If either of the first three input arg values are missing return a missing, or if not a string return a null value. If the fourth input arg is not a number return a null value. */ func (this *RegexpReplace) Apply(context Context, args ...value.Value) (value.Value, error) { null := false for i := 0; i < 3; i++ { if args[i].Type() == value.MISSING { return value.MISSING_VALUE, nil } else if args[i].Type() != value.STRING { null = true } } if null { return value.NULL_VALUE, nil } if len(args) == 4 && args[3].Type() != value.NUMBER { return value.NULL_VALUE, nil } f := args[0].Actual().(string) s := args[1].Actual().(string) r := args[2].Actual().(string) re := this.re if re == nil { var err error re, err = regexp.Compile(s) if err != nil { return nil, err } } if len(args) == 3 { return value.NewValue(re.ReplaceAllLiteralString(f, r)), nil } nf := args[3].Actual().(float64) if nf != math.Trunc(nf) { return value.NULL_VALUE, nil } n := int(nf) rv := re.ReplaceAllStringFunc(f, func(m string) string { if n > 0 { n-- return r } else { return m } }) return value.NewValue(rv), nil }
func TestMockIndex(t *testing.T) { s, err := NewDatastore("mock:") if err != nil { t.Fatalf("failed to create store: %v", err) } p, err := s.NamespaceById("p0") if err != nil || p == nil { t.Fatalf("expected namespace p0") } b, err := p.KeyspaceById("b0") if err != nil || b == nil { t.Fatalf("expected keyspace b0") } // Do a scan from keys 4 to 6 with Inclusion set to NEITHER - expect 1 result with key 5 lo := []value.Value{value.NewValue("4")} hi := []value.Value{value.NewValue("6")} span := &datastore.Span{Range: datastore.Range{Inclusion: datastore.NEITHER, Low: lo, High: hi}} items, err := doIndexScan(t, b, span) if err != nil { t.Fatalf("unexpected error in scan: %v", err) } if len(items) != 1 { t.Fatalf("unexpected number of items in scan: %d", len(items)) } if items[0].PrimaryKey != "5" { t.Fatalf("unexpected key in result: %v", items[0].PrimaryKey) } // Do a scan from keys 4 to 6 with Inclusion set to BOTH - expect 3 results span.Range.Inclusion = datastore.BOTH items, err = doIndexScan(t, b, span) if err != nil { t.Fatalf("unexpected error in scan: %v", err) } if len(items) != 3 { t.Fatalf("unexpected number of items in scan: %d", len(items)) } // Do a scan with incorrect range type - expect scan error span.Range.Low = []value.Value{value.NewValue(4.0)} items, err = doIndexScan(t, b, span) }
/* This method returns a string from a start position to the end. It is a substring. If the input argument value type is missing, then return a missing value, and if null return a null value. Loop through all the input values, and check the types. If it is a number type, then check if it is an absolute non floating point number. If not return null value. If any value other than a number or missing, return a null. If the position is negative calculate the actual offset by adding it to the length of the string. If the length of input arguments is 2 or more, it means that the start and end positions are given, hence return a value which is the slice starting from that position until the end if specified. */ func (this *Substr) Apply(context Context, args ...value.Value) (value.Value, error) { null := false if args[0].Type() == value.MISSING { return value.MISSING_VALUE, nil } else if args[0].Type() != value.STRING { null = true } for i := 1; i < len(args); i++ { switch args[i].Type() { case value.MISSING: return value.MISSING_VALUE, nil case value.NUMBER: vf := args[i].Actual().(float64) if vf != math.Trunc(vf) { null = true } default: null = true } } if null { return value.NULL_VALUE, nil } str := args[0].Actual().(string) pos := int(args[1].Actual().(float64)) if pos < 0 { pos = len(str) + pos } if pos < 0 || pos >= len(str) { return value.NULL_VALUE, nil } if len(args) == 2 { return value.NewValue(str[pos:]), nil } length := int(args[2].Actual().(float64)) if length < 0 || pos+length > len(str) { return value.NULL_VALUE, nil } return value.NewValue(str[pos : pos+length]), nil }
/* This method returns the input array with distinct elements. If the input value is of type missing return a missing value, and for all non array values return null. Create a new set and add all distinct values to the set. Return it. */ func (this *ArrayDistinct) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() == value.MISSING { return value.MISSING_VALUE, nil } else if arg.Type() != value.ARRAY { return value.NULL_VALUE, nil } aa := arg.Actual().([]interface{}) set := value.NewSet(len(aa)) for _, a := range aa { set.Add(value.NewValue(a)) } return value.NewValue(set.Actuals()), nil }
/* This method ranges through the array and returns the position of the second value in the array (first value). If the input values are of type missing return a missing value, and for all non array values return null. If not found then return -1. */ func (this *ArrayPosition) Apply(context Context, first, second value.Value) (value.Value, error) { if first.Type() == value.MISSING || second.Type() == value.MISSING { return value.MISSING_VALUE, nil } else if first.Type() != value.ARRAY { return value.NULL_VALUE, nil } fa := first.Actual().([]interface{}) for i, f := range fa { if second.Equals(value.NewValue(f)) { return value.NewValue(float64(i)), nil } } return value.NewValue(float64(-1)), nil }
/* In order to split the strings, range over the input arguments, if its type is missing, return missing. If the argument type is not a string, set boolean null as true. If null is true it indicates that one of the args is not a string and hence return a null value. If not, all input arguments are strings. If there is more than 1 input arg, use the separator and the string to call the split function from the strings package. In the event there is no input then call the Fields method which splits the string using whitespace characters as defined by unicode. This returns a slice of strings. We map it to an interface, convert it to a valid N1QL value and return. */ func (this *Split) Apply(context Context, args ...value.Value) (value.Value, error) { null := false for _, a := range args { if a.Type() == value.MISSING { return value.MISSING_VALUE, nil } else if a.Type() != value.STRING { null = true } } if null { return value.NULL_VALUE, nil } var sa []string if len(args) > 1 { sep := args[1] sa = strings.Split(args[0].Actual().(string), sep.Actual().(string)) } else { sa = strings.Fields(args[0].Actual().(string)) } rv := make([]interface{}, len(sa)) for i, s := range sa { rv[i] = s } return value.NewValue(rv), nil }
/* It returns true if type of the input value is a string value, else false. */ func (this *IsString) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() == value.MISSING || arg.Type() == value.NULL { return arg, nil } return value.NewValue(arg.Type() == value.STRING), nil }
/* This method evaluates the Field using the first and second value and returns the result value. If the second operand type is a missing return a missing value. If it is a string, and the field is case insensitive, then convert the second operand to lower case, range through the fields of the first and compare, each field with the second. When equal, return the value. If the field is case sensitive, use the Field method to directly access the field and return it. For all other types, if the first operand expression is missing, return missing, else return null. */ 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 } } }
/* It returns true if type of the input value is an number value, else false. */ func (this *IsNumber) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() == value.MISSING || arg.Type() == value.NULL { return arg, nil } return value.NewValue(arg.Type() == value.NUMBER), nil }
/* If the input argument type is greater than NULL, we return the complement of its Truth() method's return type. If Null or missing return the argument itself. */ func (this *Not) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() > value.NULL { return value.NewValue(!arg.Truth()), nil } else { return arg, nil } }
/* Generate a Version 4 UUID as specified in RFC 4122, wrap it in a value and return it. The UUID() function may return an error, if so return a nil value UUID with the error. */ func (this *Uuid) Evaluate(item value.Value, context Context) (value.Value, error) { u, err := util.UUID() if err != nil { return nil, err } return value.NewValue(u), nil }
func (this *Prepared) UnmarshalJSON(body []byte) error { var _unmarshalled struct { Operator json.RawMessage `json:"operator"` Signature json.RawMessage `json:"signature"` } var op_type struct { Operator string `json:"#operator"` } err := json.Unmarshal(body, &_unmarshalled) if err != nil { return err } err = json.Unmarshal(_unmarshalled.Operator, &op_type) if err != nil { return err } this.signature = value.NewValue(_unmarshalled.Signature) this.Operator, err = MakeOperator(op_type.Operator, _unmarshalled.Operator) return err }
/* This method evaluates the input value and returns the length based on its type. If the input argument is a missing then return a missing value. Convert it to a valid Go type. If it is a string slice of interfaces or object then return its length cast as a number float64. By default return a null value. */ func (this *PolyLength) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() == value.MISSING { return value.MISSING_VALUE, nil } switch oa := arg.Actual().(type) { case string: return value.NewValue(float64(len(oa))), nil case []interface{}: return value.NewValue(float64(len(oa))), nil case map[string]interface{}: return value.NewValue(float64(len(oa))), nil default: return value.NULL_VALUE, nil } }
/* Returns the shapeof the result expression. If raw is true return the first expression type as string value, as the signature. If raw is false, then create a map, range over the result terms and check if star is set to true to set the alias key to the the expression type. Return this map. */ func (this *Projection) Signature() value.Value { if this.raw { return value.NewValue(this.terms[0].expr.Type().String()) } rv := value.NewValue(make(map[string]interface{}, len(this.terms))) for _, term := range this.terms { if term.star { rv.SetField("*", "*") } else { rv.SetField(term.alias, term.expr.Type().String()) } } return rv }
/* It returns true if type of the input value is a boolean value, else false. */ func (this *IsBoolean) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() == value.MISSING || arg.Type() == value.NULL { return arg, nil } return value.NewValue(arg.Type() == value.BOOLEAN), nil }
/* It returns true if type of the input value is an array value, else false. */ func (this *IsArray) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() == value.MISSING || arg.Type() == value.NULL { return arg, nil } return value.NewValue(arg.Type() == value.ARRAY), nil }
/* It returns true if type of the input value is an object value, else false. */ func (this *IsObject) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() == value.MISSING || arg.Type() == value.NULL { return arg, nil } return value.NewValue(arg.Type() == value.OBJECT), nil }
func (this *urlArgs) getValue(field string) (value.Value, errors.Error) { var val value.Value value_field, err := this.getString(field, "") if err == nil && value_field != "" { val = value.NewValue([]byte(value_field)) } return val, err }
/* Create a new Constant out of an input value interface by calling NewValue and setting the value component of the struct to it. Return a pointer to the Constant structure. */ func NewConstant(val interface{}) Expression { rv := &Constant{ value: value.NewValue(val), } rv.expr = rv return rv }
/* This method returns a pointer to a Formalizer struct with Allowed set to a new map of type string to interface. */ func NewFormalizer() *Formalizer { rv := &Formalizer{ Allowed: value.NewValue(make(map[string]interface{})), } rv.mapper = rv return rv }
/* This method calculates the number of elements in the array. If the input argument is missing return missing value, and if it isnt an array then return a null value. Range through the array and count the values that are'nt null and missing. Return this value. */ func (this *ArrayCount) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() == value.MISSING { return value.MISSING_VALUE, nil } else if arg.Type() != value.ARRAY { return value.NULL_VALUE, nil } count := 0 aa := arg.Actual().([]interface{}) for _, a := range aa { v := value.NewValue(a) if v.Type() > value.NULL { count++ } } return value.NewValue(count), nil }
/* Compute the Final result. If input cumulative value is a zero value return it. Return the length of the set as the count (number of elements in the set). */ func (this *CountDistinct) ComputeFinal(cumulative value.Value, context Context) (c value.Value, e error) { if cumulative == value.ZERO_VALUE { return cumulative, nil } av := cumulative.(value.AnnotatedValue) set := av.GetAttachment("set").(*value.Set) return value.NewValue(set.Len()), nil }
/* This method returns the sum of all the fields in the array. Range through the array and if the type of field is a number then add it to the sum. Return 0 if no number value exists. If the input value is of type missing return a missing value, and for all non array values return null. */ func (this *ArraySum) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() == value.MISSING { return value.MISSING_VALUE, nil } else if arg.Type() != value.ARRAY { return value.NULL_VALUE, nil } sum := 0.0 aa := arg.Actual().([]interface{}) for _, a := range aa { v := value.NewValue(a) if v.Type() == value.NUMBER { sum += v.Actual().(float64) } } return value.NewValue(sum), nil }
/* It returns the argument itself if type of the input value is Null, a value below this (N!QL order) or an Array. Otherwise convert the argument to a valid Go type ang cast it to a slice of interface. */ func (this *ToArray) Apply(context Context, arg value.Value) (value.Value, error) { if arg.Type() <= value.NULL { return arg, nil } else if arg.Type() == value.ARRAY { return arg, nil } return value.NewValue([]interface{}{arg.Actual()}), nil }
/* This method evaluates the less than equal to condition and returns a value representing if the two operands satisfy the condition or not. If either of the input operands are missing, return missing value, and if they are null, then return null value. For all other types call the Collate method and check if it is less than equal to 0 for the two values. If it is, then return true. */ func (this *LE) Apply(context Context, first, second value.Value) (value.Value, error) { if first.Type() == value.MISSING || second.Type() == value.MISSING { return value.MISSING_VALUE, nil } else if first.Type() == value.NULL || second.Type() == value.NULL { return value.NULL_VALUE, nil } return value.NewValue(first.Collate(second) <= 0), nil }