Prechádzať zdrojové kódy

fix(sql): support normal expression after IN clause

Signed-off-by: Jianxiang Ran <rxan_embedded@163.com>
Jianxiang Ran 2 rokov pred
rodič
commit
80c9502621

+ 27 - 0
internal/topo/operator/filter_test.go

@@ -302,6 +302,33 @@ func TestFilterPlan_Apply(t *testing.T) {
 		},
 
 		{
+
+			sql: "SELECT abc FROM tbl WHERE json->abc IN json->intArraySet",
+			data: &xsql.Tuple{
+				Emitter: "tbl",
+				Message: xsql.Message{
+					"json": map[string]interface{}{
+						"abc":         int64(34),
+						"def":         "hello",
+						"strArraySet": []string{"hello", "world"},
+						"intArraySet": []int{33, 34},
+					},
+				},
+			},
+			result: &xsql.Tuple{
+				Emitter: "tbl",
+				Message: xsql.Message{
+					"json": map[string]interface{}{
+						"abc":         int64(34),
+						"def":         "hello",
+						"strArraySet": []string{"hello", "world"},
+						"intArraySet": []int{33, 34},
+					},
+				},
+			},
+		},
+
+		{
 			sql: "SELECT abc FROM src1 WHERE f1 = \"v1\" GROUP BY TUMBLINGWINDOW(ss, 10)",
 			data: xsql.WindowTuplesSet{
 				Content: []xsql.WindowTuples{

+ 2 - 3
internal/xsql/parser.go

@@ -642,10 +642,9 @@ func (p *Parser) parseValueSetExpr() (ast.Expr, error) {
 	}
 
 	if exp, err := p.parseUnaryExpr(false); err != nil {
-		return nil, fmt.Errorf("expect Ident expression after IN, but got error %v", err)
+		return nil, fmt.Errorf("expect expression after IN, but got error %v", err)
 	} else {
-		valsetExpr.ArrayExpr = exp
-		return valsetExpr, nil
+		return exp, nil
 	}
 }
 

+ 34 - 4
internal/xsql/parser_test.go

@@ -894,9 +894,9 @@ func TestParser_ParseStatement(t *testing.T) {
 				},
 				Sources: []ast.Source{&ast.Table{Name: "topic/sensor1"}},
 				Condition: &ast.BinaryExpr{
-					LHS: &ast.BinaryExpr{LHS: &ast.FieldRef{Name: "t", StreamName: ast.DefaultStream}, OP: ast.IN, RHS: &ast.ValueSetExpr{ArrayExpr: &ast.FieldRef{Name: "arraySet", StreamName: ast.DefaultStream}}},
+					LHS: &ast.BinaryExpr{LHS: &ast.FieldRef{Name: "t", StreamName: ast.DefaultStream}, OP: ast.IN, RHS: &ast.FieldRef{Name: "arraySet", StreamName: ast.DefaultStream}},
 					OP:  ast.OR,
-					RHS: &ast.BinaryExpr{LHS: &ast.FieldRef{Name: "name", StreamName: ast.DefaultStream}, OP: ast.IN, RHS: &ast.ValueSetExpr{ArrayExpr: &ast.FieldRef{Name: "arraySet", StreamName: ast.DefaultStream}}},
+					RHS: &ast.BinaryExpr{LHS: &ast.FieldRef{Name: "name", StreamName: ast.DefaultStream}, OP: ast.IN, RHS: &ast.FieldRef{Name: "arraySet", StreamName: ast.DefaultStream}},
 				},
 			},
 		},
@@ -910,9 +910,9 @@ func TestParser_ParseStatement(t *testing.T) {
 				},
 				Sources: []ast.Source{&ast.Table{Name: "topic/sensor1"}},
 				Condition: &ast.BinaryExpr{
-					LHS: &ast.BinaryExpr{LHS: &ast.FieldRef{Name: "t", StreamName: ast.DefaultStream}, OP: ast.NOTIN, RHS: &ast.ValueSetExpr{ArrayExpr: &ast.FieldRef{Name: "arraySet", StreamName: ast.DefaultStream}}},
+					LHS: &ast.BinaryExpr{LHS: &ast.FieldRef{Name: "t", StreamName: ast.DefaultStream}, OP: ast.NOTIN, RHS: &ast.FieldRef{Name: "arraySet", StreamName: ast.DefaultStream}},
 					OP:  ast.OR,
-					RHS: &ast.BinaryExpr{LHS: &ast.FieldRef{Name: "name", StreamName: ast.DefaultStream}, OP: ast.NOTIN, RHS: &ast.ValueSetExpr{ArrayExpr: &ast.FieldRef{Name: "arraySet", StreamName: ast.DefaultStream}}},
+					RHS: &ast.BinaryExpr{LHS: &ast.FieldRef{Name: "name", StreamName: ast.DefaultStream}, OP: ast.NOTIN, RHS: &ast.FieldRef{Name: "arraySet", StreamName: ast.DefaultStream}},
 				},
 			},
 		},
@@ -2142,6 +2142,36 @@ func TestParser_ParseJsonExpr(t *testing.T) {
 		},
 
 		{
+			s: `SELECT children[:1] FROM demo WHERE abc[0] IN demo.children[2:]->first`,
+			stmt: &ast.SelectStatement{
+				Fields: []ast.Field{
+					{
+						Expr: &ast.BinaryExpr{
+							LHS: &ast.FieldRef{Name: "children", StreamName: ast.DefaultStream},
+							OP:  ast.SUBSET,
+							RHS: &ast.ColonExpr{Start: &ast.IntegerLiteral{Val: 0}, End: &ast.IntegerLiteral{Val: 1}},
+						},
+						Name:  "kuiper_field_0",
+						AName: ""},
+				},
+				Sources: []ast.Source{&ast.Table{Name: "demo"}},
+				Condition: &ast.BinaryExpr{
+					LHS: &ast.BinaryExpr{
+						LHS: &ast.FieldRef{Name: "abc", StreamName: ast.DefaultStream},
+						OP:  ast.SUBSET,
+						RHS: &ast.IndexExpr{Index: &ast.IntegerLiteral{Val: 0}},
+					},
+					OP: ast.IN,
+					RHS: &ast.BinaryExpr{
+						LHS: &ast.BinaryExpr{LHS: &ast.FieldRef{StreamName: ast.StreamName("demo"), Name: "children"}, OP: ast.SUBSET, RHS: &ast.ColonExpr{Start: &ast.IntegerLiteral{Val: 2}, End: &ast.IntegerLiteral{Val: math.MinInt32}}},
+						OP:  ast.ARROW,
+						RHS: &ast.JsonFieldRef{Name: "first"},
+					},
+				},
+			},
+		},
+
+		{
 			s:    `SELECT demo.children.first AS c FROM demo`,
 			stmt: nil,
 			err:  "Too many field names. Please use -> to reference keys in struct.\n",