From 1e48911825bb1c65fda1dd82bc75cfac378dd3b3 Mon Sep 17 00:00:00 2001 From: congqixia Date: Wed, 5 Nov 2025 15:43:33 +0800 Subject: [PATCH] enhance: [GoSDK] Support struct array field type (#45291) Related to #42148 Add comprehensive support for struct array field type in the Go SDK, including data structure definitions, column operations, schema construction, and full test coverage. **Struct Array Column Implementation (`client/column/struct.go`)** - Add `columnStructArray` type to handle struct array fields - Implement `Column` interface methods: - `NewColumnStructArray()`: Create new struct array column from sub-fields - `Name()`, `Type()`: Basic metadata accessors - `Slice()`: Support slicing across all sub-fields - `FieldData()`: Convert to protobuf `StructArrayField` format - `Get()`: Retrieve struct values as `map[string]any` - `ValidateNullable()`, `CompactNullableValues()`: Nullable support - Placeholder implementations for unsupported operations (AppendValue, GetAsX, IsNull, AppendNull) **Struct Array Parsing (`client/column/columns.go`)** - Add `parseStructArrayData()` function to parse `StructArrayField` from protobuf - Update `FieldDataColumn()` to detect and parse struct array fields - Support range-based slicing for struct array data --------- Signed-off-by: Congqi Xia --- client/column/columns.go | 16 + client/column/struct.go | 138 +++++++++ client/column/struct_test.go | 292 ++++++++++++++++++ client/entity/common.go | 8 + client/entity/field.go | 23 ++ client/entity/field_test.go | 42 +++ client/entity/schema.go | 33 +- client/entity/schema_test.go | 111 +++++++ client/go.mod | 9 +- client/go.sum | 18 +- .../milvusclient/mock_milvus_server_test.go | 177 +++++++++++ tests/go_client/go.mod | 4 +- tests/go_client/go.sum | 10 +- 13 files changed, 865 insertions(+), 16 deletions(-) create mode 100644 client/column/struct.go create mode 100644 client/column/struct_test.go diff --git a/client/column/columns.go b/client/column/columns.go index 9ebf1cbbe1..c3350e1732 100644 --- a/client/column/columns.go +++ b/client/column/columns.go @@ -161,6 +161,18 @@ func parseArrayData(fieldName string, elementType schemapb.DataType, fieldDataLi } } +func parseStructArrayData(fieldName string, structArray *schemapb.StructArrayField, begin, end int) (Column, error) { + var fields []Column + for _, field := range structArray.GetFields() { + field, err := FieldDataColumn(field, begin, end) + if err != nil { + return nil, err + } + fields = append(fields, field) + } + return NewColumnStructArray(fieldName, fields), nil +} + func int32ToType[T ~int8 | int16](data []int32) []T { return lo.Map(data, func(i32 int32, _ int) T { return T(i32) @@ -206,6 +218,10 @@ func FieldDataColumn(fd *schemapb.FieldData, begin, end int) (Column, error) { return parseScalarData(fd.GetFieldName(), fd.GetScalars().GetStringData().GetData(), begin, end, validData, NewColumnVarChar, NewNullableColumnVarChar) case schemapb.DataType_Array: + // handle struct array field + if fd.GetStructArrays() != nil { + return parseStructArrayData(fd.GetFieldName(), fd.GetStructArrays(), begin, end) + } data := fd.GetScalars().GetArrayData() return parseArrayData(fd.GetFieldName(), data.GetElementType(), data.GetData(), validData, begin, end) diff --git a/client/column/struct.go b/client/column/struct.go new file mode 100644 index 0000000000..4b06886fc1 --- /dev/null +++ b/client/column/struct.go @@ -0,0 +1,138 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package column + +import ( + "github.com/cockroachdb/errors" + "github.com/samber/lo" + + "github.com/milvus-io/milvus-proto/go-api/v2/schemapb" + "github.com/milvus-io/milvus/client/v2/entity" +) + +type columnStructArray struct { + fields []Column + name string +} + +func NewColumnStructArray(name string, fields []Column) Column { + return &columnStructArray{ + fields: fields, + name: name, + } +} + +func (c *columnStructArray) Name() string { + return c.name +} + +func (c *columnStructArray) Type() entity.FieldType { + return entity.FieldTypeArray +} + +func (c *columnStructArray) Len() int { + for _, field := range c.fields { + return field.Len() + } + return 0 +} + +func (c *columnStructArray) Slice(start, end int) Column { + fields := make([]Column, len(c.fields)) + for idx, subField := range c.fields { + fields[idx] = subField.Slice(start, end) + } + c.fields = fields + return c +} + +func (c *columnStructArray) FieldData() *schemapb.FieldData { + return &schemapb.FieldData{ + Type: schemapb.DataType_Array, + FieldName: c.name, + Field: &schemapb.FieldData_StructArrays{ + StructArrays: &schemapb.StructArrayField{ + Fields: lo.Map(c.fields, func(field Column, _ int) *schemapb.FieldData { + return field.FieldData() + }), + }, + }, + } +} + +func (c *columnStructArray) AppendValue(value any) error { + return errors.New("not implemented") +} + +func (c *columnStructArray) Get(idx int) (any, error) { + m := make(map[string]any) + for _, field := range c.fields { + v, err := field.Get(idx) + if err != nil { + return nil, err + } + m[field.Name()] = v + } + return m, nil +} + +func (c *columnStructArray) GetAsInt64(idx int) (int64, error) { + return 0, errors.New("not implemented") +} + +func (c *columnStructArray) GetAsString(idx int) (string, error) { + return "", errors.New("not implemented") +} + +func (c *columnStructArray) GetAsDouble(idx int) (float64, error) { + return 0, errors.New("not implemented") +} + +func (c *columnStructArray) GetAsBool(idx int) (bool, error) { + return false, errors.New("not implemented") +} + +func (c *columnStructArray) IsNull(idx int) (bool, error) { + return false, errors.New("not implemented") +} + +func (c *columnStructArray) AppendNull() error { + return errors.New("not implemented") +} + +func (c *columnStructArray) Nullable() bool { + return false +} + +func (c *columnStructArray) SetNullable(nullable bool) { + // Shall not be set +} + +func (c *columnStructArray) ValidateNullable() error { + for _, field := range c.fields { + if err := field.ValidateNullable(); err != nil { + return err + } + } + return nil +} + +func (c *columnStructArray) CompactNullableValues() { + for _, field := range c.fields { + field.CompactNullableValues() + } +} diff --git a/client/column/struct_test.go b/client/column/struct_test.go new file mode 100644 index 0000000000..8e444d8672 --- /dev/null +++ b/client/column/struct_test.go @@ -0,0 +1,292 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package column + +import ( + "fmt" + "math/rand" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/milvus-io/milvus-proto/go-api/v2/schemapb" + "github.com/milvus-io/milvus/client/v2/entity" +) + +type StructArraySuite struct { + suite.Suite +} + +func (s *StructArraySuite) TestBasic() { + name := fmt.Sprintf("struct_array_%d", rand.Intn(100)) + + // Create sub-fields for the struct + int32Data := []int32{1, 2, 3, 4, 5} + floatData := []float32{1.1, 2.2, 3.3, 4.4, 5.5} + varcharData := []string{"a", "b", "c", "d", "e"} + + int32Col := NewColumnInt32("int_field", int32Data) + floatCol := NewColumnFloat("float_field", floatData) + varcharCol := NewColumnVarChar("varchar_field", varcharData) + + fields := []Column{int32Col, floatCol, varcharCol} + column := NewColumnStructArray(name, fields) + + // Test Name() + s.Equal(name, column.Name()) + + // Test Type() + s.Equal(entity.FieldTypeArray, column.Type()) + + // Test Len() + s.EqualValues(5, column.Len()) + + // Test FieldData() + fd := column.FieldData() + s.Equal(schemapb.DataType_Array, fd.GetType()) + s.Equal(name, fd.GetFieldName()) + + structArrays := fd.GetStructArrays() + s.NotNil(structArrays) + s.Equal(3, len(structArrays.GetFields())) + + // Verify each field in the struct array + fieldNames := []string{"int_field", "float_field", "varchar_field"} + for i, field := range structArrays.GetFields() { + s.Equal(fieldNames[i], field.GetFieldName()) + } + + // Test Get() - retrieve values as map + val, err := column.Get(0) + s.NoError(err) + m, ok := val.(map[string]any) + s.True(ok) + s.Equal(int32(1), m["int_field"]) + s.Equal(float32(1.1), m["float_field"]) + s.Equal("a", m["varchar_field"]) + + val, err = column.Get(2) + s.NoError(err) + m, ok = val.(map[string]any) + s.True(ok) + s.Equal(int32(3), m["int_field"]) + s.Equal(float32(3.3), m["float_field"]) + s.Equal("c", m["varchar_field"]) +} + +func (s *StructArraySuite) TestSlice() { + name := "struct_array_slice" + + // Create sub-fields + int64Data := []int64{10, 20, 30, 40, 50} + boolData := []bool{true, false, true, false, true} + + int64Col := NewColumnInt64("id", int64Data) + boolCol := NewColumnBool("flag", boolData) + + fields := []Column{int64Col, boolCol} + column := NewColumnStructArray(name, fields) + + // Test Slice(1, 4) - should slice all sub-fields + sliced := column.Slice(1, 4) + s.NotNil(sliced) + + // Verify sliced data + val, err := sliced.Get(0) + s.NoError(err) + m, ok := val.(map[string]any) + s.True(ok) + s.Equal(int64(20), m["id"]) + s.Equal(false, m["flag"]) + + val, err = sliced.Get(2) + s.NoError(err) + m, ok = val.(map[string]any) + s.True(ok) + s.Equal(int64(40), m["id"]) + s.Equal(false, m["flag"]) +} + +func (s *StructArraySuite) TestNullable() { + name := "struct_array_nullable" + + // Create sub-fields + int32Data := []int32{1, 2, 3} + int32Col := NewColumnInt32("field1", int32Data) + + varcharData := []string{"x", "y", "z"} + varcharCol := NewColumnVarChar("field2", varcharData) + + fields := []Column{int32Col, varcharCol} + column := NewColumnStructArray(name, fields) + + // Test Nullable() - should return false by default + s.False(column.Nullable()) + + // Test ValidateNullable() - should validate all sub-fields + err := column.ValidateNullable() + s.NoError(err) + + // Test CompactNullableValues() - should not panic + s.NotPanics(func() { + column.CompactNullableValues() + }) +} + +func (s *StructArraySuite) TestNotImplementedMethods() { + name := "struct_array_not_impl" + + int32Data := []int32{1, 2, 3} + int32Col := NewColumnInt32("field1", int32Data) + fields := []Column{int32Col} + column := NewColumnStructArray(name, fields) + + // Test AppendValue - should return error + err := column.AppendValue(map[string]any{"field1": int32(4)}) + s.Error(err) + s.Contains(err.Error(), "not implemented") + + // Test GetAsInt64 - should return error + _, err = column.GetAsInt64(0) + s.Error(err) + s.Contains(err.Error(), "not implemented") + + // Test GetAsString - should return error + _, err = column.GetAsString(0) + s.Error(err) + s.Contains(err.Error(), "not implemented") + + // Test GetAsDouble - should return error + _, err = column.GetAsDouble(0) + s.Error(err) + s.Contains(err.Error(), "not implemented") + + // Test GetAsBool - should return error + _, err = column.GetAsBool(0) + s.Error(err) + s.Contains(err.Error(), "not implemented") + + // Test IsNull - should return error + _, err = column.IsNull(0) + s.Error(err) + s.Contains(err.Error(), "not implemented") + + // Test AppendNull - should return error + err = column.AppendNull() + s.Error(err) + s.Contains(err.Error(), "not implemented") +} + +func (s *StructArraySuite) TestParseStructArrayData() { + // Create a FieldData with struct array + int32FieldData := &schemapb.FieldData{ + Type: schemapb.DataType_Int32, + FieldName: "age", + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_IntData{ + IntData: &schemapb.IntArray{ + Data: []int32{10, 20, 30}, + }, + }, + }, + }, + } + + varcharFieldData := &schemapb.FieldData{ + Type: schemapb.DataType_VarChar, + FieldName: "name", + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_StringData{ + StringData: &schemapb.StringArray{ + Data: []string{"alice", "bob", "charlie"}, + }, + }, + }, + }, + } + + structArrayField := &schemapb.StructArrayField{ + Fields: []*schemapb.FieldData{int32FieldData, varcharFieldData}, + } + + // Test parseStructArrayData + column, err := parseStructArrayData("person", structArrayField, 0, -1) + s.NoError(err) + s.NotNil(column) + s.Equal("person", column.Name()) + s.Equal(entity.FieldTypeArray, column.Type()) + + // Verify we can get values + val, err := column.Get(0) + s.NoError(err) + m, ok := val.(map[string]any) + s.True(ok) + s.Equal(int32(10), m["age"]) + s.Equal("alice", m["name"]) + + val, err = column.Get(1) + s.NoError(err) + m, ok = val.(map[string]any) + s.True(ok) + s.Equal(int32(20), m["age"]) + s.Equal("bob", m["name"]) +} + +func (s *StructArraySuite) TestParseStructArrayDataWithRange() { + // Create a FieldData with struct array + int64FieldData := &schemapb.FieldData{ + Type: schemapb.DataType_Int64, + FieldName: "id", + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_LongData{ + LongData: &schemapb.LongArray{ + Data: []int64{100, 200, 300, 400, 500}, + }, + }, + }, + }, + } + + structArrayField := &schemapb.StructArrayField{ + Fields: []*schemapb.FieldData{int64FieldData}, + } + + // Test parseStructArrayData with range [1, 4) + column, err := parseStructArrayData("data", structArrayField, 1, 4) + s.NoError(err) + s.NotNil(column) + + // Verify sliced data (should contain indices 1, 2, 3) + val, err := column.Get(0) + s.NoError(err) + m, ok := val.(map[string]any) + s.True(ok) + s.Equal(int64(200), m["id"]) + + val, err = column.Get(2) + s.NoError(err) + m, ok = val.(map[string]any) + s.True(ok) + s.Equal(int64(400), m["id"]) +} + +func TestStructArray(t *testing.T) { + suite.Run(t, new(StructArraySuite)) +} diff --git a/client/entity/common.go b/client/entity/common.go index d81919e64a..091eec1948 100644 --- a/client/entity/common.go +++ b/client/entity/common.go @@ -33,6 +33,14 @@ const ( SUPERSTRUCTURE MetricType = "SUPERSTRUCTURE" BM25 MetricType = "BM25" MHJACCARD MetricType = "MHJACCARD" + + // The same with MaxSimCosine + MaxSim MetricType = "MAX_SIM" + MaxSimCosine MetricType = "MAX_SIM_COSINE" + MaxSimL2 MetricType = "MAX_SIM_L2" + MaxSimIP MetricType = "MAX_SIM_IP" + MaxSimHamming MetricType = "MAX_SIM_HAMMING" + MaxSimJaccard MetricType = "MAX_SIM_JACCARD" ) // CompactionState enum type for compaction state diff --git a/client/entity/field.go b/client/entity/field.go index 29f2099bb8..b1795ef51e 100644 --- a/client/entity/field.go +++ b/client/entity/field.go @@ -201,6 +201,9 @@ const ( FieldTypeSparseVector FieldType = 104 // FieldTypeInt8Vector field type int8 vector FieldTypeInt8Vector FieldType = 105 + + // FieldTypeStruct field type struct + FieldTypeStruct FieldType = 201 ) // Field represent field schema in milvus @@ -219,6 +222,7 @@ type Field struct { ElementType FieldType DefaultValue *schemapb.ValueField Nullable bool + StructSchema *StructSchema } // ProtoMessage generates corresponding FieldSchema @@ -440,6 +444,11 @@ func (f *Field) WithEnableMatch(enable bool) *Field { return f } +func (f *Field) WithStructSchema(schema *StructSchema) *Field { + f.StructSchema = schema + return f +} + // ReadProto parses FieldSchema func (f *Field) ReadProto(p *schemapb.FieldSchema) *Field { f.ID = p.GetFieldID() @@ -459,3 +468,17 @@ func (f *Field) ReadProto(p *schemapb.FieldSchema) *Field { return f } + +// StructArrayField represents a struct array field +type StructSchema struct { + Fields []*Field +} + +func NewStructSchema() *StructSchema { + return &StructSchema{} +} + +func (f *StructSchema) WithField(field *Field) *StructSchema { + f.Fields = append(f.Fields, field) + return f +} diff --git a/client/entity/field_test.go b/client/entity/field_test.go index 29481be28a..2df9491b12 100644 --- a/client/entity/field_test.go +++ b/client/entity/field_test.go @@ -72,3 +72,45 @@ func TestFieldSchema(t *testing.T) { (&Field{}).WithTypeParams("a", "b") }) } + +func TestStructSchema(t *testing.T) { + // Test NewStructSchema + schema := NewStructSchema() + assert.NotNil(t, schema) + assert.Empty(t, schema.Fields) + + // Test WithField + field1 := NewField().WithName("age").WithDataType(FieldTypeInt32) + field2 := NewField().WithName("name").WithDataType(FieldTypeVarChar).WithMaxLength(100) + field3 := NewField().WithName("score").WithDataType(FieldTypeFloat) + + schema.WithField(field1).WithField(field2).WithField(field3) + assert.Equal(t, 3, len(schema.Fields)) + assert.Equal(t, "age", schema.Fields[0].Name) + assert.Equal(t, FieldTypeInt32, schema.Fields[0].DataType) + assert.Equal(t, "name", schema.Fields[1].Name) + assert.Equal(t, FieldTypeVarChar, schema.Fields[1].DataType) + assert.Equal(t, "score", schema.Fields[2].Name) + assert.Equal(t, FieldTypeFloat, schema.Fields[2].DataType) +} + +func TestFieldWithStructSchema(t *testing.T) { + // Create a struct schema + structSchema := NewStructSchema(). + WithField(NewField().WithName("id").WithDataType(FieldTypeInt64)). + WithField(NewField().WithName("value").WithDataType(FieldTypeDouble)) + + // Create a field with struct schema + field := NewField(). + WithName("struct_array_field"). + WithDataType(FieldTypeArray). + WithElementType(FieldTypeStruct). + WithStructSchema(structSchema) + + assert.NotNil(t, field.StructSchema) + assert.Equal(t, 2, len(field.StructSchema.Fields)) + assert.Equal(t, "id", field.StructSchema.Fields[0].Name) + assert.Equal(t, FieldTypeInt64, field.StructSchema.Fields[0].DataType) + assert.Equal(t, "value", field.StructSchema.Fields[1].Name) + assert.Equal(t, FieldTypeDouble, field.StructSchema.Fields[1].DataType) +} diff --git a/client/entity/schema.go b/client/entity/schema.go index 8d6714bd4a..709366ad3b 100644 --- a/client/entity/schema.go +++ b/client/entity/schema.go @@ -21,6 +21,7 @@ import ( "github.com/milvus-io/milvus-proto/go-api/v2/commonpb" "github.com/milvus-io/milvus-proto/go-api/v2/schemapb" + "github.com/milvus-io/milvus/pkg/v2/util/typeutil" ) const ( @@ -117,14 +118,42 @@ func (s *Schema) ProtoMessage() *schemapb.CollectionSchema { AutoID: s.AutoID, EnableDynamicField: s.EnableDynamicField, } - r.Fields = lo.Map(s.Fields, func(field *Field, _ int) *schemapb.FieldSchema { - return field.ProtoMessage() + r.Fields = lo.FilterMap(s.Fields, func(field *Field, _ int) (*schemapb.FieldSchema, bool) { + if field.DataType == FieldTypeArray && field.ElementType == FieldTypeStruct { + return nil, false + } + return field.ProtoMessage(), true }) r.Functions = lo.Map(s.Functions, func(function *Function, _ int) *schemapb.FunctionSchema { return function.ProtoMessage() }) + r.StructArrayFields = lo.FilterMap(s.Fields, func(field *Field, _ int) (*schemapb.StructArrayFieldSchema, bool) { + if field.DataType != FieldTypeArray || field.ElementType != FieldTypeStruct { + return nil, false + } + f := &schemapb.StructArrayFieldSchema{ + Name: field.Name, + Description: field.Description, + TypeParams: MapKvPairs(field.TypeParams), + } + if field.StructSchema != nil { + f.Fields = lo.Map(field.StructSchema.Fields, func(field *Field, _ int) *schemapb.FieldSchema { + // translate to ArrayStruct + f := field.ProtoMessage() + f.ElementType = f.DataType + if typeutil.IsVectorType(f.DataType) { + f.DataType = schemapb.DataType_ArrayOfVector + } else { + f.DataType = schemapb.DataType_Array + } + return f + }) + } + return f, true + }) + return r } diff --git a/client/entity/schema_test.go b/client/entity/schema_test.go index fb02476d98..b7bec29a3c 100644 --- a/client/entity/schema_test.go +++ b/client/entity/schema_test.go @@ -89,6 +89,117 @@ func (s *SchemaSuite) TestBasic() { } } +func (s *SchemaSuite) TestStructArrayField() { + // Create a struct schema + structSchema := NewStructSchema(). + WithField(NewField().WithName("age").WithDataType(FieldTypeInt32)). + WithField(NewField().WithName("name").WithDataType(FieldTypeVarChar).WithMaxLength(100)). + WithField(NewField().WithName("score").WithDataType(FieldTypeFloat)) + + // Create a schema with struct array field + schema := NewSchema(). + WithName("test_struct_array_collection"). + WithDescription("collection with struct array field"). + WithAutoID(false). + WithField(NewField().WithName("ID").WithDataType(FieldTypeInt64).WithIsPrimaryKey(true)). + WithField(NewField().WithName("vector").WithDataType(FieldTypeFloatVector).WithDim(128)). + WithField(NewField(). + WithName("person_data"). + WithDataType(FieldTypeArray). + WithElementType(FieldTypeStruct). + WithStructSchema(structSchema)) + + // Convert to proto + p := schema.ProtoMessage() + + // Verify basic schema properties + s.Equal("test_struct_array_collection", p.GetName()) + s.Equal("collection with struct array field", p.GetDescription()) + s.Equal(false, p.GetAutoID()) + + // Verify regular fields (should not include struct array field) + s.Equal(2, len(p.GetFields())) + s.Equal("ID", p.GetFields()[0].GetName()) + s.Equal("vector", p.GetFields()[1].GetName()) + + // Verify struct array fields + s.Equal(1, len(p.GetStructArrayFields())) + structArrayField := p.GetStructArrayFields()[0] + s.Equal("person_data", structArrayField.GetName()) + s.Equal(3, len(structArrayField.GetFields())) + + // Verify struct array sub-fields + s.Equal("age", structArrayField.GetFields()[0].GetName()) + s.Equal("name", structArrayField.GetFields()[1].GetName()) + s.Equal("score", structArrayField.GetFields()[2].GetName()) +} + +func (s *SchemaSuite) TestStructArrayFieldWithVectorElement() { + // Create a struct schema with vector field + structSchema := NewStructSchema(). + WithField(NewField().WithName("id").WithDataType(FieldTypeInt64)). + WithField(NewField().WithName("embedding").WithDataType(FieldTypeFloatVector).WithDim(256)) + + schema := NewSchema(). + WithName("test_struct_with_vector"). + WithAutoID(true). + WithField(NewField().WithName("pk").WithDataType(FieldTypeVarChar).WithMaxLength(100).WithIsPrimaryKey(true)). + WithField(NewField(). + WithName("data"). + WithDataType(FieldTypeArray). + WithElementType(FieldTypeStruct). + WithStructSchema(structSchema)) + + p := schema.ProtoMessage() + + // Verify struct array field with vector element + s.Equal(1, len(p.GetStructArrayFields())) + structArrayField := p.GetStructArrayFields()[0] + s.Equal("data", structArrayField.GetName()) + s.Equal(2, len(structArrayField.GetFields())) + + // Verify that vector field is converted to ArrayOfVector + embeddingField := structArrayField.GetFields()[1] + s.Equal("embedding", embeddingField.GetName()) + // The DataType should be changed to ArrayOfVector for vector types + s.NotEqual(FieldTypeFloatVector, embeddingField.GetDataType()) +} + +func (s *SchemaSuite) TestMultipleStructArrayFields() { + // Create multiple struct schemas + structSchema1 := NewStructSchema(). + WithField(NewField().WithName("field1").WithDataType(FieldTypeInt32)) + + structSchema2 := NewStructSchema(). + WithField(NewField().WithName("field2").WithDataType(FieldTypeVarChar).WithMaxLength(50)). + WithField(NewField().WithName("field3").WithDataType(FieldTypeDouble)) + + schema := NewSchema(). + WithName("test_multiple_struct_arrays"). + WithField(NewField().WithName("pk").WithDataType(FieldTypeInt64).WithIsPrimaryKey(true)). + WithField(NewField(). + WithName("struct_array_1"). + WithDataType(FieldTypeArray). + WithElementType(FieldTypeStruct). + WithStructSchema(structSchema1)). + WithField(NewField(). + WithName("struct_array_2"). + WithDataType(FieldTypeArray). + WithElementType(FieldTypeStruct). + WithStructSchema(structSchema2)) + + p := schema.ProtoMessage() + + // Verify we have 2 struct array fields + s.Equal(2, len(p.GetStructArrayFields())) + s.Equal("struct_array_1", p.GetStructArrayFields()[0].GetName()) + s.Equal("struct_array_2", p.GetStructArrayFields()[1].GetName()) + + // Verify each struct array has correct number of fields + s.Equal(1, len(p.GetStructArrayFields()[0].GetFields())) + s.Equal(2, len(p.GetStructArrayFields()[1].GetFields())) +} + func TestSchema(t *testing.T) { suite.Run(t, new(SchemaSuite)) } diff --git a/client/go.mod b/client/go.mod index 8edcddbb93..8cc3440a42 100644 --- a/client/go.mod +++ b/client/go.mod @@ -6,13 +6,15 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/cockroachdb/errors v1.9.1 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 - github.com/milvus-io/milvus-proto/go-api/v2 v2.6.4-0.20251013093953-f3e0a710c654 - github.com/milvus-io/milvus/pkg/v2 v2.6.3 + github.com/milvus-io/milvus-proto/go-api/v2 v2.6.5-0.20251102105128-d157e5f676d6 + github.com/milvus-io/milvus/pkg/v2 v2.6.4-0.20251104142533-a2ce70d25256 github.com/quasilyte/go-ruleguard/dsl v0.3.23 github.com/samber/lo v1.27.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.17.1 + go.opentelemetry.io/otel v1.34.0 go.uber.org/atomic v1.11.0 + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 google.golang.org/grpc v1.71.0 google.golang.org/protobuf v1.36.5 ) @@ -77,6 +79,7 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect + github.com/twpayne/go-geom v1.6.1 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect @@ -91,7 +94,6 @@ require ( go.etcd.io/etcd/server/v3 v3.5.5 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect @@ -102,7 +104,6 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.41.0 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/net v0.43.0 // indirect golang.org/x/sync v0.16.0 // indirect golang.org/x/sys v0.35.0 // indirect diff --git a/client/go.sum b/client/go.sum index 7c9d44cded..2989f605f7 100644 --- a/client/go.sum +++ b/client/go.sum @@ -16,10 +16,16 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= +github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -250,6 +256,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= @@ -322,10 +330,10 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/milvus-io/milvus-proto/go-api/v2 v2.6.4-0.20251013093953-f3e0a710c654 h1:p604i9izeR8eWrQhOFmcmxhNhYlsvTkkmph4b2GbOeg= -github.com/milvus-io/milvus-proto/go-api/v2 v2.6.4-0.20251013093953-f3e0a710c654/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= -github.com/milvus-io/milvus/pkg/v2 v2.6.3 h1:WDf4mXFWL5Sk/V87yLwRKq24MYMkjS2YA6qraXbLbJA= -github.com/milvus-io/milvus/pkg/v2 v2.6.3/go.mod h1:49umaGHK9nKHJNtgBlF/iB24s1sZ/SG5/Q7iLj/Gc14= +github.com/milvus-io/milvus-proto/go-api/v2 v2.6.5-0.20251102105128-d157e5f676d6 h1:RWrpxw+bSWWQyavtQMcc6JtqBR1x/t/io8qRvtkosmE= +github.com/milvus-io/milvus-proto/go-api/v2 v2.6.5-0.20251102105128-d157e5f676d6/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= +github.com/milvus-io/milvus/pkg/v2 v2.6.4-0.20251104142533-a2ce70d25256 h1:M2waty0w2k4YT2HHzJk3fx6EFPD4DKxNJatitIV+gGU= +github.com/milvus-io/milvus/pkg/v2 v2.6.4-0.20251104142533-a2ce70d25256/go.mod h1:HT6Wxahwj/l8+i+D/C3iwDzCjDa36U9gyVw6CjjK4pE= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -491,6 +499,8 @@ github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9f github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/twpayne/go-geom v1.6.1 h1:iLE+Opv0Ihm/ABIcvQFGIiFBXd76oBIar9drAwHFhR4= +github.com/twpayne/go-geom v1.6.1/go.mod h1:Kr+Nly6BswFsKM5sd31YaoWS5PeDDH2NftJTK7Gd028= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= diff --git a/client/milvusclient/mock_milvus_server_test.go b/client/milvusclient/mock_milvus_server_test.go index 2b9c0254a9..1edba14c37 100644 --- a/client/milvusclient/mock_milvus_server_test.go +++ b/client/milvusclient/mock_milvus_server_test.go @@ -86,6 +86,65 @@ func (_c *MilvusServiceServer_AddCollectionField_Call) RunAndReturn(run func(con return _c } +// AddCollectionFunction provides a mock function with given fields: _a0, _a1 +func (_m *MilvusServiceServer) AddCollectionFunction(_a0 context.Context, _a1 *milvuspb.AddCollectionFunctionRequest) (*commonpb.Status, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for AddCollectionFunction") + } + + var r0 *commonpb.Status + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFunctionRequest) (*commonpb.Status, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFunctionRequest) *commonpb.Status); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commonpb.Status) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.AddCollectionFunctionRequest) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MilvusServiceServer_AddCollectionFunction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddCollectionFunction' +type MilvusServiceServer_AddCollectionFunction_Call struct { + *mock.Call +} + +// AddCollectionFunction is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 *milvuspb.AddCollectionFunctionRequest +func (_e *MilvusServiceServer_Expecter) AddCollectionFunction(_a0 interface{}, _a1 interface{}) *MilvusServiceServer_AddCollectionFunction_Call { + return &MilvusServiceServer_AddCollectionFunction_Call{Call: _e.mock.On("AddCollectionFunction", _a0, _a1)} +} + +func (_c *MilvusServiceServer_AddCollectionFunction_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.AddCollectionFunctionRequest)) *MilvusServiceServer_AddCollectionFunction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*milvuspb.AddCollectionFunctionRequest)) + }) + return _c +} + +func (_c *MilvusServiceServer_AddCollectionFunction_Call) Return(_a0 *commonpb.Status, _a1 error) *MilvusServiceServer_AddCollectionFunction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MilvusServiceServer_AddCollectionFunction_Call) RunAndReturn(run func(context.Context, *milvuspb.AddCollectionFunctionRequest) (*commonpb.Status, error)) *MilvusServiceServer_AddCollectionFunction_Call { + _c.Call.Return(run) + return _c +} + // AddFileResource provides a mock function with given fields: _a0, _a1 func (_m *MilvusServiceServer) AddFileResource(_a0 context.Context, _a1 *milvuspb.AddFileResourceRequest) (*commonpb.Status, error) { ret := _m.Called(_a0, _a1) @@ -440,6 +499,65 @@ func (_c *MilvusServiceServer_AlterCollectionField_Call) RunAndReturn(run func(c return _c } +// AlterCollectionFunction provides a mock function with given fields: _a0, _a1 +func (_m *MilvusServiceServer) AlterCollectionFunction(_a0 context.Context, _a1 *milvuspb.AlterCollectionFunctionRequest) (*commonpb.Status, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for AlterCollectionFunction") + } + + var r0 *commonpb.Status + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AlterCollectionFunctionRequest) (*commonpb.Status, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AlterCollectionFunctionRequest) *commonpb.Status); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commonpb.Status) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.AlterCollectionFunctionRequest) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MilvusServiceServer_AlterCollectionFunction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AlterCollectionFunction' +type MilvusServiceServer_AlterCollectionFunction_Call struct { + *mock.Call +} + +// AlterCollectionFunction is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 *milvuspb.AlterCollectionFunctionRequest +func (_e *MilvusServiceServer_Expecter) AlterCollectionFunction(_a0 interface{}, _a1 interface{}) *MilvusServiceServer_AlterCollectionFunction_Call { + return &MilvusServiceServer_AlterCollectionFunction_Call{Call: _e.mock.On("AlterCollectionFunction", _a0, _a1)} +} + +func (_c *MilvusServiceServer_AlterCollectionFunction_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.AlterCollectionFunctionRequest)) *MilvusServiceServer_AlterCollectionFunction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*milvuspb.AlterCollectionFunctionRequest)) + }) + return _c +} + +func (_c *MilvusServiceServer_AlterCollectionFunction_Call) Return(_a0 *commonpb.Status, _a1 error) *MilvusServiceServer_AlterCollectionFunction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MilvusServiceServer_AlterCollectionFunction_Call) RunAndReturn(run func(context.Context, *milvuspb.AlterCollectionFunctionRequest) (*commonpb.Status, error)) *MilvusServiceServer_AlterCollectionFunction_Call { + _c.Call.Return(run) + return _c +} + // AlterDatabase provides a mock function with given fields: _a0, _a1 func (_m *MilvusServiceServer) AlterDatabase(_a0 context.Context, _a1 *milvuspb.AlterDatabaseRequest) (*commonpb.Status, error) { ret := _m.Called(_a0, _a1) @@ -2138,6 +2256,65 @@ func (_c *MilvusServiceServer_DropCollection_Call) RunAndReturn(run func(context return _c } +// DropCollectionFunction provides a mock function with given fields: _a0, _a1 +func (_m *MilvusServiceServer) DropCollectionFunction(_a0 context.Context, _a1 *milvuspb.DropCollectionFunctionRequest) (*commonpb.Status, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for DropCollectionFunction") + } + + var r0 *commonpb.Status + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.DropCollectionFunctionRequest) (*commonpb.Status, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.DropCollectionFunctionRequest) *commonpb.Status); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*commonpb.Status) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.DropCollectionFunctionRequest) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MilvusServiceServer_DropCollectionFunction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DropCollectionFunction' +type MilvusServiceServer_DropCollectionFunction_Call struct { + *mock.Call +} + +// DropCollectionFunction is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 *milvuspb.DropCollectionFunctionRequest +func (_e *MilvusServiceServer_Expecter) DropCollectionFunction(_a0 interface{}, _a1 interface{}) *MilvusServiceServer_DropCollectionFunction_Call { + return &MilvusServiceServer_DropCollectionFunction_Call{Call: _e.mock.On("DropCollectionFunction", _a0, _a1)} +} + +func (_c *MilvusServiceServer_DropCollectionFunction_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.DropCollectionFunctionRequest)) *MilvusServiceServer_DropCollectionFunction_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*milvuspb.DropCollectionFunctionRequest)) + }) + return _c +} + +func (_c *MilvusServiceServer_DropCollectionFunction_Call) Return(_a0 *commonpb.Status, _a1 error) *MilvusServiceServer_DropCollectionFunction_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MilvusServiceServer_DropCollectionFunction_Call) RunAndReturn(run func(context.Context, *milvuspb.DropCollectionFunctionRequest) (*commonpb.Status, error)) *MilvusServiceServer_DropCollectionFunction_Call { + _c.Call.Return(run) + return _c +} + // DropDatabase provides a mock function with given fields: _a0, _a1 func (_m *MilvusServiceServer) DropDatabase(_a0 context.Context, _a1 *milvuspb.DropDatabaseRequest) (*commonpb.Status, error) { ret := _m.Called(_a0, _a1) diff --git a/tests/go_client/go.mod b/tests/go_client/go.mod index e8a4db3f5c..bd519f852f 100644 --- a/tests/go_client/go.mod +++ b/tests/go_client/go.mod @@ -4,7 +4,7 @@ go 1.24.6 require ( github.com/milvus-io/milvus/client/v2 v2.0.0-20241125024034-0b9edb62a92d - github.com/milvus-io/milvus/pkg/v2 v2.6.3 + github.com/milvus-io/milvus/pkg/v2 v2.6.4-0.20251104142533-a2ce70d25256 github.com/peterstace/simplefeatures v0.54.0 github.com/quasilyte/go-ruleguard/dsl v0.3.23 github.com/samber/lo v1.27.0 @@ -54,7 +54,7 @@ require ( github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect - github.com/milvus-io/milvus-proto/go-api/v2 v2.6.4-0.20251013093953-f3e0a710c654 // indirect + github.com/milvus-io/milvus-proto/go-api/v2 v2.6.5-0.20251102105128-d157e5f676d6 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect diff --git a/tests/go_client/go.sum b/tests/go_client/go.sum index 3ddc3c8866..94b2846723 100644 --- a/tests/go_client/go.sum +++ b/tests/go_client/go.sum @@ -16,6 +16,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= @@ -330,10 +332,10 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/milvus-io/milvus-proto/go-api/v2 v2.6.4-0.20251013093953-f3e0a710c654 h1:p604i9izeR8eWrQhOFmcmxhNhYlsvTkkmph4b2GbOeg= -github.com/milvus-io/milvus-proto/go-api/v2 v2.6.4-0.20251013093953-f3e0a710c654/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= -github.com/milvus-io/milvus/pkg/v2 v2.6.3 h1:WDf4mXFWL5Sk/V87yLwRKq24MYMkjS2YA6qraXbLbJA= -github.com/milvus-io/milvus/pkg/v2 v2.6.3/go.mod h1:49umaGHK9nKHJNtgBlF/iB24s1sZ/SG5/Q7iLj/Gc14= +github.com/milvus-io/milvus-proto/go-api/v2 v2.6.5-0.20251102105128-d157e5f676d6 h1:RWrpxw+bSWWQyavtQMcc6JtqBR1x/t/io8qRvtkosmE= +github.com/milvus-io/milvus-proto/go-api/v2 v2.6.5-0.20251102105128-d157e5f676d6/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= +github.com/milvus-io/milvus/pkg/v2 v2.6.4-0.20251104142533-a2ce70d25256 h1:M2waty0w2k4YT2HHzJk3fx6EFPD4DKxNJatitIV+gGU= +github.com/milvus-io/milvus/pkg/v2 v2.6.4-0.20251104142533-a2ce70d25256/go.mod h1:HT6Wxahwj/l8+i+D/C3iwDzCjDa36U9gyVw6CjjK4pE= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=