diff --git a/internal/distributed/proxy/httpserver/handler_v1.go b/internal/distributed/proxy/httpserver/handler_v1.go index 6afffb23a3ff8..6878a294b3baa 100644 --- a/internal/distributed/proxy/httpserver/handler_v1.go +++ b/internal/distributed/proxy/httpserver/handler_v1.go @@ -135,8 +135,8 @@ func (h *HandlersV1) describeCollection(ctx context.Context, c *gin.Context, dbN return nil, err } primaryField, ok := getPrimaryField(response.Schema) - if ok && primaryField.AutoID && !response.Schema.AutoID { - log.Warn("primary filed autoID VS schema autoID", zap.String("collectionName", collectionName), zap.Bool("primary Field", primaryField.AutoID), zap.Bool("schema", response.Schema.AutoID)) + if ok && primaryField.AutoID && !primaryField.AutoID { + log.Warn("primary filed autoID VS schema autoID", zap.String("collectionName", collectionName), zap.Bool("primary Field", primaryField.AutoID), zap.Bool("schema", primaryField.AutoID)) response.Schema.AutoID = EnableAutoID } return response.Schema, nil @@ -219,10 +219,11 @@ func (h *HandlersV1) listCollections(c *gin.Context) { func (h *HandlersV1) createCollection(c *gin.Context) { httpReq := CreateCollectionReq{ - DbName: DefaultDbName, - MetricType: DefaultMetricType, - PrimaryField: DefaultPrimaryFieldName, - VectorField: DefaultVectorFieldName, + DbName: DefaultDbName, + MetricType: DefaultMetricType, + PrimaryField: DefaultPrimaryFieldName, + VectorField: DefaultVectorFieldName, + EnableDynamicField: EnableDynamic, } if err := c.ShouldBindWith(&httpReq, binding.JSON); err != nil { log.Warn("high level restful api, the parameter of create collection is incorrect", zap.Any("request", httpReq), zap.Error(err)) @@ -265,7 +266,7 @@ func (h *HandlersV1) createCollection(c *gin.Context) { AutoID: DisableAutoID, }, }, - EnableDynamicField: EnableDynamic, + EnableDynamicField: httpReq.EnableDynamicField, }) if err != nil { log.Warn("high level restful api, marshal collection schema fail", zap.Any("request", httpReq), zap.Error(err)) @@ -358,8 +359,8 @@ func (h *HandlersV1) getCollectionDetails(c *gin.Context) { } coll := response.(*milvuspb.DescribeCollectionResponse) primaryField, ok := getPrimaryField(coll.Schema) - if ok && primaryField.AutoID && !coll.Schema.AutoID { - log.Warn("primary filed autoID VS schema autoID", zap.String("collectionName", collectionName), zap.Bool("primary Field", primaryField.AutoID), zap.Bool("schema", coll.Schema.AutoID)) + if ok && primaryField.AutoID && !primaryField.AutoID { + log.Warn("primary filed autoID VS schema autoID", zap.String("collectionName", collectionName), zap.Bool("primary Field", primaryField.AutoID), zap.Bool("schema", primaryField.AutoID)) coll.Schema.AutoID = EnableAutoID } @@ -798,10 +799,12 @@ func (h *HandlersV1) upsert(c *gin.Context) { if err != nil || collSchema == nil { return nil, RestRequestInterceptorErr } - if collSchema.AutoID { - err := merr.WrapErrParameterInvalid("autoID: false", "autoID: true", "cannot upsert an autoID collection") - c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: merr.Code(err), HTTPReturnMessage: err.Error()}) - return nil, RestRequestInterceptorErr + for _, fieldSchema := range collSchema.Fields { + if fieldSchema.IsPrimaryKey && fieldSchema.AutoID { + err := merr.WrapErrParameterInvalid("autoID: false", "autoID: true", "cannot upsert an autoID collection") + c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: merr.Code(err), HTTPReturnMessage: err.Error()}) + return nil, RestRequestInterceptorErr + } } body, _ := c.Get(gin.BodyBytesKey) err, httpReq.Data = checkAndSetData(string(body.([]byte)), collSchema) diff --git a/internal/distributed/proxy/httpserver/request.go b/internal/distributed/proxy/httpserver/request.go index 228fe3be1dbd3..5368cfebcac57 100644 --- a/internal/distributed/proxy/httpserver/request.go +++ b/internal/distributed/proxy/httpserver/request.go @@ -1,13 +1,14 @@ package httpserver type CreateCollectionReq struct { - DbName string `json:"dbName"` - CollectionName string `json:"collectionName" validate:"required"` - Dimension int32 `json:"dimension" validate:"required"` - Description string `json:"description"` - MetricType string `json:"metricType"` - PrimaryField string `json:"primaryField"` - VectorField string `json:"vectorField"` + DbName string `json:"dbName"` + CollectionName string `json:"collectionName" validate:"required"` + Dimension int32 `json:"dimension" validate:"required"` + Description string `json:"description"` + MetricType string `json:"metricType"` + PrimaryField string `json:"primaryField"` + VectorField string `json:"vectorField"` + EnableDynamicField bool `json:"enableDynamicField"` } type DropCollectionReq struct { diff --git a/internal/distributed/proxy/httpserver/utils.go b/internal/distributed/proxy/httpserver/utils.go index 8c89f525c93d4..fd2ec60af0b63 100644 --- a/internal/distributed/proxy/httpserver/utils.go +++ b/internal/distributed/proxy/httpserver/utils.go @@ -196,7 +196,7 @@ func checkAndSetData(body string, collSchema *schemapb.CollectionSchema) (error, dataString := gjson.Get(data.Raw, fieldName).String() - if field.IsPrimaryKey && collSchema.AutoID { + if field.IsPrimaryKey && field.AutoID { if dataString != "" { return merr.WrapErrParameterInvalid("", "set primary key but autoID == true"), reallyDataArray } diff --git a/internal/proxy/meta_cache.go b/internal/proxy/meta_cache.go index 445fa0a04773f..7d230be4e3adc 100644 --- a/internal/proxy/meta_cache.go +++ b/internal/proxy/meta_cache.go @@ -1066,6 +1066,8 @@ func (m *MetaCache) RemoveDatabase(ctx context.Context, database string) { } func (m *MetaCache) HasDatabase(ctx context.Context, database string) bool { + m.mu.RLock() + defer m.mu.RUnlock() _, ok := m.collInfo[database] return ok }