From 6f4abab6c858749e4ff87341f58f440710649581 Mon Sep 17 00:00:00 2001 From: Spade A <71589810+SpadeA-Tang@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:31:36 +0800 Subject: [PATCH] fix: nextFieldID does not consider STRUCT (#45437) issue: https://github.com/milvus-io/milvus/issues/45362 Signed-off-by: SpadeA --- internal/rootcoord/util.go | 13 +++++++ internal/rootcoord/util_test.go | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/internal/rootcoord/util.go b/internal/rootcoord/util.go index 5ecfdad762..96cd9a8f1b 100644 --- a/internal/rootcoord/util.go +++ b/internal/rootcoord/util.go @@ -571,5 +571,18 @@ func nextFieldID(coll *model.Collection) int64 { maxFieldID = field.FieldID } } + + // Also check StructArrayFields and their sub-fields to avoid ID conflicts + for _, structField := range coll.StructArrayFields { + if structField.FieldID > maxFieldID { + maxFieldID = structField.FieldID + } + for _, subField := range structField.Fields { + if subField.FieldID > maxFieldID { + maxFieldID = subField.FieldID + } + } + } + return maxFieldID + 1 } diff --git a/internal/rootcoord/util_test.go b/internal/rootcoord/util_test.go index e06dec38f1..b6f25d7080 100644 --- a/internal/rootcoord/util_test.go +++ b/internal/rootcoord/util_test.go @@ -23,6 +23,7 @@ import ( "github.com/milvus-io/milvus-proto/go-api/v2/commonpb" "github.com/milvus-io/milvus-proto/go-api/v2/milvuspb" + "github.com/milvus-io/milvus/internal/metastore/model" "github.com/milvus-io/milvus/pkg/v2/common" "github.com/milvus-io/milvus/pkg/v2/mq/msgstream" "github.com/milvus-io/milvus/pkg/v2/util/typeutil" @@ -453,3 +454,67 @@ func TestIsSubsetOfProperties(t *testing.T) { }) } } + +func Test_nextFieldID(t *testing.T) { + type args struct { + coll *model.Collection + } + tests := []struct { + name string + args args + want int64 + }{ + { + name: "collection with max field ID in struct array sub-field", + args: args{ + coll: &model.Collection{ + Fields: []*model.Field{ + {FieldID: common.StartOfUserFieldID}, + }, + StructArrayFields: []*model.StructArrayField{ + { + FieldID: common.StartOfUserFieldID + 1, + Fields: []*model.Field{ + {FieldID: common.StartOfUserFieldID + 2}, + {FieldID: common.StartOfUserFieldID + 10}, + }, + }, + }, + }, + }, + want: common.StartOfUserFieldID + 11, + }, + { + name: "collection with multiple struct array fields", + args: args{ + coll: &model.Collection{ + Fields: []*model.Field{ + {FieldID: common.StartOfUserFieldID}, + }, + StructArrayFields: []*model.StructArrayField{ + { + FieldID: common.StartOfUserFieldID + 1, + Fields: []*model.Field{ + {FieldID: common.StartOfUserFieldID + 2}, + }, + }, + { + FieldID: common.StartOfUserFieldID + 5, + Fields: []*model.Field{ + {FieldID: common.StartOfUserFieldID + 6}, + {FieldID: common.StartOfUserFieldID + 7}, + }, + }, + }, + }, + }, + want: common.StartOfUserFieldID + 8, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := nextFieldID(tt.args.coll) + assert.Equal(t, tt.want, got) + }) + } +}