Beispiel #1
0
/*
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).Truth() {
		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)).Truth() {
				rv.SetField(k, _JSON_SIGNATURE)
			}
		} else {
			rv.SetField(k, v)
		}
	}

	return rv
}
Beispiel #2
0
/*
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
}
Beispiel #3
0
func BenchmarkN1QLCollateMap(b *testing.B) {
	v := qv.NewValue(testcases[0].text)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.Collate(qv.NewValue(testcases[0].text))
	}
}
Beispiel #4
0
/*
It returns a string based on the input expr value. Values
missing, null and strings return themselves. False, true
(boolean) and numbers return their string representation.
This is done using the Sprint method defined in fmt for Go.
All other values map to null.
*/
func (this *ToString) Apply(context Context, arg value.Value) (value.Value, error) {
	switch arg.Type() {
	case value.MISSING, value.NULL, value.STRING:
		return arg, nil
	case value.BOOLEAN:
		return value.NewValue(fmt.Sprint(arg.Actual())), nil
	case value.NUMBER:
		f := arg.Actual().(float64)
		if f == -0 {
			f = 0
		}

		s := strconv.FormatFloat(f, 'f', -1, 64)
		return value.NewValue(s), nil
	case value.BINARY:
		raw, ok := arg.Actual().([]byte)
		if !ok {
			return value.NULL_VALUE, nil
		}

		s := string(raw)
		return value.NewValue(s), nil
	default:
		return value.NULL_VALUE, nil
	}
}
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)
	}
}
Beispiel #6
0
/*
This method removes all the occurences of the second value from the
first array value.
*/
func (this *ArrayRemove) Apply(context Context, first, second value.Value) (value.Value, error) {
	if first.Type() == value.MISSING {
		return first, nil
	}

	if first.Type() != value.ARRAY {
		return value.NULL_VALUE, nil
	}

	if second.Type() <= value.NULL {
		return first, nil
	}

	fa := first.Actual().([]interface{})
	if len(fa) == 0 {
		return first, nil
	}

	ra := make([]interface{}, 0, len(fa))
	for _, f := range fa {
		if !second.Equals(value.NewValue(f)).Truth() {
			ra = append(ra, f)
		}
	}

	return value.NewValue(ra), nil
}
Beispiel #7
0
/*
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).Truth() {
			ra = append(ra, v2)
		} else {
			ra = append(ra, v)
		}
	}

	return value.NewValue(ra), nil
}
Beispiel #8
0
func (this *All) EvaluateForIndex(item value.Value, context Context) (value.Value, value.Values, error) {
	val, vals, err := this.array.EvaluateForIndex(item, context)
	if err != nil {
		return val, vals, err
	}

	if vals != nil {
		return nil, vals, nil
	}

	var rv value.Values
	act := val.Actual()
	switch act := act.(type) {
	case []interface{}:
		rv = make(value.Values, len(act))
		for i, a := range act {
			rv[i] = value.NewValue(a)
		}
	case nil:
		if val.Type() == value.NULL {
			rv = _NULL_ARRAY
		}
		// Else MISSING, return rv=nil
	default:
		// Coerce scalar into array
		rv = value.Values{value.NewValue(act)}
	}

	return nil, rv, nil
}
Beispiel #9
0
func (this *Any) 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, err := this.satisfies.Evaluate(cv, context)
		if err != nil {
			return nil, err
		}

		if sv.Truth() {
			return value.NewValue(true), nil
		}
	}

	return value.NewValue(false), nil
}
Beispiel #10
0
func TestObjectRemove_remove(t *testing.T) {

	/* tests insert of value in array at start */
	e1 := NewConstant(value.NewValue(map[string]interface{}{"f1": 1, "f2": 2}))
	e2 := NewConstant("f2")
	er := value.NewValue(map[string]interface{}{"f1": 1})
	testObjectRemove(e1, e2, er, t)
}
Beispiel #11
0
func BenchmarkN1QLCollateFloat(b *testing.B) {
	jsonb := []byte(`1234567890.001234556`)
	v := qv.NewValue(jsonb)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.Collate(qv.NewValue(jsonb))
	}
}
Beispiel #12
0
func TestObjectAdd_remove(t *testing.T) {

	/* tests insert of value in array at start */
	e1 := NewConstant(value.NewValue(map[string]interface{}{"f1": 1, "f2": 2}))
	e2 := NewConstant("f2")
	e3 := NewConstant(value.MISSING_VALUE)
	er := value.NewValue(value.NULL_VALUE)
	testObjectAdd(e1, e2, e3, er, false, t)
}
Beispiel #13
0
func BenchmarkN1QLCollateArray(b *testing.B) {
	jsonb := []byte(
		`[123456789, 123456789.1234567879, "hello world", true, false, null]`)
	v := qv.NewValue(jsonb)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.Collate(qv.NewValue(jsonb))
	}
}
Beispiel #14
0
func TestObjectPut_replace(t *testing.T) {

	/* tests insert of value in array at start */
	e1 := NewConstant(value.NewValue(map[string]interface{}{"f1": 1, "f2": 2}))
	e2 := NewConstant("f2")
	e3 := NewConstant(3)
	er := value.NewValue(map[string]interface{}{"f1": 1, "f2": 3})
	testObjectPut(e1, e2, e3, er, t)
}
Beispiel #15
0
/*
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
}
Beispiel #16
0
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)
}
Beispiel #17
0
/*
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
}
Beispiel #18
0
/*
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
}
Beispiel #19
0
/*
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
	}
}
Beispiel #20
0
func preparedSequence(t *testing.T, name string, stmt string) {
	// Verify a sequence of requests:

	// { "prepared": "name" }  fails with "no such name" error
	doNoSuchPrepared(t, name)

	// { "statement": "prepare name as <<N1QL statement>>" }  succeeds
	doPrepare(t, name, stmt)

	// { "prepared": "name" }  succeeds
	doJsonRequest(t, map[string]interface{}{
		"prepared": name,
	})

	prepared, _ := plan.GetPrepared(value.NewValue(name))
	if prepared == nil {
		t.Errorf("Expected to resolve prepared statement with name %v", name)
		return
	}

	// { "prepared": "name", "encoded_plan": "<<encoded plan>>" }  succeeds
	doJsonRequest(t, map[string]interface{}{
		"prepared":     name,
		"encoded_plan": prepared.EncodedPlan(),
	})

}
Beispiel #21
0
/*
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)).Truth() {
			return value.NewValue(float64(i)), nil
		}
	}

	return value.NewValue(float64(-1)), nil
}
Beispiel #22
0
/*
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
}
Beispiel #23
0
/*
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
}
Beispiel #24
0
/*
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
}
Beispiel #25
0
/*
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
}
Beispiel #26
0
/*
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
}
Beispiel #27
0
/*
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
}
Beispiel #28
0
/*
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
		}
	}
}
Beispiel #29
0
func (this *InferKeyspace) UnmarshalJSON(body []byte) error {
	var _unmarshalled struct {
		_      string                  `json:"#operator"`
		Keysp  string                  `json:"keyspace"`
		Namesp string                  `json:"namespace"`
		Using  datastore.InferenceType `json:"using"`
		With   json.RawMessage         `json:"with"`
	}

	err := json.Unmarshal(body, &_unmarshalled)
	if err != nil {
		return err
	}

	this.keyspace, err = datastore.GetKeyspace(_unmarshalled.Namesp, _unmarshalled.Keysp)
	if err != nil {
		return err
	}

	ksref := algebra.NewKeyspaceRef(_unmarshalled.Namesp, _unmarshalled.Keysp, "")

	var with value.Value
	if len(_unmarshalled.With) > 0 {
		with = value.NewValue(_unmarshalled.With)
	}

	this.node = algebra.NewInferKeyspace(ksref, _unmarshalled.Using, with)
	return nil
}
Beispiel #30
0
func (this *Prepared) UnmarshalJSON(body []byte) error {
	var _unmarshalled struct {
		Operator    json.RawMessage `json:"operator"`
		Signature   json.RawMessage `json:"signature"`
		Name        string          `json:"name"`
		EncodedPlan string          `json:"encoded_plan"`
		Text        string          `json:"text"`
	}

	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.name = _unmarshalled.Name
	this.encoded_plan = _unmarshalled.EncodedPlan
	this.text = _unmarshalled.Text
	this.Operator, err = MakeOperator(op_type.Operator, _unmarshalled.Operator)

	return err
}