Files
milvus/internal/distributed/proxy/httpserver/request_v2_test.go
T
ababab0d76 feat: [2.6.16] support partial update ops for Array fields (#49811)
pr: [#49328](https://github.com/milvus-io/milvus/pull/49328)
pr: [#49724](https://github.com/milvus-io/milvus/pull/49724)
pr: [#49763](https://github.com/milvus-io/milvus/pull/49763)
pr: [#49698](https://github.com/milvus-io/milvus/pull/49698)
issue: [#49241](https://github.com/milvus-io/milvus/issues/49241)
issue: [#49746](https://github.com/milvus-io/milvus/issues/49746)
issue: [#49634](https://github.com/milvus-io/milvus/issues/49634)

## Summary

Backport the 2.6 partial update op series to `hotfix-2.6.16`:

- support `ARRAY_APPEND` and `ARRAY_REMOVE` partial update ops for Array
fields
- expose `fieldOps` through REST upsert
- preserve existing Array rows when an op payload row is null

## Target branch

Base branch: `hotfix-2.6.16`

## Cherry-picks

- `5849977c408be2abd063d13c318e970bb4515f06` from
[#49328](https://github.com/milvus-io/milvus/pull/49328)
- `017ee8e5d97ec891c442489b1354b60676ca3b15` from
[#49724](https://github.com/milvus-io/milvus/pull/49724)
- `4e10473389843ff2cedc1911083af5a93fa83ec6` from
[#49763](https://github.com/milvus-io/milvus/pull/49763)
- `824c642c71154952bf70eaaf7b57cbcd7d08e67f` backports the applicable
WAL test/recovery stabilization from
`73dc8d4034fd352f5c69fd47266fccc062704feb` /
[#49698](https://github.com/milvus-io/milvus/pull/49698) after omitting
newer rate-limit API changes that do not exist on `hotfix-2.6.16`

The partial update cherry-picks applied cleanly on top of
`milvus/hotfix-2.6.16`.

## Additional revert

- `2753c8defc7a860446d1f5f76b11a50c3cc71550` reverts
  `8ae21f715094abc92e00369e89a7208681eecfed` to restore the 2.6.16
build environment image version after CI reported Conan 2.x in the newer
  image.

## Validation

- `git diff --check milvus/hotfix-2.6.16...HEAD`
- attempted targeted Go test for
`internal/streamingnode/server/wal/adaptor`, blocked locally because
this worktree lacks `rocksdb.pc` and `milvus_core.pc`

PR CI is the validation gate for this backport.

---------

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
Signed-off-by: Zhen Ye <chyezh@outlook.com>
Co-authored-by: Zhen Ye <chyezh@outlook.com>
2026-05-15 08:37:30 +08:00

75 lines
2.8 KiB
Go

// Licensed to the LF AI & Data foundation under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httpserver
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
"github.com/milvus-io/milvus/pkg/v2/util/requestutil"
)
func TestRequestV2_GetCollectionName(t *testing.T) {
tests := []struct {
name string
req requestutil.CollectionNameGetter
want string
}{
{"RenameCollectionReq", &RenameCollectionReq{CollectionName: "col1"}, "col1"},
{"QueryReqV2", &QueryReqV2{CollectionName: "col2"}, "col2"},
{"CollectionIDReq", &CollectionIDReq{CollectionName: "col3"}, "col3"},
{"CollectionFilterReq", &CollectionFilterReq{CollectionName: "col4"}, "col4"},
{"CollectionDataReq", &CollectionDataReq{CollectionName: "col5"}, "col5"},
{"SearchReqV2", &SearchReqV2{CollectionName: "col6"}, "col6"},
{"HybridSearchReq", &HybridSearchReq{CollectionName: "col7"}, "col7"},
{"PartitionsReq", &PartitionsReq{CollectionName: "col8"}, "col8"},
{"GrantV2Req", &GrantV2Req{CollectionName: "col9"}, "col9"},
{"IndexParamReq", &IndexParamReq{CollectionName: "col10"}, "col10"},
{"CollectionReq", &CollectionReq{CollectionName: "col11"}, "col11"},
{"RunAnalyzerReq", &RunAnalyzerReq{CollectionName: "col12"}, "col12"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, tt.req.GetCollectionName())
})
}
}
func TestBuildFieldPartialUpdateOps(t *testing.T) {
ops, err := buildFieldPartialUpdateOps([]FieldPartialUpdateOpReq{
{FieldName: "tags", Op: "ARRAY_APPEND"},
{FieldName: "scores", Op: "ARRAY_REMOVE"},
})
assert.NoError(t, err)
assert.Len(t, ops, 2)
assert.Equal(t, "tags", ops[0].GetFieldName())
assert.Equal(t, schemapb.FieldPartialUpdateOp_ARRAY_APPEND, ops[0].GetOp())
assert.Equal(t, "scores", ops[1].GetFieldName())
assert.Equal(t, schemapb.FieldPartialUpdateOp_ARRAY_REMOVE, ops[1].GetOp())
}
func TestBuildFieldPartialUpdateOps_RejectsUnknownOp(t *testing.T) {
_, err := buildFieldPartialUpdateOps([]FieldPartialUpdateOpReq{
{FieldName: "tags", Op: "ARRAY_EXTEND"},
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "unsupported partial update op")
}