diff --git a/internal/parser/planparserv2/parser_visitor.go b/internal/parser/planparserv2/parser_visitor.go index 6a5d21b936..fd8f3ac5ec 100644 --- a/internal/parser/planparserv2/parser_visitor.go +++ b/internal/parser/planparserv2/parser_visitor.go @@ -190,6 +190,10 @@ func (v *ParserVisitor) VisitAddSub(ctx *parser.AddSubContext) interface{} { return fmt.Errorf("invalid arithmetic expression, left: %s, op: %s, right: %s", ctx.Expr(0).GetText(), ctx.GetOp(), ctx.Expr(1).GetText()) } + if typeutil.IsArrayType(leftExpr.dataType) || typeutil.IsArrayType(rightExpr.dataType) { + return fmt.Errorf("invalid expression, array is not supported for AddSub") + } + if (!typeutil.IsArithmetic(leftExpr.dataType) && !typeutil.IsJSONType(leftExpr.dataType)) || (!typeutil.IsArithmetic(rightExpr.dataType) && !typeutil.IsJSONType(rightExpr.dataType)) { return fmt.Errorf("'%s' can only be used between integer or floating or json field expressions", arithNameMap[ctx.GetOp().GetTokenType()]) @@ -268,6 +272,10 @@ func (v *ParserVisitor) VisitMulDivMod(ctx *parser.MulDivModContext) interface{} return fmt.Errorf("invalid arithmetic expression, left: %s, op: %s, right: %s", ctx.Expr(0).GetText(), ctx.GetOp(), ctx.Expr(1).GetText()) } + if typeutil.IsArrayType(leftExpr.dataType) || typeutil.IsArrayType(rightExpr.dataType) { + return fmt.Errorf("invalid expression, array is not supported for MulDivMod") + } + if (!typeutil.IsArithmetic(leftExpr.dataType) && !typeutil.IsJSONType(leftExpr.dataType)) || (!typeutil.IsArithmetic(rightExpr.dataType) && !typeutil.IsJSONType(rightExpr.dataType)) { return fmt.Errorf("'%s' can only be used between integer or floating expressions", arithNameMap[ctx.GetOp().GetTokenType()]) @@ -338,6 +346,10 @@ func (v *ParserVisitor) VisitEquality(ctx *parser.EqualityContext) interface{} { rightExpr = getExpr(right) } + if typeutil.IsArrayType(leftExpr.dataType) || typeutil.IsArrayType(rightExpr.dataType) { + return fmt.Errorf("invalid expression, array is not supported for Equality") + } + expr, err := HandleCompare(ctx.GetOp().GetTokenType(), leftExpr, rightExpr) if err != nil { return err @@ -391,6 +403,10 @@ func (v *ParserVisitor) VisitRelational(ctx *parser.RelationalContext) interface rightExpr = getExpr(right) } + if typeutil.IsArrayType(leftExpr.dataType) || typeutil.IsArrayType(rightExpr.dataType) { + return fmt.Errorf("invalid expression, array is not supported for Relational") + } + expr, err := HandleCompare(ctx.GetOp().GetTokenType(), leftExpr, rightExpr) if err != nil { return err diff --git a/internal/parser/planparserv2/plan_parser_v2_test.go b/internal/parser/planparserv2/plan_parser_v2_test.go index 6fb59a430a..046bca56c6 100644 --- a/internal/parser/planparserv2/plan_parser_v2_test.go +++ b/internal/parser/planparserv2/plan_parser_v2_test.go @@ -1935,3 +1935,70 @@ func Test_InvalidJSONContainsAny(t *testing.T) { assert.Error(t, err) assert.Nil(t, plan) } + +func Test_UnsupportedExpr(t *testing.T) { + schema := newTestSchema() + expr := "" + var err error + var plan *planpb.PlanNode + + expr = `A == [1, 2, 3]` + plan, err = CreateSearchPlan(schema, expr, "FloatVectorField", &planpb.QueryInfo{ + Topk: 0, + MetricType: "", + SearchParams: "", + RoundDecimal: 0, + }) + assert.Error(t, err) + assert.Nil(t, plan) + + expr = `Int64Field == [1, 2, 3]` + plan, err = CreateSearchPlan(schema, expr, "FloatVectorField", &planpb.QueryInfo{ + Topk: 0, + MetricType: "", + SearchParams: "", + RoundDecimal: 0, + }) + assert.Error(t, err) + assert.Nil(t, plan) + + expr = `Int64Field > [1, 2, 3]` + plan, err = CreateSearchPlan(schema, expr, "FloatVectorField", &planpb.QueryInfo{ + Topk: 0, + MetricType: "", + SearchParams: "", + RoundDecimal: 0, + }) + assert.Error(t, err) + assert.Nil(t, plan) + + expr = `Int64Field + [1, 2, 3] == 10` + plan, err = CreateSearchPlan(schema, expr, "FloatVectorField", &planpb.QueryInfo{ + Topk: 0, + MetricType: "", + SearchParams: "", + RoundDecimal: 0, + }) + assert.Error(t, err) + assert.Nil(t, plan) + + expr = `Int64Field % [1, 2, 3] == 10` + plan, err = CreateSearchPlan(schema, expr, "FloatVectorField", &planpb.QueryInfo{ + Topk: 0, + MetricType: "", + SearchParams: "", + RoundDecimal: 0, + }) + assert.Error(t, err) + assert.Nil(t, plan) + + expr = `[1, 2, 3] < Int64Field < [4, 5, 6]` + plan, err = CreateSearchPlan(schema, expr, "FloatVectorField", &planpb.QueryInfo{ + Topk: 0, + MetricType: "", + SearchParams: "", + RoundDecimal: 0, + }) + assert.Error(t, err) + assert.Nil(t, plan) +} diff --git a/internal/parser/planparserv2/utils.go b/internal/parser/planparserv2/utils.go index 4a56a11a29..831bc05e6f 100644 --- a/internal/parser/planparserv2/utils.go +++ b/internal/parser/planparserv2/utils.go @@ -108,6 +108,11 @@ func toValueExpr(n *planpb.GenericValue) *ExprWithType { expr: expr, dataType: schemapb.DataType_VarChar, } + case *planpb.GenericValue_ArrayVal: + return &ExprWithType{ + expr: expr, + dataType: schemapb.DataType_Array, + } default: return nil }