func DivideOperator(elems []*parser.Value, fields []string, point *protocol.Point) (*protocol.FieldValue, error) { leftValue, err := GetValue(elems[0], fields, point) if err != nil { return nil, err } rightValues, err := GetValue(elems[1], fields, point) if err != nil { return nil, err } left, right, valueType := common.CoerceValues(leftValue, rightValues) switch valueType { case common.TYPE_DOUBLE: value := left.(float64) / right.(float64) return &protocol.FieldValue{DoubleValue: &value}, nil case common.TYPE_INT: r := right.(int64) // prevent integer division by zero (i.e., panic) if r == 0 { l := left.(int64) var value float64 if l == 0 { value = math.NaN() } else { value = math.Inf(1) } return &protocol.FieldValue{DoubleValue: &value}, nil } else { value := left.(int64) / r return &protocol.FieldValue{Int64Value: &value}, nil } } return nil, fmt.Errorf("/ operator doesn't work with %v types", valueType) }
func EqualityOperator(leftValue, rightValue *protocol.FieldValue) (OperatorResult, error) { v1, v2, cType := common.CoerceValues(leftValue, rightValue) switch cType { case common.TYPE_STRING: if v1.(string) == v2.(string) { return MATCH, nil } return NO_MATCH, nil case common.TYPE_INT: if v1.(int64) == v2.(int64) { return MATCH, nil } return NO_MATCH, nil case common.TYPE_DOUBLE: if v1.(float64) == v2.(float64) { return MATCH, nil } return NO_MATCH, nil case common.TYPE_BOOL: if v1.(bool) == v2.(bool) { return MATCH, nil } return NO_MATCH, nil default: return INVALID, nil } }
func InOperator(leftValue *protocol.FieldValue, rightValue []*protocol.FieldValue) (OperatorResult, error) { for _, v := range rightValue { v1, v2, cType := common.CoerceValues(leftValue, v) var result bool switch cType { case common.TYPE_STRING: result = v1.(string) == v2.(string) case common.TYPE_INT: result = v1.(int64) == v2.(int64) case common.TYPE_DOUBLE: result = v1.(float64) == v2.(float64) case common.TYPE_BOOL: result = v1.(bool) == v2.(bool) default: return INVALID, nil } if result { return MATCH, nil } } return NO_MATCH, nil }
func RegexMatcherOperator(leftValue, rightValue *protocol.FieldValue) (OperatorResult, error) { v1, v2, cType := common.CoerceValues(leftValue, rightValue) switch cType { case common.TYPE_STRING: // TODO: assume that the regex is valid if ok, _ := regexp.MatchString(v2.(string), v1.(string)); ok { return MATCH, nil } return NO_MATCH, nil default: return INVALID, nil } }
func MultiplyOperator(elems []*parser.Value, fields []string, point *protocol.Point) (*protocol.FieldValue, error) { leftValue, err := GetValue(elems[0], fields, point) if err != nil { return nil, err } rightValues, err := GetValue(elems[1], fields, point) if err != nil { return nil, err } left, right, valueType := common.CoerceValues(leftValue, rightValues) switch valueType { case common.TYPE_DOUBLE: value := left.(float64) * right.(float64) return &protocol.FieldValue{DoubleValue: &value}, nil case common.TYPE_INT: value := left.(int64) * right.(int64) return &protocol.FieldValue{Int64Value: &value}, nil } return nil, fmt.Errorf("* operator doesn't work with %v types", valueType) }