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
108 lines
3.5 KiB
Go
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
|
|
}
|