diff --git a/internal/distributed/proxy/httpserver/utils.go b/internal/distributed/proxy/httpserver/utils.go index f6e9e03fb7..f441d360c0 100644 --- a/internal/distributed/proxy/httpserver/utils.go +++ b/internal/distributed/proxy/httpserver/utils.go @@ -750,13 +750,22 @@ func anyToColumns(rows []map[string]interface{}, validDataMap map[string][]bool, } isDynamic := sch.EnableDynamicField + allowInsertAutoID, _ := common.IsAllowInsertAutoID(sch.GetProperties()...) + isAutoIDPK := false + pkFieldName := "" nameColumns := make(map[string]interface{}) nameDims := make(map[string]int64) fieldData := make(map[string]*schemapb.FieldData) for _, field := range sch.Fields { - if (field.IsPrimaryKey && field.AutoID && inInsert) || field.IsDynamic { + if field.IsPrimaryKey { + pkFieldName = field.Name + if field.AutoID { + isAutoIDPK = true + } + } + if (field.IsPrimaryKey && field.AutoID && inInsert && !allowInsertAutoID) || field.IsDynamic { continue } // skip function output field @@ -845,10 +854,12 @@ func anyToColumns(rows []map[string]interface{}, validDataMap map[string][]bool, } candi, ok := set[field.Name] if field.IsPrimaryKey && field.AutoID && inInsert { - if ok { + if !ok { + continue + } + if !allowInsertAutoID { return nil, merr.WrapErrParameterInvalidMsg(fmt.Sprintf("no need to pass pk field(%s) when autoid==true in insert", field.Name)) } - continue } if (field.Nullable || field.DefaultValue != nil) && !ok { continue @@ -947,6 +958,9 @@ func anyToColumns(rows []map[string]interface{}, validDataMap map[string][]bool, } columns := make([]*schemapb.FieldData, 0, len(nameColumns)) for name, column := range nameColumns { + if fieldLen[name] == 0 && name == pkFieldName && isAutoIDPK { + continue + } if fieldLen[name] == 0 && partialUpdate { // for partial update, skip update for nullable field // cause we cannot distinguish between missing fields and fields explicitly set to null diff --git a/internal/distributed/proxy/httpserver/utils_test.go b/internal/distributed/proxy/httpserver/utils_test.go index 8dddaa4398..67a90200cd 100644 --- a/internal/distributed/proxy/httpserver/utils_test.go +++ b/internal/distributed/proxy/httpserver/utils_test.go @@ -649,6 +649,25 @@ func TestAnyToColumns(t *testing.T) { assert.Equal(t, true, strings.HasPrefix(err.Error(), "no need to pass pk field")) }) + t.Run("insert,autoid==true,allow_insert_auto_id=true", func(t *testing.T) { + body := []byte("{\"data\": {\"id\": 0, \"book_id\": 1, \"book_intro\": [0.1, 0.2], \"word_count\": 2, \"classified\": false, \"databaseID\": null}}") + req := InsertReq{} + coll := generateCollectionSchema(schemapb.DataType_Int64, true, true) + coll.Properties = append(coll.Properties, &commonpb.KeyValuePair{ + Key: common.AllowInsertAutoIDKey, + Value: "true", + }) + var err error + err, req.Data, _ = checkAndSetData(body, coll, false) + assert.Equal(t, nil, err) + assert.Equal(t, int64(0), req.Data[0]["id"]) + assert.Equal(t, int64(1), req.Data[0]["book_id"]) + assert.Equal(t, int64(2), req.Data[0]["word_count"]) + t.Log(req.Data) + _, err = anyToColumns(req.Data, nil, coll, true, false) + assert.NoError(t, err) + }) + t.Run("pass more field", func(t *testing.T) { body := []byte("{\"data\": {\"id\": 0, \"book_id\": 1, \"book_intro\": [0.1, 0.2], \"word_count\": 2, \"classified\": false, \"databaseID\": null}}") coll := generateCollectionSchema(schemapb.DataType_Int64, true, false)