feat: support to drop properties of field (#41954)

issue: https://github.com/milvus-io/milvus/issues/41990
pr: https://github.com/milvus-io/milvus/pull/41996

Signed-off-by: yhmo <yihua.mo@zilliz.com>
This commit is contained in:
groot 2025-05-27 14:32:34 +08:00 committed by GitHub
parent f4e4bb20fa
commit a48001f999
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 335 additions and 34 deletions

View File

@ -6,7 +6,7 @@ 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.5.12
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad
github.com/milvus-io/milvus/pkg/v2 v2.5.7
github.com/quasilyte/go-ruleguard/dsl v0.3.22
github.com/samber/lo v1.27.0

View File

@ -318,8 +318,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr
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.5.12 h1:zRMCf6W4kzBNqZb1CMmmfetUAG0y3hlT5Ow0H9MaASM=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.12/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad h1:tkSvshW0g1nbf7gPIsku838FFvrlucnPtAXYBiGuTAs=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/milvus/pkg/v2 v2.5.7 h1:b45jq1s1v03AekFucs2/dkkXohB57gEx7gspJuAkfbY=
github.com/milvus-io/milvus/pkg/v2 v2.5.7/go.mod h1:pImw1IGNS7k/5yvlZV2tZi5vZu1VQRlQij+r39d+XnI=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=

2
go.mod
View File

@ -21,7 +21,7 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/klauspost/compress v1.18.0
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.12
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad
github.com/minio/minio-go/v7 v7.0.73
github.com/panjf2000/ants/v2 v2.11.3 // indirect
github.com/pingcap/log v1.1.1-0.20221015072633-39906604fb81

4
go.sum
View File

@ -634,8 +634,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/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/milvus-proto/go-api/v2 v2.5.12 h1:zRMCf6W4kzBNqZb1CMmmfetUAG0y3hlT5Ow0H9MaASM=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.12/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad h1:tkSvshW0g1nbf7gPIsku838FFvrlucnPtAXYBiGuTAs=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad/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/go.mod h1:dkutuH4oS2pXiGm+Ti7fQZ4MRjrMPZ8IJeEGAWMeckk=
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs=

View File

@ -1157,14 +1157,18 @@ const (
MmapEnabledKey = "mmap_enabled"
)
var allowedProps = []string{
var allowedAlterProps = []string{
common.MaxLengthKey,
common.MmapEnabledKey,
common.MaxCapacityKey,
}
func IsKeyAllowed(key string) bool {
for _, allowedKey := range allowedProps {
var allowedDropProps = []string{
common.MmapEnabledKey,
}
func IsKeyAllowAlter(key string) bool {
for _, allowedKey := range allowedAlterProps {
if key == allowedKey {
return true
}
@ -1172,15 +1176,29 @@ func IsKeyAllowed(key string) bool {
return false
}
func IsKeyAllowDrop(key string) bool {
for _, allowedKey := range allowedDropProps {
if key == allowedKey {
return true
}
}
return false
}
func updateKey(key string) string {
var updatedKey string
if key == MmapEnabledKey {
updatedKey = common.MmapEnabledKey
} else {
updatedKey = key
}
return updatedKey
}
func updatePropertiesKeys(oldProps []*commonpb.KeyValuePair) []*commonpb.KeyValuePair {
props := make(map[string]string)
for _, prop := range oldProps {
var updatedKey string
if prop.Key == MmapEnabledKey {
updatedKey = common.MmapEnabledKey
} else {
updatedKey = prop.Key
}
updatedKey := updateKey(prop.Key)
props[updatedKey] = prop.Value
}
@ -1200,22 +1218,31 @@ func (t *alterCollectionFieldTask) PreExecute(ctx context.Context) error {
if err != nil {
return err
}
isCollectionLoadedFn := func() (bool, error) {
collectionID, err := globalMetaCache.GetCollectionID(ctx, t.GetDbName(), t.CollectionName)
if err != nil {
return false, err
}
loaded, err1 := isCollectionLoaded(ctx, t.queryCoord, collectionID)
if err1 != nil {
return false, err1
}
return loaded, nil
}
t.Properties = updatePropertiesKeys(t.Properties)
for _, prop := range t.Properties {
if !IsKeyAllowed(prop.Key) {
if !IsKeyAllowAlter(prop.Key) {
return merr.WrapErrParameterInvalidMsg("%s does not allow update in collection field param", prop.Key)
}
// Check the value type based on the key
switch prop.Key {
case common.MmapEnabledKey:
collectionID, err := globalMetaCache.GetCollectionID(ctx, t.GetDbName(), t.CollectionName)
loaded, err := isCollectionLoadedFn()
if err != nil {
return err
}
loaded, err1 := isCollectionLoaded(ctx, t.queryCoord, collectionID)
if err1 != nil {
return err1
}
if loaded {
return merr.WrapErrCollectionLoaded(t.CollectionName, "can not alter collection field properties if collection loaded")
}
@ -1266,6 +1293,27 @@ func (t *alterCollectionFieldTask) PreExecute(ctx context.Context) error {
}
}
deleteKeys := make([]string, 0)
for _, key := range t.DeleteKeys {
updatedKey := updateKey(key)
if !IsKeyAllowDrop(updatedKey) {
return merr.WrapErrParameterInvalidMsg("%s is not allowed to drop in collection field param", key)
}
if updatedKey == common.MmapEnabledKey {
loaded, err := isCollectionLoadedFn()
if err != nil {
return err
}
if loaded {
return merr.WrapErrCollectionLoaded(t.CollectionName, "can not drop collection field properties if collection loaded")
}
}
deleteKeys = append(deleteKeys, updatedKey)
}
t.DeleteKeys = deleteKeys
return nil
}

View File

@ -4451,6 +4451,8 @@ func TestAlterCollectionFieldCheckLoaded(t *testing.T) {
CollectionIDs: []int64{resp.CollectionID},
InMemoryPercentages: []int64{100},
}, nil)
// update property "mmap.enabled" but the collection is loaded
task := &alterCollectionFieldTask{
AlterCollectionFieldRequest: &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{},
@ -4461,6 +4463,18 @@ func TestAlterCollectionFieldCheckLoaded(t *testing.T) {
}
err = task.PreExecute(context.Background())
assert.Equal(t, merr.Code(merr.ErrCollectionLoaded), merr.Code(err))
// delete property "mmap.enabled" but the collection is loaded
task = &alterCollectionFieldTask{
AlterCollectionFieldRequest: &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{},
CollectionName: collectionName,
DeleteKeys: []string{common.MmapEnabledKey},
},
queryCoord: qc,
}
err = task.PreExecute(context.Background())
assert.Equal(t, merr.Code(merr.ErrCollectionLoaded), merr.Code(err))
}
func TestAlterCollectionField1(t *testing.T) {
@ -4504,18 +4518,25 @@ func TestAlterCollectionField1(t *testing.T) {
ShardsNum: 1,
}
rc.CreateCollection(context.Background(), createColReq)
resp, err := rc.DescribeCollection(context.Background(), &milvuspb.DescribeCollectionRequest{CollectionName: collectionName})
assert.NoError(t, err)
// The collection is not loaded
qc.EXPECT().ShowCollections(mock.Anything, mock.Anything).Return(&querypb.ShowCollectionsResponse{
Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
CollectionIDs: []int64{resp.CollectionID},
InMemoryPercentages: []int64{100},
CollectionIDs: []int64{},
InMemoryPercentages: []int64{},
}, nil)
// Test cases
// 1. the collection is not loaded, updating properties is allowed, deleting mmap.enabled/mmap_enabled is allowed
// 2. max_length can only be updated on varchar field or arrar field with varchar element
// 3. max_capacity can only be updated on array field
// 4. invalid number for max_length/max_capacity is not allowed
// 5. not allow to delete max_length/max_capacity
tests := []struct {
name string
fieldName string
properties []*commonpb.KeyValuePair
deleteKeys []string
expectError bool
errCode int32
}{
@ -4598,6 +4619,41 @@ func TestAlterCollectionField1(t *testing.T) {
expectError: true,
errCode: merr.Code(merr.ErrParameterInvalid),
},
{
name: "not allow to update max_length on non-varchar field",
fieldName: "array_field",
properties: []*commonpb.KeyValuePair{
{Key: common.MaxLengthKey, Value: "10"},
},
expectError: true,
errCode: merr.Code(merr.ErrParameterInvalid),
},
{
name: "delete mmap.enabled is allowed",
fieldName: "string_field",
deleteKeys: []string{common.MmapEnabledKey},
expectError: false,
},
{
name: "delete mmap_enabled is allowed",
fieldName: "string_field",
deleteKeys: []string{MmapEnabledKey},
expectError: false,
},
{
name: "delete max_length is not allowed",
fieldName: "string_field",
deleteKeys: []string{common.MaxLengthKey},
expectError: true,
errCode: merr.Code(merr.ErrParameterInvalid),
},
{
name: "delete max_capacity is not allowed",
fieldName: "array_field",
deleteKeys: []string{common.MaxCapacityKey},
expectError: true,
errCode: merr.Code(merr.ErrParameterInvalid),
},
}
for _, test := range tests {
@ -4608,6 +4664,7 @@ func TestAlterCollectionField1(t *testing.T) {
CollectionName: collectionName,
FieldName: test.fieldName,
Properties: test.properties,
DeleteKeys: test.deleteKeys,
},
queryCoord: qc,
}

View File

@ -274,8 +274,8 @@ func (a *alterCollectionFieldTask) Prepare(ctx context.Context) error {
}
func (a *alterCollectionFieldTask) Execute(ctx context.Context) error {
if a.Req.GetProperties() == nil {
return errors.New("only support alter collection properties, but collection field properties is empty")
if len(a.Req.GetProperties()) == 0 && len(a.Req.GetDeleteKeys()) == 0 {
return errors.New("The field properties to alter and keys to delete must not be empty at the same time")
}
oldColl, err := a.core.meta.GetCollectionByName(ctx, a.Req.GetDbName(), a.Req.GetCollectionName(), a.ts)
@ -314,7 +314,13 @@ func executeAlterCollectionFieldTaskSteps(ctx context.Context,
) error {
var err error
filedName := request.GetFieldName()
newFieldProperties := UpdateFieldPropertyParams(oldFieldProperties, request.GetProperties())
var newFieldProperties []*commonpb.KeyValuePair
if len(request.Properties) > 0 {
newFieldProperties = UpdateFieldPropertyParams(oldFieldProperties, request.GetProperties())
} else if len(request.DeleteKeys) > 0 {
newFieldProperties = DeleteProperties(oldFieldProperties, request.GetDeleteKeys())
}
oldColl := col.Clone()
err = ResetFieldProperties(oldColl, filedName, oldFieldProperties)
if err != nil {

View File

@ -27,6 +27,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-proto/go-api/v2/schemapb"
"github.com/milvus-io/milvus/internal/metastore/model"
mockrootcoord "github.com/milvus-io/milvus/internal/rootcoord/mocks"
"github.com/milvus-io/milvus/pkg/v2/common"
@ -412,3 +413,192 @@ func Test_alterCollectionTask_Execute(t *testing.T) {
testFunc(t, nil, nil, []string{common.CollectionDescription})
})
}
func Test_alterCollectionFieldTask_Prepare(t *testing.T) {
t.Run("invalid collection name", func(t *testing.T) {
task := &alterCollectionFieldTask{
Req: &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterCollectionField},
},
}
err := task.Prepare(context.Background())
assert.Error(t, err)
})
t.Run("invalid field name", func(t *testing.T) {
task := &alterCollectionFieldTask{
Req: &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterCollectionField},
CollectionName: "cn",
},
}
err := task.Prepare(context.Background())
assert.Error(t, err)
})
t.Run("normal name", func(t *testing.T) {
task := &alterCollectionFieldTask{
Req: &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterCollectionField},
CollectionName: "cn",
FieldName: "ok",
},
}
err := task.Prepare(context.Background())
assert.NoError(t, err)
})
}
func Test_alterCollectionFieldTask_Execute(t *testing.T) {
testFn := func(req *milvuspb.AlterCollectionFieldRequest, meta *mockrootcoord.IMetaTable, expectError bool) {
broker := newMockBroker()
broker.BroadcastAlteredCollectionFunc = func(ctx context.Context, req *milvuspb.AlterCollectionRequest) error {
return nil
}
packChan := make(chan *msgstream.MsgPack, 10)
ticker := newChanTimeTickSync(packChan)
ticker.addDmlChannels("by-dev-rootcoord-dml_1")
core := newTestCore(withValidProxyManager(), withMeta(meta), withBroker(broker), withTtSynchronizer(ticker), withInvalidTsoAllocator())
task := &alterCollectionFieldTask{
baseTask: newBaseTask(context.Background(), core),
Req: req,
}
err := task.Execute(context.Background())
if expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
}
t.Run("properties and deleteKeys are empty", func(t *testing.T) {
meta := mockrootcoord.NewIMetaTable(t)
req := &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterCollectionField},
Properties: []*commonpb.KeyValuePair{},
DeleteKeys: []string{},
}
testFn(req, meta, true)
})
t.Run("collection not found", func(t *testing.T) {
meta := mockrootcoord.NewIMetaTable(t)
meta.On("GetCollectionByName",
mock.Anything,
mock.Anything,
mock.Anything,
mock.Anything,
).Return(nil, errors.New("collection not found"))
req := &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterCollectionField},
CollectionName: "cn",
DeleteKeys: []string{common.MaxLengthKey},
}
testFn(req, meta, true)
})
t.Run("field not found", func(t *testing.T) {
meta := mockrootcoord.NewIMetaTable(t)
meta.On("GetCollectionByName",
mock.Anything,
mock.Anything,
mock.Anything,
mock.Anything,
).Return(&model.Collection{
CollectionID: int64(1),
Name: "cn",
DBName: "foo",
Fields: []*model.Field{},
}, nil)
req := &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterCollectionField},
CollectionName: "cn",
DbName: "foo",
FieldName: "bar",
DeleteKeys: []string{common.MaxLengthKey},
}
testFn(req, meta, true)
})
t.Run("update properties", func(t *testing.T) {
meta := mockrootcoord.NewIMetaTable(t)
meta.On("GetCollectionByName",
mock.Anything,
mock.Anything,
mock.Anything,
mock.Anything,
).Return(&model.Collection{
CollectionID: int64(1),
Name: "cn",
DBName: "foo",
Fields: []*model.Field{{
FieldID: int64(1),
Name: "bar",
DataType: schemapb.DataType_VarChar,
TypeParams: []*commonpb.KeyValuePair{
{Key: common.MaxLengthKey, Value: "50"},
},
}},
}, nil)
meta.On("AlterCollection",
mock.Anything,
mock.Anything,
mock.Anything,
mock.Anything,
).Return(nil)
req := &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterCollectionField},
CollectionName: "cn",
DbName: "foo",
FieldName: "bar",
Properties: []*commonpb.KeyValuePair{
{Key: common.MaxLengthKey, Value: "100"},
},
}
testFn(req, meta, false)
})
t.Run("delete properties", func(t *testing.T) {
meta := mockrootcoord.NewIMetaTable(t)
meta.On("GetCollectionByName",
mock.Anything,
mock.Anything,
mock.Anything,
mock.Anything,
).Return(&model.Collection{
CollectionID: int64(1),
Name: "cn",
DBName: "foo",
Fields: []*model.Field{{
FieldID: int64(1),
Name: "bar",
DataType: schemapb.DataType_VarChar,
TypeParams: []*commonpb.KeyValuePair{
{Key: common.MaxLengthKey, Value: "100"},
{Key: common.MmapEnabledKey, Value: "true"},
},
}},
}, nil)
meta.On("AlterCollection",
mock.Anything,
mock.Anything,
mock.Anything,
mock.Anything,
).Return(nil)
req := &milvuspb.AlterCollectionFieldRequest{
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterCollectionField},
CollectionName: "cn",
DbName: "foo",
FieldName: "bar",
DeleteKeys: []string{common.MmapEnabledKey},
}
testFn(req, meta, false)
})
}

