package row import ( "reflect" "testing" "github.com/stretchr/testify/suite" "github.com/milvus-io/milvus/client/v2/entity" ) type ValidStruct struct { ID int64 `milvus:"primary_key"` Attr1 int8 Attr2 int16 Attr3 int32 Attr4 float32 Attr5 float64 Attr6 string Attr7 bool Vector []float32 `milvus:"dim:16"` Vector2 []byte `milvus:"dim:32"` } type ValidStruct2 struct { ID int64 `milvus:"primary_key"` Vector [16]float32 Vector2 [4]byte Ignored bool `milvus:"-"` } type ValidStructWithNamedTag struct { ID int64 `milvus:"primary_key;name:id"` Vector [16]float32 `milvus:"name:vector"` } type RowsSuite struct { suite.Suite } func (s *RowsSuite) TestRowsToColumns() { s.Run("valid_cases", func() { columns, err := AnyToColumns([]any{&ValidStruct{}}) s.Nil(err) s.Equal(10, len(columns)) columns, err = AnyToColumns([]any{&ValidStruct2{}}) s.Nil(err) s.Equal(3, len(columns)) }) s.Run("auto_id_pk", func() { type AutoPK struct { ID int64 `milvus:"primary_key;auto_id"` Vector []float32 `milvus:"dim:32"` } columns, err := AnyToColumns([]any{&AutoPK{}}) s.Nil(err) s.Require().Equal(1, len(columns)) s.Equal("Vector", columns[0].Name()) }) s.Run("fp16", func() { type BF16Struct struct { ID int64 `milvus:"primary_key;auto_id"` Vector []byte `milvus:"dim:16;vector_type:bf16"` } columns, err := AnyToColumns([]any{&BF16Struct{}}) s.Nil(err) s.Require().Equal(1, len(columns)) s.Equal("Vector", columns[0].Name()) s.Equal(entity.FieldTypeBFloat16Vector, columns[0].Type()) }) s.Run("fp16", func() { type FP16Struct struct { ID int64 `milvus:"primary_key;auto_id"` Vector []byte `milvus:"dim:16;vector_type:fp16"` } columns, err := AnyToColumns([]any{&FP16Struct{}}) s.Nil(err) s.Require().Equal(1, len(columns)) s.Equal("Vector", columns[0].Name()) s.Equal(entity.FieldTypeFloat16Vector, columns[0].Type()) }) s.Run("invalid_cases", func() { // empty input _, err := AnyToColumns([]any{}) s.NotNil(err) // incompatible rows _, err = AnyToColumns([]any{&ValidStruct{}, &ValidStruct2{}}) s.NotNil(err) // schema & row not compatible _, err = AnyToColumns([]any{&ValidStruct{}}, &entity.Schema{ Fields: []*entity.Field{ { Name: "int64", DataType: entity.FieldTypeInt64, }, }, }) s.NotNil(err) }) } func (s *RowsSuite) TestDynamicSchema() { s.Run("all_fallback_dynamic", func() { columns, err := AnyToColumns([]any{&ValidStruct{}}, entity.NewSchema().WithDynamicFieldEnabled(true), ) s.NoError(err) s.Equal(1, len(columns)) }) s.Run("dynamic_not_found", func() { _, err := AnyToColumns([]any{&ValidStruct{}}, entity.NewSchema().WithField( entity.NewField().WithName("ID").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true), ).WithDynamicFieldEnabled(true), ) s.NoError(err) }) } func (s *RowsSuite) TestReflectValueCandi() { cases := []struct { tag string v reflect.Value expect map[string]fieldCandi expectErr bool }{ { tag: "MapRow", v: reflect.ValueOf(map[string]interface{}{ "A": "abd", "B": int64(8), }), expect: map[string]fieldCandi{ "A": { name: "A", v: reflect.ValueOf("abd"), }, "B": { name: "B", v: reflect.ValueOf(int64(8)), }, }, expectErr: false, }, } for _, c := range cases { s.Run(c.tag, func() { r, err := reflectValueCandi(c.v) if c.expectErr { s.Error(err) return } s.NoError(err) s.Equal(len(c.expect), len(r)) for k, v := range c.expect { rv, has := r[k] s.Require().True(has) s.Equal(v.name, rv.name) } }) } } func TestRows(t *testing.T) { suite.Run(t, new(RowsSuite)) }