mirror of
https://github.com/milvus-io/milvus.git
synced 2026-07-21 10:15:43 +00:00
enhance: forbid two column comparison with json type in parser stage (#43382)
#43381 Signed-off-by: luzhang <luzhang@zilliz.com> Co-authored-by: luzhang <luzhang@zilliz.com>
This commit is contained in:
@@ -173,8 +173,6 @@ func TestExpr_Compare(t *testing.T) {
|
||||
`Int64Field >= FloatField`,
|
||||
`FloatField == DoubleField`,
|
||||
`StringField != VarCharField`,
|
||||
`JSONField["A"] > Int16Field`,
|
||||
`$meta["A"] > Int16Field`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExpr(t, helper, exprStr)
|
||||
|
||||
@@ -399,6 +399,11 @@ func handleCompare(op planpb.OpType, left *ExprWithType, right *ExprWithType) (*
|
||||
return nil, errors.New("only comparison between two fields is supported")
|
||||
}
|
||||
|
||||
// Check if both left and right are non-JSON types
|
||||
if typeutil.IsJSONType(leftColumnInfo.GetDataType()) || typeutil.IsJSONType(rightColumnInfo.GetDataType()) {
|
||||
return nil, errors.New("two column comparison with JSON type is not supported")
|
||||
}
|
||||
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_CompareExpr{
|
||||
CompareExpr: &planpb.CompareExpr{
|
||||
|
||||
@@ -335,3 +335,258 @@ func Test_decodeUnicode(t *testing.T) {
|
||||
assert.NotEqual(t, `A["年份"]["月份"]`, s1)
|
||||
assert.Equal(t, `A["年份"]["月份"]`, decodeUnicode(s1))
|
||||
}
|
||||
|
||||
func Test_handleCompare(t *testing.T) {
|
||||
t.Run("normal field comparison", func(t *testing.T) {
|
||||
left := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 101,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
right := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 102,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
result, err := handleCompare(planpb.OpType_GreaterThan, left, right)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, result)
|
||||
assert.NotNil(t, result.GetCompareExpr())
|
||||
assert.Equal(t, planpb.OpType_GreaterThan, result.GetCompareExpr().GetOp())
|
||||
})
|
||||
|
||||
t.Run("left field is JSON type", func(t *testing.T) {
|
||||
left := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 101,
|
||||
DataType: schemapb.DataType_JSON,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_JSON,
|
||||
}
|
||||
|
||||
right := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 102,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
result, err := handleCompare(planpb.OpType_GreaterThan, left, right)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, result)
|
||||
assert.Contains(t, err.Error(), "two column comparison with JSON type is not supported")
|
||||
})
|
||||
|
||||
t.Run("right field is JSON type", func(t *testing.T) {
|
||||
left := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 101,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
right := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 102,
|
||||
DataType: schemapb.DataType_JSON,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_JSON,
|
||||
}
|
||||
|
||||
result, err := handleCompare(planpb.OpType_GreaterThan, left, right)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, result)
|
||||
assert.Contains(t, err.Error(), "two column comparison with JSON type is not supported")
|
||||
})
|
||||
|
||||
t.Run("both fields are JSON type", func(t *testing.T) {
|
||||
left := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 101,
|
||||
DataType: schemapb.DataType_JSON,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_JSON,
|
||||
}
|
||||
|
||||
right := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 102,
|
||||
DataType: schemapb.DataType_JSON,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_JSON,
|
||||
}
|
||||
|
||||
result, err := handleCompare(planpb.OpType_GreaterThan, left, right)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, result)
|
||||
assert.Contains(t, err.Error(), "two column comparison with JSON type is not supported")
|
||||
})
|
||||
|
||||
t.Run("left field is nil", func(t *testing.T) {
|
||||
left := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: &planpb.GenericValue{
|
||||
Val: &planpb.GenericValue_Int64Val{
|
||||
Int64Val: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
right := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 102,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
result, err := handleCompare(planpb.OpType_GreaterThan, left, right)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, result)
|
||||
assert.Contains(t, err.Error(), "only comparison between two fields is supported")
|
||||
})
|
||||
|
||||
t.Run("right field is nil", func(t *testing.T) {
|
||||
left := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 101,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
right := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: &planpb.GenericValue{
|
||||
Val: &planpb.GenericValue_Int64Val{
|
||||
Int64Val: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
result, err := handleCompare(planpb.OpType_GreaterThan, left, right)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, result)
|
||||
assert.Contains(t, err.Error(), "only comparison between two fields is supported")
|
||||
})
|
||||
|
||||
t.Run("template expression", func(t *testing.T) {
|
||||
left := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
IsTemplate: true,
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: &planpb.GenericValue{
|
||||
Val: &planpb.GenericValue_Int64Val{
|
||||
Int64Val: 100,
|
||||
},
|
||||
},
|
||||
TemplateVariableName: "var1",
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
right := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: 102,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
|
||||
result, err := handleCompare(planpb.OpType_GreaterThan, left, right)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, result)
|
||||
assert.NotNil(t, result.GetUnaryRangeExpr())
|
||||
assert.Equal(t, planpb.OpType_GreaterThan, result.GetUnaryRangeExpr().GetOp())
|
||||
assert.Equal(t, "var1", result.GetUnaryRangeExpr().GetTemplateVariableName())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1280,8 +1280,8 @@ class TestCollectionSearchInvalid(TestcaseBase):
|
||||
default_search_params, default_limit,
|
||||
expr,
|
||||
check_task=CheckTasks.err_res,
|
||||
check_items={"err_code": 65535,
|
||||
"err_msg": "query failed: N6milvus21ExecOperatorExceptionE :Operator::GetOutput failed"})
|
||||
check_items={"err_code": 1100,
|
||||
"err_msg": "error: two column comparison with JSON type is not supported"})
|
||||
|
||||
@pytest.mark.tags(CaseLabel.L2)
|
||||
def test_search_ef_less_than_limit(self):
|
||||
|
||||
Reference in New Issue
Block a user