enhance: Update the template expression proto to improve transmission efficiency (#37484)

issue: #36672

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
This commit is contained in:
cai.zhang 2024-11-07 16:28:25 +08:00 committed by GitHub
parent 4dc684126e
commit de627644f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 348 additions and 317 deletions

2
go.mod
View File

@ -23,7 +23,7 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/klauspost/compress v1.17.9 github.com/klauspost/compress v1.17.9
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20241025031121-4d5c88b00cf7 github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20241106083218-5de5d0cfb1c1
github.com/minio/minio-go/v7 v7.0.73 github.com/minio/minio-go/v7 v7.0.73
github.com/pingcap/log v1.1.1-0.20221015072633-39906604fb81 github.com/pingcap/log v1.1.1-0.20221015072633-39906604fb81
github.com/prometheus/client_golang v1.14.0 github.com/prometheus/client_golang v1.14.0

4
go.sum
View File

@ -627,8 +627,8 @@ github.com/milvus-io/cgosymbolizer v0.0.0-20240722103217-b7dee0e50119 h1:9VXijWu
github.com/milvus-io/cgosymbolizer v0.0.0-20240722103217-b7dee0e50119/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg= github.com/milvus-io/cgosymbolizer v0.0.0-20240722103217-b7dee0e50119/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg=
github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b h1:TfeY0NxYxZzUfIfYe5qYDBzt4ZYRqzUjTR6CvUzjat8= github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b h1:TfeY0NxYxZzUfIfYe5qYDBzt4ZYRqzUjTR6CvUzjat8=
github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b/go.mod h1:iwW+9cWfIzzDseEBCCeDSN5SD16Tidvy8cwQ7ZY8Qj4= github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b/go.mod h1:iwW+9cWfIzzDseEBCCeDSN5SD16Tidvy8cwQ7ZY8Qj4=
github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20241025031121-4d5c88b00cf7 h1:HwAitQk+V59QdYUwwVVYHTujd4QZrebg2Cc2hmcjhAg= github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20241106083218-5de5d0cfb1c1 h1:GFS5AxKPcEstcfJgMGxRH+l/mKA0kK1sHDOxnOqMnoA=
github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20241025031121-4d5c88b00cf7/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= github.com/milvus-io/milvus-proto/go-api/v2 v2.3.4-0.20241106083218-5de5d0cfb1c1/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/pulsar-client-go v0.12.1 h1:O2JZp1tsYiO7C0MQ4hrUY/aJXnn2Gry6hpm7UodghmE= github.com/milvus-io/pulsar-client-go v0.12.1 h1:O2JZp1tsYiO7C0MQ4hrUY/aJXnn2Gry6hpm7UodghmE=
github.com/milvus-io/pulsar-client-go v0.12.1/go.mod h1:dkutuH4oS2pXiGm+Ti7fQZ4MRjrMPZ8IJeEGAWMeckk= github.com/milvus-io/pulsar-client-go v0.12.1/go.mod h1:dkutuH4oS2pXiGm+Ti7fQZ4MRjrMPZ8IJeEGAWMeckk=
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs=

View File

@ -1,60 +1,140 @@
package planparserv2 package planparserv2
import ( import (
"bytes"
"encoding/json"
"fmt" "fmt"
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb" "github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
"github.com/milvus-io/milvus/internal/proto/planpb" "github.com/milvus-io/milvus/internal/proto/planpb"
) )
func convertArrayValue(templateName string, templateValue *schemapb.TemplateArrayValue) (*planpb.GenericValue, error) {
var arrayValues []*planpb.GenericValue
var elementType schemapb.DataType
switch templateValue.GetData().(type) {
case *schemapb.TemplateArrayValue_BoolData:
elements := templateValue.GetBoolData().GetData()
arrayValues = make([]*planpb.GenericValue, len(elements))
for i, element := range elements {
arrayValues[i] = &planpb.GenericValue{
Val: &planpb.GenericValue_BoolVal{
BoolVal: element,
},
}
}
elementType = schemapb.DataType_Bool
case *schemapb.TemplateArrayValue_LongData:
elements := templateValue.GetLongData().GetData()
arrayValues = make([]*planpb.GenericValue, len(elements))
for i, element := range elements {
arrayValues[i] = &planpb.GenericValue{
Val: &planpb.GenericValue_Int64Val{
Int64Val: element,
},
}
}
elementType = schemapb.DataType_Int64
case *schemapb.TemplateArrayValue_DoubleData:
elements := templateValue.GetDoubleData().GetData()
arrayValues = make([]*planpb.GenericValue, len(elements))
for i, element := range elements {
arrayValues[i] = &planpb.GenericValue{
Val: &planpb.GenericValue_FloatVal{
FloatVal: element,
},
}
}
elementType = schemapb.DataType_Double
case *schemapb.TemplateArrayValue_StringData:
elements := templateValue.GetStringData().GetData()
arrayValues = make([]*planpb.GenericValue, len(elements))
for i, element := range elements {
arrayValues[i] = &planpb.GenericValue{
Val: &planpb.GenericValue_StringVal{
StringVal: element,
},
}
}
elementType = schemapb.DataType_VarChar
case *schemapb.TemplateArrayValue_ArrayData:
elements := templateValue.GetArrayData().GetData()
arrayValues = make([]*planpb.GenericValue, len(elements))
for i, element := range elements {
targetValue, err := convertArrayValue(templateName, element)
if err != nil {
return nil, err
}
arrayValues[i] = targetValue
}
elementType = schemapb.DataType_Array
case *schemapb.TemplateArrayValue_JsonData:
elements := templateValue.GetJsonData().GetData()
arrayValues = make([]*planpb.GenericValue, len(elements))
for i, element := range elements {
var jsonElement interface{}
err := json.Unmarshal(element, &jsonElement)
if err != nil {
return nil, err
}
decoder := json.NewDecoder(bytes.NewBuffer(element))
decoder.UseNumber()
var value interface{}
if err = decoder.Decode(&value); err != nil {
return nil, err
}
parsedValue, _, err := parseJSONValue(value)
if err != nil {
return nil, err
}
arrayValues[i] = parsedValue
}
elementType = schemapb.DataType_JSON
default:
return nil, fmt.Errorf("unknown template variable value type: %v", templateValue.GetData())
}
return &planpb.GenericValue{
Val: &planpb.GenericValue_ArrayVal{
ArrayVal: &planpb.Array{
Array: arrayValues,
SameType: elementType != schemapb.DataType_JSON,
ElementType: elementType,
},
},
}, nil
}
func ConvertToGenericValue(templateName string, templateValue *schemapb.TemplateValue) (*planpb.GenericValue, error) { func ConvertToGenericValue(templateName string, templateValue *schemapb.TemplateValue) (*planpb.GenericValue, error) {
if templateValue == nil { if templateValue == nil {
return nil, fmt.Errorf("expression template variable value is nil, template name: {%s}", templateName) return nil, fmt.Errorf("expression template variable value is nil, template name: {%s}", templateName)
} }
switch templateValue.GetType() { switch templateValue.GetVal().(type) {
case schemapb.DataType_Bool: case *schemapb.TemplateValue_BoolVal:
return &planpb.GenericValue{ return &planpb.GenericValue{
Val: &planpb.GenericValue_BoolVal{ Val: &planpb.GenericValue_BoolVal{
BoolVal: templateValue.GetBoolVal(), BoolVal: templateValue.GetBoolVal(),
}, },
}, nil }, nil
case schemapb.DataType_Int8, schemapb.DataType_Int16, schemapb.DataType_Int32, schemapb.DataType_Int64: case *schemapb.TemplateValue_Int64Val:
return &planpb.GenericValue{ return &planpb.GenericValue{
Val: &planpb.GenericValue_Int64Val{ Val: &planpb.GenericValue_Int64Val{
Int64Val: templateValue.GetInt64Val(), Int64Val: templateValue.GetInt64Val(),
}, },
}, nil }, nil
case schemapb.DataType_Float, schemapb.DataType_Double: case *schemapb.TemplateValue_FloatVal:
return &planpb.GenericValue{ return &planpb.GenericValue{
Val: &planpb.GenericValue_FloatVal{ Val: &planpb.GenericValue_FloatVal{
FloatVal: templateValue.GetFloatVal(), FloatVal: templateValue.GetFloatVal(),
}, },
}, nil }, nil
case schemapb.DataType_String, schemapb.DataType_VarChar: case *schemapb.TemplateValue_StringVal:
return &planpb.GenericValue{ return &planpb.GenericValue{
Val: &planpb.GenericValue_StringVal{ Val: &planpb.GenericValue_StringVal{
StringVal: templateValue.GetStringVal(), StringVal: templateValue.GetStringVal(),
}, },
}, nil }, nil
case schemapb.DataType_Array: case *schemapb.TemplateValue_ArrayVal:
elements := templateValue.GetArrayVal().GetArray() return convertArrayValue(templateName, templateValue.GetArrayVal())
arrayValues := make([]*planpb.GenericValue, len(elements))
for i, element := range elements {
arrayElement, err := ConvertToGenericValue(templateName, element)
if err != nil {
return nil, err
}
arrayValues[i] = arrayElement
}
return &planpb.GenericValue{
Val: &planpb.GenericValue_ArrayVal{
ArrayVal: &planpb.Array{
Array: arrayValues,
SameType: templateValue.GetArrayVal().GetSameType(),
ElementType: templateValue.GetArrayVal().GetElementType(),
},
},
}, nil
default: default:
return nil, fmt.Errorf("expression elements can only be scalars") return nil, fmt.Errorf("expression elements can only be scalars")
} }

View File

@ -1,6 +1,7 @@
package planparserv2 package planparserv2
import ( import (
"encoding/json"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -14,12 +15,16 @@ type convertTestcase struct {
expect map[string]*planpb.GenericValue expect map[string]*planpb.GenericValue
} }
func generateJSONData(v interface{}) []byte {
data, _ := json.Marshal(v)
return data
}
func Test_ConvertToGenericValue(t *testing.T) { func Test_ConvertToGenericValue(t *testing.T) {
tests := []convertTestcase{ tests := []convertTestcase{
{ {
input: map[string]*schemapb.TemplateValue{ input: map[string]*schemapb.TemplateValue{
"bool": { "bool": {
Type: schemapb.DataType_Bool,
Val: &schemapb.TemplateValue_BoolVal{ Val: &schemapb.TemplateValue_BoolVal{
BoolVal: false, BoolVal: false,
}, },
@ -36,7 +41,6 @@ func Test_ConvertToGenericValue(t *testing.T) {
{ {
input: map[string]*schemapb.TemplateValue{ input: map[string]*schemapb.TemplateValue{
"int": { "int": {
Type: schemapb.DataType_Int64,
Val: &schemapb.TemplateValue_Int64Val{ Val: &schemapb.TemplateValue_Int64Val{
Int64Val: 999, Int64Val: 999,
}, },
@ -53,7 +57,6 @@ func Test_ConvertToGenericValue(t *testing.T) {
{ {
input: map[string]*schemapb.TemplateValue{ input: map[string]*schemapb.TemplateValue{
"float": { "float": {
Type: schemapb.DataType_Float,
Val: &schemapb.TemplateValue_FloatVal{ Val: &schemapb.TemplateValue_FloatVal{
FloatVal: 55.55, FloatVal: 55.55,
}, },
@ -70,7 +73,6 @@ func Test_ConvertToGenericValue(t *testing.T) {
{ {
input: map[string]*schemapb.TemplateValue{ input: map[string]*schemapb.TemplateValue{
"string": { "string": {
Type: schemapb.DataType_VarChar,
Val: &schemapb.TemplateValue_StringVal{ Val: &schemapb.TemplateValue_StringVal{
StringVal: "abc", StringVal: "abc",
}, },
@ -87,31 +89,13 @@ func Test_ConvertToGenericValue(t *testing.T) {
{ {
input: map[string]*schemapb.TemplateValue{ input: map[string]*schemapb.TemplateValue{
"array": { "array": {
Type: schemapb.DataType_Array,
Val: &schemapb.TemplateValue_ArrayVal{ Val: &schemapb.TemplateValue_ArrayVal{
ArrayVal: &schemapb.TemplateArrayValue{ ArrayVal: &schemapb.TemplateArrayValue{
Array: []*schemapb.TemplateValue{ Data: &schemapb.TemplateArrayValue_LongData{
{ LongData: &schemapb.LongArray{
Type: schemapb.DataType_Int64, Data: []int64{111, 222, 333},
Val: &schemapb.TemplateValue_Int64Val{
Int64Val: 111,
},
},
{
Type: schemapb.DataType_Int64,
Val: &schemapb.TemplateValue_Int64Val{
Int64Val: 222,
},
},
{
Type: schemapb.DataType_Int64,
Val: &schemapb.TemplateValue_Int64Val{
Int64Val: 333,
},
}, },
}, },
SameType: true,
ElementType: schemapb.DataType_Int64,
}, },
}, },
}, },
@ -147,33 +131,11 @@ func Test_ConvertToGenericValue(t *testing.T) {
{ {
input: map[string]*schemapb.TemplateValue{ input: map[string]*schemapb.TemplateValue{
"not_same_array": { "not_same_array": {
Type: schemapb.DataType_Array,
Val: &schemapb.TemplateValue_ArrayVal{ Val: &schemapb.TemplateValue_ArrayVal{
ArrayVal: &schemapb.TemplateArrayValue{ ArrayVal: &schemapb.TemplateArrayValue{
Array: []*schemapb.TemplateValue{ Data: &schemapb.TemplateArrayValue_JsonData{
{ JsonData: &schemapb.JSONArray{
Type: schemapb.DataType_Int64, Data: [][]byte{generateJSONData(111), generateJSONData(222.222), generateJSONData(true), generateJSONData("abc")},
Val: &schemapb.TemplateValue_Int64Val{
Int64Val: 111,
},
},
{
Type: schemapb.DataType_Float,
Val: &schemapb.TemplateValue_FloatVal{
FloatVal: 222.222,
},
},
{
Type: schemapb.DataType_Bool,
Val: &schemapb.TemplateValue_BoolVal{
BoolVal: true,
},
},
{
Type: schemapb.DataType_VarChar,
Val: &schemapb.TemplateValue_StringVal{
StringVal: "abc",
},
}, },
}, },
}, },
@ -206,6 +168,7 @@ func Test_ConvertToGenericValue(t *testing.T) {
}, },
}, },
}, },
ElementType: schemapb.DataType_JSON,
}, },
}, },
}, },
@ -220,32 +183,28 @@ func Test_ConvertToGenericValue(t *testing.T) {
} }
} }
func generateExpressionFieldData(dataType schemapb.DataType, data interface{}) *schemapb.TemplateValue { func generateTemplateValue(dataType schemapb.DataType, data interface{}) *schemapb.TemplateValue {
switch dataType { switch dataType {
case schemapb.DataType_Bool: case schemapb.DataType_Bool:
return &schemapb.TemplateValue{ return &schemapb.TemplateValue{
Type: dataType,
Val: &schemapb.TemplateValue_BoolVal{ Val: &schemapb.TemplateValue_BoolVal{
BoolVal: data.(bool), BoolVal: data.(bool),
}, },
} }
case schemapb.DataType_Int8, schemapb.DataType_Int16, schemapb.DataType_Int32, schemapb.DataType_Int64: case schemapb.DataType_Int8, schemapb.DataType_Int16, schemapb.DataType_Int32, schemapb.DataType_Int64:
return &schemapb.TemplateValue{ return &schemapb.TemplateValue{
Type: dataType,
Val: &schemapb.TemplateValue_Int64Val{ Val: &schemapb.TemplateValue_Int64Val{
Int64Val: data.(int64), Int64Val: data.(int64),
}, },
} }
case schemapb.DataType_Float, schemapb.DataType_Double: case schemapb.DataType_Float, schemapb.DataType_Double:
return &schemapb.TemplateValue{ return &schemapb.TemplateValue{
Type: dataType,
Val: &schemapb.TemplateValue_FloatVal{ Val: &schemapb.TemplateValue_FloatVal{
FloatVal: data.(float64), FloatVal: data.(float64),
}, },
} }
case schemapb.DataType_String, schemapb.DataType_VarChar: case schemapb.DataType_String, schemapb.DataType_VarChar:
return &schemapb.TemplateValue{ return &schemapb.TemplateValue{
Type: dataType,
Val: &schemapb.TemplateValue_StringVal{ Val: &schemapb.TemplateValue_StringVal{
StringVal: data.(string), StringVal: data.(string),
}, },
@ -255,31 +214,66 @@ func generateExpressionFieldData(dataType schemapb.DataType, data interface{}) *
// Assume the inner data is already in an appropriate format. // Assume the inner data is already in an appropriate format.
// Placeholder for array implementation. // Placeholder for array implementation.
// You might want to define a recursive approach based on the data structure. // You might want to define a recursive approach based on the data structure.
value := data.([]interface{})
arrayData := make([]*schemapb.TemplateValue, len(value))
elementType := schemapb.DataType_None
sameType := true
for i, v := range value {
element := v.(*schemapb.TemplateValue)
arrayData[i] = element
if elementType == schemapb.DataType_None {
elementType = element.GetType()
} else if elementType != element.GetType() {
sameType = false
elementType = schemapb.DataType_JSON
}
}
return &schemapb.TemplateValue{ return &schemapb.TemplateValue{
Type: dataType,
Val: &schemapb.TemplateValue_ArrayVal{ Val: &schemapb.TemplateValue_ArrayVal{
ArrayVal: &schemapb.TemplateArrayValue{ ArrayVal: data.(*schemapb.TemplateArrayValue),
Array: arrayData, },
ElementType: elementType, }
SameType: sameType, default:
}, return nil
}
}
func generateTemplateArrayValue(dataType schemapb.DataType, data interface{}) *schemapb.TemplateArrayValue {
switch dataType {
case schemapb.DataType_Bool:
return &schemapb.TemplateArrayValue{
Data: &schemapb.TemplateArrayValue_BoolData{
BoolData: &schemapb.BoolArray{
Data: data.([]bool),
},
},
}
case schemapb.DataType_Int64:
return &schemapb.TemplateArrayValue{
Data: &schemapb.TemplateArrayValue_LongData{
LongData: &schemapb.LongArray{
Data: data.([]int64),
},
},
}
case schemapb.DataType_Double:
return &schemapb.TemplateArrayValue{
Data: &schemapb.TemplateArrayValue_DoubleData{
DoubleData: &schemapb.DoubleArray{
Data: data.([]float64),
},
},
}
case schemapb.DataType_VarChar, schemapb.DataType_String:
return &schemapb.TemplateArrayValue{
Data: &schemapb.TemplateArrayValue_StringData{
StringData: &schemapb.StringArray{
Data: data.([]string),
},
},
}
case schemapb.DataType_JSON:
return &schemapb.TemplateArrayValue{
Data: &schemapb.TemplateArrayValue_JsonData{
JsonData: &schemapb.JSONArray{
Data: data.([][]byte),
},
},
}
case schemapb.DataType_Array:
return &schemapb.TemplateArrayValue{
Data: &schemapb.TemplateArrayValue_ArrayData{
ArrayData: &schemapb.TemplateArrayValueArray{
Data: data.([]*schemapb.TemplateArrayValue),
},
}, },
} }
default: default:
return nil return nil
} }

View File

@ -39,57 +39,35 @@ func (s *FillExpressionValueSuite) TestTermExpr() {
s.Run("normal case", func() { s.Run("normal case", func() {
testcases := []testcase{ testcases := []testcase{
{`Int64Field in {age}`, map[string]*schemapb.TemplateValue{ {`Int64Field in {age}`, map[string]*schemapb.TemplateValue{
"age": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "age": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3), int64(4)})),
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(4)),
}),
}}, }},
{`FloatField in {age}`, map[string]*schemapb.TemplateValue{ {`FloatField in {age}`, map[string]*schemapb.TemplateValue{
"age": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "age": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Float, 1.1), generateTemplateArrayValue(schemapb.DataType_Double, []float64{1.1, 2.2, 3.3, 4.4})),
generateExpressionFieldData(schemapb.DataType_Float, 2.2),
generateExpressionFieldData(schemapb.DataType_Float, 3.3),
generateExpressionFieldData(schemapb.DataType_Float, 4.4),
}),
}}, }},
{`A in {list}`, map[string]*schemapb.TemplateValue{ {`A in {list}`, map[string]*schemapb.TemplateValue{
"list": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "list": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_JSON, [][]byte{
generateExpressionFieldData(schemapb.DataType_Float, 2.2), generateJSONData(int64(1)),
generateExpressionFieldData(schemapb.DataType_String, "abc"), generateJSONData(2.2),
generateExpressionFieldData(schemapb.DataType_Bool, false), generateJSONData("abc"),
}), generateJSONData(false),
})),
}}, }},
{`ArrayField in {list}`, map[string]*schemapb.TemplateValue{ {`ArrayField in {list}`, map[string]*schemapb.TemplateValue{
"list": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "list": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ generateTemplateArrayValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), []*schemapb.TemplateArrayValue{
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3)}),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(4), int64(5), int64(6)}),
}), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(7), int64(8), int64(9)}),
generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ })),
generateExpressionFieldData(schemapb.DataType_Int64, int64(4)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(5)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(6)),
}),
generateExpressionFieldData(schemapb.DataType_Array, []interface{}{
generateExpressionFieldData(schemapb.DataType_Int64, int64(7)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(8)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(9)),
}),
}),
}}, }},
{`ArrayField[0] in {list}`, map[string]*schemapb.TemplateValue{ {`ArrayField[0] in {list}`, map[string]*schemapb.TemplateValue{
"list": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "list": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3)})),
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)),
}),
}},
{`Int64Field in {empty_list}`, map[string]*schemapb.TemplateValue{
"empty_list": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{}),
}}, }},
} }
schemaH := newTestSchemaHelper(s.T()) schemaH := newTestSchemaHelper(s.T())
@ -101,33 +79,37 @@ func (s *FillExpressionValueSuite) TestTermExpr() {
s.Run("failed case", func() { s.Run("failed case", func() {
testcases := []testcase{ testcases := []testcase{
{`Int64Field in {age}`, map[string]*schemapb.TemplateValue{ {`Int64Field in {age}`, map[string]*schemapb.TemplateValue{
"age": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "age": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_String, "abc"), generateTemplateArrayValue(schemapb.DataType_String, []string{"abc", "def"})),
generateExpressionFieldData(schemapb.DataType_String, "def"),
}),
}}, }},
{`StringField in {list}`, map[string]*schemapb.TemplateValue{ {`StringField in {list}`, map[string]*schemapb.TemplateValue{
"list": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "list": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_JSON, [][]byte{
generateExpressionFieldData(schemapb.DataType_String, "abc"), generateJSONData(int64(1)),
generateExpressionFieldData(schemapb.DataType_Float, 2.2), generateJSONData("abc"),
generateExpressionFieldData(schemapb.DataType_Bool, false), generateJSONData(2.2),
}), generateJSONData(false),
})),
}}, }},
{"ArrayField[0] in {list}", map[string]*schemapb.TemplateValue{ {"ArrayField[0] in {list}", map[string]*schemapb.TemplateValue{
"list": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "list": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_JSON, [][]byte{
generateExpressionFieldData(schemapb.DataType_String, "abc"), generateJSONData(int64(1)),
generateExpressionFieldData(schemapb.DataType_Float, 3.2), generateJSONData("abc"),
}), generateJSONData(3.2),
})),
}}, }},
{"Int64Field not in {not_list}", map[string]*schemapb.TemplateValue{ {"Int64Field not in {not_list}", map[string]*schemapb.TemplateValue{
"not_list": generateExpressionFieldData(schemapb.DataType_Int64, int64(33)), "not_list": generateTemplateValue(schemapb.DataType_Int64, int64(33)),
}}, }},
{"Int64Field not in {not_list}", map[string]*schemapb.TemplateValue{ {"Int64Field not in {not_list}", map[string]*schemapb.TemplateValue{
"age": generateExpressionFieldData(schemapb.DataType_Int64, int64(33)), "age": generateTemplateValue(schemapb.DataType_Int64, int64(33)),
}},
{`Int64Field in {empty_list}`, map[string]*schemapb.TemplateValue{
"empty_list": generateTemplateValue(schemapb.DataType_Array, &schemapb.TemplateArrayValue{}),
}}, }},
} }
schemaH := newTestSchemaHelper(s.T()) schemaH := newTestSchemaHelper(s.T())
for _, c := range testcases { for _, c := range testcases {
s.assertInvalidExpr(schemaH, c.expr, c.values) s.assertInvalidExpr(schemaH, c.expr, c.values)
@ -140,27 +122,28 @@ func (s *FillExpressionValueSuite) TestUnaryRange() {
testcases := []testcase{ testcases := []testcase{
{`Int64Field == 10`, nil}, {`Int64Field == 10`, nil},
{`Int64Field > {target}`, map[string]*schemapb.TemplateValue{ {`Int64Field > {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Int64, int64(11)), "target": generateTemplateValue(schemapb.DataType_Int64, int64(11)),
}}, }},
{`FloatField < {target}`, map[string]*schemapb.TemplateValue{ {`FloatField < {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Float, float64(12.3)), "target": generateTemplateValue(schemapb.DataType_Double, float64(12.3)),
}}, }},
{`DoubleField != {target}`, map[string]*schemapb.TemplateValue{ {`DoubleField != {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Double, 3.5), "target": generateTemplateValue(schemapb.DataType_Double, float64(3.5)),
}}, }},
{`ArrayField[0] >= {target}`, map[string]*schemapb.TemplateValue{ {`ArrayField[0] >= {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Int64, int64(3)), "target": generateTemplateValue(schemapb.DataType_Int64, int64(3)),
}}, }},
{`BoolField == {bool}`, map[string]*schemapb.TemplateValue{ {`BoolField == {bool}`, map[string]*schemapb.TemplateValue{
"bool": generateExpressionFieldData(schemapb.DataType_Bool, false), "bool": generateTemplateValue(schemapb.DataType_Bool, false),
}}, }},
{`{str} != StringField`, map[string]*schemapb.TemplateValue{ {`{str} != StringField`, map[string]*schemapb.TemplateValue{
"str": generateExpressionFieldData(schemapb.DataType_String, "abc"), "str": generateTemplateValue(schemapb.DataType_String, "abc"),
}}, }},
{`{target} > Int64Field`, map[string]*schemapb.TemplateValue{ {`{target} > Int64Field`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Int64, int64(11)), "target": generateTemplateValue(schemapb.DataType_Int64, int64(11)),
}}, }},
} }
schemaH := newTestSchemaHelper(s.T()) schemaH := newTestSchemaHelper(s.T())
for _, c := range testcases { for _, c := range testcases {
s.assertValidExpr(schemaH, c.expr, c.values) s.assertValidExpr(schemaH, c.expr, c.values)
@ -171,28 +154,28 @@ func (s *FillExpressionValueSuite) TestUnaryRange() {
testcases := []testcase{ testcases := []testcase{
{`Int64Field == 10.5`, nil}, {`Int64Field == 10.5`, nil},
{`Int64Field > {target}`, map[string]*schemapb.TemplateValue{ {`Int64Field > {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Double, 11.2), "target": generateTemplateValue(schemapb.DataType_Double, 11.2),
}}, }},
{`FloatField < {target}`, map[string]*schemapb.TemplateValue{ {`FloatField < {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_String, "abc"), "target": generateTemplateValue(schemapb.DataType_String, "abc"),
}}, }},
{`DoubleField != {target}`, map[string]*schemapb.TemplateValue{ {`DoubleField != {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Bool, false), "target": generateTemplateValue(schemapb.DataType_Bool, false),
}}, }},
{`ArrayField[0] >= {target}`, map[string]*schemapb.TemplateValue{ {`ArrayField[0] >= {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Double, 3.5), "target": generateTemplateValue(schemapb.DataType_Double, 3.5),
}}, }},
{`BoolField == {bool}`, map[string]*schemapb.TemplateValue{ {`BoolField == {bool}`, map[string]*schemapb.TemplateValue{
"bool": generateExpressionFieldData(schemapb.DataType_String, "abc"), "bool": generateTemplateValue(schemapb.DataType_String, "abc"),
}}, }},
{`{str} != StringField`, map[string]*schemapb.TemplateValue{ {`{str} != StringField`, map[string]*schemapb.TemplateValue{
"str": generateExpressionFieldData(schemapb.DataType_Int64, int64(5)), "str": generateTemplateValue(schemapb.DataType_Int64, int64(5)),
}}, }},
{`{int} != StringField`, map[string]*schemapb.TemplateValue{ {`{int} != StringField`, map[string]*schemapb.TemplateValue{
"int": generateExpressionFieldData(schemapb.DataType_Int64, int64(5)), "int": generateTemplateValue(schemapb.DataType_Int64, int64(5)),
}}, }},
{`{str} != StringField`, map[string]*schemapb.TemplateValue{ {`{str} != StringField`, map[string]*schemapb.TemplateValue{
"int": generateExpressionFieldData(schemapb.DataType_Int64, int64(5)), "int": generateTemplateValue(schemapb.DataType_Int64, int64(5)),
}}, }},
} }
schemaH := newTestSchemaHelper(s.T()) schemaH := newTestSchemaHelper(s.T())
@ -207,32 +190,32 @@ func (s *FillExpressionValueSuite) TestBinaryRange() {
testcases := []testcase{ testcases := []testcase{
{`10 < Int64Field < 20`, nil}, {`10 < Int64Field < 20`, nil},
{`{max} > Int64Field > {min}`, map[string]*schemapb.TemplateValue{ {`{max} > Int64Field > {min}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Int64, int64(11)), "min": generateTemplateValue(schemapb.DataType_Int64, int64(11)),
"max": generateExpressionFieldData(schemapb.DataType_Int64, int64(22)), "max": generateTemplateValue(schemapb.DataType_Int64, int64(22)),
}}, }},
{`{min} <= FloatField <= {max}`, map[string]*schemapb.TemplateValue{ {`{min} <= FloatField <= {max}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Float, float64(11)), "min": generateTemplateValue(schemapb.DataType_Float, float64(11)),
"max": generateExpressionFieldData(schemapb.DataType_Float, float64(22)), "max": generateTemplateValue(schemapb.DataType_Float, float64(22)),
}}, }},
{`{min} < DoubleField < {max}`, map[string]*schemapb.TemplateValue{ {`{min} < DoubleField < {max}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Double, float64(11)), "min": generateTemplateValue(schemapb.DataType_Double, float64(11)),
"max": generateExpressionFieldData(schemapb.DataType_Double, float64(22)), "max": generateTemplateValue(schemapb.DataType_Double, float64(22)),
}}, }},
{`{max} >= ArrayField[0] >= {min}`, map[string]*schemapb.TemplateValue{ {`{max} >= ArrayField[0] >= {min}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Int64, int64(11)), "min": generateTemplateValue(schemapb.DataType_Int64, int64(11)),
"max": generateExpressionFieldData(schemapb.DataType_Int64, int64(22)), "max": generateTemplateValue(schemapb.DataType_Int64, int64(22)),
}}, }},
{`{max} > Int64Field >= 10`, map[string]*schemapb.TemplateValue{ {`{max} > Int64Field >= 10`, map[string]*schemapb.TemplateValue{
"max": generateExpressionFieldData(schemapb.DataType_Int64, int64(22)), "max": generateTemplateValue(schemapb.DataType_Int64, int64(22)),
}}, }},
{`30 >= Int64Field > {min}`, map[string]*schemapb.TemplateValue{ {`30 >= Int64Field > {min}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Int64, int64(11)), "min": generateTemplateValue(schemapb.DataType_Int64, int64(11)),
}}, }},
{`10 < Int64Field <= {max}`, map[string]*schemapb.TemplateValue{ {`10 < Int64Field <= {max}`, map[string]*schemapb.TemplateValue{
"max": generateExpressionFieldData(schemapb.DataType_Int64, int64(22)), "max": generateTemplateValue(schemapb.DataType_Int64, int64(22)),
}}, }},
{`{min} <= Int64Field < 20`, map[string]*schemapb.TemplateValue{ {`{min} <= Int64Field < 20`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Int64, int64(11)), "min": generateTemplateValue(schemapb.DataType_Int64, int64(11)),
}}, }},
} }
@ -246,29 +229,29 @@ func (s *FillExpressionValueSuite) TestBinaryRange() {
testcases := []testcase{ testcases := []testcase{
{`10 < Int64Field < 20.5`, nil}, {`10 < Int64Field < 20.5`, nil},
{`{max} > Int64Field > {min}`, map[string]*schemapb.TemplateValue{ {`{max} > Int64Field > {min}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Int64, int64(11)), "min": generateTemplateValue(schemapb.DataType_Int64, int64(11)),
"max": generateExpressionFieldData(schemapb.DataType_Double, 22.5), "max": generateTemplateValue(schemapb.DataType_Double, 22.5),
}}, }},
{`{min} <= FloatField <= {max}`, map[string]*schemapb.TemplateValue{ {`{min} <= FloatField <= {max}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_String, "abc"), "min": generateTemplateValue(schemapb.DataType_String, "abc"),
"max": generateExpressionFieldData(schemapb.DataType_Int64, int64(11)), "max": generateTemplateValue(schemapb.DataType_Int64, int64(11)),
}}, }},
{`{min} < DoubleField < {max}`, map[string]*schemapb.TemplateValue{ {`{min} < DoubleField < {max}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Int64, int64(33)), "min": generateTemplateValue(schemapb.DataType_Int64, int64(33)),
"max": generateExpressionFieldData(schemapb.DataType_Int64, int64(22)), "max": generateTemplateValue(schemapb.DataType_Int64, int64(22)),
}}, }},
{`{max} >= ArrayField[0] >= {min}`, map[string]*schemapb.TemplateValue{ {`{max} >= ArrayField[0] >= {min}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Double, 11.5), "min": generateTemplateValue(schemapb.DataType_Double, 11.5),
"max": generateExpressionFieldData(schemapb.DataType_Int64, int64(22)), "max": generateTemplateValue(schemapb.DataType_Int64, int64(22)),
}}, }},
{`{max} >= Int64Field >= {min}`, map[string]*schemapb.TemplateValue{ {`{max} >= Int64Field >= {min}`, map[string]*schemapb.TemplateValue{
"max": generateExpressionFieldData(schemapb.DataType_Int64, int64(22)), "max": generateTemplateValue(schemapb.DataType_Int64, int64(22)),
}}, }},
{`{max} > Int64Field`, map[string]*schemapb.TemplateValue{ {`{max} > Int64Field`, map[string]*schemapb.TemplateValue{
"max": generateExpressionFieldData(schemapb.DataType_Bool, false), "max": generateTemplateValue(schemapb.DataType_Bool, false),
}}, }},
{`{$meta} > Int64Field`, map[string]*schemapb.TemplateValue{ {`{$meta} > Int64Field`, map[string]*schemapb.TemplateValue{
"$meta": generateExpressionFieldData(schemapb.DataType_Int64, int64(22)), "$meta": generateTemplateValue(schemapb.DataType_Int64, int64(22)),
}}, }},
} }
@ -284,23 +267,23 @@ func (s *FillExpressionValueSuite) TestBinaryArithOpEvalRange() {
testcases := []testcase{ testcases := []testcase{
{`Int64Field + 5.5 == 10.5`, nil}, {`Int64Field + 5.5 == 10.5`, nil},
{`Int64Field - {offset} >= {target}`, map[string]*schemapb.TemplateValue{ {`Int64Field - {offset} >= {target}`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_Double, 3.5), "offset": generateTemplateValue(schemapb.DataType_Double, 3.5),
"target": generateExpressionFieldData(schemapb.DataType_Double, 11.5), "target": generateTemplateValue(schemapb.DataType_Double, 11.5),
}}, }},
{`Int64Field * 3.5 <= {target}`, map[string]*schemapb.TemplateValue{ {`Int64Field * 3.5 <= {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Double, 11.5), "target": generateTemplateValue(schemapb.DataType_Double, 11.5),
}}, }},
{`Int64Field / {offset} > 11.5`, map[string]*schemapb.TemplateValue{ {`Int64Field / {offset} > 11.5`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_Double, 3.5), "offset": generateTemplateValue(schemapb.DataType_Double, 3.5),
}}, }},
{`ArrayField[0] % {offset} < 11`, map[string]*schemapb.TemplateValue{ {`ArrayField[0] % {offset} < 11`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_Int64, int64(3)), "offset": generateTemplateValue(schemapb.DataType_Int64, int64(3)),
}}, }},
{`array_length(ArrayField) == {length}`, map[string]*schemapb.TemplateValue{ {`array_length(ArrayField) == {length}`, map[string]*schemapb.TemplateValue{
"length": generateExpressionFieldData(schemapb.DataType_Int64, int64(3)), "length": generateTemplateValue(schemapb.DataType_Int64, int64(3)),
}}, }},
{`array_length(ArrayField) > {length}`, map[string]*schemapb.TemplateValue{ {`array_length(ArrayField) > {length}`, map[string]*schemapb.TemplateValue{
"length": generateExpressionFieldData(schemapb.DataType_Int64, int64(3)), "length": generateTemplateValue(schemapb.DataType_Int64, int64(3)),
}}, }},
} }
@ -314,43 +297,40 @@ func (s *FillExpressionValueSuite) TestBinaryArithOpEvalRange() {
testcases := []testcase{ testcases := []testcase{
{`Int64Field + 6 == 12.5`, nil}, {`Int64Field + 6 == 12.5`, nil},
{`Int64Field - {offset} == {target}`, map[string]*schemapb.TemplateValue{ {`Int64Field - {offset} == {target}`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_Int64, int64(4)), "offset": generateTemplateValue(schemapb.DataType_Int64, int64(4)),
"target": generateExpressionFieldData(schemapb.DataType_Double, 13.5), "target": generateTemplateValue(schemapb.DataType_Double, 13.5),
}}, }},
{`Int64Field * 6 == {target}`, map[string]*schemapb.TemplateValue{ {`Int64Field * 6 == {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Double, 13.5), "target": generateTemplateValue(schemapb.DataType_Double, 13.5),
}}, }},
{`Int64Field / {offset} == 11.5`, map[string]*schemapb.TemplateValue{ {`Int64Field / {offset} == 11.5`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_Int64, int64(6)), "offset": generateTemplateValue(schemapb.DataType_Int64, int64(6)),
}}, }},
{`Int64Field % {offset} < 11`, map[string]*schemapb.TemplateValue{ {`Int64Field % {offset} < 11`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_Double, 3.5), "offset": generateTemplateValue(schemapb.DataType_Double, 3.5),
}}, }},
{`Int64Field + {offset} < {target}`, map[string]*schemapb.TemplateValue{ {`Int64Field + {offset} < {target}`, map[string]*schemapb.TemplateValue{
"target": generateExpressionFieldData(schemapb.DataType_Double, 3.5), "target": generateTemplateValue(schemapb.DataType_Double, 3.5),
}}, }},
{`Int64Field + {offset} < {target}`, map[string]*schemapb.TemplateValue{ {`Int64Field + {offset} < {target}`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_String, "abc"), "offset": generateTemplateValue(schemapb.DataType_String, "abc"),
"target": generateExpressionFieldData(schemapb.DataType_Int64, int64(15)), "target": generateTemplateValue(schemapb.DataType_Int64, int64(15)),
}}, }},
{`Int64Field + {offset} < {target}`, map[string]*schemapb.TemplateValue{ {`Int64Field + {offset} < {target}`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_Int64, int64(15)), "offset": generateTemplateValue(schemapb.DataType_Int64, int64(15)),
"target": generateExpressionFieldData(schemapb.DataType_String, "def"), "target": generateTemplateValue(schemapb.DataType_String, "def"),
}}, }},
{`ArrayField + {offset} < {target}`, map[string]*schemapb.TemplateValue{ {`ArrayField + {offset} < {target}`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_Double, 3.5), "offset": generateTemplateValue(schemapb.DataType_Double, 3.5),
"target": generateExpressionFieldData(schemapb.DataType_Int64, int64(5)), "target": generateTemplateValue(schemapb.DataType_Int64, int64(5)),
}}, }},
{`ArrayField[0] + {offset} < {target}`, map[string]*schemapb.TemplateValue{ {`ArrayField[0] + {offset} < {target}`, map[string]*schemapb.TemplateValue{
"offset": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "offset": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3)})),
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)), "target": generateTemplateValue(schemapb.DataType_Int64, int64(5)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)),
}),
"target": generateExpressionFieldData(schemapb.DataType_Int64, int64(5)),
}}, }},
{`array_length(ArrayField) == {length}`, map[string]*schemapb.TemplateValue{ {`array_length(ArrayField) == {length}`, map[string]*schemapb.TemplateValue{
"length": generateExpressionFieldData(schemapb.DataType_String, "abc"), "length": generateTemplateValue(schemapb.DataType_String, "abc"),
}}, }},
} }
@ -366,70 +346,53 @@ func (s *FillExpressionValueSuite) TestJSONContainsExpression() {
testcases := []testcase{ testcases := []testcase{
{`json_contains(A, 5)`, nil}, {`json_contains(A, 5)`, nil},
{`json_contains(A, {age})`, map[string]*schemapb.TemplateValue{ {`json_contains(A, {age})`, map[string]*schemapb.TemplateValue{
"age": generateExpressionFieldData(schemapb.DataType_Int64, int64(18)), "age": generateTemplateValue(schemapb.DataType_Int64, int64(18)),
}}, }},
{`json_contains(A, {str})`, map[string]*schemapb.TemplateValue{ {`json_contains(A, {str})`, map[string]*schemapb.TemplateValue{
"str": generateExpressionFieldData(schemapb.DataType_String, "abc"), "str": generateTemplateValue(schemapb.DataType_String, "abc"),
}}, }},
{`json_contains(A, {bool})`, map[string]*schemapb.TemplateValue{ {`json_contains(A, {bool})`, map[string]*schemapb.TemplateValue{
"bool": generateExpressionFieldData(schemapb.DataType_Bool, false), "bool": generateTemplateValue(schemapb.DataType_Bool, false),
}}, }},
{`json_contains_any(JSONField, {array})`, map[string]*schemapb.TemplateValue{ {`json_contains_any(JSONField, {array})`, map[string]*schemapb.TemplateValue{
"array": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "array": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_JSON, [][]byte{
generateExpressionFieldData(schemapb.DataType_String, "abc"), generateJSONData(int64(1)),
generateExpressionFieldData(schemapb.DataType_Double, 2.2), generateJSONData("abc"),
generateExpressionFieldData(schemapb.DataType_Bool, false), generateJSONData(2.2),
}), generateJSONData(false),
})),
}}, }},
{`json_contains_any(JSONField, {array})`, map[string]*schemapb.TemplateValue{ {`json_contains_any(JSONField, {array})`, map[string]*schemapb.TemplateValue{
"array": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "array": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3), int64(4)})),
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(4)),
}),
}}, }},
{`json_contains_any(JSONField["A"], {array})`, map[string]*schemapb.TemplateValue{ {`json_contains_any(JSONField["A"], {array})`, map[string]*schemapb.TemplateValue{
"array": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "array": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3), int64(4)})),
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(4)),
}),
}}, }},
{`json_contains_all(JSONField["A"], {array})`, map[string]*schemapb.TemplateValue{ {`json_contains_all(JSONField["A"], {array})`, map[string]*schemapb.TemplateValue{
"array": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "array": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_JSON, [][]byte{
generateExpressionFieldData(schemapb.DataType_String, "abc"), generateJSONData(int64(1)),
generateExpressionFieldData(schemapb.DataType_Double, 2.2), generateJSONData("abc"),
generateExpressionFieldData(schemapb.DataType_Bool, false), generateJSONData(2.2),
}), generateJSONData(false),
})),
}}, }},
{`json_contains_all(JSONField["A"], {array})`, map[string]*schemapb.TemplateValue{ {`json_contains_all(JSONField["A"], {array})`, map[string]*schemapb.TemplateValue{
"array": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "array": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ generateTemplateArrayValue(schemapb.DataType_Array, []*schemapb.TemplateArrayValue{
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3)}),
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(4), int64(5), int64(6)}),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)), })),
}),
generateExpressionFieldData(schemapb.DataType_Array, []interface{}{
generateExpressionFieldData(schemapb.DataType_Int64, int64(4)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(5)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(6)),
}),
}),
}}, }},
{`json_contains(ArrayField, {int})`, map[string]*schemapb.TemplateValue{ {`json_contains(ArrayField, {int})`, map[string]*schemapb.TemplateValue{
"int": generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), "int": generateTemplateValue(schemapb.DataType_Int64, int64(1)),
}}, }},
{`json_contains_any(ArrayField, {list})`, map[string]*schemapb.TemplateValue{ {`json_contains_any(ArrayField, {list})`, map[string]*schemapb.TemplateValue{
"list": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "list": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3), int64(4)})),
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(4)),
}),
}}, }},
} }
@ -443,43 +406,39 @@ func (s *FillExpressionValueSuite) TestJSONContainsExpression() {
s.Run("failed case", func() { s.Run("failed case", func() {
testcases := []testcase{ testcases := []testcase{
{`json_contains(ArrayField[0], {str})`, map[string]*schemapb.TemplateValue{ {`json_contains(ArrayField[0], {str})`, map[string]*schemapb.TemplateValue{
"str": generateExpressionFieldData(schemapb.DataType_String, "abc"), "str": generateTemplateValue(schemapb.DataType_String, "abc"),
}}, }},
{`json_contains_any(JSONField, {not_array})`, map[string]*schemapb.TemplateValue{ {`json_contains_any(JSONField, {not_array})`, map[string]*schemapb.TemplateValue{
"not_array": generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), "not_array": generateTemplateValue(schemapb.DataType_Int64, int64(1)),
}}, }},
{`json_contains_all(JSONField, {not_array})`, map[string]*schemapb.TemplateValue{ {`json_contains_all(JSONField, {not_array})`, map[string]*schemapb.TemplateValue{
"not_array": generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), "not_array": generateTemplateValue(schemapb.DataType_Int64, int64(1)),
}}, }},
{`json_contains_all(JSONField, {not_array})`, map[string]*schemapb.TemplateValue{ {`json_contains_all(JSONField, {not_array})`, map[string]*schemapb.TemplateValue{
"array": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "array": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3)})),
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)),
}),
}}, }},
{`json_contains_all(ArrayField, {array})`, map[string]*schemapb.TemplateValue{ {`json_contains_all(ArrayField, {array})`, map[string]*schemapb.TemplateValue{
"array": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "array": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_JSON, [][]byte{
generateExpressionFieldData(schemapb.DataType_String, "abc"), generateJSONData(int64(1)),
generateExpressionFieldData(schemapb.DataType_Double, 2.2), generateJSONData("abc"),
generateExpressionFieldData(schemapb.DataType_Bool, false), generateJSONData(2.2),
}), generateJSONData(false),
})),
}}, }},
{`json_contains(ArrayField, {array})`, map[string]*schemapb.TemplateValue{ {`json_contains(ArrayField, {array})`, map[string]*schemapb.TemplateValue{
"array": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "array": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_Int64, []int64{int64(1), int64(2), int64(3)})),
generateExpressionFieldData(schemapb.DataType_Int64, int64(2)),
generateExpressionFieldData(schemapb.DataType_Int64, int64(3)),
}),
}}, }},
{`json_contains_any(ArrayField, {array})`, map[string]*schemapb.TemplateValue{ {`json_contains_any(ArrayField, {array})`, map[string]*schemapb.TemplateValue{
"array": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "array": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_Int64, int64(1)), generateTemplateArrayValue(schemapb.DataType_JSON, [][]byte{
generateExpressionFieldData(schemapb.DataType_String, "abc"), generateJSONData(int64(1)),
generateExpressionFieldData(schemapb.DataType_Double, 2.2), generateJSONData("abc"),
generateExpressionFieldData(schemapb.DataType_Bool, false), generateJSONData(2.2),
}), generateJSONData(false),
})),
}}, }},
} }
@ -495,17 +454,14 @@ func (s *FillExpressionValueSuite) TestBinaryExpression() {
s.Run("normal case", func() { s.Run("normal case", func() {
testcases := []testcase{ testcases := []testcase{
{`Int64Field > {int} && StringField in {list}`, map[string]*schemapb.TemplateValue{ {`Int64Field > {int} && StringField in {list}`, map[string]*schemapb.TemplateValue{
"int": generateExpressionFieldData(schemapb.DataType_Int64, int64(10)), "int": generateTemplateValue(schemapb.DataType_Int64, int64(10)),
"list": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "list": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_VarChar, "abc"), generateTemplateArrayValue(schemapb.DataType_String, []string{"abc", "def", "ghi"})),
generateExpressionFieldData(schemapb.DataType_VarChar, "def"),
generateExpressionFieldData(schemapb.DataType_VarChar, "ghi"),
}),
}}, }},
{`{max} > FloatField >= {min} or BoolField == {bool}`, map[string]*schemapb.TemplateValue{ {`{max} > FloatField >= {min} or BoolField == {bool}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Int64, int64(10)), "min": generateTemplateValue(schemapb.DataType_Int64, int64(10)),
"max": generateExpressionFieldData(schemapb.DataType_Float, 22.22), "max": generateTemplateValue(schemapb.DataType_Float, 22.22),
"bool": generateExpressionFieldData(schemapb.DataType_Bool, true), "bool": generateTemplateValue(schemapb.DataType_Bool, true),
}}, }},
} }
@ -519,16 +475,17 @@ func (s *FillExpressionValueSuite) TestBinaryExpression() {
s.Run("failed case", func() { s.Run("failed case", func() {
testcases := []testcase{ testcases := []testcase{
{`Int64Field > {int} && StringField in {list}`, map[string]*schemapb.TemplateValue{ {`Int64Field > {int} && StringField in {list}`, map[string]*schemapb.TemplateValue{
"int": generateExpressionFieldData(schemapb.DataType_String, "abc"), "int": generateTemplateValue(schemapb.DataType_String, "abc"),
"list": generateExpressionFieldData(schemapb.DataType_Array, []interface{}{ "list": generateTemplateValue(schemapb.DataType_Array,
generateExpressionFieldData(schemapb.DataType_VarChar, "abc"), generateTemplateArrayValue(schemapb.DataType_JSON, [][]byte{
generateExpressionFieldData(schemapb.DataType_Int64, int64(10)), generateJSONData("abc"),
generateExpressionFieldData(schemapb.DataType_VarChar, "ghi"), generateJSONData(int64(10)),
}), generateJSONData("ghi"),
})),
}}, }},
{`{max} > FloatField >= {min} or BoolField == {bool}`, map[string]*schemapb.TemplateValue{ {`{max} > FloatField >= {min} or BoolField == {bool}`, map[string]*schemapb.TemplateValue{
"min": generateExpressionFieldData(schemapb.DataType_Int64, int64(10)), "min": generateTemplateValue(schemapb.DataType_Int64, int64(10)),
"bool": generateExpressionFieldData(schemapb.DataType_Bool, true), "bool": generateTemplateValue(schemapb.DataType_Bool, true),
}}, }},
} }

View File

@ -1454,12 +1454,12 @@ func BenchmarkTemplateWithString(b *testing.B) {
elements := make([]interface{}, 100) elements := make([]interface{}, 100)
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
elements[i] = generateExpressionFieldData(schemapb.DataType_String, fmt.Sprintf(`"%s",`, randomChineseString(rand.Intn(100)))) elements[i] = generateTemplateValue(schemapb.DataType_String, fmt.Sprintf(`"%s",`, randomChineseString(rand.Intn(100))))
} }
expr := "StringField in {list}" expr := "StringField in {list}"
mv := map[string]*schemapb.TemplateValue{ mv := map[string]*schemapb.TemplateValue{
"list": generateExpressionFieldData(schemapb.DataType_Array, elements), "list": generateTemplateValue(schemapb.DataType_Array, elements),
} }
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {