Example #1
0
func (this *FunctionCallLower) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first evaluate the argument
	av, err := this.Operands[0].Expr.Evaluate(item)

	// the spec defines this functin to ONLY operate on strings
	// all other types result in NULL
	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns null
			return dparval.NewValue(nil), nil
		default:
			// any other error return to caller
			return nil, err
		}
	}

	if av.Type() == dparval.STRING {
		avalue := av.Value()
		switch avalue := avalue.(type) {
		case string:
			return dparval.NewValue(strings.ToLower(avalue)), nil
		}
	}
	return dparval.NewValue(nil), nil
}
func TestCount(t *testing.T) {

	dataset := dparval.ValueCollection{
		dparval.NewValue(map[string]interface{}{
			"name":   "marty",
			"status": "alive",
		}),
		dparval.NewValue(map[string]interface{}{
			"name":   "gerald",
			"status": nil,
		}),
		dparval.NewValue(map[string]interface{}{
			"name": "steve",
		}),
	}

	tests := AggregateTestSet{
		// test * (counts all rows)
		{
			NewFunctionCall("COUNT", FunctionArgExpressionList{NewStarFunctionArgExpression()}),
			dparval.NewValue(3.0),
		},
		// test expression (eliminiates null and missing)
		{
			NewFunctionCall("COUNT", FunctionArgExpressionList{NewFunctionArgExpression(NewProperty("status"))}),
			dparval.NewValue(1.0),
		},
	}

	tests.Run(t, dataset)

}
Example #3
0
func (this *FunctionCallCeil) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first evaluate the argument
	av, err := this.Operands[0].Expr.Evaluate(item)

	// the spec defines this functin to ONLY operate on numeric values
	// all other types result in NULL
	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns null
			return dparval.NewValue(nil), nil
		default:
			// any other error return to caller
			return nil, err
		}
	}

	if av.Type() == dparval.NUMBER {
		avalue := av.Value()
		switch avalue := avalue.(type) {
		case float64:
			return dparval.NewValue(math.Ceil(avalue)), nil
		}
	}

	return dparval.NewValue(nil), nil
}
Example #4
0
func (this *OrOperator) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	var rv interface{}
	var re error
	rv = false
	re = nil
	for _, operand := range this.Operands {
		operandVal, err := operand.Evaluate(item)
		if err != nil {
			switch err := err.(type) {
			case *dparval.Undefined:
				rv = nil
				re = err
				continue
			default:
				// any other error should be returned to caller
				return nil, err
			}
		}
		// now interpret the evaluated value in a boolean context
		operandValVal := operandVal.Value()
		operandBoolVal := ValueInBooleanContext(operandValVal)
		if operandBoolVal == true {
			return dparval.NewValue(true), nil
		} else if operandBoolVal == nil && rv == false {
			rv = operandBoolVal
			re = nil
		}
		// if operandBoolVal is true, do nothing
		// rv starts as true, and should never change back to true
	}
	if re != nil {
		return nil, re
	}
	return dparval.NewValue(rv), re
}
Example #5
0
func init() {
	doc := dparval.NewValue(map[string]interface{}{
		"name": "mike",
		"children": []interface{}{
			map[string]interface{}{
				"name": "bob",
			},
			map[string]interface{}{
				"name": "dan",
			},
		},
	})
	doc.SetAttachment("meta", map[string]interface{}{"id": "1"})
	joinerTestData = append(joinerTestData, doc)

	doc = dparval.NewValue(map[string]interface{}{
		"name": "dustin",
		"children": []interface{}{
			map[string]interface{}{
				"name": "mary",
			},
			map[string]interface{}{
				"name": "jane",
			},
		},
	})
	doc.SetAttachment("meta", map[string]interface{}{"id": "2"})
	joinerTestData = append(joinerTestData, doc)
}
Example #6
0
func (vi *viewIndex) ValueCount() (int64, query.Error) {
	indexItemChannel := make(catalog.EntryChannel)
	indexWarnChannel := make(query.ErrorChannel)
	indexErrorChannel := make(query.ErrorChannel)

	go vi.ScanRange(catalog.LookupValue{dparval.NewValue(nil)}, catalog.LookupValue{dparval.NewValue(nil)}, catalog.Both, 0, indexItemChannel, indexWarnChannel, indexErrorChannel)

	var err query.Error
	nullCount := int64(0)
	ok := true
	for ok {
		select {
		case _, ok = <-indexItemChannel:
			if ok {
				nullCount += 1
			}
		case _, ok = <-indexWarnChannel:
			// ignore warnings here
		case err, ok = <-indexErrorChannel:
			if err != nil {
				return 0, err
			}
		}
	}

	totalCount, err := ViewTotalRows(vi.bucket.cbbucket, vi.DDocName(), vi.ViewName(), map[string]interface{}{})
	if err != nil {
		return 0, err
	}

	return totalCount - nullCount, nil

}
Example #7
0
func (this *FunctionCallLength) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first evaluate the argument
	av, err := this.Operands[0].Expr.Evaluate(item)

	// the spec does not define it to operate on missing, so return null
	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns null
			return dparval.NewValue(nil), nil
		default:
			// any other error return to caller
			return nil, err
		}
	}

	// return the length only if the operand is a string
	if av.Type() == dparval.STRING {
		avalue := av.Value()
		switch avalue := avalue.(type) {
		case string:
			return dparval.NewValue(float64(len(avalue))), nil
		}
	}
	return dparval.NewValue(nil), nil
}
Example #8
0
func (this *FunctionCallStrToMillis) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	av, err := this.Operands[0].Expr.Evaluate(item)

	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns null
			return dparval.NewValue(nil), nil
		default:
			// any other error return to caller
			return nil, err
		}
	}

	val := av.Value()

	switch val := val.(type) {
	case string:
		t, err := strToTime(val)
		if err != nil {
			return nil, fmt.Errorf("Date not in a recognized format.")
		}
		return dparval.NewValue(timeToMillis(t)), nil
	default:
		return dparval.NewValue(nil), nil
	}
}
Example #9
0
func (this *FunctionCallMin) UpdateAggregate(group *dparval.Value, item *dparval.Value) error {
	aggregate_key := this.Key()
	currentVal, err := aggregateValue(group, aggregate_key)
	if err != nil {
		return fmt.Errorf("group defaults not set correctly")
	}

	if this.Operands[0].Expr != nil {
		val, err := this.Operands[0].Expr.Evaluate(item)
		val, err = eliminateNullMissing(val, err)
		if err != nil {
			return err
		}
		if val != nil {

			nextVal := val.Value()
			currVal := currentVal.Value()

			if currVal == nil {
				// any value is greater than nil (we eliminated null/mising already)
				setAggregateValue(group, aggregate_key, dparval.NewValue(nextVal))
			} else {
				// check to see
				comp := CollateJSON(nextVal, currVal)
				if comp < 0 {
					setAggregateValue(group, aggregate_key, dparval.NewValue(nextVal))
				}
			}
		}
	}
	return nil
}
Example #10
0
func (this *CollectionAnyOperator) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first evaluate the over
	ov, err := this.Over.Evaluate(item)
	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// spec says return false
			return dparval.NewValue(false), nil
		default:
			// any other error should be returned to caller
			return nil, err
		}
	}

	// see if we're dealing with an array
	if ov.Type() == dparval.ARRAY {
		// by accessing the array contents this way
		// we avoid parsing it
		ok := true
		index := 0
		for ok {
			inner, err := ov.Index(index)
			index = index + 1
			if err != nil {
				switch err := err.(type) {
				case *dparval.Undefined:
					ok = false
				default:
					return nil, err
				}
			} else {
				// duplicate the existing context
				innerContext := item.Duplicate()
				// add this object named as the alias
				innerContext.SetPath(this.As, inner)
				// now evaluate the condition in this new context
				innerResult, err := this.Condition.Evaluate(innerContext)
				if err != nil {
					switch err := err.(type) {
					case *dparval.Undefined:
						// this is not true, keep trying
						continue
					default:
						// any other error should be returned to caller
						return nil, err
					}
				}
				innerResultVal := innerResult.Value()
				// check to see if this value is true
				innerBoolResult := ValueInBooleanContext(innerResultVal)
				if innerBoolResult == true {
					return dparval.NewValue(true), nil
				}
			}
		}
		return dparval.NewValue(false), nil
	}
	return dparval.NewValue(false), nil
}
Example #11
0
func (this *FunctionCallAvg) UpdateAggregate(group *dparval.Value, item *dparval.Value) error {
	aggregate_key := this.Key()
	// avg needs to track sum and count to produce its value
	count_key := aggregate_key + "_count"
	sum_key := aggregate_key + "_sum"
	_, err := aggregateValue(group, aggregate_key)
	if err != nil {
		return fmt.Errorf("group defaults not set correctly")
	}

	currentCount, err := aggregateValue(group, count_key)
	if err != nil {
		return fmt.Errorf("group defaults not set correctly")
	}

	currentSum, err := aggregateValue(group, sum_key)
	if err != nil {
		return fmt.Errorf("group defaults not set correctly")
	}

	if this.Operands[0].Expr != nil {
		val, err := this.Operands[0].Expr.Evaluate(item)
		val, err = eliminateNonNumber(val, err)
		if err != nil {
			return err
		}
		if val != nil {
			nextVal := val.Value()
			nextValFloat := nextVal.(float64)

			if currentCount.Type() == dparval.NUMBER {
				currentCountVal := currentCount.Value()
				currentCountFloat, ok := currentCountVal.(float64)
				if !ok {
					return fmt.Errorf("count value not a number")
				}
				if currentSum.Type() == dparval.NUMBER {
					currentSumVal := currentSum.Value()
					currentSumFloat, ok := currentSumVal.(float64)
					if !ok {
						return fmt.Errorf("sum value not a number")
					}
					nextCountFloat := currentCountFloat + 1
					nextSumFloat := currentSumFloat + nextValFloat
					nextVal := nextSumFloat / nextCountFloat

					setAggregateValue(group, count_key, dparval.NewValue(nextCountFloat))
					setAggregateValue(group, sum_key, dparval.NewValue(nextSumFloat))
					setAggregateValue(group, aggregate_key, dparval.NewValue(nextVal))
				}
			}

		}
	}
	return nil
}
Example #12
0
func (this *FunctionCallMax) DefaultAggregate(group *dparval.Value) error {
	aggregate_key := this.Key()
	currentVal, err := aggregateValue(group, aggregate_key)
	if err != nil {
		currentVal = dparval.NewValue(nil)
		// store this, so that even if all values are eliminated we return null
		setAggregateValue(group, aggregate_key, dparval.NewValue(currentVal))
	}
	return nil
}
Example #13
0
func (this *FunctionCallTrunc) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first evaluate the argument
	av, err := this.Operands[0].Expr.Evaluate(item)
	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns null
			return dparval.NewValue(nil), nil
		default:
			// any other error return to caller
			return nil, err
		}
	}

	precision := 0
	if len(this.Operands) > 1 {
		// evaluate the second argument
		pv, err := this.Operands[1].Expr.Evaluate(item)

		// we need precision to be an integer
		if err != nil {
			switch err := err.(type) {
			case *dparval.Undefined:
				// undefined returns null
				return dparval.NewValue(nil), nil
			default:
				// any other error return to caller
				return nil, err
			}
		}

		if pv.Type() == dparval.NUMBER {
			pvalue := pv.Value()
			switch pvalue := pvalue.(type) {
			case float64:
				precision = int(pvalue)
			}
		} else {
			// FIXME log warning here?
			return dparval.NewValue(nil), nil
		}

	}

	// the spec defines this functin to ONLY operate on numeric values
	// all other types result in NULL
	if av.Type() == dparval.NUMBER {
		avalue := av.Value()
		switch avalue := avalue.(type) {
		case float64:
			return dparval.NewValue(TruncateFloat(avalue, precision)), nil
		}
	}
	return dparval.NewValue(nil), nil
}
Example #14
0
func (this *FunctionCallSplit) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first evaluate the arguments
	av, err := this.Operands[0].Expr.Evaluate(item)

	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns null
			return dparval.NewValue(nil), nil
		default:
			// any other error return to caller
			return nil, err
		}

		// FIXME warn if arguments were wrong type?
		if av.Type() != dparval.STRING {
			return dparval.NewValue(nil), nil
		}
	}

	var sep *dparval.Value = nil
	if len(this.Operands) > 1 {
		sep, err = this.Operands[1].Expr.Evaluate(item)
		if err != nil {
			switch err := err.(type) {
			case *dparval.Undefined:
				// undefined returns null
				return dparval.NewValue(nil), nil
			default:
				// any other error return to caller
				return nil, err
			}
		}

		// FIXME warn if arguments were wrong type?
		if sep.Type() != dparval.STRING {
			return dparval.NewValue(nil), nil
		}
	}

	var sa []string
	if sep != nil {
		sa = strings.Split(av.Value().(string),
			sep.Value().(string))
	} else {
		sa = strings.Fields(av.Value().(string))
	}

	rv := make([]interface{}, len(sa))
	for i, s := range sa {
		rv[i] = s
	}

	return dparval.NewValue(rv), nil
}
Example #15
0
func (this *FunctionCallNowMillis) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first retrieve the query object
	q := item.GetAttachment("query")

	query, ok := q.(network.Query)
	if !ok {
		return dparval.NewValue(nil), nil
	}

	return dparval.NewValue(timeToMillis(query.StartTime())), nil
}
Example #16
0
func (this *InOperator) Evaluate(context *dparval.Value) (*dparval.Value, error) {

	false_result := dparval.NewValue(false)
	true_result := dparval.NewValue(true)

	lv, err := this.Left.Evaluate(context)
	if err != nil {
		return nil, err
	}

	rv, err := this.Right.Evaluate(context)
	if err != nil {
		return nil, err
	}

	lvalue := lv.Value()
	if rv.Type() == dparval.ARRAY {
		ok := true
		index := 0
		for ok {
			inner, err := rv.Index(index)
			index = index + 1
			if err != nil {
				switch err := err.(type) {
				case *dparval.Undefined:
					ok = false
				default:
					return nil, err
				}
			} else {
				if lv.Type() != inner.Type() {
					continue
				} else {
					iv := inner.Value()
					switch lvalue := lvalue.(type) {
					case string:
						if lvalue == iv {
							return true_result, nil
						}
					default:
						if reflect.DeepEqual(lvalue, iv) == true {
							return true_result, nil
						}
					}
				}
			}
		}
	}

	return false_result, nil
}
// sum and avg have same elimination rules, test them together
func TestSumAndAvg(t *testing.T) {

	dataset := dparval.ValueCollection{
		dparval.NewValue(map[string]interface{}{
			"name":  "marty",
			"score": 20.0,
		}),
		dparval.NewValue(map[string]interface{}{
			"name":  "gerald",
			"score": nil,
		}),
		dparval.NewValue(map[string]interface{}{
			"name": "steve",
		}),
		dparval.NewValue(map[string]interface{}{
			"name":  "siri",
			"score": "thirty",
		}),
		dparval.NewValue(map[string]interface{}{
			"name":  "deep",
			"score": 10.0,
		}),
		dparval.NewValue(map[string]interface{}{
			"name":  "ketaki",
			"score": "false",
		}),
		dparval.NewValue(map[string]interface{}{
			"name":  "pratap",
			"score": []interface{}{5.5},
		}),
		dparval.NewValue(map[string]interface{}{
			"name":  "karen",
			"score": map[string]interface{}{"score": 5.5},
		}),
	}

	tests := AggregateTestSet{
		// test expression (eliminiates null and missing)
		{
			NewFunctionCall("SUM", FunctionArgExpressionList{NewFunctionArgExpression(NewProperty("score"))}),
			dparval.NewValue(30.0),
		},
		{
			NewFunctionCall("AVG", FunctionArgExpressionList{NewFunctionArgExpression(NewProperty("score"))}),
			dparval.NewValue(15.0),
		},
	}

	tests.Run(t, dataset)

}
Example #18
0
func init() {
	doc := dparval.NewValue(map[string]interface{}{"name": "mike", "age": 100.0})
	doc.SetAttachment("meta", map[string]interface{}{"id": "1"})
	testData = append(testData, doc)

	doc = dparval.NewValue(map[string]interface{}{"name": "dustin"})
	doc.SetAttachment("meta", map[string]interface{}{"id": "1"})
	testData = append(testData, doc)

	doc = dparval.NewValue(map[string]interface{}{"name": "bob", "age": nil})
	doc.SetAttachment("meta", map[string]interface{}{"id": "1"})
	testData = append(testData, doc)

	doc = dparval.NewValue(map[string]interface{}{"name": "marty", "age": 99.0})
	doc.SetAttachment("meta", map[string]interface{}{"id": "1"})
	testData = append(testData, doc)

	doc = dparval.NewValue(map[string]interface{}{"name": "steve", "age": 200.0})
	doc.SetAttachment("meta", map[string]interface{}{"id": "2"})
	testData = append(testData, doc)

	doc = dparval.NewValue(map[string]interface{}{"name": "gerald", "age": 175.0})
	doc.SetAttachment("meta", map[string]interface{}{"id": "3"})
	testData = append(testData, doc)

	doc = dparval.NewValue(map[string]interface{}{"name": "siri", "age": 74.0})
	doc.SetAttachment("meta", map[string]interface{}{"id": "4"})
	testData = append(testData, doc)

	doc = dparval.NewValue(map[string]interface{}{"name": "ali", "age": 100.0})
	doc.SetAttachment("meta", map[string]interface{}{"id": "1"})
	testData = append(testData, doc)
}
Example #19
0
func (this *FunctionCallTypeName) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first evaluate the argument
	av, err := this.Operands[0].Expr.Evaluate(item)

	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns "missing"
			return dparval.NewValue("missing"), nil
		default:
			// any other error return to caller
			return nil, err
		}
	}

	switch av.Type() {
	case dparval.NUMBER:
		return dparval.NewValue("number"), nil
	case dparval.STRING:
		return dparval.NewValue("string"), nil
	case dparval.BOOLEAN:
		return dparval.NewValue("boolean"), nil
	case dparval.ARRAY:
		return dparval.NewValue("array"), nil
	case dparval.OBJECT:
		return dparval.NewValue("object"), nil
	case dparval.NULL:
		return dparval.NewValue("null"), nil
	default:
		return dparval.NewValue(nil), nil
	}
}
Example #20
0
func (this *FunctionCallDatePartMillis) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first evaluate the argument (part)
	av, err := this.Operands[0].Expr.Evaluate(item)

	// the part must be a string, undefined results in ull
	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns null
			return dparval.NewValue(nil), nil
		default:
			// any other error return to caller
			return nil, err
		}
	}

	if av.Type() == dparval.STRING {
		part := av.Value()
		switch part := part.(type) {
		case string:
			// now look at the second argument
			dv, err := this.Operands[1].Expr.Evaluate(item)

			// the part must be a string, undefined results in null
			if err != nil {
				switch err := err.(type) {
				case *dparval.Undefined:
					// undefined returns null
					return dparval.NewValue(nil), nil
				default:
					// any other error return to caller
					return nil, err
				}
			}

			if dv.Type() == dparval.NUMBER {
				millis := dv.Value()
				switch millis := millis.(type) {
				case float64:
					t := time.Unix(0, int64(millis)*1000000)
					return datePart(part, t)
				}
			}

		}
	}

	return dparval.NewValue(nil), nil
}
Example #21
0
func (this *FunctionCallArrayAgg) DefaultAggregate(group *dparval.Value) error {
	aggregate_key := this.Key()
	if this.Distinct {
		aggregate_unique_key := aggregate_key + "_unique"
		uniqueness_map := dparval.NewValue(map[string]interface{}{})
		setAggregateValue(group, aggregate_unique_key, uniqueness_map)
	}
	currentVal, err := aggregateValue(group, aggregate_key)
	if err != nil {
		currentVal = dparval.NewValue([]interface{}{})
		// store this, so that even if all values are eliminated we return null
		setAggregateValue(group, aggregate_key, dparval.NewValue(currentVal))
	}
	return nil
}
Example #22
0
func (this *FunctionCallLTrim) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	// first evaluate the argument
	av, err := this.Operands[0].Expr.Evaluate(item)

	// the spec defines this functin to ONLY operate on strings
	// all other types result in NULL
	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns null
			return dparval.NewValue(nil), nil
		default:
			// any other error return to caller
			return nil, err
		}
	}

	// evaluate the second argument
	cutlist, err := this.Operands[1].Expr.Evaluate(item)
	// the cut list MUST be a string, otherwise return null
	if err != nil {
		switch err := err.(type) {
		case *dparval.Undefined:
			// undefined returns null
			return dparval.NewValue(nil), nil
		default:
			// any other error return to caller
			return nil, err
		}
	}

	if av.Type() == dparval.STRING {
		if cutlist.Type() == dparval.STRING {
			avalue := av.Value()
			switch avalue := avalue.(type) {
			case string:
				cutvlal := cutlist.Value()
				switch cutvlal := cutvlal.(type) {
				case string:
					return dparval.NewValue(strings.TrimLeft(avalue, cutvlal)), nil
				}
			}
		}

	}
	// FIXME warn if cutlist wasnt string?
	return dparval.NewValue(nil), nil
}
Example #23
0
func (this *FunctionCallGreatest) Evaluate(item *dparval.Value) (*dparval.Value, error) {

	var rv interface{} = nil

	for _, arg := range this.Operands {
		av, err := arg.Expr.Evaluate(item)
		if err != nil {
			switch err := err.(type) {
			case *dparval.Undefined:
				// undefined doesn't change the result
			default:
				// any other error return to caller
				return nil, err
			}
		}

		avalue := av.Value()

		// now compare this value with rv
		compres := CollateJSON(avalue, rv)
		if compres > 0 {
			rv = avalue
		}
	}

	return dparval.NewValue(rv), nil
}
Example #24
0
func (this *FunctionCallSum) UpdateAggregate(group *dparval.Value, item *dparval.Value) error {
	aggregate_key := this.Key()
	currentVal, err := aggregateValue(group, aggregate_key)
	if err != nil {
		return fmt.Errorf("group defaults not set correctly")
	}

	if this.Operands[0].Expr != nil {
		val, err := this.Operands[0].Expr.Evaluate(item)
		val, err = eliminateNonNumber(val, err)
		if err != nil {
			return err
		}
		if val != nil {
			nextVal := val.Value()
			if currentVal.Type() == dparval.NUMBER {
				currentValVal := currentVal.Value()
				currentFloat, ok := currentValVal.(float64)
				if !ok {
					return fmt.Errorf("count value not a number")
				}
				nextVal = nextVal.(float64) + currentFloat
			}
			setAggregateValue(group, aggregate_key, dparval.NewValue(nextVal))
		}
	}
	return nil
}
func (this *FunctionCallFirstNum) Evaluate(item *dparval.Value) (*dparval.Value, error) {
	for _, arg := range this.Operands {
		av, err := arg.Expr.Evaluate(item)
		if err != nil {
			switch err := err.(type) {
			case *dparval.Undefined:
				// do NOT return missing
				continue
			default:
				// any other error return to caller
				return nil, err
			}
		}

		if av.Type() == dparval.NUMBER {
			num := av.Value().(float64)
			if !math.IsNaN(num) && !math.IsInf(num, 1) && !math.IsInf(num, -1) {
				return av, nil
			} else {
				continue
			}
		} else {
			continue
		}
	}

	// if all values were +/-Infinity or NaN return NULL
	return dparval.NewValue(nil), nil
}
Example #26
0
func (this *BinaryOperator) compare(context *dparval.Value) (*dparval.Value, error) {
	lv, rv, err := this.EvaluateBoth(context)
	if err != nil {
		return nil, err
	}

	// if either side is NULL, the result is NULL
	if lv.Type() == dparval.NULL || rv.Type() == dparval.NULL {
		return nil, nil
	}

	lvalue := lv.Value()
	rvalue := rv.Value()

	// if we got this far, we evaluated both sides
	// there were no errors, and neither side was NULL or MISSING
	// now check types (types must be the same)
	ltype := collationType(lvalue)
	rtype := collationType(rvalue)
	// ugly fixups for boolean (returns different values for true/false)
	if ltype == 2 {
		// fixup for boolean type
		ltype = 1
	}
	if rtype == 2 {
		rtype = 1
	}

	if ltype != rtype {
		return nil, &TypeMismatch{ltype, rtype}
	}

	return dparval.NewValue(float64(CollateJSON(lvalue, rvalue))), nil
}
Example #27
0
func (this *Grouper) processItem(item *dparval.Value) bool {
	groupkey := dparval.NewValue(make([]interface{}, len(this.GroupBy)))
	for i, groupElement := range this.GroupBy {
		groupkeyval, err := this.Base.Evaluate(groupElement, item)
		if err == nil {
			groupkey.SetIndex(i, groupkeyval)
		} else {
			switch err := err.(type) {
			case *dparval.Undefined:
				// FIXME better way?
				groupkey.SetIndex(i, "__tuqtng__MISSING__")
			default:
				return this.Base.SendError(query.NewError(err, "error evaluating group by"))
			}
		}
	}
	// FIXME slow, but lets me use map to match same groups
	groupkeybytes := groupkey.Bytes()
	groupkeystring := string(groupkeybytes)

	group, ok := this.groups[groupkeystring]
	if !ok {
		// new group
		this.groups[groupkeystring] = item
		group = item
		this.setGroupDefaults(group)
	}
	this.updateGroup(group, item)
	return true
}
Example #28
0
// CompositeKeysToArray convert list of composite keys to JSON array of
// values.
func CompositeKeysToArray(keys []*dparval.Value) []byte {
	secKey := dparval.NewValue(make([]interface{}, len(keys)))
	for i, key := range keys {
		secKey.SetIndex(i, key)
	}
	return secKey.Bytes()
}
Example #29
0
// N1QLTransform will use compile list of expression from N1QL's DDL
// statement and evaluate a document using them to return a secondary
// key as JSON object.
func N1QLTransform(document []byte, cExprs []interface{}) ([]byte, error) {
	arrValue := make([]*dparval.Value, 0, len(cExprs))
	for _, cExpr := range cExprs {
		expr := cExpr.(ast.Expression)
		// TODO: CBIDXT-133: needs to send nil secondary keys to indexer
		key, err := expr.Evaluate(dparval.NewValueFromBytes(document))
		if err != nil {
			return nil, nil
		}
		arrValue = append(arrValue, key)
	}

	if len(arrValue) > 1 {
		secKey := dparval.NewValue(make([]interface{}, len(cExprs)))
		for i, key := range arrValue {
			secKey.SetIndex(i, key)
		}
		return secKey.Bytes(), nil // [ seckey1, seckey2, ... ]

	} else if len(arrValue) == 1 {
		return arrValue[0].Bytes(), nil // seckey1

	}
	return nil, ErrorEmptyN1QLExpression
}
Example #30
0
func TestDotMember(t *testing.T) {

	sampleContext := map[string]interface{}{
		"address": map[string]interface{}{
			"street": "1 recursive function",
		},
		"contact": map[string]interface{}{
			"name": map[string]interface{}{
				"first": "n1ql",
				"last":  "couchbase",
				"all": []interface{}{
					"n1ql",
					"couchbase",
				},
			},
		},
		"friends": []interface{}{
			"a",
			"b",
			"c",
		},
		"name": "bob",
	}
	sampleMeta := map[string]interface{}{
		"id": "first",
	}

	tests := ExpressionTestSet{
		{NewDotMemberOperator(NewProperty("address"), NewProperty("street")), "1 recursive function", nil},
		{NewDotMemberOperator(NewDotMemberOperator(NewProperty("contact"), NewProperty("name")), NewProperty("first")), "n1ql", nil},
		{NewDotMemberOperator(NewDotMemberOperator(NewProperty("contact"), NewProperty("name")), NewProperty("last")), "couchbase", nil},

		{NewDotMemberOperator(NewProperty("address"), NewProperty("city")), nil, &dparval.Undefined{"city"}},
		{NewDotMemberOperator(NewDotMemberOperator(NewProperty("contact"), NewProperty("name")), NewProperty("middle")), nil, &dparval.Undefined{"middle"}},
		{NewDotMemberOperator(NewDotMemberOperator(NewProperty("contact"), NewProperty("namez")), NewProperty("first")), nil, &dparval.Undefined{"namez"}},

		{NewDotMemberOperator(NewProperty("name"), NewProperty("city")), nil, &dparval.Undefined{"city"}},

		{NewBracketMemberOperator(NewProperty("friends"), NewLiteralNumber(0.0)), "a", nil},
		{NewBracketMemberOperator(NewProperty("friends"), NewLiteralNumber(1.0)), "b", nil},
		{NewBracketMemberOperator(NewProperty("friends"), NewLiteralNumber(2.0)), "c", nil},
		{NewBracketMemberOperator(NewProperty("friends"), NewLiteralNumber(-1.0)), nil, &dparval.Undefined{}},
		{NewBracketMemberOperator(NewProperty("friends"), NewLiteralNumber(10.0)), nil, &dparval.Undefined{}},

		{NewBracketMemberOperator(NewProperty("foo"), NewLiteralNumber(10.0)), nil, &dparval.Undefined{"foo"}},
		{NewBracketMemberOperator(NewProperty("friends"), NewProperty("bar")), nil, &dparval.Undefined{"bar"}},

		//compound test
		{NewBracketMemberOperator(NewDotMemberOperator(NewDotMemberOperator(NewProperty("contact"), NewProperty("name")), NewProperty("all")), NewLiteralNumber(0.0)), "n1ql", nil},

		// test using bracket member on object instead of array
		{NewBracketMemberOperator(NewProperty("address"), NewLiteralString("street")), "1 recursive function", nil},
	}

	context := dparval.NewValue(sampleContext)
	context.SetAttachment("meta", sampleMeta)

	tests.RunWithItem(t, context)

}