Skip to content

Commit 0774543

Browse files
MrPresent-HanMrPresent-Han
andauthored
fix: empty search groupby result causing crash(milvus-io#43137) (milvus-io#43214)
related: milvus-io#43137 Signed-off-by: MrPresent-Han <chun.han@gmail.com> Co-authored-by: MrPresent-Han <chun.han@gmail.com>
1 parent 4714442 commit 0774543

7 files changed

Lines changed: 35 additions & 9 deletions

File tree

internal/core/src/segcore/ReduceUtils.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ AssembleGroupByValues(
2525
const std::vector<GroupByValueType>& group_by_vals,
2626
milvus::query::Plan* plan) {
2727
auto group_by_field_id = plan->plan_node_->search_info_.group_by_field_id_;
28-
if (group_by_field_id.has_value() && group_by_vals.size() > 0) {
29-
auto group_by_values_field =
30-
std::make_unique<milvus::proto::schema::ScalarField>();
28+
if (group_by_field_id.has_value()) {
3129
auto valid_data =
3230
std::make_unique<google::protobuf::RepeatedField<bool>>();
3331
valid_data->Resize(group_by_vals.size(), true);
32+
auto group_by_values_field =
33+
std::make_unique<milvus::proto::schema::ScalarField>();
3434
auto group_by_field =
3535
plan->schema_->operator[](group_by_field_id.value());
3636
auto group_by_data_type = group_by_field.get_data_type();
@@ -134,7 +134,6 @@ AssembleGroupByValues(
134134
group_by_field_value->mutable_valid_data()->MergeFrom(*valid_data);
135135
group_by_field_value->mutable_scalars()->MergeFrom(
136136
*group_by_values_field.get());
137-
return;
138137
}
139138
}
140139

internal/proxy/search_reduce_util.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func reduceAdvanceGroupBy(ctx context.Context, subSearchResultData []*schemapb.S
118118

119119
gpFieldBuilder, err := typeutil.NewFieldDataBuilder(subSearchResultData[0].GetGroupByFieldValue().GetType(), true, int(limit))
120120
if err != nil {
121-
return ret, err
121+
return ret, merr.WrapErrServiceInternal("failed to construct group by field data builder, this is abnormal as segcore should always set up a group by field, no matter data status, check code on qn", err.Error())
122122
}
123123
// reducing nq * topk results
124124
for nqIdx := int64(0); nqIdx < nq; nqIdx++ {
@@ -222,9 +222,10 @@ func reduceSearchResultDataWithGroupBy(ctx context.Context, subSearchResultData
222222
totalResCount += subSearchNqOffset[i][nq-1]
223223
subSearchGroupByValIterator[i] = typeutil.GetDataIterator(subSearchResultData[i].GetGroupByFieldValue())
224224
}
225+
225226
gpFieldBuilder, err := typeutil.NewFieldDataBuilder(subSearchResultData[0].GetGroupByFieldValue().GetType(), true, int(limit))
226227
if err != nil {
227-
return ret, err
228+
return ret, merr.WrapErrServiceInternal("failed to construct group by field data builder, this is abnormal as segcore should always set up a group by field, no matter data status, check code on qn", err.Error())
228229
}
229230

230231
var realTopK int64 = -1

internal/proxy/search_reduce_util_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,29 @@ func (struts *SearchReduceUtilTestSuite) TestReduceSearchResult() {
6161
}
6262
}
6363

64+
func (struts *SearchReduceUtilTestSuite) TestReduceSearchResultWithEmtpyGroupData() {
65+
nq := int64(1)
66+
topk := int64(1)
67+
emptyData := &schemapb.SearchResultData{
68+
NumQueries: nq,
69+
TopK: topk,
70+
FieldsData: make([]*schemapb.FieldData, 0),
71+
Scores: make([]float32, 0),
72+
Ids: &schemapb.IDs{},
73+
Topks: make([]int64, 0),
74+
OutputFields: make([]string, 0),
75+
AllSearchCount: 0,
76+
Distances: make([]float32, 0),
77+
Recalls: make([]float32, 0),
78+
PrimaryFieldName: "",
79+
}
80+
results, err := reduceSearchResultDataWithGroupBy(context.Background(), []*schemapb.SearchResultData{emptyData},
81+
nq, topk, "L2", schemapb.DataType_Int64, 0, 1)
82+
struts.Error(err)
83+
struts.ErrorContains(err, "failed to construct group by field data builder")
84+
struts.Nil(results.Results.GetGroupByFieldValue())
85+
}
86+
6487
func TestSearchReduceUtilTestSuite(t *testing.T) {
6588
suite.Run(t, new(SearchReduceUtilTestSuite))
6689
}

internal/querynodev2/delegator/delegator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ func (sd *shardDelegator) search(ctx context.Context, req *querypb.SearchRequest
368368
return nil, err
369369
}
370370

371-
log.Debug("Delegator search done")
371+
log.Debug("Delegator search done", zap.Int("results", len(results)))
372372

373373
return results, nil
374374
}

internal/querynodev2/segments/result.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ func ReduceSearchResults(ctx context.Context, results []*internalpb.SearchResult
5757
})
5858

5959
if len(results) == 1 {
60+
log.Debug("Shortcut return ReduceSearchResults", zap.Any("result info", info))
6061
return results[0], nil
6162
}
6263

internal/querynodev2/segments/search_reduce.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
1111
"github.com/milvus-io/milvus/internal/util/reduce"
1212
"github.com/milvus-io/milvus/pkg/v2/log"
13+
"github.com/milvus-io/milvus/pkg/v2/util/merr"
1314
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
1415
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
1516
)
@@ -107,6 +108,7 @@ func (sbr *SearchGroupByReduce) ReduceSearchResultData(ctx context.Context, sear
107108
log := log.Ctx(ctx)
108109

109110
if len(searchResultData) == 0 {
111+
log.Debug("Shortcut return SearchGroupByReduce, directly return empty result", zap.Any("result info", info))
110112
return &schemapb.SearchResultData{
111113
NumQueries: info.GetNq(),
112114
TopK: info.GetTopK(),
@@ -137,7 +139,7 @@ func (sbr *SearchGroupByReduce) ReduceSearchResultData(ctx context.Context, sear
137139
}
138140
gpFieldBuilder, err := typeutil.NewFieldDataBuilder(searchResultData[0].GetGroupByFieldValue().GetType(), true, int(info.GetTopK()))
139141
if err != nil {
140-
return nil, err
142+
return ret, merr.WrapErrServiceInternal("failed to construct group by field data builder, this is abnormal as segcore should always set up a group by field, no matter data status, check code on qn", err.Error())
141143
}
142144

143145
var filteredCount int64

pkg/util/typeutil/schema.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,7 @@ func GetPK(data *schemapb.IDs, idx int64) interface{} {
14581458
}
14591459

14601460
func GetDataIterator(field *schemapb.FieldData) func(int) any {
1461-
if field.ValidData != nil {
1461+
if field.GetValidData() != nil {
14621462
// unpack valid data
14631463
idxs := make([]int, len(field.ValidData))
14641464
validCnt := 0

0 commit comments

Comments
 (0)