View File

@ -14,7 +14,7 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/json-iterator/go v1.1.12
github.com/klauspost/compress v1.17.7
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.12
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad
github.com/nats-io/nats-server/v2 v2.10.12
github.com/nats-io/nats.go v1.34.1
github.com/panjf2000/ants/v2 v2.11.3

View File

@ -488,8 +488,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/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/milvus-proto/go-api/v2 v2.5.12 h1:zRMCf6W4kzBNqZb1CMmmfetUAG0y3hlT5Ow0H9MaASM=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.12/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad h1:tkSvshW0g1nbf7gPIsku838FFvrlucnPtAXYBiGuTAs=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad/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/go.mod h1:dkutuH4oS2pXiGm+Ti7fQZ4MRjrMPZ8IJeEGAWMeckk=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=

View File

@ -51,7 +51,7 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.12 // indirect
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/opencontainers/runtime-spec v1.0.2 // indirect

View File

@ -318,8 +318,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr
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.5.12 h1:zRMCf6W4kzBNqZb1CMmmfetUAG0y3hlT5Ow0H9MaASM=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.12/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad h1:tkSvshW0g1nbf7gPIsku838FFvrlucnPtAXYBiGuTAs=
github.com/milvus-io/milvus-proto/go-api/v2 v2.5.13-0.20250520065018-13f9a20ffaad/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/milvus/pkg/v2 v2.5.7 h1:b45jq1s1v03AekFucs2/dkkXohB57gEx7gspJuAkfbY=
github.com/milvus-io/milvus/pkg/v2 v2.5.7/go.mod h1:pImw1IGNS7k/5yvlZV2tZi5vZu1VQRlQij+r39d+XnI=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=