diff --git a/pkg/interpreter/interpreter.go b/pkg/interpreter/interpreter.go index 0cd0c19..f1a8f8b 100644 --- a/pkg/interpreter/interpreter.go +++ b/pkg/interpreter/interpreter.go @@ -121,24 +121,36 @@ func (intr *treeInterpreter) execute(node parsing.ASTNode, value interface{}, fu case parsing.TOKNE: return !util.ObjsEqual(left, right), nil } - leftNum, ok := util.ToNumber(left) - if !ok { - return nil, nil - } - rightNum, ok := util.ToNumber(right) - if !ok { - return nil, nil + if leftStr, ok := left.(string); ok { + if rightStr, ok := right.(string); ok { + switch node.Value { + case parsing.TOKGT: + return leftStr > rightStr, nil + case parsing.TOKGTE: + return leftStr >= rightStr, nil + case parsing.TOKLT: + return leftStr < rightStr, nil + case parsing.TOKLTE: + return leftStr <= rightStr, nil + } + } } - switch node.Value { - case parsing.TOKGT: - return leftNum > rightNum, nil - case parsing.TOKGTE: - return leftNum >= rightNum, nil - case parsing.TOKLT: - return leftNum < rightNum, nil - case parsing.TOKLTE: - return leftNum <= rightNum, nil + if leftNum, ok := util.ToNumber(left); ok { + if rightNum, ok := util.ToNumber(right); ok { + switch node.Value { + case parsing.TOKGT: + return leftNum > rightNum, nil + case parsing.TOKGTE: + return leftNum >= rightNum, nil + case parsing.TOKLT: + return leftNum < rightNum, nil + case parsing.TOKLTE: + return leftNum <= rightNum, nil + } + } } + // TODO: don't we want to return an error here ? + return nil, nil case parsing.ASTExpRef: return func(data interface{}) (interface{}, error) { return intr.execute(node.Children[0], data, functionCaller) diff --git a/pkg/interpreter/interpreter_test.go b/pkg/interpreter/interpreter_test.go index 67c6422..57e9313 100644 --- a/pkg/interpreter/interpreter_test.go +++ b/pkg/interpreter/interpreter_test.go @@ -185,6 +185,31 @@ func TestCanSupportProjectionsWithStructs(t *testing.T) { assert.Equal([]interface{}{"first", "second", "third"}, result) } +func TestCompareStrings(t *testing.T) { + assert := assert.New(t) + data := []string{"a", "b", "c"} + { + result, err := search(t, "@[?@ > 'a']", data) + assert.Nil(err) + assert.Equal([]interface{}{"b", "c"}, result) + } + { + result, err := search(t, "@[?@ >= 'b']", data) + assert.Nil(err) + assert.Equal([]interface{}{"b", "c"}, result) + } + { + result, err := search(t, "@[?@ < 'b']", data) + assert.Nil(err) + assert.Equal([]interface{}{"a"}, result) + } + { + result, err := search(t, "@[?@ <= 'b']", data) + assert.Nil(err) + assert.Equal([]interface{}{"a", "b"}, result) + } +} + func TestCanSupportSliceOfStructsWithFunctions(t *testing.T) { assert := assert.New(t) data := []scalars{{"a1", "b1"}, {"a2", "b2"}}