package rootcoord import ( "context" "google.golang.org/protobuf/types/known/fieldmaskpb" "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/distributed/streaming" "github.com/milvus-io/milvus/internal/metastore/model" "github.com/milvus-io/milvus/pkg/v2/common" "github.com/milvus-io/milvus/pkg/v2/proto/messagespb" "github.com/milvus-io/milvus/pkg/v2/streaming/util/message" "github.com/milvus-io/milvus/pkg/v2/util/typeutil" ) func (c *Core) broadcastAlterCollectionV2ForAlterCollectionField(ctx context.Context, req *milvuspb.AlterCollectionFieldRequest) error { broadcaster, err := c.startBroadcastWithAliasOrCollectionLock(ctx, req.GetDbName(), req.GetCollectionName()) if err != nil { return err } defer broadcaster.Close() coll, err := c.meta.GetCollectionByName(ctx, req.GetDbName(), req.GetCollectionName(), typeutil.MaxTimestamp) if err != nil { return err } oldFieldProperties, err := GetFieldProperties(coll, req.GetFieldName()) if err != nil { return err } oldFieldPropertiesMap := common.CloneKeyValuePairs(oldFieldProperties).ToMap() for _, prop := range req.GetProperties() { oldFieldPropertiesMap[prop.GetKey()] = prop.GetValue() } for _, deleteKey := range req.GetDeleteKeys() { delete(oldFieldPropertiesMap, deleteKey) } newFieldProperties := common.NewKeyValuePairs(oldFieldPropertiesMap) if newFieldProperties.Equal(oldFieldProperties) { // if there's no change, return nil directly to promise idempotent. return errIgnoredAlterCollection } // build new collection schema. schema := &schemapb.CollectionSchema{ Name: coll.Name, Description: coll.Description, AutoID: coll.AutoID, Fields: model.MarshalFieldModels(coll.Fields), StructArrayFields: model.MarshalStructArrayFieldModels(coll.StructArrayFields), Functions: model.MarshalFunctionModels(coll.Functions), EnableDynamicField: coll.EnableDynamicField, Properties: coll.Properties, Version: coll.SchemaVersion + 1, } for _, field := range schema.Fields { if field.Name == req.GetFieldName() { field.TypeParams = newFieldProperties break } } cacheExpirations, err := c.getCacheExpireForCollection(ctx, req.GetDbName(), req.GetCollectionName()) if err != nil { return err } header := &messagespb.AlterCollectionMessageHeader{ DbId: coll.DBID, CollectionId: coll.CollectionID, UpdateMask: &fieldmaskpb.FieldMask{ Paths: []string{message.FieldMaskCollectionSchema}, }, CacheExpirations: cacheExpirations, } body := &messagespb.AlterCollectionMessageBody{ Updates: &messagespb.AlterCollectionMessageUpdates{ Schema: schema, }, } channels := make([]string, 0, len(coll.VirtualChannelNames)+1) channels = append(channels, streaming.WAL().ControlChannel()) channels = append(channels, coll.VirtualChannelNames...) msg := message.NewAlterCollectionMessageBuilderV2(). WithHeader(header). WithBody(body). WithBroadcast(channels). MustBuildBroadcast() if _, err := broadcaster.Broadcast(ctx, msg); err != nil { return err } return nil }