Files
wehub-resource-sync 498b235461
Build and test / Build and test AMD64 Ubuntu 22.04 (push) Failing after 0s
Publish Builder / amazonlinux2023 (push) Failing after 1s
Build and test / UT for Go (push) Has been skipped
Publish KRTE Images / KRTE (push) Failing after 1s
Build and test / Integration Test (push) Has been skipped
Build and test / Upload Code Coverage (push) Has been skipped
Publish Builder / rockylinux9 (push) Failing after 1s
Publish Builder / ubuntu22.04 (push) Failing after 0s
Publish Builder / ubuntu24.04 (push) Failing after 0s
Publish Gpu Builder / publish-gpu-builder (push) Failing after 1s
Publish Test Images / PyTest (push) Failing after 0s
Build and test / UT for Cpp (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:17 +08:00

108 lines
3.5 KiB
Go

package reduce
import (
"github.com/milvus-io/milvus-proto/go-api/v3/schemapb"
"github.com/milvus-io/milvus/pkg/v3/util/merr"
"github.com/milvus-io/milvus/pkg/v3/util/typeutil"
)
// FindFieldDataByID returns the first FieldData whose FieldId matches fieldID,
// or nil if none. Callers rely on FieldId being set upstream; when reducers
// re-emit group-by columns they must preserve FieldId for downstream lookup.
func FindFieldDataByID(fieldsData []*schemapb.FieldData, fieldID int64) *schemapb.FieldData {
for _, fd := range fieldsData {
if fd.GetFieldId() == fieldID {
return fd
}
}
return nil
}
func FindGroupByFieldData(data *schemapb.SearchResultData, fieldID int64, allowSingularFallback bool) *schemapb.FieldData {
if data == nil {
return nil
}
if fd := FindFieldDataByID(data.GetGroupByFieldValues(), fieldID); fd != nil {
return fd
}
if allowSingularFallback {
return data.GetGroupByFieldValue()
}
return nil
}
func ValidateGroupByFieldsPresent(searchResultData []*schemapb.SearchResultData, fieldIDs []int64, allowSingularFallback bool) error {
for resultIdx, data := range searchResultData {
if data == nil || typeutil.GetSizeOfIDs(data.GetIds()) == 0 {
continue
}
for _, fieldID := range fieldIDs {
if FindGroupByFieldData(data, fieldID, allowSingularFallback) == nil {
return merr.WrapErrParameterInvalidMsg("group-by field %d missing from search result %d", fieldID, resultIdx)
}
}
}
return nil
}
// WriteGroupByFieldValues emits one FieldData per composite-key field into
// ret.GroupByFieldValues, pulling values for each accepted row from the
// source shard it originated in. Each emitted FieldData carries FieldId so
// downstream consumers can look up by id rather than position.
//
// Shared by delegator-side SearchGroupByReduce and proxy-side cross-shard
// reduce, so both layers produce a byte-for-byte identical field-17 payload.
func WriteGroupByFieldValues(
ret *schemapb.SearchResultData,
acceptedRows []RowRef,
sources []*schemapb.SearchResultData,
fieldIDs []int64,
) error {
if len(fieldIDs) == 0 || len(acceptedRows) == 0 {
return nil
}
ret.GroupByFieldValues = make([]*schemapb.FieldData, 0, len(fieldIDs))
for _, fid := range fieldIDs {
iters := make([]func(int) any, len(sources))
var template *schemapb.FieldData
for i, srd := range sources {
fd := FindFieldDataByID(srd.GetGroupByFieldValues(), fid)
// N=1 legacy path: upstream wrote the group-by column to the
// singular channel (SearchResultData.group_by_field_value) without
// a FieldId stamp. Fall back to that channel so the unified
// proxy-side reducer can read legacy inputs and still emit the
// plural output downstream consumers expect.
if fd == nil && len(fieldIDs) == 1 {
fd = srd.GetGroupByFieldValue()
}
if fd == nil {
continue
}
iters[i] = typeutil.GetDataIterator(fd)
if template == nil {
template = fd
}
}
if template == nil {
return merr.WrapErrParameterInvalidMsg("group-by field %d missing from all source shards", fid)
}
builder, err := typeutil.NewFieldDataBuilder(template.GetType(), true, len(acceptedRows))
if err != nil {
return err
}
for _, row := range acceptedRows {
iter := iters[row.ResultIdx]
if iter == nil {
return merr.WrapErrParameterInvalidMsg("group-by field %d missing at source shard index %d", fid, row.ResultIdx)
}
builder.Add(iter(int(row.RowIdx)))
}
fd := builder.Build()
fd.FieldId = fid
fd.FieldName = template.GetFieldName()
ret.GroupByFieldValues = append(ret.GroupByFieldValues, fd)
}
return nil
}