fix: record cursor for query iterator in element-level query (#49394)

issue: https://github.com/milvus-io/milvus/issues/49355
ref: https://github.com/milvus-io/milvus/issues/42148

---------

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
This commit is contained in:
Spade A
2026-04-28 17:01:51 +08:00
committed by GitHub
parent 54c25d00a1
commit ed44081b30
17 changed files with 1090 additions and 257 deletions
+5
View File
@@ -113,6 +113,11 @@ using InsertRecordProto = proto::segcore::InsertRecord;
using PkType = std::variant<std::monostate, int64_t, std::string>;
using DefaultValueType = proto::schema::ValueField;
struct QueryIteratorCursor {
PkType last_pk;
int64_t last_element_offset = -1;
};
inline size_t
GetDataTypeSize(DataType data_type, int dim = 1) {
switch (data_type) {
@@ -346,8 +346,10 @@ ExecPlanNodeVisitor::setupRetrieveResult(
"Element Level Find", tracer::GetRootSpan(), true);
auto array_offsets = query_context->get_array_offsets();
auto [doc_offsets, element_indices, has_more] =
segment->find_first_n_element(
node.limit_, view, array_offsets.get());
segment->find_first_n_element(node.limit_,
view,
array_offsets.get(),
node.query_iterator_cursor_);
tmp_retrieve_result.result_offsets_ = std::move(doc_offsets);
tmp_retrieve_result.element_indices_ = std::move(element_indices);
tmp_retrieve_result.has_more_result = has_more;
+3
View File
@@ -13,11 +13,13 @@
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "common/FieldMeta.h"
#include "common/QueryInfo.h"
#include "common/Types.h"
namespace milvus::plan {
class PlanNode;
@@ -67,6 +69,7 @@ struct RetrievePlanNode : PlanNode {
// Field IDs for pipeline columns in the same order as the ProjectNode output.
// Used by FillOrderByResult to set field_id on DataArrays produced by the pipeline.
std::vector<FieldId> pipeline_field_ids_;
std::optional<QueryIteratorCursor> query_iterator_cursor_;
};
} // namespace milvus::query
+17
View File
@@ -755,6 +755,23 @@ ProtoParser::RetrievePlanNodeFromProto(
parse_expr_to_filter_node(query.predicates());
}
}
if (query.has_query_iterator_cursor()) {
AssertInfo(is_element_level,
"query iterator cursor is only supported for "
"element-level query");
const auto& cursor_proto = query.query_iterator_cursor();
QueryIteratorCursor cursor;
if (cursor_proto.has_last_int_pk()) {
cursor.last_pk = cursor_proto.last_int_pk();
} else if (cursor_proto.has_last_str_pk()) {
cursor.last_pk = cursor_proto.last_str_pk();
} else {
ThrowInfo(ErrorCode::UnexpectedError,
"query iterator cursor requires last primary key");
}
cursor.last_element_offset = cursor_proto.last_element_offset();
plan_node->query_iterator_cursor_ = std::move(cursor);
}
// 2. Build MvccNode
plannode = std::make_shared<milvus::plan::MvccNode>(
@@ -2241,11 +2241,12 @@ std::tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
ChunkedSegmentSealedImpl::find_first_n_element(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const {
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const {
if (!is_sorted_by_pk_) {
// Not sorted by PK, use pk2offset_ to iterate in PK order
return insert_record_.pk2offset_->find_first_n_element(
limit, element_bitset, array_offsets);
limit, element_bitset, array_offsets, cursor);
}
// Sorted by PK, element_id order = (PK, element_index) order
@@ -2254,6 +2255,36 @@ ChunkedSegmentSealedImpl::find_first_n_element(
limit = static_cast<int64_t>(element_bitset.size());
}
// We iterate matching elements by global element id, which maps back
// to (doc_offset, element_offset). The cursor, however, only tells us the
// last returned PK and element offset. Find the row for that PK first; the
// scan can then skip only elements from that row whose element offset has
// already been returned.
std::optional<int64_t> cursor_doc_offset;
if (cursor.has_value()) {
auto pk_field_id =
schema_->get_primary_field_id().value_or(FieldId(-1));
AssertInfo(pk_field_id.get() != -1, "Primary key is -1");
auto pk_column = get_column(pk_field_id);
AssertInfo(pk_column != nullptr, "primary key column not loaded");
switch (schema_->get_fields().at(pk_field_id).get_data_type()) {
case DataType::INT64:
cursor_doc_offset = find_sorted_pk_doc_offset<int64_t>(
std::get<int64_t>(cursor->last_pk), pk_column);
break;
case DataType::VARCHAR:
cursor_doc_offset = find_sorted_pk_doc_offset<std::string>(
std::get<std::string>(cursor->last_pk), pk_column);
break;
default:
ThrowInfo(
DataTypeInvalid,
fmt::format(
"unsupported type {}",
schema_->get_fields().at(pk_field_id).get_data_type()));
}
}
int64_t hit_num = 0;
auto element_size = static_cast<int64_t>(element_bitset.size());
int64_t cnt = element_size - element_bitset.count();
@@ -2268,6 +2299,12 @@ ChunkedSegmentSealedImpl::find_first_n_element(
while (elem_opt.has_value() && hit_num < limit) {
int64_t elem_id = static_cast<int64_t>(elem_opt.value());
auto [doc_id, elem_idx] = array_offsets->ElementIDToRowID(elem_id);
if (cursor_doc_offset.has_value() &&
doc_id == cursor_doc_offset.value() &&
elem_idx <= cursor->last_element_offset) {
elem_opt = element_bitset.find_next(elem_id, false);
continue;
}
if (doc_id != current_doc_id) {
// New document - start a new entry
@@ -393,9 +393,11 @@ class ChunkedSegmentSealedImpl : public SegmentSealed {
find_first_n(int64_t limit, const BitsetTypeView& bitset) const override;
std::tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
find_first_n_element(int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const override;
find_first_n_element(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const override;
// Calculate: output[i] = Vec[seg_offset[i]]
// where Vec is determined from field_offset
@@ -727,6 +729,20 @@ class ChunkedSegmentSealedImpl : public SegmentSealed {
}
}
template <typename PK>
std::optional<int64_t>
find_sorted_pk_doc_offset(
const PK& pk,
const std::shared_ptr<ChunkedColumnInterface>& pk_column) const {
auto all_chunk_pins = pk_column->GetAllChunks(nullptr);
auto [chunk_id, in_chunk_offset, exact_match] =
this->pk_lower_bound<PK>(pk, pk_column.get(), all_chunk_pins, 0);
if (!exact_match) {
return std::nullopt;
}
return pk_column->GetNumRowsUntilChunk(chunk_id) + in_chunk_offset;
}
template <typename PK>
void
search_pks_with_two_pointers_impl(
+95 -23
View File
@@ -16,6 +16,7 @@
#include <cstddef>
#include <memory>
#include <mutex>
#include <optional>
#include <shared_mutex>
#include <string>
#include <unordered_map>
@@ -279,9 +280,11 @@ class OffsetMap {
// - has_more flag indicating if there are more results
virtual std::
tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
find_first_n_element(int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const = 0;
find_first_n_element(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const = 0;
virtual void
clear() = 0;
@@ -409,9 +412,11 @@ class OffsetOrderedMap : public OffsetMap {
}
std::tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
find_first_n_element(int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const override {
find_first_n_element(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const override {
std::shared_lock<std::shared_mutex> lck(mtx_);
if (limit == Unlimited || limit == NoLimit) {
@@ -419,7 +424,7 @@ class OffsetOrderedMap : public OffsetMap {
}
return find_first_n_element_by_index(
limit, element_bitset, array_offsets);
limit, element_bitset, array_offsets, cursor);
}
void
@@ -467,9 +472,11 @@ class OffsetOrderedMap : public OffsetMap {
}
std::tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
find_first_n_element_by_index(int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const {
find_first_n_element_by_index(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const {
std::vector<int64_t> doc_offsets;
std::vector<std::vector<int32_t>> element_indices;
@@ -504,6 +511,10 @@ class OffsetOrderedMap : public OffsetMap {
if (elem_id >= element_size) {
continue;
}
if (is_skipped_by_cursor(
it->first, elem_id - first_elem, cursor)) {
continue;
}
if (!element_bitset[elem_id]) { // 0 means pass filter
matching_indices.push_back(
static_cast<int32_t>(elem_id - first_elem));
@@ -518,13 +529,37 @@ class OffsetOrderedMap : public OffsetMap {
// PK hit, no need to continue traversing older offsets with the same PK.
break;
}
if (is_cursor_pk(it->first, cursor)) {
// The cursor applies to the newest visible row for this PK.
// Do not fall through to older offsets of the same PK.
break;
}
}
}
bool has_more = more_hit_than_limit && (it != map_.end());
bool has_more = more_hit_than_limit && hit_num >= limit;
return {std::move(doc_offsets), std::move(element_indices), has_more};
}
bool
is_skipped_by_cursor(
const T& pk,
int64_t element_offset,
const std::optional<QueryIteratorCursor>& cursor) const {
return is_cursor_pk(pk, cursor) &&
element_offset <= cursor->last_element_offset;
}
bool
is_cursor_pk(const T& pk,
const std::optional<QueryIteratorCursor>& cursor) const {
if (!cursor.has_value()) {
return false;
}
auto last_pk = std::get_if<T>(&cursor->last_pk);
return last_pk != nullptr && *last_pk == pk;
}
private:
OrderedMap map_;
mutable std::shared_mutex mtx_;
@@ -663,9 +698,11 @@ class OffsetOrderedArray : public OffsetMap {
}
std::tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
find_first_n_element(int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const override {
find_first_n_element(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const override {
check_search();
if (limit == Unlimited || limit == NoLimit) {
@@ -673,7 +710,7 @@ class OffsetOrderedArray : public OffsetMap {
}
return find_first_n_element_by_index(
limit, element_bitset, array_offsets);
limit, element_bitset, array_offsets, cursor);
}
void
@@ -714,9 +751,11 @@ class OffsetOrderedArray : public OffsetMap {
}
std::tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
find_first_n_element_by_index(int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const {
find_first_n_element_by_index(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const {
std::vector<int64_t> doc_offsets;
std::vector<std::vector<int32_t>> element_indices;
@@ -746,6 +785,10 @@ class OffsetOrderedArray : public OffsetMap {
if (elem_id >= element_size) {
continue;
}
if (is_skipped_by_cursor(
it->first, elem_id - first_elem, cursor)) {
continue;
}
if (!element_bitset[elem_id]) { // 0 means pass filter
matching_indices.push_back(
static_cast<int32_t>(elem_id - first_elem));
@@ -760,10 +803,23 @@ class OffsetOrderedArray : public OffsetMap {
}
}
bool has_more = more_hit_than_limit && (it != array_.end());
bool has_more = more_hit_than_limit && hit_num >= limit;
return {std::move(doc_offsets), std::move(element_indices), has_more};
}
bool
is_skipped_by_cursor(
const T& pk,
int64_t element_offset,
const std::optional<QueryIteratorCursor>& cursor) const {
if (!cursor.has_value()) {
return false;
}
auto last_pk = std::get_if<T>(&cursor->last_pk);
return last_pk != nullptr && *last_pk == pk &&
element_offset <= cursor->last_element_offset;
}
void
check_search() const {
AssertInfo(is_sealed,
@@ -908,9 +964,11 @@ class VirtualPKOffsetMap : public OffsetMap {
}
std::tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
find_first_n_element(int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const override {
find_first_n_element(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const override {
// External tables don't support array fields, but implement
// the interface for completeness.
auto element_size = static_cast<int64_t>(element_bitset.size());
@@ -931,7 +989,8 @@ class VirtualPKOffsetMap : public OffsetMap {
std::vector<int32_t> matching;
for (int64_t e = first_elem; e < last_elem && hit_num < limit;
e++) {
if (e < element_size && !element_bitset[e]) {
if (e < element_size && !element_bitset[e] &&
!is_skipped_by_cursor(doc, e - first_elem, cursor)) {
matching.push_back(static_cast<int32_t>(e - first_elem));
hit_num++;
}
@@ -956,6 +1015,19 @@ class VirtualPKOffsetMap : public OffsetMap {
return sizeof(VirtualPKOffsetMap);
}
bool
is_skipped_by_cursor(
int64_t doc,
int64_t element_offset,
const std::optional<QueryIteratorCursor>& cursor) const {
if (!cursor.has_value()) {
return false;
}
auto last_pk = std::get_if<int64_t>(&cursor->last_pk);
return last_pk != nullptr && *last_pk == (shifted_segment_id_ | doc) &&
element_offset <= cursor->last_element_offset;
}
private:
int64_t truncated_segment_id_;
int64_t shifted_segment_id_;
@@ -174,7 +174,7 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first_n_element) {
BitsetTypeView view(all.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
ASSERT_EQ(doc_offsets.size(), num);
for (size_t i = 0; i < doc_offsets.size(); i++) {
ASSERT_EQ(elem_indices[i].size(), array_len);
@@ -188,7 +188,8 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first_n_element) {
all.reset();
BitsetTypeView view(all.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(4, view, array_offsets.get());
this->map_.find_first_n_element(
4, view, array_offsets.get(), std::nullopt);
int total = 0;
for (auto& indices : elem_indices) {
total += indices.size();
@@ -210,7 +211,7 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first_n_element) {
BitsetTypeView view(partial.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
ASSERT_EQ(doc_offsets.size(), num);
for (size_t i = 0; i < doc_offsets.size(); i++) {
ASSERT_EQ(elem_indices[i].size(), 1);
@@ -225,7 +226,7 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first_n_element) {
BitsetTypeView view(none.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
ASSERT_EQ(doc_offsets.size(), 0);
ASSERT_EQ(elem_indices.size(), 0);
ASSERT_FALSE(has_more);
@@ -239,7 +240,7 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first_n_element) {
BitsetTypeView view(small.data(), smaller_size);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
int total = 0;
for (auto& indices : elem_indices) {
total += indices.size();
@@ -289,7 +290,7 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first_n_element_has_more) {
BitsetTypeView view(all.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
int collected = 0;
for (auto& indices : elem_indices) {
collected += indices.size();
@@ -310,7 +311,8 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first_n_element_has_more) {
}
BitsetTypeView view(partial.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(num, view, array_offsets.get());
this->map_.find_first_n_element(
num, view, array_offsets.get(), std::nullopt);
int collected = 0;
for (auto& indices : elem_indices) {
collected += indices.size();
@@ -326,7 +328,8 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first_n_element_has_more) {
all.reset();
BitsetTypeView view(all.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(3, view, array_offsets.get());
this->map_.find_first_n_element(
3, view, array_offsets.get(), std::nullopt);
int collected = 0;
for (auto& indices : elem_indices) {
collected += indices.size();
@@ -337,10 +340,62 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first_n_element_has_more) {
}
}
TYPED_TEST_P(TypedOffsetOrderedArrayTest,
find_first_n_element_with_iterator_cursor) {
auto make_pk = [](int i) {
if constexpr (std::is_same_v<std::string, TypeParam>) {
return std::to_string(i);
} else {
return static_cast<TypeParam>(i);
}
};
int num = 3;
int array_len = 4;
for (int i = 0; i < num; i++) {
this->insert(make_pk(i));
}
this->seal();
std::vector<int32_t> row_to_element_start = {0};
for (int doc = 0; doc < num; doc++) {
row_to_element_start.push_back(
static_cast<int32_t>((doc + 1) * array_len));
}
auto array_offsets =
std::make_shared<ArrayOffsetsSealed>(std::move(row_to_element_start));
BitsetType bitset(num * array_len);
bitset.reset();
for (int e = 0; e < array_len; e++) {
bitset.set(e); // Simulate query expr pk >= 1.
}
BitsetTypeView view(bitset.data(), bitset.size());
QueryIteratorCursor cursor;
cursor.last_pk = make_pk(1);
cursor.last_element_offset = 1;
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(10, view, array_offsets.get(), cursor);
ASSERT_EQ(doc_offsets, std::vector<int64_t>({1, 2}));
ASSERT_EQ(elem_indices[0], std::vector<int32_t>({2, 3}));
ASSERT_EQ(elem_indices[1], std::vector<int32_t>({0, 1, 2, 3}));
ASSERT_FALSE(has_more);
auto [limited_docs, limited_indices, limited_has_more] =
this->map_.find_first_n_element(3, view, array_offsets.get(), cursor);
ASSERT_EQ(limited_docs, std::vector<int64_t>({1, 2}));
ASSERT_EQ(limited_indices[0], std::vector<int32_t>({2, 3}));
ASSERT_EQ(limited_indices[1], std::vector<int32_t>({0}));
ASSERT_TRUE(limited_has_more);
}
REGISTER_TYPED_TEST_SUITE_P(TypedOffsetOrderedArrayTest,
find_first_n,
find_first_n_element,
find_first_n_element_has_more);
find_first_n_element_has_more,
find_first_n_element_with_iterator_cursor);
INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TypedOffsetOrderedArrayTest, TypeOfPks);
// =====================================================================
@@ -174,7 +174,7 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first_n_element) {
BitsetTypeView view(all.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
ASSERT_EQ(doc_offsets.size(), num);
for (size_t i = 0; i < doc_offsets.size(); i++) {
ASSERT_EQ(elem_indices[i].size(), array_len)
@@ -190,7 +190,8 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first_n_element) {
BitsetTypeView view(all.data(), total_elements);
// limit=4: first doc contributes 3 elements, second doc contributes 1
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(4, view, array_offsets.get());
this->map_.find_first_n_element(
4, view, array_offsets.get(), std::nullopt);
int total = 0;
for (auto& indices : elem_indices) {
total += indices.size();
@@ -212,7 +213,7 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first_n_element) {
BitsetTypeView view(partial.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
ASSERT_EQ(doc_offsets.size(), num);
for (size_t i = 0; i < doc_offsets.size(); i++) {
ASSERT_EQ(elem_indices[i].size(), 1);
@@ -227,7 +228,7 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first_n_element) {
BitsetTypeView view(none.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
ASSERT_EQ(doc_offsets.size(), 0);
ASSERT_EQ(elem_indices.size(), 0);
}
@@ -240,7 +241,7 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first_n_element) {
BitsetTypeView view(small.data(), smaller_size);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
// Last doc's elements are beyond bitset, should be skipped
int total = 0;
for (auto& indices : elem_indices) {
@@ -288,7 +289,7 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first_n_element_has_more) {
BitsetTypeView view(all.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(
total_elements, view, array_offsets.get());
total_elements, view, array_offsets.get(), std::nullopt);
int collected = 0;
for (auto& indices : elem_indices) {
collected += indices.size();
@@ -308,7 +309,8 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first_n_element_has_more) {
}
BitsetTypeView view(partial.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(num, view, array_offsets.get());
this->map_.find_first_n_element(
num, view, array_offsets.get(), std::nullopt);
int collected = 0;
for (auto& indices : elem_indices) {
collected += indices.size();
@@ -324,7 +326,8 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first_n_element_has_more) {
all.reset();
BitsetTypeView view(all.data(), total_elements);
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(3, view, array_offsets.get());
this->map_.find_first_n_element(
3, view, array_offsets.get(), std::nullopt);
int collected = 0;
for (auto& indices : elem_indices) {
collected += indices.size();
@@ -335,8 +338,103 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first_n_element_has_more) {
}
}
REGISTER_TYPED_TEST_SUITE_P(TypedOffsetOrderedMapTest,
find_first_n,
find_first_n_element,
find_first_n_element_has_more);
TYPED_TEST_P(TypedOffsetOrderedMapTest,
find_first_n_element_with_iterator_cursor) {
auto make_pk = [](int i) {
if constexpr (std::is_same_v<std::string, TypeParam>) {
return std::to_string(i);
} else {
return static_cast<TypeParam>(i);
}
};
int num = 3;
int array_len = 4;
for (int i = 0; i < num; i++) {
this->insert(make_pk(i));
}
std::vector<int32_t> row_to_element_start = {0};
for (int doc = 0; doc < num; doc++) {
row_to_element_start.push_back(
static_cast<int32_t>((doc + 1) * array_len));
}
auto array_offsets =
std::make_shared<ArrayOffsetsSealed>(std::move(row_to_element_start));
BitsetType bitset(num * array_len);
bitset.reset();
for (int e = 0; e < array_len; e++) {
bitset.set(e); // Simulate query expr pk >= 1.
}
BitsetTypeView view(bitset.data(), bitset.size());
QueryIteratorCursor cursor;
cursor.last_pk = make_pk(1);
cursor.last_element_offset = 1;
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(10, view, array_offsets.get(), cursor);
ASSERT_EQ(doc_offsets, std::vector<int64_t>({1, 2}));
ASSERT_EQ(elem_indices[0], std::vector<int32_t>({2, 3}));
ASSERT_EQ(elem_indices[1], std::vector<int32_t>({0, 1, 2, 3}));
ASSERT_FALSE(has_more);
auto [limited_docs, limited_indices, limited_has_more] =
this->map_.find_first_n_element(3, view, array_offsets.get(), cursor);
ASSERT_EQ(limited_docs, std::vector<int64_t>({1, 2}));
ASSERT_EQ(limited_indices[0], std::vector<int32_t>({2, 3}));
ASSERT_EQ(limited_indices[1], std::vector<int32_t>({0}));
ASSERT_TRUE(limited_has_more);
}
TYPED_TEST_P(TypedOffsetOrderedMapTest,
find_first_n_element_cursor_does_not_return_stale_pk) {
auto make_pk = [](int i) {
if constexpr (std::is_same_v<std::string, TypeParam>) {
return std::to_string(i);
} else {
return static_cast<TypeParam>(i);
}
};
int array_len = 3;
this->insert(make_pk(0));
this->insert(make_pk(1)); // older version of pk=1
this->insert(make_pk(1)); // newest version of pk=1
this->insert(make_pk(2));
std::vector<int32_t> row_to_element_start = {0};
for (int doc = 0; doc < 4; doc++) {
row_to_element_start.push_back(
static_cast<int32_t>((doc + 1) * array_len));
}
auto array_offsets =
std::make_shared<ArrayOffsetsSealed>(std::move(row_to_element_start));
BitsetType bitset(4 * array_len);
bitset.reset();
for (int e = 0; e < array_len; e++) {
bitset.set(e); // Simulate query expr pk >= 1.
}
BitsetTypeView view(bitset.data(), bitset.size());
QueryIteratorCursor cursor;
cursor.last_pk = make_pk(1);
cursor.last_element_offset = 2;
auto [doc_offsets, elem_indices, has_more] =
this->map_.find_first_n_element(10, view, array_offsets.get(), cursor);
ASSERT_EQ(doc_offsets, std::vector<int64_t>({3}));
ASSERT_EQ(elem_indices[0], std::vector<int32_t>({0, 1, 2}));
ASSERT_FALSE(has_more);
}
REGISTER_TYPED_TEST_SUITE_P(
TypedOffsetOrderedMapTest,
find_first_n,
find_first_n_element,
find_first_n_element_has_more,
find_first_n_element_with_iterator_cursor,
find_first_n_element_cursor_does_not_return_stale_pk);
INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TypedOffsetOrderedMapTest, TypeOfPks);
@@ -555,11 +555,13 @@ class SegmentGrowingImpl : public SegmentGrowing {
}
std::tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
find_first_n_element(int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const override {
find_first_n_element(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const override {
return insert_record_.pk2offset_->find_first_n_element(
limit, element_bitset, array_offsets);
limit, element_bitset, array_offsets, cursor);
}
bool
+5 -3
View File
@@ -615,9 +615,11 @@ class SegmentInternalInterface : public SegmentInterface {
*/
virtual std::
tuple<std::vector<int64_t>, std::vector<std::vector<int32_t>>, bool>
find_first_n_element(int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets) const = 0;
find_first_n_element(
int64_t limit,
const BitsetTypeView& element_bitset,
const IArrayOffsets* array_offsets,
const std::optional<QueryIteratorCursor>& cursor) const = 0;
void
FillTargetEntryDirectly(
@@ -1849,6 +1849,197 @@ TEST(ElementFilter, RetrieveSortedByPk) {
EXEC_EVAL_EXPR_BATCH_SIZE.store(saved_batch_size);
}
TEST(ElementFilter, RetrieveIteratorCursorSkipsReturnedElements) {
auto saved_batch_size = EXEC_EVAL_EXPR_BATCH_SIZE.load();
EXEC_EVAL_EXPR_BATCH_SIZE.store(100);
int dim = 4;
auto schema = std::make_shared<Schema>();
auto vec_fid = schema->AddDebugVectorArrayField("structA[array_float_vec]",
DataType::VECTOR_FLOAT,
dim,
knowhere::metric::L2);
auto int_array_fid = schema->AddDebugArrayField(
"structA[price_array]", DataType::INT32, false);
auto int64_fid = schema->AddDebugField("id", DataType::INT64);
schema->set_primary_field_id(int64_fid);
size_t N = 20;
int array_len = 5;
auto raw_data = DataGen(schema, N, 42, 0, 1, array_len);
for (int i = 0; i < raw_data.raw_->fields_data_size(); i++) {
auto* field_data = raw_data.raw_->mutable_fields_data(i);
if (field_data->field_id() == int_array_fid.get()) {
field_data->mutable_scalars()
->mutable_array_data()
->mutable_data()
->Clear();
for (int row = 0; row < N; row++) {
auto* array_data = field_data->mutable_scalars()
->mutable_array_data()
->mutable_data()
->Add();
for (int elem = 0; elem < array_len; elem++) {
array_data->mutable_int_data()->mutable_data()->Add(elem);
}
}
break;
}
}
auto segment = CreateSealedSegment(schema,
empty_index_meta,
/*segment_id=*/0,
SegcoreConfig::default_config(),
/*is_sorted_by_pk=*/true);
LoadGeneratedDataIntoSegment(raw_data, segment.get());
auto build_plan = [&](int64_t limit,
std::optional<int64_t> min_pk,
std::optional<std::pair<int64_t, int64_t>> cursor) {
proto::plan::PlanNode plan_node;
auto* query = plan_node.mutable_query();
query->set_is_count(false);
query->set_limit(limit);
auto* expr = query->mutable_predicates();
auto* element_filter = expr->mutable_element_filter_expr();
element_filter->set_struct_name("structA");
auto* element_expr = element_filter->mutable_element_expr();
auto* element_range = element_expr->mutable_unary_range_expr();
auto* element_column = element_range->mutable_column_info();
element_column->set_field_id(int_array_fid.get());
element_column->set_data_type(proto::schema::DataType::Int32);
element_column->set_element_type(proto::schema::DataType::Int32);
element_column->set_is_element_level(true);
element_range->set_op(proto::plan::OpType::GreaterEqual);
element_range->mutable_value()->set_int64_val(0);
if (min_pk.has_value()) {
auto* predicate = element_filter->mutable_predicate();
auto* pk_range = predicate->mutable_unary_range_expr();
auto* pk_column = pk_range->mutable_column_info();
pk_column->set_field_id(int64_fid.get());
pk_column->set_data_type(proto::schema::DataType::Int64);
pk_range->set_op(proto::plan::OpType::GreaterEqual);
pk_range->mutable_value()->set_int64_val(min_pk.value());
}
if (cursor.has_value()) {
auto* query_cursor = query->mutable_query_iterator_cursor();
query_cursor->set_last_int_pk(cursor->first);
query_cursor->set_last_element_offset(cursor->second);
}
plan_node.add_output_field_ids(int64_fid.get());
plan_node.add_output_field_ids(int_array_fid.get());
auto parser = ProtoParser(schema);
return parser.CreateRetrievePlan(plan_node);
};
auto retrieve = [&](const RetrievePlan* plan) {
return segment->Retrieve(nullptr,
plan,
1L << 63,
INT64_MAX,
false,
folly::CancellationToken(),
0,
0);
};
auto first_plan = build_plan(
/*limit=*/8, /*min_pk=*/std::nullopt, /*cursor=*/std::nullopt);
auto first_results = retrieve(first_plan.get());
ASSERT_NE(first_results, nullptr);
ASSERT_TRUE(first_results->element_level());
ASSERT_TRUE(first_results->has_more_result());
ASSERT_EQ(first_results->offset_size(), 2);
ASSERT_EQ(first_results->offset(0), 0);
ASSERT_EQ(first_results->element_indices(0).indices_size(), 5);
for (int i = 0; i < 5; i++) {
ASSERT_EQ(first_results->element_indices(0).indices(i), i);
}
ASSERT_EQ(first_results->offset(1), 1);
ASSERT_EQ(first_results->element_indices(1).indices_size(), 3);
for (int i = 0; i < 3; i++) {
ASSERT_EQ(first_results->element_indices(1).indices(i), i);
}
auto second_plan =
build_plan(/*limit=*/8,
/*min_pk=*/std::optional<int64_t>(1),
/*cursor=*/std::make_pair<int64_t, int64_t>(1, 2));
auto second_results = retrieve(second_plan.get());
ASSERT_NE(second_results, nullptr);
ASSERT_TRUE(second_results->element_level());
ASSERT_TRUE(second_results->has_more_result());
ASSERT_EQ(second_results->offset_size(), 3);
ASSERT_EQ(second_results->offset(0), 1);
ASSERT_EQ(second_results->element_indices(0).indices_size(), 2);
ASSERT_EQ(second_results->element_indices(0).indices(0), 3);
ASSERT_EQ(second_results->element_indices(0).indices(1), 4);
ASSERT_EQ(second_results->offset(1), 2);
ASSERT_EQ(second_results->element_indices(1).indices_size(), 5);
for (int i = 0; i < 5; i++) {
ASSERT_EQ(second_results->element_indices(1).indices(i), i);
}
ASSERT_EQ(second_results->offset(2), 3);
ASSERT_EQ(second_results->element_indices(2).indices_size(), 1);
ASSERT_EQ(second_results->element_indices(2).indices(0), 0);
auto last_page_plan =
build_plan(/*limit=*/2,
/*min_pk=*/std::optional<int64_t>(19),
/*cursor=*/std::make_pair<int64_t, int64_t>(19, 2));
auto last_page_results = retrieve(last_page_plan.get());
ASSERT_NE(last_page_results, nullptr);
ASSERT_TRUE(last_page_results->element_level());
ASSERT_FALSE(last_page_results->has_more_result());
ASSERT_EQ(last_page_results->offset_size(), 1);
ASSERT_EQ(last_page_results->offset(0), 19);
ASSERT_EQ(last_page_results->element_indices(0).indices_size(), 2);
ASSERT_EQ(last_page_results->element_indices(0).indices(0), 3);
ASSERT_EQ(last_page_results->element_indices(0).indices(1), 4);
EXEC_EVAL_EXPR_BATCH_SIZE.store(saved_batch_size);
}
TEST(ElementFilter, QueryIteratorCursorRequiresElementFilter) {
auto schema = std::make_shared<Schema>();
auto int64_fid = schema->AddDebugField("id", DataType::INT64);
schema->set_primary_field_id(int64_fid);
proto::plan::PlanNode plan_node;
auto* query = plan_node.mutable_query();
query->set_is_count(false);
query->set_limit(10);
auto* predicate = query->mutable_predicates();
auto* range = predicate->mutable_unary_range_expr();
auto* column_info = range->mutable_column_info();
column_info->set_field_id(int64_fid.get());
column_info->set_data_type(proto::schema::DataType::Int64);
range->set_op(proto::plan::OpType::GreaterEqual);
range->mutable_value()->set_int64_val(0);
auto* cursor = query->mutable_query_iterator_cursor();
cursor->set_last_int_pk(1);
cursor->set_last_element_offset(2);
plan_node.add_output_field_ids(int64_fid.get());
auto parser = ProtoParser(schema);
ASSERT_ANY_THROW(parser.CreateRetrievePlan(plan_node));
}
// Regression test for https://github.com/milvus-io/milvus/issues/49260
// ElementFilterBitsNode: when element_filter is AND-composed with a predicate
// that matches 0 docs on a segment, doc_hit_ratio = 0 triggers offset_mode
+2
View File
@@ -81,6 +81,8 @@ const (
SearchIterBatchSizeKey = "search_iter_batch_size"
SearchIterLastBoundKey = "search_iter_last_bound"
SearchIterIdKey = "search_iter_id"
QueryIterLastPKKey = "query_iter_last_pk"
QueryIterLastOffsetKey = "query_iter_last_element_offset"
QueryGroupByFieldsKey = "group_by_fields"
OrderByFieldsKey = "order_by_fields"
PipelineTraceKey = "pipeline_trace"
+81 -20
View File
@@ -97,15 +97,16 @@ func (t *queryTask) getQueryLabel() string {
}
type queryParams struct {
limit int64
offset int64
reduceType reduce.IReduceType
isIterator bool
collectionID int64
groupByFields []string
orderByFields []string // NEW: ORDER BY field specifications (e.g., "price:desc")
timezone string
extractTimeFields []string
limit int64
offset int64
reduceType reduce.IReduceType
isIterator bool
collectionID int64
groupByFields []string
orderByFields []string // NEW: ORDER BY field specifications (e.g., "price:desc")
timezone string
extractTimeFields []string
queryIteratorCursor *planpb.QueryIteratorCursor
}
func isSupportedGroupByFieldType(dt schemapb.DataType) bool {
@@ -325,7 +326,7 @@ func filterSystemFields(outputFieldIDs []UniqueID) []UniqueID {
}
// parseQueryParams get limit and offset from queryParamsPair, both are optional.
func parseQueryParams(queryParamsPair []*commonpb.KeyValuePair, largeTopKEnabled bool) (*queryParams, error) {
func parseQueryParams(queryParamsPair []*commonpb.KeyValuePair, largeTopKEnabled bool, pkDataType schemapb.DataType) (*queryParams, error) {
var (
limit int64
offset int64
@@ -438,19 +439,76 @@ func parseQueryParams(queryParamsPair []*commonpb.KeyValuePair, largeTopKEnabled
}
}
queryIteratorCursor, err := parseQueryIteratorCursor(queryParamsPair, isIterator, pkDataType)
if err != nil {
return nil, err
}
return &queryParams{
limit: limit,
offset: offset,
reduceType: reduceType,
isIterator: isIterator,
collectionID: collectionID,
groupByFields: groupByFields,
orderByFields: orderByFields,
timezone: timezone,
extractTimeFields: extractTimeFields,
limit: limit,
offset: offset,
reduceType: reduceType,
isIterator: isIterator,
collectionID: collectionID,
groupByFields: groupByFields,
orderByFields: orderByFields,
queryIteratorCursor: queryIteratorCursor,
timezone: timezone,
extractTimeFields: extractTimeFields,
}, nil
}
func parseQueryIteratorCursor(queryParamsPair []*commonpb.KeyValuePair, isIterator bool, pkDataType schemapb.DataType) (*planpb.QueryIteratorCursor, error) {
lastPK, hasLastPK := funcutil.TryGetAttrByKeyFromRepeatedKV(QueryIterLastPKKey, queryParamsPair)
lastOffsetStr, hasLastOffset := funcutil.TryGetAttrByKeyFromRepeatedKV(QueryIterLastOffsetKey, queryParamsPair)
if !hasLastPK && !hasLastOffset {
return nil, nil
}
if !isIterator {
return nil, merr.WrapErrAsInputError(merr.WrapErrParameterInvalidMsg(
"invalid query iterator cursor params: %s and %s can only be used when iterator=true",
QueryIterLastPKKey, QueryIterLastOffsetKey))
}
if !hasLastPK || !hasLastOffset {
return nil, merr.WrapErrAsInputError(merr.WrapErrParameterInvalidMsg(
"incomplete query iterator cursor params: %s and %s must be provided together, has_last_pk=%t, has_last_element_offset=%t",
QueryIterLastPKKey, QueryIterLastOffsetKey, hasLastPK, hasLastOffset))
}
lastOffset, err := strconv.ParseInt(lastOffsetStr, 0, 64)
if err != nil || lastOffset < 0 {
return nil, merr.WrapErrParameterInvalid("non-negative int value", lastOffsetStr,
"value for query iterator last element offset is invalid")
}
cursor := &planpb.QueryIteratorCursor{
LastElementOffset: lastOffset,
}
switch pkDataType {
case schemapb.DataType_Int64:
lastIntPK, err := strconv.ParseInt(lastPK, 0, 64)
if err != nil {
return nil, merr.WrapErrParameterInvalid("int64 primary key", lastPK,
"value for query iterator last primary key is invalid")
}
cursor.LastIntPk = &lastIntPK
case schemapb.DataType_VarChar:
cursor.LastStrPk = &lastPK
default:
return nil, merr.WrapErrAsInputError(merr.WrapErrParameterInvalidMsg("unsupported primary key type %s for query iterator cursor", pkDataType.String()))
}
return cursor, nil
}
func getPrimaryKeyDataType(schema *schemapb.CollectionSchema) schemapb.DataType {
for _, field := range schema.GetFields() {
if field.GetIsPrimaryKey() {
return field.GetDataType()
}
}
return schemapb.DataType_None
}
func matchCountRule(outputs []string) bool {
return len(outputs) == 1 && strings.ToLower(strings.TrimSpace(outputs[0])) == "count(*)"
}
@@ -665,7 +723,7 @@ func (t *queryTask) PreExecute(ctx context.Context) error {
if t.IgnoreGrowing, err = isIgnoreGrowing(t.request.GetQueryParams()); err != nil {
return err
}
queryParams, err := parseQueryParams(t.request.GetQueryParams(), colInfo.queryMode == common.QueryModeLargeTopK)
queryParams, err := parseQueryParams(t.request.GetQueryParams(), colInfo.queryMode == common.QueryModeLargeTopK, getPrimaryKeyDataType(schema.CollectionSchema))
if err != nil {
return err
}
@@ -720,6 +778,9 @@ func (t *queryTask) PreExecute(ctx context.Context) error {
return err
}
t.plan.GetQuery().Limit = t.Limit
if t.queryParams.queryIteratorCursor != nil {
t.plan.GetQuery().QueryIteratorCursor = t.queryParams.queryIteratorCursor
}
// Aggregation queries have bounded result sizes:
// - global aggregation (no GROUP BY) returns exactly one row
+165 -8
View File
@@ -746,7 +746,7 @@ func TestTaskQuery_functions(t *testing.T) {
Value: test.inValue[i],
})
}
ret, err := parseQueryParams(inParams, false)
ret, err := parseQueryParams(inParams, false, schemapb.DataType_Int64)
if test.expectErr {
assert.Error(t, err)
assert.Empty(t, ret)
@@ -770,7 +770,7 @@ func TestTaskQuery_functions(t *testing.T) {
Key: IteratorField,
Value: "True",
})
ret, err := parseQueryParams(inParams, false)
ret, err := parseQueryParams(inParams, false, schemapb.DataType_Int64)
assert.NoError(t, err)
assert.Equal(t, reduce.IReduceInOrderForBest, ret.reduceType)
}
@@ -784,7 +784,7 @@ func TestTaskQuery_functions(t *testing.T) {
Key: IteratorField,
Value: "TrueXXXX",
})
ret, err := parseQueryParams(inParams, false)
ret, err := parseQueryParams(inParams, false, schemapb.DataType_Int64)
assert.Error(t, err)
assert.Nil(t, ret)
}
@@ -798,7 +798,7 @@ func TestTaskQuery_functions(t *testing.T) {
Key: IteratorField,
Value: "True",
})
ret, err := parseQueryParams(inParams, false)
ret, err := parseQueryParams(inParams, false, schemapb.DataType_Int64)
assert.Error(t, err)
assert.Nil(t, ret)
}
@@ -809,7 +809,7 @@ func TestTaskQuery_functions(t *testing.T) {
Value: "True",
})
// when not setting iterator tag, ignore reduce_stop_for_best
ret, err := parseQueryParams(inParams, false)
ret, err := parseQueryParams(inParams, false, schemapb.DataType_Int64)
assert.NoError(t, err)
assert.Equal(t, reduce.IReduceNoOrder, ret.reduceType)
}
@@ -820,7 +820,7 @@ func TestTaskQuery_functions(t *testing.T) {
Value: "True",
})
// when not setting reduce_stop_for_best tag, reduce by keep results in order
ret, err := parseQueryParams(inParams, false)
ret, err := parseQueryParams(inParams, false, schemapb.DataType_Int64)
assert.NoError(t, err)
assert.Equal(t, reduce.IReduceInOrder, ret.reduceType)
}
@@ -834,7 +834,7 @@ func TestTaskQuery_functions(t *testing.T) {
Key: IteratorField,
Value: "True",
})
ret, err := parseQueryParams(inParams, false)
ret, err := parseQueryParams(inParams, false, schemapb.DataType_Int64)
assert.NoError(t, err)
assert.Equal(t, reduce.IReduceInOrder, ret.reduceType)
}
@@ -848,12 +848,169 @@ func TestTaskQuery_functions(t *testing.T) {
Key: IteratorField,
Value: "False",
})
ret, err := parseQueryParams(inParams, false)
ret, err := parseQueryParams(inParams, false, schemapb.DataType_Int64)
assert.NoError(t, err)
assert.Equal(t, reduce.IReduceNoOrder, ret.reduceType)
}
})
t.Run("test parseQueryParams for query iterator cursor", func(t *testing.T) {
params := []*commonpb.KeyValuePair{
{Key: IteratorField, Value: "true"},
{Key: QueryIterLastPKKey, Value: "7"},
{Key: QueryIterLastOffsetKey, Value: "2"},
}
ret, err := parseQueryParams(params, false, schemapb.DataType_Int64)
require.NoError(t, err)
require.NotNil(t, ret.queryIteratorCursor)
require.NotNil(t, ret.queryIteratorCursor.LastIntPk)
assert.EqualValues(t, 7, ret.queryIteratorCursor.GetLastIntPk())
assert.EqualValues(t, 2, ret.queryIteratorCursor.GetLastElementOffset())
params = []*commonpb.KeyValuePair{
{Key: IteratorField, Value: "true"},
{Key: QueryIterLastPKKey, Value: "pk-7"},
{Key: QueryIterLastOffsetKey, Value: "2"},
}
ret, err = parseQueryParams(params, false, schemapb.DataType_VarChar)
require.NoError(t, err)
require.NotNil(t, ret.queryIteratorCursor)
assert.Equal(t, "pk-7", ret.queryIteratorCursor.GetLastStrPk())
params = []*commonpb.KeyValuePair{
{Key: QueryIterLastPKKey, Value: "7"},
{Key: QueryIterLastOffsetKey, Value: "2"},
}
ret, err = parseQueryParams(params, false, schemapb.DataType_Int64)
assert.Error(t, err)
assert.Nil(t, ret)
params = []*commonpb.KeyValuePair{
{Key: IteratorField, Value: "true"},
{Key: QueryIterLastPKKey, Value: "7"},
{Key: QueryIterLastOffsetKey, Value: "-1"},
}
ret, err = parseQueryParams(params, false, schemapb.DataType_Int64)
assert.Error(t, err)
assert.Nil(t, ret)
})
t.Run("test parseQueryIteratorCursor", func(t *testing.T) {
tests := []struct {
name string
params []*commonpb.KeyValuePair
isIterator bool
pkDataType schemapb.DataType
wantNil bool
wantIntPK int64
checkIntPK bool
wantStrPK string
wantOffset int64
wantErrSubstr string
}{
{
name: "no cursor params",
params: nil,
isIterator: true,
pkDataType: schemapb.DataType_Int64,
wantNil: true,
},
{
name: "int64 pk with zero offset",
params: []*commonpb.KeyValuePair{{Key: QueryIterLastPKKey, Value: "7"}, {Key: QueryIterLastOffsetKey, Value: "0"}},
isIterator: true,
pkDataType: schemapb.DataType_Int64,
wantIntPK: 7,
checkIntPK: true,
wantOffset: 0,
},
{
name: "varchar pk",
params: []*commonpb.KeyValuePair{{Key: QueryIterLastPKKey, Value: "pk-7"}, {Key: QueryIterLastOffsetKey, Value: "2"}},
isIterator: true,
pkDataType: schemapb.DataType_VarChar,
wantStrPK: "pk-7",
wantOffset: 2,
},
{
name: "cursor params require iterator",
params: []*commonpb.KeyValuePair{{Key: QueryIterLastPKKey, Value: "7"}, {Key: QueryIterLastOffsetKey, Value: "2"}},
isIterator: false,
pkDataType: schemapb.DataType_Int64,
wantErrSubstr: "invalid query iterator cursor params",
},
{
name: "missing offset",
params: []*commonpb.KeyValuePair{{Key: QueryIterLastPKKey, Value: "7"}},
isIterator: true,
pkDataType: schemapb.DataType_Int64,
wantErrSubstr: "incomplete query iterator cursor params",
},
{
name: "missing pk",
params: []*commonpb.KeyValuePair{{Key: QueryIterLastOffsetKey, Value: "2"}},
isIterator: true,
pkDataType: schemapb.DataType_Int64,
wantErrSubstr: "incomplete query iterator cursor params",
},
{
name: "invalid offset",
params: []*commonpb.KeyValuePair{{Key: QueryIterLastPKKey, Value: "7"}, {Key: QueryIterLastOffsetKey, Value: "abc"}},
isIterator: true,
pkDataType: schemapb.DataType_Int64,
wantErrSubstr: "value for query iterator last element offset is invalid",
},
{
name: "negative offset",
params: []*commonpb.KeyValuePair{{Key: QueryIterLastPKKey, Value: "7"}, {Key: QueryIterLastOffsetKey, Value: "-1"}},
isIterator: true,
pkDataType: schemapb.DataType_Int64,
wantErrSubstr: "value for query iterator last element offset is invalid",
},
{
name: "invalid int64 pk",
params: []*commonpb.KeyValuePair{{Key: QueryIterLastPKKey, Value: "abc"}, {Key: QueryIterLastOffsetKey, Value: "2"}},
isIterator: true,
pkDataType: schemapb.DataType_Int64,
wantErrSubstr: "value for query iterator last primary key is invalid",
},
{
name: "unsupported pk type",
params: []*commonpb.KeyValuePair{{Key: QueryIterLastPKKey, Value: "7"}, {Key: QueryIterLastOffsetKey, Value: "2"}},
isIterator: true,
pkDataType: schemapb.DataType_Int32,
wantErrSubstr: "unsupported primary key type",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cursor, err := parseQueryIteratorCursor(test.params, test.isIterator, test.pkDataType)
if test.wantErrSubstr != "" {
require.Error(t, err)
assert.Contains(t, err.Error(), test.wantErrSubstr)
assert.Nil(t, cursor)
return
}
require.NoError(t, err)
if test.wantNil {
assert.Nil(t, cursor)
return
}
require.NotNil(t, cursor)
assert.Equal(t, test.wantOffset, cursor.GetLastElementOffset())
if test.checkIntPK {
require.NotNil(t, cursor.LastIntPk)
assert.Equal(t, test.wantIntPK, cursor.GetLastIntPk())
}
if test.wantStrPK != "" {
require.NotNil(t, cursor.LastStrPk)
assert.Equal(t, test.wantStrPK, cursor.GetLastStrPk())
}
})
}
})
t.Run("test reduceRetrieveResults", func(t *testing.T) {
const (
Dim = 8
+7
View File
@@ -353,8 +353,15 @@ message QueryPlanNode {
repeated int64 group_by_field_ids = 4;
repeated Aggregate aggregates = 5;
repeated OrderByField order_by_fields = 6; // ORDER BY specifications
optional QueryIteratorCursor query_iterator_cursor = 7;
};
message QueryIteratorCursor {
optional int64 last_int_pk = 1;
optional string last_str_pk = 2;
int64 last_element_offset = 3;
}
enum FunctionType{
FunctionTypeWeight = 0;
FunctionTypeRandom = 1;
+277 -171
View File
@@ -3315,12 +3315,13 @@ type QueryPlanNode struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Predicates *Expr `protobuf:"bytes,1,opt,name=predicates,proto3" json:"predicates,omitempty"`
IsCount bool `protobuf:"varint,2,opt,name=is_count,json=isCount,proto3" json:"is_count,omitempty"`
Limit int64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
GroupByFieldIds []int64 `protobuf:"varint,4,rep,packed,name=group_by_field_ids,json=groupByFieldIds,proto3" json:"group_by_field_ids,omitempty"`
Aggregates []*Aggregate `protobuf:"bytes,5,rep,name=aggregates,proto3" json:"aggregates,omitempty"`
OrderByFields []*OrderByField `protobuf:"bytes,6,rep,name=order_by_fields,json=orderByFields,proto3" json:"order_by_fields,omitempty"` // ORDER BY specifications
Predicates *Expr `protobuf:"bytes,1,opt,name=predicates,proto3" json:"predicates,omitempty"`
IsCount bool `protobuf:"varint,2,opt,name=is_count,json=isCount,proto3" json:"is_count,omitempty"`
Limit int64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
GroupByFieldIds []int64 `protobuf:"varint,4,rep,packed,name=group_by_field_ids,json=groupByFieldIds,proto3" json:"group_by_field_ids,omitempty"`
Aggregates []*Aggregate `protobuf:"bytes,5,rep,name=aggregates,proto3" json:"aggregates,omitempty"`
OrderByFields []*OrderByField `protobuf:"bytes,6,rep,name=order_by_fields,json=orderByFields,proto3" json:"order_by_fields,omitempty"` // ORDER BY specifications
QueryIteratorCursor *QueryIteratorCursor `protobuf:"bytes,7,opt,name=query_iterator_cursor,json=queryIteratorCursor,proto3,oneof" json:"query_iterator_cursor,omitempty"`
}
func (x *QueryPlanNode) Reset() {
@@ -3397,6 +3398,76 @@ func (x *QueryPlanNode) GetOrderByFields() []*OrderByField {
return nil
}
func (x *QueryPlanNode) GetQueryIteratorCursor() *QueryIteratorCursor {
if x != nil {
return x.QueryIteratorCursor
}
return nil
}
type QueryIteratorCursor struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
LastIntPk *int64 `protobuf:"varint,1,opt,name=last_int_pk,json=lastIntPk,proto3,oneof" json:"last_int_pk,omitempty"`
LastStrPk *string `protobuf:"bytes,2,opt,name=last_str_pk,json=lastStrPk,proto3,oneof" json:"last_str_pk,omitempty"`
LastElementOffset int64 `protobuf:"varint,3,opt,name=last_element_offset,json=lastElementOffset,proto3" json:"last_element_offset,omitempty"`
}
func (x *QueryIteratorCursor) Reset() {
*x = QueryIteratorCursor{}
if protoimpl.UnsafeEnabled {
mi := &file_plan_proto_msgTypes[32]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *QueryIteratorCursor) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*QueryIteratorCursor) ProtoMessage() {}
func (x *QueryIteratorCursor) ProtoReflect() protoreflect.Message {
mi := &file_plan_proto_msgTypes[32]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use QueryIteratorCursor.ProtoReflect.Descriptor instead.
func (*QueryIteratorCursor) Descriptor() ([]byte, []int) {
return file_plan_proto_rawDescGZIP(), []int{32}
}
func (x *QueryIteratorCursor) GetLastIntPk() int64 {
if x != nil && x.LastIntPk != nil {
return *x.LastIntPk
}
return 0
}
func (x *QueryIteratorCursor) GetLastStrPk() string {
if x != nil && x.LastStrPk != nil {
return *x.LastStrPk
}
return ""
}
func (x *QueryIteratorCursor) GetLastElementOffset() int64 {
if x != nil {
return x.LastElementOffset
}
return 0
}
type ScoreFunction struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -3411,7 +3482,7 @@ type ScoreFunction struct {
func (x *ScoreFunction) Reset() {
*x = ScoreFunction{}
if protoimpl.UnsafeEnabled {
mi := &file_plan_proto_msgTypes[32]
mi := &file_plan_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3424,7 +3495,7 @@ func (x *ScoreFunction) String() string {
func (*ScoreFunction) ProtoMessage() {}
func (x *ScoreFunction) ProtoReflect() protoreflect.Message {
mi := &file_plan_proto_msgTypes[32]
mi := &file_plan_proto_msgTypes[33]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3437,7 +3508,7 @@ func (x *ScoreFunction) ProtoReflect() protoreflect.Message {
// Deprecated: Use ScoreFunction.ProtoReflect.Descriptor instead.
func (*ScoreFunction) Descriptor() ([]byte, []int) {
return file_plan_proto_rawDescGZIP(), []int{32}
return file_plan_proto_rawDescGZIP(), []int{33}
}
func (x *ScoreFunction) GetFilter() *Expr {
@@ -3480,7 +3551,7 @@ type ScoreOption struct {
func (x *ScoreOption) Reset() {
*x = ScoreOption{}
if protoimpl.UnsafeEnabled {
mi := &file_plan_proto_msgTypes[33]
mi := &file_plan_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3493,7 +3564,7 @@ func (x *ScoreOption) String() string {
func (*ScoreOption) ProtoMessage() {}
func (x *ScoreOption) ProtoReflect() protoreflect.Message {
mi := &file_plan_proto_msgTypes[33]
mi := &file_plan_proto_msgTypes[34]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3506,7 +3577,7 @@ func (x *ScoreOption) ProtoReflect() protoreflect.Message {
// Deprecated: Use ScoreOption.ProtoReflect.Descriptor instead.
func (*ScoreOption) Descriptor() ([]byte, []int) {
return file_plan_proto_rawDescGZIP(), []int{33}
return file_plan_proto_rawDescGZIP(), []int{34}
}
func (x *ScoreOption) GetBoostMode() BoostMode {
@@ -3534,7 +3605,7 @@ type PlanOption struct {
func (x *PlanOption) Reset() {
*x = PlanOption{}
if protoimpl.UnsafeEnabled {
mi := &file_plan_proto_msgTypes[34]
mi := &file_plan_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3547,7 +3618,7 @@ func (x *PlanOption) String() string {
func (*PlanOption) ProtoMessage() {}
func (x *PlanOption) ProtoReflect() protoreflect.Message {
mi := &file_plan_proto_msgTypes[34]
mi := &file_plan_proto_msgTypes[35]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3560,7 +3631,7 @@ func (x *PlanOption) ProtoReflect() protoreflect.Message {
// Deprecated: Use PlanOption.ProtoReflect.Descriptor instead.
func (*PlanOption) Descriptor() ([]byte, []int) {
return file_plan_proto_rawDescGZIP(), []int{34}
return file_plan_proto_rawDescGZIP(), []int{35}
}
func (x *PlanOption) GetExprUseJsonStats() bool {
@@ -3592,7 +3663,7 @@ type PlanNode struct {
func (x *PlanNode) Reset() {
*x = PlanNode{}
if protoimpl.UnsafeEnabled {
mi := &file_plan_proto_msgTypes[35]
mi := &file_plan_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3605,7 +3676,7 @@ func (x *PlanNode) String() string {
func (*PlanNode) ProtoMessage() {}
func (x *PlanNode) ProtoReflect() protoreflect.Message {
mi := &file_plan_proto_msgTypes[35]
mi := &file_plan_proto_msgTypes[36]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3618,7 +3689,7 @@ func (x *PlanNode) ProtoReflect() protoreflect.Message {
// Deprecated: Use PlanNode.ProtoReflect.Descriptor instead.
func (*PlanNode) Descriptor() ([]byte, []int) {
return file_plan_proto_rawDescGZIP(), []int{35}
return file_plan_proto_rawDescGZIP(), []int{36}
}
func (m *PlanNode) GetNode() isPlanNode_Node {
@@ -4245,7 +4316,7 @@ var file_plan_proto_rawDesc = []byte{
0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69,
0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x75, 0x6c, 0x6c, 0x73, 0x5f, 0x66, 0x69, 0x72, 0x73,
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x73, 0x46, 0x69,
0x72, 0x73, 0x74, 0x22, 0xad, 0x02, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x6c, 0x61,
0x72, 0x73, 0x74, 0x22, 0xa8, 0x03, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x6c, 0x61,
0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61,
0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x45, 0x78,
@@ -4264,126 +4335,145 @@ var file_plan_proto_rawDesc = []byte{
0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x46,
0x69, 0x65, 0x6c, 0x64, 0x52, 0x0d, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x46, 0x69, 0x65,
0x6c, 0x64, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x0d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x46, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x06,
0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74,
0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x33,
0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x6d,
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e,
0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74,
0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x90,
0x01, 0x0a, 0x0b, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b,
0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65,
0x52, 0x09, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d,
0x6f, 0x64, 0x65, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64,
0x65, 0x22, 0x3b, 0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x2d, 0x0a, 0x13, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x5f, 0x6a, 0x73, 0x6f, 0x6e,
0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78,
0x70, 0x72, 0x55, 0x73, 0x65, 0x4a, 0x73, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0x8c,
0x04, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x76,
0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x6e, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x1d, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x4e, 0x4e, 0x53, 0x48,
0x00, 0x52, 0x0a, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6e, 0x6e, 0x73, 0x12, 0x39, 0x0a,
0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x70, 0x72,
0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72,
0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x51, 0x75, 0x65, 0x72,
0x79, 0x50, 0x6c, 0x61, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x05, 0x71, 0x75, 0x65,
0x72, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x66, 0x69, 0x65,
0x6c, 0x64, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0e, 0x6f, 0x75,
0x74, 0x70, 0x75, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e,
0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05,
0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x46, 0x69, 0x65,
0x6c, 0x64, 0x73, 0x12, 0x3a, 0x0a, 0x07, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x72, 0x73, 0x18, 0x06,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x46, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x72, 0x73, 0x12,
0x40, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x4f, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x6c, 0x61, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x12, 0x41, 0x0a, 0x0c, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x53, 0x63, 0x6f, 0x72,
0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x4f, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x42,
0x0c, 0x0a, 0x0a, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2a, 0xea, 0x01,
0x0a, 0x06, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61,
0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72,
0x54, 0x68, 0x61, 0x6e, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65,
0x72, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x4c, 0x65, 0x73, 0x73,
0x54, 0x68, 0x61, 0x6e, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x65, 0x73, 0x73, 0x45, 0x71,
0x75, 0x61, 0x6c, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x10, 0x05,
0x12, 0x0c, 0x0a, 0x08, 0x4e, 0x6f, 0x74, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x10, 0x06, 0x12, 0x0f,
0x0a, 0x0b, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x07, 0x12,
0x10, 0x0a, 0x0c, 0x50, 0x6f, 0x73, 0x74, 0x66, 0x69, 0x78, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10,
0x08, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x09, 0x12, 0x09, 0x0a, 0x05,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x10, 0x0a, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x6e, 0x10, 0x0b, 0x12,
0x09, 0x0a, 0x05, 0x4e, 0x6f, 0x74, 0x49, 0x6e, 0x10, 0x0c, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x65,
0x78, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x0d, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x68, 0x72,
0x61, 0x73, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x0e, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x6e,
0x6e, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x0f, 0x2a, 0x58, 0x0a, 0x0b, 0x41, 0x72,
0x69, 0x74, 0x68, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b,
0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x10, 0x01, 0x12,
0x07, 0x0a, 0x03, 0x53, 0x75, 0x62, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x75, 0x6c, 0x10,
0x03, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x69, 0x76, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x6f,
0x64, 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x72, 0x72, 0x61, 0x79, 0x4c, 0x65, 0x6e, 0x67,
0x74, 0x68, 0x10, 0x06, 0x2a, 0xfa, 0x01, 0x0a, 0x0a, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54,
0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x63,
0x74, 0x6f, 0x72, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x65,
0x63, 0x74, 0x6f, 0x72, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x31,
0x36, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x42, 0x46, 0x6c,
0x6f, 0x61, 0x74, 0x31, 0x36, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x03, 0x12, 0x15, 0x0a,
0x11, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x65, 0x63, 0x74,
0x6f, 0x72, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x38, 0x56, 0x65, 0x63, 0x74,
0x6f, 0x72, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x6d, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x46,
0x6c, 0x6f, 0x61, 0x74, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14,
0x45, 0x6d, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x31, 0x36, 0x56, 0x65,
0x63, 0x74, 0x6f, 0x72, 0x10, 0x07, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x6d, 0x62, 0x4c, 0x69, 0x73,
0x74, 0x42, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x31, 0x36, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10,
0x08, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x6d, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x74, 0x38,
0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x09, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x6d, 0x62, 0x4c,
0x69, 0x73, 0x74, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10,
0x0a, 0x2a, 0x56, 0x0a, 0x09, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c,
0x0a, 0x08, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x41, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08,
0x4d, 0x61, 0x74, 0x63, 0x68, 0x41, 0x6e, 0x79, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x61,
0x74, 0x63, 0x68, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x4d, 0x61,
0x74, 0x63, 0x68, 0x4d, 0x6f, 0x73, 0x74, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x61, 0x74,
0x63, 0x68, 0x45, 0x78, 0x61, 0x63, 0x74, 0x10, 0x04, 0x2a, 0x3c, 0x0a, 0x0b, 0x41, 0x67, 0x67,
0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x12, 0x07, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x10,
0x00, 0x12, 0x09, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03,
0x61, 0x76, 0x67, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x10, 0x03, 0x12, 0x07,
0x0a, 0x03, 0x6d, 0x61, 0x78, 0x10, 0x04, 0x2a, 0x3e, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x46, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x10, 0x00, 0x12,
0x16, 0x0a, 0x12, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52,
0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x10, 0x01, 0x2a, 0x3d, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, 0x10,
0x00, 0x12, 0x13, 0x0a, 0x0f, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64,
0x65, 0x53, 0x75, 0x6d, 0x10, 0x01, 0x2a, 0x34, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x4d,
0x6f, 0x64, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65,
0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x42, 0x6f,
0x6f, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x53, 0x75, 0x6d, 0x10, 0x01, 0x42, 0x31, 0x5a, 0x2f,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75,
0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x70, 0x62, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6c, 0x64, 0x73, 0x12, 0x5f, 0x0a, 0x15, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x74, 0x65,
0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x74, 0x65, 0x72,
0x61, 0x74, 0x6f, 0x72, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x13, 0x71, 0x75,
0x65, 0x72, 0x79, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x75, 0x72, 0x73, 0x6f,
0x72, 0x88, 0x01, 0x01, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x69,
0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0xaf,
0x01, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72,
0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69,
0x6e, 0x74, 0x5f, 0x70, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x09, 0x6c,
0x61, 0x73, 0x74, 0x49, 0x6e, 0x74, 0x50, 0x6b, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x0b, 0x6c,
0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x5f, 0x70, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x48, 0x01, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x72, 0x50, 0x6b, 0x88, 0x01, 0x01,
0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x6c,
0x61, 0x73, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74,
0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x70, 0x6b,
0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x5f, 0x70, 0x6b,
0x22, 0xc8, 0x01, 0x0a, 0x0d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c,
0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20,
0x01, 0x28, 0x02, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x33, 0x0a, 0x04, 0x74,
0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x46, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
0x12, 0x39, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50,
0x61, 0x69, 0x72, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x0b,
0x53, 0x63, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x0a, 0x62,
0x6f, 0x6f, 0x73, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x1c, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70,
0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x09, 0x62,
0x6f, 0x6f, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70,
0x6c, 0x61, 0x6e, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65,
0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x3b,
0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x13,
0x65, 0x78, 0x70, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x73, 0x74,
0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x70, 0x72, 0x55,
0x73, 0x65, 0x4a, 0x73, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0x8c, 0x04, 0x0a, 0x08,
0x50, 0x6c, 0x61, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x76, 0x65, 0x63, 0x74,
0x6f, 0x72, 0x5f, 0x61, 0x6e, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e,
0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61,
0x6e, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x4e, 0x4e, 0x53, 0x48, 0x00, 0x52, 0x0a,
0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6e, 0x6e, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x70, 0x72,
0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c,
0x61, 0x6e, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69,
0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x6c,
0x61, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12,
0x28, 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f,
0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x70, 0x75,
0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x79, 0x6e,
0x61, 0x6d, 0x69, 0x63, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28,
0x09, 0x52, 0x0d, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73,
0x12, 0x3a, 0x0a, 0x07, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x72, 0x73, 0x12, 0x40, 0x0a, 0x0c,
0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x0b, 0x70, 0x6c, 0x61, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41,
0x0a, 0x0c, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x4f, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x21, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x09,
0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x42, 0x0c, 0x0a, 0x0a,
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2a, 0xea, 0x01, 0x0a, 0x06, 0x4f,
0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x54, 0x68, 0x61,
0x6e, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x45, 0x71,
0x75, 0x61, 0x6c, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x4c, 0x65, 0x73, 0x73, 0x54, 0x68, 0x61,
0x6e, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x65, 0x73, 0x73, 0x45, 0x71, 0x75, 0x61, 0x6c,
0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x10, 0x05, 0x12, 0x0c, 0x0a,
0x08, 0x4e, 0x6f, 0x74, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x50,
0x72, 0x65, 0x66, 0x69, 0x78, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x07, 0x12, 0x10, 0x0a, 0x0c,
0x50, 0x6f, 0x73, 0x74, 0x66, 0x69, 0x78, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x08, 0x12, 0x09,
0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x09, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x61, 0x6e,
0x67, 0x65, 0x10, 0x0a, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x6e, 0x10, 0x0b, 0x12, 0x09, 0x0a, 0x05,
0x4e, 0x6f, 0x74, 0x49, 0x6e, 0x10, 0x0c, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x65, 0x78, 0x74, 0x4d,
0x61, 0x74, 0x63, 0x68, 0x10, 0x0d, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x68, 0x72, 0x61, 0x73, 0x65,
0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x0e, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x6e, 0x6e, 0x65, 0x72,
0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x0f, 0x2a, 0x58, 0x0a, 0x0b, 0x41, 0x72, 0x69, 0x74, 0x68,
0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
0x6e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03,
0x53, 0x75, 0x62, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x75, 0x6c, 0x10, 0x03, 0x12, 0x07,
0x0a, 0x03, 0x44, 0x69, 0x76, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x6f, 0x64, 0x10, 0x05,
0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x72, 0x72, 0x61, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x10,
0x06, 0x2a, 0xfa, 0x01, 0x0a, 0x0a, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65,
0x12, 0x10, 0x0a, 0x0c, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72,
0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x65, 0x63, 0x74, 0x6f,
0x72, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x31, 0x36, 0x56, 0x65,
0x63, 0x74, 0x6f, 0x72, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x42, 0x46, 0x6c, 0x6f, 0x61, 0x74,
0x31, 0x36, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x70,
0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10,
0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x38, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10,
0x05, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x6d, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6c, 0x6f, 0x61,
0x74, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x6d, 0x62,
0x4c, 0x69, 0x73, 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x31, 0x36, 0x56, 0x65, 0x63, 0x74, 0x6f,
0x72, 0x10, 0x07, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x6d, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x46,
0x6c, 0x6f, 0x61, 0x74, 0x31, 0x36, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x08, 0x12, 0x15,
0x0a, 0x11, 0x45, 0x6d, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x74, 0x38, 0x56, 0x65, 0x63,
0x74, 0x6f, 0x72, 0x10, 0x09, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x6d, 0x62, 0x4c, 0x69, 0x73, 0x74,
0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x0a, 0x2a, 0x56,
0x0a, 0x09, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x4d,
0x61, 0x74, 0x63, 0x68, 0x41, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x61, 0x74,
0x63, 0x68, 0x41, 0x6e, 0x79, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x61, 0x74, 0x63, 0x68,
0x4c, 0x65, 0x61, 0x73, 0x74, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x4d, 0x61, 0x74, 0x63, 0x68,
0x4d, 0x6f, 0x73, 0x74, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x45,
0x78, 0x61, 0x63, 0x74, 0x10, 0x04, 0x2a, 0x3c, 0x0a, 0x0b, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
0x61, 0x74, 0x65, 0x4f, 0x70, 0x12, 0x07, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x10, 0x00, 0x12, 0x09,
0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x61, 0x76, 0x67,
0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x6d,
0x61, 0x78, 0x10, 0x04, 0x2a, 0x3e, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x54, 0x79, 0x70, 0x65, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12,
0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x61, 0x6e, 0x64,
0x6f, 0x6d, 0x10, 0x01, 0x2a, 0x3d, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x4d, 0x6f, 0x64, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, 0x10, 0x00, 0x12, 0x13,
0x0a, 0x0f, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x53, 0x75,
0x6d, 0x10, 0x01, 0x2a, 0x34, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65,
0x12, 0x15, 0x0a, 0x11, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x4d, 0x75, 0x6c,
0x74, 0x69, 0x70, 0x6c, 0x79, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x42, 0x6f, 0x6f, 0x73, 0x74,
0x4d, 0x6f, 0x64, 0x65, 0x53, 0x75, 0x6d, 0x10, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2d, 0x69,
0x6f, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x76, 0x32, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -4399,7 +4489,7 @@ func file_plan_proto_rawDescGZIP() []byte {
}
var file_plan_proto_enumTypes = make([]protoimpl.EnumInfo, 13)
var file_plan_proto_msgTypes = make([]protoimpl.MessageInfo, 36)
var file_plan_proto_msgTypes = make([]protoimpl.MessageInfo, 37)
var file_plan_proto_goTypes = []interface{}{
(OpType)(0), // 0: milvus.proto.plan.OpType
(ArithOpType)(0), // 1: milvus.proto.plan.ArithOpType
@@ -4446,21 +4536,22 @@ var file_plan_proto_goTypes = []interface{}{
(*Aggregate)(nil), // 42: milvus.proto.plan.Aggregate
(*OrderByField)(nil), // 43: milvus.proto.plan.OrderByField
(*QueryPlanNode)(nil), // 44: milvus.proto.plan.QueryPlanNode
(*ScoreFunction)(nil), // 45: milvus.proto.plan.ScoreFunction
(*ScoreOption)(nil), // 46: milvus.proto.plan.ScoreOption
(*PlanOption)(nil), // 47: milvus.proto.plan.PlanOption
(*PlanNode)(nil), // 48: milvus.proto.plan.PlanNode
(schemapb.DataType)(0), // 49: milvus.proto.schema.DataType
(*commonpb.KeyValuePair)(nil), // 50: milvus.proto.common.KeyValuePair
(*QueryIteratorCursor)(nil), // 45: milvus.proto.plan.QueryIteratorCursor
(*ScoreFunction)(nil), // 46: milvus.proto.plan.ScoreFunction
(*ScoreOption)(nil), // 47: milvus.proto.plan.ScoreOption
(*PlanOption)(nil), // 48: milvus.proto.plan.PlanOption
(*PlanNode)(nil), // 49: milvus.proto.plan.PlanNode
(schemapb.DataType)(0), // 50: milvus.proto.schema.DataType
(*commonpb.KeyValuePair)(nil), // 51: milvus.proto.common.KeyValuePair
}
var file_plan_proto_depIdxs = []int32{
14, // 0: milvus.proto.plan.GenericValue.array_val:type_name -> milvus.proto.plan.Array
13, // 1: milvus.proto.plan.Array.array:type_name -> milvus.proto.plan.GenericValue
49, // 2: milvus.proto.plan.Array.element_type:type_name -> milvus.proto.schema.DataType
50, // 2: milvus.proto.plan.Array.element_type:type_name -> milvus.proto.schema.DataType
15, // 3: milvus.proto.plan.QueryInfo.search_iterator_v2_info:type_name -> milvus.proto.plan.SearchIteratorV2Info
49, // 4: milvus.proto.plan.QueryInfo.json_type:type_name -> milvus.proto.schema.DataType
49, // 5: milvus.proto.plan.ColumnInfo.data_type:type_name -> milvus.proto.schema.DataType
49, // 6: milvus.proto.plan.ColumnInfo.element_type:type_name -> milvus.proto.schema.DataType
50, // 4: milvus.proto.plan.QueryInfo.json_type:type_name -> milvus.proto.schema.DataType
50, // 5: milvus.proto.plan.ColumnInfo.data_type:type_name -> milvus.proto.schema.DataType
50, // 6: milvus.proto.plan.ColumnInfo.element_type:type_name -> milvus.proto.schema.DataType
17, // 7: milvus.proto.plan.ColumnExpr.info:type_name -> milvus.proto.plan.ColumnInfo
17, // 8: milvus.proto.plan.ExistsExpr.info:type_name -> milvus.proto.plan.ColumnInfo
13, // 9: milvus.proto.plan.ValueExpr.value:type_name -> milvus.proto.plan.GenericValue
@@ -4537,22 +4628,23 @@ var file_plan_proto_depIdxs = []int32{
40, // 80: milvus.proto.plan.QueryPlanNode.predicates:type_name -> milvus.proto.plan.Expr
42, // 81: milvus.proto.plan.QueryPlanNode.aggregates:type_name -> milvus.proto.plan.Aggregate
43, // 82: milvus.proto.plan.QueryPlanNode.order_by_fields:type_name -> milvus.proto.plan.OrderByField
40, // 83: milvus.proto.plan.ScoreFunction.filter:type_name -> milvus.proto.plan.Expr
5, // 84: milvus.proto.plan.ScoreFunction.type:type_name -> milvus.proto.plan.FunctionType
50, // 85: milvus.proto.plan.ScoreFunction.params:type_name -> milvus.proto.common.KeyValuePair
7, // 86: milvus.proto.plan.ScoreOption.boost_mode:type_name -> milvus.proto.plan.BoostMode
6, // 87: milvus.proto.plan.ScoreOption.function_mode:type_name -> milvus.proto.plan.FunctionMode
41, // 88: milvus.proto.plan.PlanNode.vector_anns:type_name -> milvus.proto.plan.VectorANNS
40, // 89: milvus.proto.plan.PlanNode.predicates:type_name -> milvus.proto.plan.Expr
44, // 90: milvus.proto.plan.PlanNode.query:type_name -> milvus.proto.plan.QueryPlanNode
45, // 91: milvus.proto.plan.PlanNode.scorers:type_name -> milvus.proto.plan.ScoreFunction
47, // 92: milvus.proto.plan.PlanNode.plan_options:type_name -> milvus.proto.plan.PlanOption
46, // 93: milvus.proto.plan.PlanNode.score_option:type_name -> milvus.proto.plan.ScoreOption
94, // [94:94] is the sub-list for method output_type
94, // [94:94] is the sub-list for method input_type
94, // [94:94] is the sub-list for extension type_name
94, // [94:94] is the sub-list for extension extendee
0, // [0:94] is the sub-list for field type_name
45, // 83: milvus.proto.plan.QueryPlanNode.query_iterator_cursor:type_name -> milvus.proto.plan.QueryIteratorCursor
40, // 84: milvus.proto.plan.ScoreFunction.filter:type_name -> milvus.proto.plan.Expr
5, // 85: milvus.proto.plan.ScoreFunction.type:type_name -> milvus.proto.plan.FunctionType
51, // 86: milvus.proto.plan.ScoreFunction.params:type_name -> milvus.proto.common.KeyValuePair
7, // 87: milvus.proto.plan.ScoreOption.boost_mode:type_name -> milvus.proto.plan.BoostMode
6, // 88: milvus.proto.plan.ScoreOption.function_mode:type_name -> milvus.proto.plan.FunctionMode
41, // 89: milvus.proto.plan.PlanNode.vector_anns:type_name -> milvus.proto.plan.VectorANNS
40, // 90: milvus.proto.plan.PlanNode.predicates:type_name -> milvus.proto.plan.Expr
44, // 91: milvus.proto.plan.PlanNode.query:type_name -> milvus.proto.plan.QueryPlanNode
46, // 92: milvus.proto.plan.PlanNode.scorers:type_name -> milvus.proto.plan.ScoreFunction
48, // 93: milvus.proto.plan.PlanNode.plan_options:type_name -> milvus.proto.plan.PlanOption
47, // 94: milvus.proto.plan.PlanNode.score_option:type_name -> milvus.proto.plan.ScoreOption
95, // [95:95] is the sub-list for method output_type
95, // [95:95] is the sub-list for method input_type
95, // [95:95] is the sub-list for extension type_name
95, // [95:95] is the sub-list for extension extendee
0, // [0:95] is the sub-list for field type_name
}
func init() { file_plan_proto_init() }
@@ -4946,7 +5038,7 @@ func file_plan_proto_init() {
}
}
file_plan_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ScoreFunction); i {
switch v := v.(*QueryIteratorCursor); i {
case 0:
return &v.state
case 1:
@@ -4958,7 +5050,7 @@ func file_plan_proto_init() {
}
}
file_plan_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ScoreOption); i {
switch v := v.(*ScoreFunction); i {
case 0:
return &v.state
case 1:
@@ -4970,7 +5062,7 @@ func file_plan_proto_init() {
}
}
file_plan_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PlanOption); i {
switch v := v.(*ScoreOption); i {
case 0:
return &v.state
case 1:
@@ -4982,6 +5074,18 @@ func file_plan_proto_init() {
}
}
file_plan_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PlanOption); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_plan_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PlanNode); i {
case 0:
return &v.state
@@ -5025,7 +5129,9 @@ func file_plan_proto_init() {
(*Expr_ElementFilterExpr)(nil),
(*Expr_MatchExpr)(nil),
}
file_plan_proto_msgTypes[35].OneofWrappers = []interface{}{
file_plan_proto_msgTypes[31].OneofWrappers = []interface{}{}
file_plan_proto_msgTypes[32].OneofWrappers = []interface{}{}
file_plan_proto_msgTypes[36].OneofWrappers = []interface{}{
(*PlanNode_VectorAnns)(nil),
(*PlanNode_Predicates)(nil),
(*PlanNode_Query)(nil),
@@ -5036,7 +5142,7 @@ func file_plan_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_plan_proto_rawDesc,
NumEnums: 13,
NumMessages: 36,
NumMessages: 37,
NumExtensions: 0,
NumServices: 0,
},