From c6d951adb8a95959fe8a279c9150ef2c8f5a6c6e Mon Sep 17 00:00:00 2001 From: Spade A <71589810+SpadeA-Tang@users.noreply.github.com> Date: Fri, 17 Oct 2025 15:26:02 +0800 Subject: [PATCH] feat: impl StructArray -- ban non-float-vector for now [2.6] (#44876) ref https://github.com/milvus-io/milvus/issues/42148 pr: https://github.com/milvus-io/milvus/pull/44875 --------- Signed-off-by: SpadeA --- internal/proxy/util.go | 9 ++++++-- internal/proxy/util_test.go | 34 +++++++++++++++--------------- internal/storage/payload_writer.go | 9 ++++---- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/internal/proxy/util.go b/internal/proxy/util.go index 26a0ce3968..479bc860ca 100644 --- a/internal/proxy/util.go +++ b/internal/proxy/util.go @@ -663,9 +663,14 @@ func ValidateFieldsInStruct(field *schemapb.FieldSchema, schema *schemapb.Collec return fmt.Errorf("Inconsistent schema: element type of array field %s is a vector type", field.Name) } } else { - if !typeutil.IsVectorType(field.GetElementType()) { - return fmt.Errorf("Inconsistent schema: element type of array field %s is not a vector type", field.Name) + // TODO(SpadeA): only support float vector now + if field.GetElementType() != schemapb.DataType_FloatVector { + return fmt.Errorf("Unsupported element type of array field %s, now only float vector is supported", field.Name) } + + // if !typeutil.IsVectorType(field.GetElementType()) { + // return fmt.Errorf("Inconsistent schema: element type of array field %s is not a vector type", field.Name) + // } err = validateDimension(field) if err != nil { return err diff --git a/internal/proxy/util_test.go b/internal/proxy/util_test.go index fc01696abb..00fb872dfa 100644 --- a/internal/proxy/util_test.go +++ b/internal/proxy/util_test.go @@ -3951,7 +3951,7 @@ func TestValidateFieldsInStruct(t *testing.T) { } err := ValidateFieldsInStruct(field, schema) assert.Error(t, err) - assert.Contains(t, err.Error(), "element type of array field array_vector_with_scalar is not a vector type") + assert.Contains(t, err.Error(), "Unsupported element type of array field array_vector_with_scalar, now only float vector is supported") }) t.Run("array of vector missing dimension", func(t *testing.T) { @@ -4031,19 +4031,19 @@ func TestValidateFieldsInStruct(t *testing.T) { assert.Contains(t, err.Error(), "nullable is not supported for fields in struct array now") }) - t.Run("sparse float vector in array of vector", func(t *testing.T) { - // Note: ArrayOfVector with sparse vector element type still requires dimension - // because validateDimension checks the field's DataType (ArrayOfVector), not ElementType - field := &schemapb.FieldSchema{ - Name: "sparse_vector_array", - DataType: schemapb.DataType_ArrayOfVector, - ElementType: schemapb.DataType_SparseFloatVector, - TypeParams: []*commonpb.KeyValuePair{}, - } - err := ValidateFieldsInStruct(field, schema) - assert.Error(t, err) - assert.Contains(t, err.Error(), "dimension is not defined") - }) + // t.Run("sparse float vector in array of vector", func(t *testing.T) { + // // Note: ArrayOfVector with sparse vector element type still requires dimension + // // because validateDimension checks the field's DataType (ArrayOfVector), not ElementType + // field := &schemapb.FieldSchema{ + // Name: "sparse_vector_array", + // DataType: schemapb.DataType_ArrayOfVector, + // ElementType: schemapb.DataType_SparseFloatVector, + // TypeParams: []*commonpb.KeyValuePair{}, + // } + // err := ValidateFieldsInStruct(field, schema) + // assert.Error(t, err) + // assert.Contains(t, err.Error(), "dimension is not defined") + // }) t.Run("array with various scalar element types", func(t *testing.T) { validScalarTypes := []schemapb.DataType{ @@ -4071,9 +4071,9 @@ func TestValidateFieldsInStruct(t *testing.T) { t.Run("array of vector with various vector types", func(t *testing.T) { validVectorTypes := []schemapb.DataType{ schemapb.DataType_FloatVector, - schemapb.DataType_BinaryVector, - schemapb.DataType_Float16Vector, - schemapb.DataType_BFloat16Vector, + // schemapb.DataType_BinaryVector, + // schemapb.DataType_Float16Vector, + // schemapb.DataType_BFloat16Vector, // Note: SparseFloatVector is excluded because validateDimension checks // the field's DataType (ArrayOfVector), not ElementType, so it still requires dimension } diff --git a/internal/storage/payload_writer.go b/internal/storage/payload_writer.go index d8b0c948fc..17694ab225 100644 --- a/internal/storage/payload_writer.go +++ b/internal/storage/payload_writer.go @@ -996,13 +996,14 @@ func (w *NativePayloadWriter) addFloatVectorArrayToPayload(builder *array.ListBu floatData := vectorField.GetFloatVector().GetData() - numVectors := len(floatData) / int(data.Dim) + dim := vectorField.GetDim() + numVectors := len(floatData) / int(dim) for i := 0; i < numVectors; i++ { - start := i * int(data.Dim) - end := start + int(data.Dim) + start := i * int(dim) + end := start + int(dim) vectorSlice := floatData[start:end] - bytes := make([]byte, data.Dim*4) + bytes := make([]byte, dim*4) for j, f := range vectorSlice { binary.LittleEndian.PutUint32(bytes[j*4:], math.Float32bits(f)) }