From add08deaff414eec7b83f5bbb43587dc061685a4 Mon Sep 17 00:00:00 2001 From: ngjaying Date: Wed, 26 Jun 2024 12:03:42 +0800 Subject: [PATCH] fix(valuer): nil handling (#2952) Signed-off-by: Jiyong Huang --- internal/topo/operator/filter_test.go | 7 +------ internal/topo/operator/join_test.go | 15 ++++---------- internal/xsql/valuer.go | 29 ++++++++++++--------------- internal/xsql/valuer_test.go | 6 +++--- pkg/ast/token.go | 4 ++-- 5 files changed, 23 insertions(+), 38 deletions(-) diff --git a/internal/topo/operator/filter_test.go b/internal/topo/operator/filter_test.go index cf3e68f269..4751cd076d 100644 --- a/internal/topo/operator/filter_test.go +++ b/internal/topo/operator/filter_test.go @@ -52,12 +52,7 @@ func TestFilterPlan_Apply(t *testing.T) { "a": int64(6), }, }, - result: &xsql.Tuple{ - Emitter: "tbl", - Message: xsql.Message{ - "a": int64(6), - }, - }, + result: nil, }, { sql: "SELECT * FROM tbl WHERE abc > def and abc <= ghi", diff --git a/internal/topo/operator/join_test.go b/internal/topo/operator/join_test.go index 9fe1a73909..74e69b46fc 100644 --- a/internal/topo/operator/join_test.go +++ b/internal/topo/operator/join_test.go @@ -22,6 +22,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/lf-edge/ekuiper/internal/conf" "github.com/lf-edge/ekuiper/internal/topo/context" "github.com/lf-edge/ekuiper/internal/xsql" @@ -433,13 +435,6 @@ func TestLeftJoinPlan_Apply(t *testing.T) { { Tuples: []xsql.TupleRow{ &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f2": "w1"}}, - &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 2, "f2": "w1"}}, - }, - }, - { - Tuples: []xsql.TupleRow{ - &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f2": "w1"}}, - &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 2, "f2": "w2"}}, }, }, }, @@ -762,7 +757,7 @@ func TestLeftJoinPlan_Apply(t *testing.T) { fmt.Printf("The test bucket size is %d.\n\n", len(tests)) contextLogger := conf.Log.WithField("rule", "TestLeftJoinPlan_Apply") ctx := context.WithValue(context.Background(), context.LoggerKey, contextLogger) - for i, tt := range tests { + for _, tt := range tests { stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse() if err != nil { t.Errorf("statement parse error %s", err) @@ -775,9 +770,7 @@ func TestLeftJoinPlan_Apply(t *testing.T) { fv, afv := xsql.NewFunctionValuersForOp(nil) pp := &JoinOp{Joins: stmt.Joins, From: table} result := pp.Apply(ctx, tt.data, fv, afv) - if !reflect.DeepEqual(tt.result, result) { - t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result) - } + assert.Equal(t, tt.result, result) } } } diff --git a/internal/xsql/valuer.go b/internal/xsql/valuer.go index 81763b91a6..a30c9f5a4a 100644 --- a/internal/xsql/valuer.go +++ b/internal/xsql/valuer.go @@ -1,4 +1,4 @@ -// Copyright 2022-2023 EMQ Technologies Co., Ltd. +// Copyright 2022-2024 EMQ Technologies Co., Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -483,6 +483,11 @@ func (v *ValuerEval) Eval(expr ast.Expr) interface{} { case *ast.ValueSetExpr: return v.evalValueSet(expr) case *ast.BetweenExpr: + lower := v.Eval(expr.Lower) + higher := v.Eval(expr.Higher) + if lower == nil || higher == nil { + return nil + } return []interface{}{ v.Eval(expr.Lower), v.Eval(expr.Higher), } @@ -538,6 +543,9 @@ func (v *ValuerEval) evalBinaryExpr(expr *ast.BinaryExpr) interface{} { } switch expr.OP { case ast.BETWEEN, ast.NOTBETWEEN: + if lhs == nil || rhs == nil { + return false + } arr, ok := rhs.([]interface{}) if !ok { return fmt.Errorf("between operator expects two arguments, but found %v", rhs) @@ -656,7 +664,7 @@ func (v *ValuerEval) evalSetsExpr(lhs interface{}, op ast.Token, rhsSet interfac } } if lhs == nil { - return nil + return false } rhsSetVals := reflect.ValueOf(rhsSet) for i := 0; i < rhsSetVals.Len(); i++ { @@ -751,22 +759,11 @@ func (v *ValuerEval) subset(result interface{}, expr ast.Expr) interface{} { } // lhs and rhs are non-nil -func (v *ValuerEval) simpleDataEval(lhs, rhs interface{}, op ast.Token) interface{} { +func (v *ValuerEval) simpleDataEval(lhs, rhs interface{}, op ast.Token) any { if lhs == nil || rhs == nil { + // for relationship, return false switch op { - case ast.EQ, ast.LTE, ast.GTE: - if lhs == nil && rhs == nil { - return true - } else { - return false - } - case ast.NEQ: - if lhs == nil && rhs == nil { - return false - } else { - return true - } - case ast.LT, ast.GT: + case ast.AND, ast.OR, ast.BITWISE_AND, ast.BITWISE_OR, ast.BITWISE_XOR, ast.EQ, ast.NEQ, ast.GT, ast.GTE, ast.LT, ast.LTE: return false default: return nil diff --git a/internal/xsql/valuer_test.go b/internal/xsql/valuer_test.go index c6cc501c02..cbaeb30aac 100644 --- a/internal/xsql/valuer_test.go +++ b/internal/xsql/valuer_test.go @@ -1,4 +1,4 @@ -// Copyright 2021-2023 EMQ Technologies Co., Ltd. +// Copyright 2021-2024 EMQ Technologies Co., Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -128,7 +128,7 @@ func TestComparison(t *testing.T) { }, r: []interface{}{ false, false, false, - true, false, true, false, false, true, + false, false, false, false, false, false, }, }, { // 11 m: map[string]interface{}{ @@ -137,7 +137,7 @@ func TestComparison(t *testing.T) { }, r: []interface{}{ false, true, errors.New("invalid operation int64(12) = string(string literal)"), - false, false, false, true, false, true, + false, false, false, false, false, false, }, }, { // 12 m: map[string]interface{}{ diff --git a/pkg/ast/token.go b/pkg/ast/token.go index 662c0aac77..fa084b86fe 100644 --- a/pkg/ast/token.go +++ b/pkg/ast/token.go @@ -1,4 +1,4 @@ -// Copyright 2021-2023 EMQ Technologies Co., Ltd. +// Copyright 2021-2024 EMQ Technologies Co., Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ const ( BADSTRING // "abc operatorBeg - // ADD and the following are InfluxQL Operators + // ADD and the following ADD // + SUB // - MUL // *