From f6f716bcfdf5f26f5b98efad09d01a1de5cb2361 Mon Sep 17 00:00:00 2001 From: Spade A <71589810+SpadeA-Tang@users.noreply.github.com> Date: Mon, 15 Dec 2025 12:01:15 +0800 Subject: [PATCH] feat: impl StructArray -- support embedding searches embeddings in embedding list with element level filter expression (#45830) issue: https://github.com/milvus-io/milvus/issues/42148 For a vector field inside a STRUCT, since a STRUCT can only appear as the element type of an ARRAY field, the vector field in STRUCT is effectively an array of vectors, i.e. an embedding list. Milvus already supports searching embedding lists with metrics whose names start with the prefix MAX_SIM_. This PR allows Milvus to search embeddings inside an embedding list using the same metrics as normal embedding fields. Each embedding in the list is treated as an independent vector and participates in ANN search. Further, since STRUCT may contain scalar fields that are highly related to the embedding field, this PR introduces an element-level filter expression to refine search results. The grammar of the element-level filter is: element_filter(structFieldName, $[subFieldName] == 3) where $[subFieldName] refers to the value of subFieldName in each element of the STRUCT array structFieldName. It can be combined with existing filter expressions, for example: "varcharField == 'aaa' && element_filter(struct_field, $[struct_int] == 3)" A full example: ``` struct_schema = milvus_client.create_struct_field_schema() struct_schema.add_field("struct_str", DataType.VARCHAR, max_length=65535) struct_schema.add_field("struct_int", DataType.INT32) struct_schema.add_field("struct_float_vec", DataType.FLOAT_VECTOR, dim=EMBEDDING_DIM) schema.add_field( "struct_field", datatype=DataType.ARRAY, element_type=DataType.STRUCT, struct_schema=struct_schema, max_capacity=1000, ) ... filter = "varcharField == 'aaa' && element_filter(struct_field, $[struct_int] == 3 && $[struct_str] == 'abc')" res = milvus_client.search( COLLECTION_NAME, data=query_embeddings, limit=10, anns_field="struct_field[struct_float_vec]", filter=filter, output_fields=["struct_field[struct_int]", "varcharField"], ) ``` TODO: 1. When an `element_filter` expression is used, a regular filter expression must also be present. Remove this restriction. 2. Implement `element_filter` expressions in the `query`. --------- Signed-off-by: SpadeA --- internal/core/src/common/ArrayOffsets.cpp | 292 ++ internal/core/src/common/ArrayOffsets.h | 164 + internal/core/src/common/ArrayOffsetsTest.cpp | 427 ++ .../core/src/common/ElementFilterIterator.cpp | 115 + .../core/src/common/ElementFilterIterator.h | 74 + internal/core/src/common/QueryInfo.h | 8 + internal/core/src/common/QueryResult.h | 74 +- internal/core/src/common/Schema.cpp | 11 + internal/core/src/common/Schema.h | 26 +- internal/core/src/common/Utils.h | 1 + internal/core/src/common/VectorArray.h | 5 + internal/core/src/exec/Driver.cpp | 15 + internal/core/src/exec/QueryContext.h | 65 + .../expression/BinaryArithOpEvalRangeExpr.cpp | 33 +- .../src/exec/expression/BinaryRangeExpr.cpp | 35 +- .../core/src/exec/expression/ColumnExpr.cpp | 3 + internal/core/src/exec/expression/Expr.h | 169 + .../core/src/exec/expression/TermExpr.cpp | 30 +- .../core/src/exec/expression/UnaryExpr.cpp | 18 +- .../exec/operator/ElementFilterBitsNode.cpp | 215 + .../src/exec/operator/ElementFilterBitsNode.h | 93 + .../src/exec/operator/ElementFilterNode.cpp | 129 + .../src/exec/operator/ElementFilterNode.h | 87 + .../src/exec/operator/IterativeFilterNode.cpp | 131 +- .../src/exec/operator/VectorSearchNode.cpp | 37 + internal/core/src/expr/ITypeExpr.h | 32 +- internal/core/src/plan/PlanNode.h | 120 + .../core/src/query/ExecPlanNodeVisitor.cpp | 7 +- internal/core/src/query/Plan.cpp | 57 +- internal/core/src/query/PlanImpl.h | 1 + internal/core/src/query/PlanProto.cpp | 472 +- internal/core/src/query/PlanProto.h | 6 + internal/core/src/query/SearchBruteForce.cpp | 17 +- .../src/query/SearchBruteForceSparseTest.cpp | 4 +- .../core/src/query/SearchBruteForceTest.cpp | 2 +- internal/core/src/query/SearchOnGrowing.cpp | 94 +- internal/core/src/query/SearchOnSealed.cpp | 52 +- internal/core/src/query/SubSearchResult.cpp | 2 +- internal/core/src/query/SubSearchResult.h | 38 +- .../core/src/query/SubSearchResultTest.cpp | 4 +- .../src/segcore/ChunkedSegmentSealedImpl.cpp | 68 +- .../src/segcore/ChunkedSegmentSealedImpl.h | 17 + .../core/src/segcore/SegmentGrowingImpl.cpp | 194 + .../core/src/segcore/SegmentGrowingImpl.h | 23 + internal/core/src/segcore/SegmentInterface.h | 6 + .../core/src/segcore/reduce/GroupReduce.cpp | 11 + internal/core/src/segcore/reduce/Reduce.cpp | 40 + internal/core/unittest/CMakeLists.txt | 1 + .../core/unittest/test_element_filter.cpp | 977 ++++ internal/core/unittest/test_indexing.cpp | 2 +- internal/core/unittest/test_string_expr.cpp | 2 +- internal/core/unittest/test_utils/DataGen.h | 6 +- internal/parser/planparserv2/Plan.g4 | 98 +- .../planparserv2/fill_expression_value.go | 8 + .../parser/planparserv2/generated/Plan.interp | 6 +- .../parser/planparserv2/generated/Plan.tokens | 40 +- .../planparserv2/generated/PlanLexer.interp | 8 +- .../planparserv2/generated/PlanLexer.tokens | 40 +- .../generated/plan_base_visitor.go | 172 +- .../planparserv2/generated/plan_lexer.go | 1176 ++--- .../planparserv2/generated/plan_parser.go | 3973 +++++++++-------- .../planparserv2/generated/plan_visitor.go | 132 +- .../parser/planparserv2/parser_visitor.go | 166 +- .../planparserv2/plan_parser_v2_test.go | 70 + internal/proxy/search_reduce_util.go | 36 + internal/proxy/task_index.go | 18 +- internal/proxy/task_index_test.go | 31 - .../querynodev2/segments/search_reduce.go | 34 + .../querynodev2/segments/segment_loader.go | 12 +- .../indexparamcheck/vector_index_checker.go | 16 +- pkg/proto/plan.proto | 8 + pkg/proto/planpb/plan.pb.go | 1304 +++--- 72 files changed, 8180 insertions(+), 3680 deletions(-) create mode 100644 internal/core/src/common/ArrayOffsets.cpp create mode 100644 internal/core/src/common/ArrayOffsets.h create mode 100644 internal/core/src/common/ArrayOffsetsTest.cpp create mode 100644 internal/core/src/common/ElementFilterIterator.cpp create mode 100644 internal/core/src/common/ElementFilterIterator.h create mode 100644 internal/core/src/exec/operator/ElementFilterBitsNode.cpp create mode 100644 internal/core/src/exec/operator/ElementFilterBitsNode.h create mode 100644 internal/core/src/exec/operator/ElementFilterNode.cpp create mode 100644 internal/core/src/exec/operator/ElementFilterNode.h create mode 100644 internal/core/unittest/test_element_filter.cpp diff --git a/internal/core/src/common/ArrayOffsets.cpp b/internal/core/src/common/ArrayOffsets.cpp new file mode 100644 index 0000000000..8e9bdf1460 --- /dev/null +++ b/internal/core/src/common/ArrayOffsets.cpp @@ -0,0 +1,292 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ArrayOffsets.h" +#include "segcore/SegmentInterface.h" +#include "log/Log.h" +#include "common/EasyAssert.h" + +namespace milvus { + +std::pair +ArrayOffsetsSealed::ElementIDToRowID(int32_t elem_id) const { + assert(elem_id >= 0 && elem_id < GetTotalElementCount()); + + int32_t row_id = element_row_ids_[elem_id]; + // Compute elem_idx: elem_idx = elem_id - start_of_this_row + int32_t elem_idx = elem_id - row_to_element_start_[row_id]; + return {row_id, elem_idx}; +} + +std::pair +ArrayOffsetsSealed::ElementIDRangeOfRow(int32_t row_id) const { + int32_t row_count = GetRowCount(); + assert(row_id >= 0 && row_id <= row_count); + + if (row_id == row_count) { + auto total = row_to_element_start_[row_count]; + return {total, total}; + } + return {row_to_element_start_[row_id], row_to_element_start_[row_id + 1]}; +} + +std::pair +ArrayOffsetsSealed::RowBitsetToElementBitset( + const TargetBitmapView& row_bitset, + const TargetBitmapView& valid_row_bitset) const { + int64_t row_count = GetRowCount(); + int64_t element_count = GetTotalElementCount(); + TargetBitmap element_bitset(element_count); + TargetBitmap valid_element_bitset(element_count); + + for (int64_t row_id = 0; row_id < row_count; ++row_id) { + int64_t start = row_to_element_start_[row_id]; + int64_t end = row_to_element_start_[row_id + 1]; + if (start < end) { + element_bitset.set(start, end - start, row_bitset[row_id]); + valid_element_bitset.set( + start, end - start, valid_row_bitset[row_id]); + } + } + + return {std::move(element_bitset), std::move(valid_element_bitset)}; +} + +std::shared_ptr +ArrayOffsetsSealed::BuildFromSegment(const void* segment, + const FieldMeta& field_meta) { + auto seg = static_cast(segment); + + int64_t row_count = seg->get_row_count(); + if (row_count == 0) { + LOG_INFO( + "ArrayOffsetsSealed::BuildFromSegment: empty segment for struct " + "'{}'", + field_meta.get_name().get()); + return std::make_shared(std::vector{}, + std::vector{0}); + } + + FieldId field_id = field_meta.get_id(); + auto data_type = field_meta.get_data_type(); + + std::vector element_row_ids; + // Size is row_count + 1, last element stores total_element_count + std::vector row_to_element_start(row_count + 1); + + auto temp_op_ctx = std::make_unique(); + auto op_ctx_ptr = temp_op_ctx.get(); + + int64_t num_chunks = seg->num_chunk(field_id); + int32_t current_row_id = 0; + + if (data_type == DataType::VECTOR_ARRAY) { + for (int64_t chunk_id = 0; chunk_id < num_chunks; ++chunk_id) { + auto pin_wrapper = seg->chunk_view( + op_ctx_ptr, field_id, chunk_id); + const auto& [vector_array_views, valid_flags] = pin_wrapper.get(); + + for (size_t i = 0; i < vector_array_views.size(); ++i) { + int32_t array_len = 0; + if (valid_flags.empty() || valid_flags[i]) { + array_len = vector_array_views[i].length(); + } + + // Record the start position for this row + row_to_element_start[current_row_id] = element_row_ids.size(); + + // Add row_id for each element (elem_idx computed on access) + for (int32_t j = 0; j < array_len; ++j) { + element_row_ids.emplace_back(current_row_id); + } + + current_row_id++; + } + } + } else { + for (int64_t chunk_id = 0; chunk_id < num_chunks; ++chunk_id) { + auto pin_wrapper = + seg->chunk_view(op_ctx_ptr, field_id, chunk_id); + const auto& [array_views, valid_flags] = pin_wrapper.get(); + + for (size_t i = 0; i < array_views.size(); ++i) { + int32_t array_len = 0; + if (valid_flags.empty() || valid_flags[i]) { + array_len = array_views[i].length(); + } + + // Record the start position for this row + row_to_element_start[current_row_id] = element_row_ids.size(); + + // Add row_id for each element (elem_idx computed on access) + for (int32_t j = 0; j < array_len; ++j) { + element_row_ids.emplace_back(current_row_id); + } + + current_row_id++; + } + } + } + + // Store total element count as the last entry + row_to_element_start[row_count] = element_row_ids.size(); + + AssertInfo(current_row_id == row_count, + "Row count mismatch: expected {}, got {}", + row_count, + current_row_id); + + int64_t total_elements = element_row_ids.size(); + + LOG_INFO( + "ArrayOffsetsSealed::BuildFromSegment: struct_name='{}', " + "field_id={}, row_count={}, total_elements={}", + field_meta.get_name().get(), + field_meta.get_id().get(), + row_count, + total_elements); + + auto result = std::make_shared( + std::move(element_row_ids), std::move(row_to_element_start)); + result->resource_size_ = 4 * (row_count + 1) + 4 * total_elements; + cachinglayer::Manager::GetInstance().ChargeLoadedResource( + cachinglayer::ResourceUsage{result->resource_size_, 0}); + return result; +} + +std::pair +ArrayOffsetsGrowing::ElementIDToRowID(int32_t elem_id) const { + std::shared_lock lock(mutex_); + assert(elem_id >= 0 && + elem_id < static_cast(element_row_ids_.size())); + int32_t row_id = element_row_ids_[elem_id]; + // Compute elem_idx: elem_idx = elem_id - start_of_this_row + int32_t elem_idx = elem_id - row_to_element_start_[row_id]; + return {row_id, elem_idx}; +} + +std::pair +ArrayOffsetsGrowing::ElementIDRangeOfRow(int32_t row_id) const { + std::shared_lock lock(mutex_); + assert(row_id >= 0 && row_id <= committed_row_count_); + + if (row_id == committed_row_count_) { + auto total = row_to_element_start_[committed_row_count_]; + return {total, total}; + } + return {row_to_element_start_[row_id], row_to_element_start_[row_id + 1]}; +} + +std::pair +ArrayOffsetsGrowing::RowBitsetToElementBitset( + const TargetBitmapView& row_bitset, + const TargetBitmapView& valid_row_bitset) const { + std::shared_lock lock(mutex_); + + int64_t element_count = element_row_ids_.size(); + TargetBitmap element_bitset(element_count); + TargetBitmap valid_element_bitset(element_count); + + // Direct access to element_row_ids_, no virtual function calls + for (size_t elem_id = 0; elem_id < element_row_ids_.size(); ++elem_id) { + auto row_id = element_row_ids_[elem_id]; + element_bitset[elem_id] = row_bitset[row_id]; + valid_element_bitset[elem_id] = valid_row_bitset[row_id]; + } + + return {std::move(element_bitset), std::move(valid_element_bitset)}; +} + +void +ArrayOffsetsGrowing::Insert(int64_t row_id_start, + const int32_t* array_lengths, + int64_t count) { + std::unique_lock lock(mutex_); + + row_to_element_start_.reserve(row_id_start + count + 1); + + int32_t original_committed_count = committed_row_count_; + + for (int64_t i = 0; i < count; ++i) { + int32_t row_id = row_id_start + i; + int32_t array_len = array_lengths[i]; + + if (row_id == committed_row_count_) { + // Record the start position for this row + // If sentinel exists at current position, overwrite it; otherwise push_back + if (row_to_element_start_.size() > + static_cast(committed_row_count_)) { + row_to_element_start_[committed_row_count_] = + element_row_ids_.size(); + } else { + row_to_element_start_.push_back(element_row_ids_.size()); + } + + // Add row_id for each element (elem_idx computed on access) + for (int32_t j = 0; j < array_len; ++j) { + element_row_ids_.emplace_back(row_id); + } + + committed_row_count_++; + } else { + pending_rows_[row_id] = {row_id, array_len}; + } + } + + DrainPendingRows(); + + // Update the sentinel (total element count) only if we committed new rows + if (committed_row_count_ > original_committed_count) { + if (row_to_element_start_.size() == + static_cast(committed_row_count_)) { + row_to_element_start_.push_back(element_row_ids_.size()); + } else { + row_to_element_start_[committed_row_count_] = + element_row_ids_.size(); + } + } +} + +void +ArrayOffsetsGrowing::DrainPendingRows() { + while (true) { + auto it = pending_rows_.find(committed_row_count_); + if (it == pending_rows_.end()) { + break; + } + + const auto& pending = it->second; + + // If sentinel exists at current position, overwrite it; otherwise push_back + if (row_to_element_start_.size() > + static_cast(committed_row_count_)) { + row_to_element_start_[committed_row_count_] = + element_row_ids_.size(); + } else { + row_to_element_start_.push_back(element_row_ids_.size()); + } + + for (int32_t j = 0; j < pending.array_len; ++j) { + element_row_ids_.emplace_back(static_cast(pending.row_id)); + } + + committed_row_count_++; + + pending_rows_.erase(it); + } +} + +} // namespace milvus diff --git a/internal/core/src/common/ArrayOffsets.h b/internal/core/src/common/ArrayOffsets.h new file mode 100644 index 0000000000..77ac98c53f --- /dev/null +++ b/internal/core/src/common/ArrayOffsets.h @@ -0,0 +1,164 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include +#include +#include +#include "cachinglayer/Manager.h" +#include "common/Types.h" +#include "common/EasyAssert.h" +#include "common/FieldMeta.h" + +namespace milvus { + +class IArrayOffsets { + public: + virtual ~IArrayOffsets() = default; + + virtual int64_t + GetRowCount() const = 0; + + virtual int64_t + GetTotalElementCount() const = 0; + + // Convert element ID to row ID + // returns pair of + // element id is contiguous between rows + virtual std::pair + ElementIDToRowID(int32_t elem_id) const = 0; + + // Convert row ID to element ID range + // elements with id in [ret.first, ret.last) belong to row_id + virtual std::pair + ElementIDRangeOfRow(int32_t row_id) const = 0; + + // Convert row-level bitsets to element-level bitsets + virtual std::pair + RowBitsetToElementBitset( + const TargetBitmapView& row_bitset, + const TargetBitmapView& valid_row_bitset) const = 0; +}; + +class ArrayOffsetsSealed : public IArrayOffsets { + friend class ArrayOffsetsTest; + + public: + ArrayOffsetsSealed() : element_row_ids_(), row_to_element_start_({0}) { + } + + ArrayOffsetsSealed(std::vector element_row_ids, + std::vector row_to_element_start) + : element_row_ids_(std::move(element_row_ids)), + row_to_element_start_(std::move(row_to_element_start)) { + AssertInfo(!row_to_element_start_.empty(), + "row_to_element_start must have at least one element"); + } + + ~ArrayOffsetsSealed() { + cachinglayer::Manager::GetInstance().RefundLoadedResource( + {resource_size_, 0}); + } + + int64_t + GetRowCount() const override { + return static_cast(row_to_element_start_.size()) - 1; + } + + int64_t + GetTotalElementCount() const override { + return element_row_ids_.size(); + } + + std::pair + ElementIDToRowID(int32_t elem_id) const override; + + std::pair + ElementIDRangeOfRow(int32_t row_id) const override; + + std::pair + RowBitsetToElementBitset( + const TargetBitmapView& row_bitset, + const TargetBitmapView& valid_row_bitset) const override; + + static std::shared_ptr + BuildFromSegment(const void* segment, const FieldMeta& field_meta); + + private: + const std::vector element_row_ids_; + const std::vector row_to_element_start_; + int64_t resource_size_{0}; +}; + +class ArrayOffsetsGrowing : public IArrayOffsets { + public: + ArrayOffsetsGrowing() = default; + + void + Insert(int64_t row_id_start, const int32_t* array_lengths, int64_t count); + + int64_t + GetRowCount() const override { + std::shared_lock lock(mutex_); + return committed_row_count_; + } + + int64_t + GetTotalElementCount() const override { + std::shared_lock lock(mutex_); + return element_row_ids_.size(); + } + + std::pair + ElementIDToRowID(int32_t elem_id) const override; + + std::pair + ElementIDRangeOfRow(int32_t row_id) const override; + + std::pair + RowBitsetToElementBitset( + const TargetBitmapView& row_bitset, + const TargetBitmapView& valid_row_bitset) const override; + + private: + struct PendingRow { + int64_t row_id; + int32_t array_len; + }; + + void + DrainPendingRows(); + + private: + std::vector element_row_ids_; + + std::vector row_to_element_start_; + + // Number of rows committed (contiguous from 0) + int32_t committed_row_count_ = 0; + + // Pending rows waiting for earlier rows to complete + // Key: row_id, automatically sorted + std::map pending_rows_; + + // Protects all member variables + mutable std::shared_mutex mutex_; +}; + +} // namespace milvus diff --git a/internal/core/src/common/ArrayOffsetsTest.cpp b/internal/core/src/common/ArrayOffsetsTest.cpp new file mode 100644 index 0000000000..85792d8474 --- /dev/null +++ b/internal/core/src/common/ArrayOffsetsTest.cpp @@ -0,0 +1,427 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +#include "common/ArrayOffsets.h" + +using namespace milvus; + +class ArrayOffsetsTest : public ::testing::Test { + protected: + void + SetUp() override { + } +}; + +TEST_F(ArrayOffsetsTest, SealedBasic) { + // Create a simple ArrayOffsetsSealed manually + // row 0: 2 elements (elem 0, 1) + // row 1: 3 elements (elem 2, 3, 4) + // row 2: 1 element (elem 5) + ArrayOffsetsSealed offsets( + {0, 0, 1, 1, 1, 2}, // element_row_ids + {0, 2, 5, 6} // row_to_element_start (size = row_count + 1) + ); + + // Test GetRowCount + EXPECT_EQ(offsets.GetRowCount(), 3); + + // Test GetTotalElementCount + EXPECT_EQ(offsets.GetTotalElementCount(), 6); + + // Test ElementIDToRowID + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(0); + EXPECT_EQ(row_id, 0); + EXPECT_EQ(elem_idx, 0); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(1); + EXPECT_EQ(row_id, 0); + EXPECT_EQ(elem_idx, 1); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(2); + EXPECT_EQ(row_id, 1); + EXPECT_EQ(elem_idx, 0); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(4); + EXPECT_EQ(row_id, 1); + EXPECT_EQ(elem_idx, 2); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(5); + EXPECT_EQ(row_id, 2); + EXPECT_EQ(elem_idx, 0); + } + + // Test ElementIDRangeOfRow + { + auto [start, end] = offsets.ElementIDRangeOfRow(0); + EXPECT_EQ(start, 0); + EXPECT_EQ(end, 2); + } + { + auto [start, end] = offsets.ElementIDRangeOfRow(1); + EXPECT_EQ(start, 2); + EXPECT_EQ(end, 5); + } + { + auto [start, end] = offsets.ElementIDRangeOfRow(2); + EXPECT_EQ(start, 5); + EXPECT_EQ(end, 6); + } + // When row_id == row_count, return (total_elements, total_elements) + { + auto [start, end] = offsets.ElementIDRangeOfRow(3); + EXPECT_EQ(start, 6); + EXPECT_EQ(end, 6); + } +} + +TEST_F(ArrayOffsetsTest, SealedRowBitsetToElementBitset) { + ArrayOffsetsSealed offsets({0, 0, 1, 1, 1, 2}, // element_row_ids + {0, 2, 5, 6} // row_to_element_start + ); + + // row_bitset: row 0 = true, row 1 = false, row 2 = true + TargetBitmap row_bitset(3); + row_bitset[0] = true; + row_bitset[1] = false; + row_bitset[2] = true; + + TargetBitmap valid_row_bitset(3, true); + + TargetBitmapView row_view(row_bitset.data(), row_bitset.size()); + TargetBitmapView valid_view(valid_row_bitset.data(), + valid_row_bitset.size()); + + auto [elem_bitset, valid_elem_bitset] = + offsets.RowBitsetToElementBitset(row_view, valid_view); + + EXPECT_EQ(elem_bitset.size(), 6); + // Elements of row 0 (elem 0, 1) should be true + EXPECT_TRUE(elem_bitset[0]); + EXPECT_TRUE(elem_bitset[1]); + // Elements of row 1 (elem 2, 3, 4) should be false + EXPECT_FALSE(elem_bitset[2]); + EXPECT_FALSE(elem_bitset[3]); + EXPECT_FALSE(elem_bitset[4]); + // Elements of row 2 (elem 5) should be true + EXPECT_TRUE(elem_bitset[5]); +} + +TEST_F(ArrayOffsetsTest, SealedEmptyArrays) { + // Test with some rows having empty arrays + // row 1 and row 3 are empty + ArrayOffsetsSealed offsets({0, 0, 2, 2, 2}, // element_row_ids + {0, 2, 2, 5, 5} // row_to_element_start + ); + + EXPECT_EQ(offsets.GetRowCount(), 4); + EXPECT_EQ(offsets.GetTotalElementCount(), 5); + + // Row 1 has no elements + { + auto [start, end] = offsets.ElementIDRangeOfRow(1); + EXPECT_EQ(start, 2); + EXPECT_EQ(end, 2); // empty range + } + // Row 3 has no elements + { + auto [start, end] = offsets.ElementIDRangeOfRow(3); + EXPECT_EQ(start, 5); + EXPECT_EQ(end, 5); // empty range + } +} + +TEST_F(ArrayOffsetsTest, GrowingBasicInsert) { + ArrayOffsetsGrowing offsets; + + // Insert rows in order + std::vector lens1 = {2}; // row 0: 2 elements + offsets.Insert(0, lens1.data(), 1); + + std::vector lens2 = {3}; // row 1: 3 elements + offsets.Insert(1, lens2.data(), 1); + + std::vector lens3 = {1}; // row 2: 1 element + offsets.Insert(2, lens3.data(), 1); + + EXPECT_EQ(offsets.GetRowCount(), 3); + EXPECT_EQ(offsets.GetTotalElementCount(), 6); + + // Test ElementIDToRowID + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(0); + EXPECT_EQ(row_id, 0); + EXPECT_EQ(elem_idx, 0); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(2); + EXPECT_EQ(row_id, 1); + EXPECT_EQ(elem_idx, 0); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(5); + EXPECT_EQ(row_id, 2); + EXPECT_EQ(elem_idx, 0); + } + + // Test ElementIDRangeOfRow + { + auto [start, end] = offsets.ElementIDRangeOfRow(0); + EXPECT_EQ(start, 0); + EXPECT_EQ(end, 2); + } + { + auto [start, end] = offsets.ElementIDRangeOfRow(1); + EXPECT_EQ(start, 2); + EXPECT_EQ(end, 5); + } + // When row_id == row_count, return (total_elements, total_elements) + { + auto [start, end] = offsets.ElementIDRangeOfRow(3); + EXPECT_EQ(start, 6); + EXPECT_EQ(end, 6); + } +} + +TEST_F(ArrayOffsetsTest, GrowingBatchInsert) { + ArrayOffsetsGrowing offsets; + + // Insert multiple rows at once + std::vector lens = {2, 3, 1}; // row 0, 1, 2 + offsets.Insert(0, lens.data(), 3); + + EXPECT_EQ(offsets.GetRowCount(), 3); + EXPECT_EQ(offsets.GetTotalElementCount(), 6); + + { + auto [start, end] = offsets.ElementIDRangeOfRow(0); + EXPECT_EQ(start, 0); + EXPECT_EQ(end, 2); + } + { + auto [start, end] = offsets.ElementIDRangeOfRow(1); + EXPECT_EQ(start, 2); + EXPECT_EQ(end, 5); + } + { + auto [start, end] = offsets.ElementIDRangeOfRow(2); + EXPECT_EQ(start, 5); + EXPECT_EQ(end, 6); + } +} + +TEST_F(ArrayOffsetsTest, GrowingOutOfOrderInsert) { + ArrayOffsetsGrowing offsets; + + // Insert out of order - row 2 arrives before row 1 + std::vector lens0 = {2}; + offsets.Insert(0, lens0.data(), 1); // row 0 + + std::vector lens2 = {1}; + offsets.Insert(2, lens2.data(), 1); // row 2 (pending) + + // row 1 not inserted yet, so only row 0 should be committed + EXPECT_EQ(offsets.GetRowCount(), 1); + EXPECT_EQ(offsets.GetTotalElementCount(), 2); + + // Now insert row 1, which should drain pending row 2 + std::vector lens1 = {3}; + offsets.Insert(1, lens1.data(), 1); // row 1 + + // Now all 3 rows should be committed + EXPECT_EQ(offsets.GetRowCount(), 3); + EXPECT_EQ(offsets.GetTotalElementCount(), 6); + + // Verify order is correct + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(0); + EXPECT_EQ(row_id, 0); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(2); + EXPECT_EQ(row_id, 1); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(5); + EXPECT_EQ(row_id, 2); + } +} + +TEST_F(ArrayOffsetsTest, GrowingEmptyArrays) { + ArrayOffsetsGrowing offsets; + + // Insert rows with some empty arrays + std::vector lens = {2, 0, 3, 0}; // row 1 and row 3 are empty + offsets.Insert(0, lens.data(), 4); + + EXPECT_EQ(offsets.GetRowCount(), 4); + EXPECT_EQ(offsets.GetTotalElementCount(), 5); + + // Row 1 has no elements + { + auto [start, end] = offsets.ElementIDRangeOfRow(1); + EXPECT_EQ(start, 2); + EXPECT_EQ(end, 2); + } + // Row 3 has no elements + { + auto [start, end] = offsets.ElementIDRangeOfRow(3); + EXPECT_EQ(start, 5); + EXPECT_EQ(end, 5); + } +} + +TEST_F(ArrayOffsetsTest, GrowingRowBitsetToElementBitset) { + ArrayOffsetsGrowing offsets; + + std::vector lens = {2, 3, 1}; + offsets.Insert(0, lens.data(), 3); + + TargetBitmap row_bitset(3); + row_bitset[0] = true; + row_bitset[1] = false; + row_bitset[2] = true; + + TargetBitmap valid_row_bitset(3, true); + + TargetBitmapView row_view(row_bitset.data(), row_bitset.size()); + TargetBitmapView valid_view(valid_row_bitset.data(), + valid_row_bitset.size()); + + auto [elem_bitset, valid_elem_bitset] = + offsets.RowBitsetToElementBitset(row_view, valid_view); + + EXPECT_EQ(elem_bitset.size(), 6); + EXPECT_TRUE(elem_bitset[0]); + EXPECT_TRUE(elem_bitset[1]); + EXPECT_FALSE(elem_bitset[2]); + EXPECT_FALSE(elem_bitset[3]); + EXPECT_FALSE(elem_bitset[4]); + EXPECT_TRUE(elem_bitset[5]); +} + +TEST_F(ArrayOffsetsTest, GrowingConcurrentRead) { + ArrayOffsetsGrowing offsets; + + // Insert initial data + std::vector lens = {2, 3, 1}; + offsets.Insert(0, lens.data(), 3); + + // Concurrent reads should be safe + std::vector threads; + for (int t = 0; t < 4; ++t) { + threads.emplace_back([&offsets]() { + for (int i = 0; i < 1000; ++i) { + auto row_count = offsets.GetRowCount(); + auto elem_count = offsets.GetTotalElementCount(); + EXPECT_GE(row_count, 0); + EXPECT_GE(elem_count, 0); + + if (row_count > 0) { + auto [start, end] = offsets.ElementIDRangeOfRow(0); + EXPECT_GE(start, 0); + EXPECT_GE(end, start); + } + + if (elem_count > 0) { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(0); + EXPECT_GE(row_id, 0); + EXPECT_GE(elem_idx, 0); + } + } + }); + } + + for (auto& t : threads) { + t.join(); + } +} + +TEST_F(ArrayOffsetsTest, SingleRow) { + ArrayOffsetsGrowing offsets; + + std::vector lens = {5}; + offsets.Insert(0, lens.data(), 1); + + EXPECT_EQ(offsets.GetRowCount(), 1); + EXPECT_EQ(offsets.GetTotalElementCount(), 5); + + for (int i = 0; i < 5; ++i) { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(i); + EXPECT_EQ(row_id, 0); + EXPECT_EQ(elem_idx, i); + } + + auto [start, end] = offsets.ElementIDRangeOfRow(0); + EXPECT_EQ(start, 0); + EXPECT_EQ(end, 5); +} + +TEST_F(ArrayOffsetsTest, SingleElementPerRow) { + ArrayOffsetsGrowing offsets; + + std::vector lens = {1, 1, 1, 1, 1}; + offsets.Insert(0, lens.data(), 5); + + EXPECT_EQ(offsets.GetRowCount(), 5); + EXPECT_EQ(offsets.GetTotalElementCount(), 5); + + for (int i = 0; i < 5; ++i) { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(i); + EXPECT_EQ(row_id, i); + EXPECT_EQ(elem_idx, 0); + + auto [start, end] = offsets.ElementIDRangeOfRow(i); + EXPECT_EQ(start, i); + EXPECT_EQ(end, i + 1); + } +} + +TEST_F(ArrayOffsetsTest, LargeArrayLength) { + ArrayOffsetsGrowing offsets; + + // Single row with many elements + std::vector lens = {10000}; + offsets.Insert(0, lens.data(), 1); + + EXPECT_EQ(offsets.GetRowCount(), 1); + EXPECT_EQ(offsets.GetTotalElementCount(), 10000); + + // Test first, middle, and last elements + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(0); + EXPECT_EQ(row_id, 0); + EXPECT_EQ(elem_idx, 0); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(5000); + EXPECT_EQ(row_id, 0); + EXPECT_EQ(elem_idx, 5000); + } + { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(9999); + EXPECT_EQ(row_id, 0); + EXPECT_EQ(elem_idx, 9999); + } +} diff --git a/internal/core/src/common/ElementFilterIterator.cpp b/internal/core/src/common/ElementFilterIterator.cpp new file mode 100644 index 0000000000..a3005b812a --- /dev/null +++ b/internal/core/src/common/ElementFilterIterator.cpp @@ -0,0 +1,115 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ElementFilterIterator.h" + +#include "common/EasyAssert.h" +#include "exec/expression/EvalCtx.h" +#include "exec/expression/Expr.h" + +namespace milvus { + +ElementFilterIterator::ElementFilterIterator( + std::shared_ptr base_iterator, + exec::ExecContext* exec_context, + exec::ExprSet* expr_set) + : base_iterator_(std::move(base_iterator)), + exec_context_(exec_context), + expr_set_(expr_set) { + AssertInfo(base_iterator_ != nullptr, "Base iterator cannot be null"); + AssertInfo(exec_context_ != nullptr, "Exec context cannot be null"); + AssertInfo(expr_set_ != nullptr, "ExprSet cannot be null"); +} + +bool +ElementFilterIterator::HasNext() { + // If cache is empty and base iterator has more, fetch more + while (filtered_buffer_.empty() && base_iterator_->HasNext()) { + FetchAndFilterBatch(); + } + return !filtered_buffer_.empty(); +} + +std::optional> +ElementFilterIterator::Next() { + if (!HasNext()) { + return std::nullopt; + } + + auto result = filtered_buffer_.front(); + filtered_buffer_.pop_front(); + return result; +} + +void +ElementFilterIterator::FetchAndFilterBatch() { + constexpr size_t kBatchSize = 1024; + + // Step 1: Fetch a batch from base iterator (up to kBatchSize elements) + element_ids_buffer_.clear(); + distances_buffer_.clear(); + element_ids_buffer_.reserve(kBatchSize); + distances_buffer_.reserve(kBatchSize); + + while (base_iterator_->HasNext() && + element_ids_buffer_.size() < kBatchSize) { + auto pair = base_iterator_->Next(); + if (pair.has_value()) { + element_ids_buffer_.push_back(static_cast(pair->first)); + distances_buffer_.push_back(pair->second); + } + } + + // If no elements fetched, base iterator is exhausted + if (element_ids_buffer_.empty()) { + return; + } + + // Step 2: Batch evaluate element-level expression + exec::EvalCtx eval_ctx(exec_context_, expr_set_, &element_ids_buffer_); + std::vector results; + + // Evaluate the expression set (should contain only element_expr) + expr_set_->Eval(0, 1, true, eval_ctx, results); + + AssertInfo(results.size() == 1 && results[0] != nullptr, + "ElementFilterIterator: expression evaluation should return " + "exactly one result"); + + // Step 3: Extract evaluation results as bitmap + auto col_vec = std::dynamic_pointer_cast(results[0]); + AssertInfo(col_vec != nullptr, + "ElementFilterIterator: result should be ColumnVector"); + AssertInfo(col_vec->IsBitmap(), + "ElementFilterIterator: result should be bitmap"); + + auto col_vec_size = col_vec->size(); + AssertInfo(col_vec_size == element_ids_buffer_.size(), + "ElementFilterIterator: evaluation result size mismatch"); + + TargetBitmapView bitsetview(col_vec->GetRawData(), col_vec_size); + + // Step 4: Filter elements based on evaluation results and cache them + for (size_t i = 0; i < element_ids_buffer_.size(); ++i) { + if (bitsetview[i]) { + // Element passes filter, cache it + filtered_buffer_.emplace_back(element_ids_buffer_[i], + distances_buffer_[i]); + } + } +} + +} // namespace milvus diff --git a/internal/core/src/common/ElementFilterIterator.h b/internal/core/src/common/ElementFilterIterator.h new file mode 100644 index 0000000000..44a7a76202 --- /dev/null +++ b/internal/core/src/common/ElementFilterIterator.h @@ -0,0 +1,74 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include + +#include "common/QueryResult.h" +#include "common/Vector.h" +#include "exec/expression/Expr.h" + +namespace milvus { + +// Forward declarations +namespace exec { +class ExecContext; +class ExprSet; +} // namespace exec + +class ElementFilterIterator : public VectorIterator { + public: + ElementFilterIterator(std::shared_ptr base_iterator, + exec::ExecContext* exec_context, + exec::ExprSet* expr_set); + + bool + HasNext() override; + + std::optional> + Next() override; + + private: + // Fetch a batch from base iterator, evaluate expression, and cache results + // Steps: + // 1. Fetch up to batch_size elements from base_iterator + // 2. Batch evaluate element_expr on fetched elements + // 3. Filter elements based on evaluation results + // 4. Cache passing elements in filtered_buffer_ + void + FetchAndFilterBatch(); + + // Base iterator to fetch elements from + std::shared_ptr base_iterator_; + + // Execution context for expression evaluation + exec::ExecContext* exec_context_; + + // Expression set containing element-level filter expression + exec::ExprSet* expr_set_; + + // Cache of filtered elements ready to be consumed + std::deque> filtered_buffer_; + + // Reusable buffers for batch fetching (avoid repeated allocations) + FixedVector element_ids_buffer_; + FixedVector distances_buffer_; +}; + +} // namespace milvus diff --git a/internal/core/src/common/QueryInfo.h b/internal/core/src/common/QueryInfo.h index 21b4dc13e7..3a40b9b6a9 100644 --- a/internal/core/src/common/QueryInfo.h +++ b/internal/core/src/common/QueryInfo.h @@ -18,6 +18,7 @@ #include +#include "ArrayOffsets.h" #include "common/Tracer.h" #include "common/Types.h" #include "knowhere/config.h" @@ -46,6 +47,13 @@ struct SearchInfo { std::optional json_path_; std::optional json_type_; bool strict_cast_{false}; + std::shared_ptr array_offsets_{ + nullptr}; // For element-level search + + bool + element_level() const { + return array_offsets_ != nullptr; + } }; using SearchInfoPtr = std::shared_ptr; diff --git a/internal/core/src/common/QueryResult.h b/internal/core/src/common/QueryResult.h index 78eb4a48af..024d5ad069 100644 --- a/internal/core/src/common/QueryResult.h +++ b/internal/core/src/common/QueryResult.h @@ -28,6 +28,7 @@ #include #include "common/FieldMeta.h" +#include "common/ArrayOffsets.h" #include "pb/schema.pb.h" #include "knowhere/index/index_node.h" @@ -122,16 +123,37 @@ struct OffsetDisPairComparator { return left->GetOffDis().first < right->GetOffDis().first; } }; -struct VectorIterator { + +class VectorIterator { public: - VectorIterator(int chunk_count, - const std::vector& total_rows_until_chunk = {}) + virtual ~VectorIterator() = default; + + virtual bool + HasNext() = 0; + + virtual std::optional> + Next() = 0; +}; + +// Multi-way merge iterator for vector search results from multiple chunks +// +// Merges knowhere iterators from different chunks using a min-heap, +// returning results in distance-sorted order. +class ChunkMergeIterator : public VectorIterator { + public: + ChunkMergeIterator(int chunk_count, + const std::vector& total_rows_until_chunk = {}) : total_rows_until_chunk_(total_rows_until_chunk) { iterators_.reserve(chunk_count); } + bool + HasNext() override { + return !heap_.empty(); + } + std::optional> - Next() { + Next() override { if (!heap_.empty()) { auto top = heap_.top(); heap_.pop(); @@ -145,10 +167,7 @@ struct VectorIterator { } return std::nullopt; } - bool - HasNext() { - return !heap_.empty(); - } + bool AddIterator(knowhere::IndexNode::IteratorPtr iter) { if (!sealed && iter != nullptr) { @@ -157,6 +176,7 @@ struct VectorIterator { } return false; } + void seal() { sealed = true; @@ -195,7 +215,7 @@ struct VectorIterator { heap_; bool sealed = false; std::vector total_rows_until_chunk_; - //currently, VectorIterator is guaranteed to be used serially without concurrent problem, in the future + //currently, ChunkMergeIterator is guaranteed to be used serially without concurrent problem, in the future //we may need to add mutex to protect the variable sealed }; @@ -230,15 +250,21 @@ struct SearchResult { for (int i = 0, vec_iter_idx = 0; i < kw_iterators.size(); i++) { vec_iter_idx = vec_iter_idx % nq; if (vector_iterators.size() < nq) { - auto vector_iterator = std::make_shared( + auto chunk_merge_iter = std::make_shared( chunk_count, total_rows_until_chunk); - vector_iterators.emplace_back(vector_iterator); + vector_iterators.emplace_back(chunk_merge_iter); } const auto& kw_iterator = kw_iterators[i]; - vector_iterators[vec_iter_idx++]->AddIterator(kw_iterator); + auto chunk_merge_iter = + std::static_pointer_cast( + vector_iterators[vec_iter_idx++]); + chunk_merge_iter->AddIterator(kw_iterator); } for (const auto& vector_iter : vector_iterators) { - vector_iter->seal(); + // Cast to ChunkMergeIterator to call seal + auto chunk_merge_iter = + std::static_pointer_cast(vector_iter); + chunk_merge_iter->seal(); } this->vector_iterators_ = vector_iterators; } @@ -275,6 +301,28 @@ struct SearchResult { vector_iterators_; // record the storage usage in search StorageCost search_storage_cost_; + + bool element_level_{false}; + std::vector element_indices_; + std::optional>> + element_iterators_; + std::shared_ptr array_offsets_{nullptr}; + std::vector> chunk_buffers_{}; + + bool + HasIterators() const { + return (element_level_ && element_iterators_.has_value()) || + (!element_level_ && vector_iterators_.has_value()); + } + + std::optional>> + GetIterators() { + if (element_level_) { + return element_iterators_; + } else { + return vector_iterators_; + } + } }; using SearchResultPtr = std::shared_ptr; diff --git a/internal/core/src/common/Schema.cpp b/internal/core/src/common/Schema.cpp index 4dc91723f8..507a827c54 100644 --- a/internal/core/src/common/Schema.cpp +++ b/internal/core/src/common/Schema.cpp @@ -171,4 +171,15 @@ Schema::MmapEnabled(const FieldId& field_id) const { return {true, it->second}; } +const FieldMeta& +Schema::GetFirstArrayFieldInStruct(const std::string& struct_name) const { + auto cache_it = struct_array_field_cache_.find(struct_name); + if (cache_it != struct_array_field_cache_.end()) { + return fields_.at(cache_it->second); + } + + ThrowInfo(ErrorCode::UnexpectedError, + "No array field found in struct: {}", + struct_name); +} } // namespace milvus diff --git a/internal/core/src/common/Schema.h b/internal/core/src/common/Schema.h index 7562294de5..c3e1f0d962 100644 --- a/internal/core/src/common/Schema.h +++ b/internal/core/src/common/Schema.h @@ -367,7 +367,24 @@ class Schema { name_ids_.emplace(field_name, field_id); id_names_.emplace(field_id, field_name); - fields_.emplace(field_id, field_meta); + // Build struct_array_field_cache_ for ARRAY/VECTOR_ARRAY fields + // Field name format: "struct_name[0].field_name" + auto data_type = field_meta.get_data_type(); + if (data_type == DataType::ARRAY || + data_type == DataType::VECTOR_ARRAY) { + const std::string& name_str = field_name.get(); + auto bracket_pos = name_str.find('['); + if (bracket_pos != std::string::npos && bracket_pos > 0) { + std::string struct_name = name_str.substr(0, bracket_pos); + // Only cache the first array field for each struct + if (struct_array_field_cache_.find(struct_name) == + struct_array_field_cache_.end()) { + struct_array_field_cache_[struct_name] = field_id; + } + } + } + + fields_.emplace(field_id, std::move(field_meta)); field_ids_.emplace_back(field_id); } @@ -392,6 +409,10 @@ class Schema { std::pair MmapEnabled(const FieldId& field) const; + // Find the first array field belonging to a struct (cached) + const FieldMeta& + GetFirstArrayFieldInStruct(const std::string& struct_name) const; + private: int64_t debug_id = START_USER_FIELDID; std::vector field_ids_; @@ -418,6 +439,9 @@ class Schema { bool has_mmap_setting_ = false; bool mmap_enabled_ = false; std::unordered_map mmap_fields_; + + // Cache for struct_name -> first array field mapping (built during AddField) + std::unordered_map struct_array_field_cache_; }; using SchemaPtr = std::shared_ptr; diff --git a/internal/core/src/common/Utils.h b/internal/core/src/common/Utils.h index 8353c39d98..275618a0d1 100644 --- a/internal/core/src/common/Utils.h +++ b/internal/core/src/common/Utils.h @@ -28,6 +28,7 @@ #include "common/Consts.h" #include "common/FieldMeta.h" #include "common/LoadInfo.h" +#include "common/Schema.h" #include "common/Types.h" #include "common/EasyAssert.h" #include "knowhere/dataset.h" diff --git a/internal/core/src/common/VectorArray.h b/internal/core/src/common/VectorArray.h index aa7f57c64b..7d548fdf1c 100644 --- a/internal/core/src/common/VectorArray.h +++ b/internal/core/src/common/VectorArray.h @@ -458,6 +458,11 @@ class VectorArrayView { } } + int + length() const { + return length_; + } + private: char* data_{nullptr}; int64_t dim_ = 0; diff --git a/internal/core/src/exec/Driver.cpp b/internal/core/src/exec/Driver.cpp index fed2ca6dc1..b267932eb6 100644 --- a/internal/core/src/exec/Driver.cpp +++ b/internal/core/src/exec/Driver.cpp @@ -32,6 +32,8 @@ #include "exec/operator/VectorSearchNode.h" #include "exec/operator/RandomSampleNode.h" #include "exec/operator/GroupByNode.h" +#include "exec/operator/ElementFilterNode.h" +#include "exec/operator/ElementFilterBitsNode.h" #include "exec/Task.h" #include "plan/PlanNode.h" @@ -104,6 +106,19 @@ DriverFactory::CreateDriver(std::unique_ptr ctx, tracer::AddEvent("create_operator: RescoresNode"); operators.push_back( std::make_unique(id, ctx.get(), rescoresnode)); + } else if (auto node = + std::dynamic_pointer_cast( + plannode)) { + tracer::AddEvent("create_operator: ElementFilterNode"); + operators.push_back( + std::make_unique(id, ctx.get(), node)); + } else if (auto node = std::dynamic_pointer_cast< + const plan::ElementFilterBitsNode>(plannode)) { + tracer::AddEvent("create_operator: ElementFilterBitsNode"); + operators.push_back(std::make_unique( + id, ctx.get(), node)); + } else { + ThrowInfo(ErrorCode::UnexpectedError, "Unknown plan node type"); } // TODO: add more operators } diff --git a/internal/core/src/exec/QueryContext.h b/internal/core/src/exec/QueryContext.h index 02dc46668f..ded1c095fa 100644 --- a/internal/core/src/exec/QueryContext.h +++ b/internal/core/src/exec/QueryContext.h @@ -28,6 +28,7 @@ #include "common/Common.h" #include "common/Types.h" #include "common/Exception.h" +#include "common/ArrayOffsets.h" #include "common/OpContext.h" #include "segcore/SegmentInterface.h" @@ -303,6 +304,64 @@ class QueryContext : public Context { return plan_options_; } + void + set_element_level_query(bool element_level) { + element_level_query_ = element_level; + } + + bool + element_level_query() const { + return element_level_query_; + } + + void + set_struct_name(const std::string& field_name) { + struct_name_ = field_name; + } + + const std::string& + get_struct_name() const { + return struct_name_; + } + + void + set_array_offsets(std::shared_ptr offsets) { + array_offsets_ = std::move(offsets); + } + + std::shared_ptr + get_array_offsets() const { + return array_offsets_; + } + + void + set_active_element_count(int64_t count) { + active_element_count_ = count; + } + + int64_t + get_active_element_count() const { + return active_element_count_; + } + + void + set_element_level_bitset(TargetBitmap&& bitset) { + element_level_bitset_ = std::move(bitset); + } + + std::optional + get_element_level_bitset() { + if (element_level_bitset_.has_value()) { + return std::move(element_level_bitset_.value()); + } + return std::nullopt; + } + + bool + has_element_level_bitset() const { + return element_level_bitset_.has_value(); + } + private: folly::Executor* executor_; //folly::Executor::KeepAlive<> executor_keepalive_; @@ -331,6 +390,12 @@ class QueryContext : public Context { int32_t consistency_level_ = 0; query::PlanOptions plan_options_; + + bool element_level_query_{false}; + std::string struct_name_; + std::shared_ptr array_offsets_{nullptr}; + int64_t active_element_count_{0}; // Total elements in active documents + std::optional element_level_bitset_; }; // Represent the state of one thread of query execution. diff --git a/internal/core/src/exec/expression/BinaryArithOpEvalRangeExpr.cpp b/internal/core/src/exec/expression/BinaryArithOpEvalRangeExpr.cpp index 0047e20636..1fa2368204 100644 --- a/internal/core/src/exec/expression/BinaryArithOpEvalRangeExpr.cpp +++ b/internal/core/src/exec/expression/BinaryArithOpEvalRangeExpr.cpp @@ -29,7 +29,11 @@ PhyBinaryArithOpEvalRangeExpr::Eval(EvalCtx& context, VectorPtr& result) { auto input = context.get_offset_input(); SetHasOffsetInput((input != nullptr)); - switch (expr_->column_.data_type_) { + auto data_type = expr_->column_.data_type_; + if (expr_->column_.element_level_) { + data_type = expr_->column_.element_type_; + } + switch (data_type) { case DataType::BOOL: { result = ExecRangeVisitorImpl(input); break; @@ -1840,14 +1844,27 @@ PhyBinaryArithOpEvalRangeExpr::ExecRangeVisitorImplForData( int64_t processed_size; if (has_offset_input_) { - processed_size = ProcessDataByOffsets(execute_sub_batch, - skip_index_func, - input, - res, - valid_res, - value, - right_operand); + if (expr_->column_.element_level_) { + // For element-level filtering + processed_size = ProcessElementLevelByOffsets(execute_sub_batch, + skip_index_func, + input, + res, + valid_res, + value, + right_operand); + } else { + processed_size = ProcessDataByOffsets(execute_sub_batch, + skip_index_func, + input, + res, + valid_res, + value, + right_operand); + } } else { + AssertInfo(!expr_->column_.element_level_, + "Element-level filtering is not supported without offsets"); processed_size = ProcessDataChunks(execute_sub_batch, skip_index_func, res, diff --git a/internal/core/src/exec/expression/BinaryRangeExpr.cpp b/internal/core/src/exec/expression/BinaryRangeExpr.cpp index cf2253714d..bd01d855f3 100644 --- a/internal/core/src/exec/expression/BinaryRangeExpr.cpp +++ b/internal/core/src/exec/expression/BinaryRangeExpr.cpp @@ -31,7 +31,12 @@ PhyBinaryRangeFilterExpr::Eval(EvalCtx& context, VectorPtr& result) { auto input = context.get_offset_input(); SetHasOffsetInput((input != nullptr)); - switch (expr_->column_.data_type_) { + + auto data_type = expr_->column_.data_type_; + if (expr_->column_.element_level_) { + data_type = expr_->column_.element_type_; + } + switch (data_type) { case DataType::BOOL: { result = ExecRangeVisitorImpl(context); break; @@ -414,14 +419,28 @@ PhyBinaryRangeFilterExpr::ExecRangeVisitorImplForData(EvalCtx& context) { }; int64_t processed_size; if (has_offset_input_) { - processed_size = ProcessDataByOffsets(execute_sub_batch, - skip_index_func, - input, - res, - valid_res, - val1, - val2); + if (expr_->column_.element_level_) { + // For element-level filtering + processed_size = ProcessElementLevelByOffsets(execute_sub_batch, + skip_index_func, + input, + res, + valid_res, + val1, + val2); + } else { + // For doc-level filtering + processed_size = ProcessDataByOffsets(execute_sub_batch, + skip_index_func, + input, + res, + valid_res, + val1, + val2); + } } else { + AssertInfo(!expr_->column_.element_level_, + "Element-level filtering is not supported without offsets"); processed_size = ProcessDataChunks( execute_sub_batch, skip_index_func, res, valid_res, val1, val2); } diff --git a/internal/core/src/exec/expression/ColumnExpr.cpp b/internal/core/src/exec/expression/ColumnExpr.cpp index 3a78bcdf25..d2a2d81165 100644 --- a/internal/core/src/exec/expression/ColumnExpr.cpp +++ b/internal/core/src/exec/expression/ColumnExpr.cpp @@ -71,6 +71,9 @@ PhyColumnExpr::Eval(EvalCtx& context, VectorPtr& result) { template VectorPtr PhyColumnExpr::DoEval(OffsetVector* input) { + AssertInfo(!expr_->GetColumn().element_level_, + "ColumnExpr of row-level access is not supported"); + // similar to PhyCompareFilterExpr::ExecCompareExprDispatcher(OpType op) // take offsets as input if (has_offset_input_) { diff --git a/internal/core/src/exec/expression/Expr.h b/internal/core/src/exec/expression/Expr.h index 46406f000b..3e1ec85bf7 100644 --- a/internal/core/src/exec/expression/Expr.h +++ b/internal/core/src/exec/expression/Expr.h @@ -21,6 +21,8 @@ #include #include +#include "common/Array.h" +#include "common/ArrayOffsets.h" #include "common/FieldDataInterface.h" #include "common/Json.h" #include "common/OpContext.h" @@ -679,6 +681,173 @@ class SegmentExpr : public Expr { return input->size(); } + // Process element-level data by element IDs + // Handles the type mismatch between storage (ArrayView) and element type + // Currently only implemented for sealed chunked segments + template + int64_t + ProcessElementLevelByOffsets( + FUNC func, + std::function skip_func, + OffsetVector* element_ids, + TargetBitmapView res, + TargetBitmapView valid_res, + const ValTypes&... values) { + auto& skip_index = segment_->GetSkipIndex(); + if (segment_->type() == SegmentType::Sealed) { + AssertInfo( + segment_->is_chunked(), + "Element-level filtering requires chunked segment for sealed"); + + auto array_offsets = segment_->GetArrayOffsets(field_id_); + if (!array_offsets) { + ThrowInfo(ErrorCode::UnexpectedError, + "IArrayOffsets not found for field {}", + field_id_.get()); + } + + // Batch process consecutive elements belonging to the same chunk + size_t processed_size = 0; + size_t i = 0; + + // Reuse these vectors to avoid repeated heap allocations + FixedVector offsets; + FixedVector elem_indices; + + while (i < element_ids->size()) { + // Start of a new chunk batch + int64_t element_id = (*element_ids)[i]; + auto [doc_id, elem_idx] = + array_offsets->ElementIDToRowID(element_id); + auto [chunk_id, chunk_offset] = + segment_->get_chunk_by_offset(field_id_, doc_id); + + // Collect consecutive elements belonging to the same chunk + offsets.clear(); + elem_indices.clear(); + offsets.push_back(chunk_offset); + elem_indices.push_back(elem_idx); + + size_t batch_start = i; + i++; + + // Look ahead for more elements in the same chunk + while (i < element_ids->size()) { + int64_t next_element_id = (*element_ids)[i]; + auto [next_doc_id, next_elem_idx] = + array_offsets->ElementIDToRowID(next_element_id); + auto [next_chunk_id, next_chunk_offset] = + segment_->get_chunk_by_offset(field_id_, next_doc_id); + + if (next_chunk_id != chunk_id) { + break; // Different chunk, process current batch + } + + offsets.push_back(next_chunk_offset); + elem_indices.push_back(next_elem_idx); + i++; + } + + // Batch fetch all ArrayViews for this chunk + auto pw = segment_->get_views_by_offsets( + op_ctx_, field_id_, chunk_id, offsets); + + auto [array_vec, valid_data] = pw.get(); + + // Process each element in this batch + for (size_t j = 0; j < offsets.size(); j++) { + size_t result_idx = batch_start + j; + + if ((!skip_func || + !skip_func(skip_index, field_id_, chunk_id)) && + (!namespace_skip_func_.has_value() || + !namespace_skip_func_.value()(chunk_id))) { + // Extract element from ArrayView + auto value = + array_vec[j].template get_data( + elem_indices[j]); + bool is_valid = !valid_data.data() || valid_data[j]; + + func.template operator()( + &value, + &is_valid, + nullptr, + 1, + res + result_idx, + valid_res + result_idx, + values...); + } else { + // Chunk is skipped - handle exactly like ProcessDataByOffsets + if (valid_data.size() > j && !valid_data[j]) { + res[result_idx] = valid_res[result_idx] = false; + } + } + + processed_size++; + } + } + return processed_size; + } else { + auto array_offsets = segment_->GetArrayOffsets(field_id_); + if (!array_offsets) { + ThrowInfo(ErrorCode::UnexpectedError, + "IArrayOffsets not found for field {}", + field_id_.get()); + } + + auto& skip_index = segment_->GetSkipIndex(); + size_t processed_size = 0; + + for (size_t i = 0; i < element_ids->size(); i++) { + int64_t element_id = (*element_ids)[i]; + + auto [doc_id, elem_idx] = + array_offsets->ElementIDToRowID(element_id); + + // Calculate chunk_id and chunk_offset for this doc + auto chunk_id = doc_id / size_per_chunk_; + auto chunk_offset = doc_id % size_per_chunk_; + + // Get the Array chunk (Growing segment stores Array, not ArrayView) + auto pw = + segment_->chunk_data(op_ctx_, field_id_, chunk_id); + auto chunk = pw.get(); + const Array* array_ptr = chunk.data() + chunk_offset; + const bool* valid_data = chunk.valid_data(); + if (valid_data != nullptr) { + valid_data += chunk_offset; + } + + if ((!skip_func || + !skip_func(skip_index, field_id_, chunk_id)) && + (!namespace_skip_func_.has_value() || + !namespace_skip_func_.value()(chunk_id))) { + // Extract element from Array + auto value = array_ptr->get_data(elem_idx); + bool is_valid = !valid_data || valid_data[0]; + + func.template operator()( + &value, + &is_valid, + nullptr, + 1, + res + processed_size, + valid_res + processed_size, + values...); + } else { + // Chunk is skipped + if (valid_data && !valid_data[0]) { + res[processed_size] = valid_res[processed_size] = false; + } + } + + processed_size++; + } + + return processed_size; + } + } + // Template parameter to control whether segment offsets are needed (for GIS functions) template column_.data_type_) { + auto data_type = expr_->column_.data_type_; + if (expr_->column_.element_level_) { + data_type = expr_->column_.element_type_; + } + switch (data_type) { case DataType::BOOL: { result = ExecVisitorImpl(context); break; @@ -1001,13 +1005,25 @@ PhyTermFilterExpr::ExecVisitorImplForData(EvalCtx& context) { int64_t processed_size; if (has_offset_input_) { - processed_size = ProcessDataByOffsets(execute_sub_batch, - skip_index_func, - input, - res, - valid_res, - arg_set_); + if (expr_->column_.element_level_) { + // For element-level filtering + processed_size = ProcessElementLevelByOffsets(execute_sub_batch, + skip_index_func, + input, + res, + valid_res, + arg_set_); + } else { + processed_size = ProcessDataByOffsets(execute_sub_batch, + skip_index_func, + input, + res, + valid_res, + arg_set_); + } } else { + AssertInfo(!expr_->column_.element_level_, + "Element-level filtering is not supported without offsets"); processed_size = ProcessDataChunks( execute_sub_batch, skip_index_func, res, valid_res, arg_set_); } diff --git a/internal/core/src/exec/expression/UnaryExpr.cpp b/internal/core/src/exec/expression/UnaryExpr.cpp index 005c469a70..a11ab01800 100644 --- a/internal/core/src/exec/expression/UnaryExpr.cpp +++ b/internal/core/src/exec/expression/UnaryExpr.cpp @@ -163,7 +163,11 @@ PhyUnaryRangeFilterExpr::Eval(EvalCtx& context, VectorPtr& result) { auto input = context.get_offset_input(); SetHasOffsetInput((input != nullptr)); - switch (expr_->column_.data_type_) { + auto data_type = expr_->column_.data_type_; + if (expr_->column_.element_level_) { + data_type = expr_->column_.element_type_; + } + switch (data_type) { case DataType::BOOL: { result = ExecRangeVisitorImpl(context); break; @@ -1713,9 +1717,17 @@ PhyUnaryRangeFilterExpr::ExecRangeVisitorImplForData(EvalCtx& context) { int64_t processed_size; if (has_offset_input_) { - processed_size = ProcessDataByOffsets( - execute_sub_batch, skip_index_func, input, res, valid_res, val); + if (expr_->column_.element_level_) { + // For element-level filtering + processed_size = ProcessElementLevelByOffsets( + execute_sub_batch, skip_index_func, input, res, valid_res, val); + } else { + processed_size = ProcessDataByOffsets( + execute_sub_batch, skip_index_func, input, res, valid_res, val); + } } else { + AssertInfo(!expr_->column_.element_level_, + "Element-level filtering is not supported without offsets"); processed_size = ProcessDataChunks( execute_sub_batch, skip_index_func, res, valid_res, val); } diff --git a/internal/core/src/exec/operator/ElementFilterBitsNode.cpp b/internal/core/src/exec/operator/ElementFilterBitsNode.cpp new file mode 100644 index 0000000000..a686c68fd1 --- /dev/null +++ b/internal/core/src/exec/operator/ElementFilterBitsNode.cpp @@ -0,0 +1,215 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ElementFilterBitsNode.h" +#include "common/Tracer.h" +#include "fmt/format.h" + +#include "monitor/Monitor.h" + +namespace milvus { +namespace exec { + +PhyElementFilterBitsNode::PhyElementFilterBitsNode( + int32_t operator_id, + DriverContext* driverctx, + const std::shared_ptr& + element_filter_bits_node) + : Operator(driverctx, + DataType::NONE, + operator_id, + "element_filter_bits_plan_node", + "PhyElementFilterBitsNode"), + struct_name_(element_filter_bits_node->struct_name()) { + ExecContext* exec_context = operator_context_->get_exec_context(); + query_context_ = exec_context->get_query_context(); + + // Build expression set from element-level expression + std::vector exprs; + exprs.emplace_back(element_filter_bits_node->element_filter()); + element_exprs_ = std::make_unique(exprs, exec_context); +} + +void +PhyElementFilterBitsNode::AddInput(RowVectorPtr& input) { + input_ = std::move(input); +} + +RowVectorPtr +PhyElementFilterBitsNode::GetOutput() { + if (is_finished_ || input_ == nullptr) { + return nullptr; + } + + DeferLambda([&]() { is_finished_ = true; }); + + tracer::AutoSpan span( + "PhyElementFilterBitsNode::GetOutput", tracer::GetRootSpan(), true); + + std::chrono::high_resolution_clock::time_point start_time = + std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point step_time; + + // Step 1: Get array offsets + auto segment = query_context_->get_segment(); + auto& field_meta = + segment->get_schema().GetFirstArrayFieldInStruct(struct_name_); + auto field_id = field_meta.get_id(); + auto array_offsets = segment->GetArrayOffsets(field_id); + if (array_offsets == nullptr) { + ThrowInfo(ErrorCode::UnexpectedError, + "IArrayOffsets not found for field {}", + field_id.get()); + } + query_context_->set_array_offsets(array_offsets); + auto [first_elem, _] = + array_offsets->ElementIDRangeOfRow(query_context_->get_active_count()); + query_context_->set_active_element_count(first_elem); + + // Step 2: Prepare doc bitset + auto col_input = GetColumnVector(input_); + TargetBitmapView doc_bitset(col_input->GetRawData(), col_input->size()); + TargetBitmapView doc_bitset_valid(col_input->GetValidRawData(), + col_input->size()); + doc_bitset.flip(); + + // Step 3: Convert doc bitset to element offsets + FixedVector element_offsets = + DocBitsetToElementOffsets(doc_bitset); + + // Step 4: Evaluate element expression + auto [expr_result, valid_expr_result] = + EvaluateElementExpression(element_offsets); + + // Step 5: Set query context + query_context_->set_element_level_query(true); + query_context_->set_struct_name(struct_name_); + + std::chrono::high_resolution_clock::time_point end_time = + std::chrono::high_resolution_clock::now(); + double total_cost = + std::chrono::duration(end_time - start_time) + .count(); + milvus::monitor::internal_core_search_latency_scalar.Observe(total_cost / + 1000); + + auto filtered_count = expr_result.count(); + tracer::AddEvent( + fmt::format("struct_name: {}, total_elements: {}, output_rows: {}, " + "filtered: {}, cost_us: {}", + struct_name_, + array_offsets->GetTotalElementCount(), + array_offsets->GetTotalElementCount() - filtered_count, + filtered_count, + total_cost)); + + std::vector col_res; + col_res.push_back(std::make_shared( + std::move(expr_result), std::move(valid_expr_result))); + return std::make_shared(col_res); +} + +FixedVector +PhyElementFilterBitsNode::DocBitsetToElementOffsets( + const TargetBitmapView& doc_bitset) { + auto array_offsets = query_context_->get_array_offsets(); + AssertInfo(array_offsets != nullptr, "Array offsets not available"); + + int64_t doc_count = array_offsets->GetRowCount(); + AssertInfo(doc_bitset.size() == doc_count, + "Doc bitset size mismatch: {} vs {}", + doc_bitset.size(), + doc_count); + + FixedVector element_offsets; + element_offsets.reserve(array_offsets->GetTotalElementCount()); + + // For each document that passes the filter, get all its element offsets + for (int64_t doc_id = 0; doc_id < doc_count; ++doc_id) { + if (doc_bitset[doc_id]) { + // Get element range for this document + auto [first_elem, last_elem] = + array_offsets->ElementIDRangeOfRow(doc_id); + + // Add all element IDs for this document + for (int64_t elem_id = first_elem; elem_id < last_elem; ++elem_id) { + element_offsets.push_back(static_cast(elem_id)); + } + } + } + + return element_offsets; +} + +std::pair +PhyElementFilterBitsNode::EvaluateElementExpression( + FixedVector& element_offsets) { + tracer::AutoSpan span("PhyElementFilterBitsNode::EvaluateElementExpression", + tracer::GetRootSpan(), + true); + tracer::AddEvent(fmt::format("input_elements: {}", element_offsets.size())); + + // Use offset interface by passing element_offsets as third parameter + EvalCtx eval_ctx(operator_context_->get_exec_context(), + element_exprs_.get(), + &element_offsets); + + std::vector results; + element_exprs_->Eval(0, 1, true, eval_ctx, results); + + AssertInfo(results.size() == 1 && results[0] != nullptr, + "ElementFilterBitsNode: expression evaluation should return " + "exactly one result"); + + TargetBitmap bitset; + TargetBitmap valid_bitset; + int64_t total_elements = query_context_->get_active_element_count(); + bitset = TargetBitmap(total_elements, false); + valid_bitset = TargetBitmap(total_elements, true); + + auto col_vec = std::dynamic_pointer_cast(results[0]); + if (!col_vec) { + ThrowInfo(ExprInvalid, + "ElementFilterBitsNode result should be ColumnVector"); + } + if (!col_vec->IsBitmap()) { + ThrowInfo(ExprInvalid, "ElementFilterBitsNode result should be bitmap"); + } + auto col_vec_size = col_vec->size(); + TargetBitmapView bitsetview(col_vec->GetRawData(), col_vec_size); + + AssertInfo(col_vec_size == element_offsets.size(), + "ElementFilterBitsNode result size mismatch: {} vs {}", + col_vec_size, + element_offsets.size()); + + for (size_t i = 0; i < element_offsets.size(); ++i) { + if (bitsetview[i]) { + bitset[element_offsets[i]] = true; + } + } + + bitset.flip(); + + tracer::AddEvent(fmt::format("evaluated_elements: {}, total_elements: {}", + element_offsets.size(), + total_elements)); + + return std::make_pair(std::move(bitset), std::move(valid_bitset)); +} + +} // namespace exec +} // namespace milvus \ No newline at end of file diff --git a/internal/core/src/exec/operator/ElementFilterBitsNode.h b/internal/core/src/exec/operator/ElementFilterBitsNode.h new file mode 100644 index 0000000000..d6dcf19ab2 --- /dev/null +++ b/internal/core/src/exec/operator/ElementFilterBitsNode.h @@ -0,0 +1,93 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include + +#include "exec/Driver.h" +#include "exec/expression/Expr.h" +#include "exec/operator/Operator.h" +#include "exec/QueryContext.h" +#include "common/ArrayOffsets.h" +#include "expr/ITypeExpr.h" + +namespace milvus { +namespace exec { + +class PhyElementFilterBitsNode : public Operator { + public: + PhyElementFilterBitsNode( + int32_t operator_id, + DriverContext* ctx, + const std::shared_ptr& + element_filter_bits_node); + + bool + IsFilter() override { + return true; + } + + bool + NeedInput() const override { + return !input_; + } + + void + AddInput(RowVectorPtr& input) override; + + RowVectorPtr + GetOutput() override; + + bool + IsFinished() override { + return is_finished_; + } + + void + Close() override { + Operator::Close(); + if (element_exprs_) { + element_exprs_->Clear(); + } + } + + BlockingReason + IsBlocked(ContinueFuture* /* unused */) override { + return BlockingReason::kNotBlocked; + } + + std::string + ToString() const override { + return "PhyElementFilterBitsNode"; + } + + private: + FixedVector + DocBitsetToElementOffsets(const TargetBitmapView& doc_bitset); + + std::pair + EvaluateElementExpression(FixedVector& element_offsets); + + std::unique_ptr element_exprs_; + QueryContext* query_context_; + std::string struct_name_; + bool is_finished_{false}; +}; + +} // namespace exec +} // namespace milvus diff --git a/internal/core/src/exec/operator/ElementFilterNode.cpp b/internal/core/src/exec/operator/ElementFilterNode.cpp new file mode 100644 index 0000000000..74935563eb --- /dev/null +++ b/internal/core/src/exec/operator/ElementFilterNode.cpp @@ -0,0 +1,129 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ElementFilterNode.h" +#include "common/Tracer.h" +#include "common/ElementFilterIterator.h" +#include "monitor/Monitor.h" + +namespace milvus { +namespace exec { + +PhyElementFilterNode::PhyElementFilterNode( + int32_t operator_id, + DriverContext* driverctx, + const std::shared_ptr& element_filter_node) + : Operator(driverctx, + element_filter_node->output_type(), + operator_id, + element_filter_node->id(), + "PhyElementFilterNode"), + struct_name_(element_filter_node->struct_name()) { + ExecContext* exec_context = operator_context_->get_exec_context(); + query_context_ = exec_context->get_query_context(); + std::vector exprs; + exprs.emplace_back(element_filter_node->element_filter()); + element_exprs_ = std::make_unique(exprs, exec_context); +} + +void +PhyElementFilterNode::AddInput(RowVectorPtr& input) { + input_ = std::move(input); +} + +RowVectorPtr +PhyElementFilterNode::GetOutput() { + if (is_finished_ || !no_more_input_) { + return nullptr; + } + + tracer::AutoSpan span( + "PhyElementFilterNode::GetOutput", tracer::GetRootSpan(), true); + + DeferLambda([&]() { is_finished_ = true; }); + + if (input_ == nullptr) { + return nullptr; + } + + std::chrono::high_resolution_clock::time_point start_time = + std::chrono::high_resolution_clock::now(); + + // Step 1: Get search result with iterators + milvus::SearchResult search_result = query_context_->get_search_result(); + + if (!search_result.element_level_) { + ThrowInfo(ExprInvalid, + "PhyElementFilterNode expects element-level search result"); + } + + if (!search_result.vector_iterators_.has_value()) { + ThrowInfo( + ExprInvalid, + "PhyElementFilterNode expects vector_iterators in search result"); + } + + auto segment = query_context_->get_segment(); + auto& field_meta = + segment->get_schema().GetFirstArrayFieldInStruct(struct_name_); + auto field_id = field_meta.get_id(); + auto array_offsets = segment->GetArrayOffsets(field_id); + if (array_offsets == nullptr) { + ThrowInfo(ErrorCode::UnexpectedError, + "IArrayOffsets not found for field {}", + field_id.get()); + } + query_context_->set_array_offsets(array_offsets); + + // Step 2: Wrap each iterator with ElementFilterIterator + auto& base_iterators = search_result.vector_iterators_.value(); + std::vector> wrapped_iterators; + wrapped_iterators.reserve(base_iterators.size()); + + ExecContext* exec_context = operator_context_->get_exec_context(); + + for (auto& base_iter : base_iterators) { + // Wrap each iterator with ElementFilterIterator + auto wrapped_iter = std::make_shared( + base_iter, exec_context, element_exprs_.get()); + + wrapped_iterators.push_back(wrapped_iter); + } + + // Step 3: Update search result with wrapped iterators + search_result.vector_iterators_ = std::move(wrapped_iterators); + query_context_->set_search_result(std::move(search_result)); + + // Step 4: Record metrics + std::chrono::high_resolution_clock::time_point end_time = + std::chrono::high_resolution_clock::now(); + double cost = + std::chrono::duration(end_time - start_time) + .count(); + + tracer::AddEvent( + fmt::format("PhyElementFilterNode: wrapped {} iterators, struct_name: " + "{}, cost_us: {}", + wrapped_iterators.size(), + struct_name_, + cost)); + + // Pass through input to downstream + return input_; +} + +} // namespace exec +} // namespace milvus diff --git a/internal/core/src/exec/operator/ElementFilterNode.h b/internal/core/src/exec/operator/ElementFilterNode.h new file mode 100644 index 0000000000..76853a69a1 --- /dev/null +++ b/internal/core/src/exec/operator/ElementFilterNode.h @@ -0,0 +1,87 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include + +#include "exec/Driver.h" +#include "exec/expression/Expr.h" +#include "exec/operator/Operator.h" +#include "exec/QueryContext.h" +#include "common/ArrayOffsets.h" +#include "expr/ITypeExpr.h" + +namespace milvus { +namespace exec { + +class PhyElementFilterNode : public Operator { + public: + PhyElementFilterNode(int32_t operator_id, + DriverContext* ctx, + const std::shared_ptr& + element_filter_node); + + bool + IsFilter() override { + return true; + } + + bool + NeedInput() const override { + return !is_finished_; + } + + void + AddInput(RowVectorPtr& input) override; + + RowVectorPtr + GetOutput() override; + + bool + IsFinished() override { + return is_finished_; + } + + void + Close() override { + Operator::Close(); + if (element_exprs_) { + element_exprs_->Clear(); + } + } + + BlockingReason + IsBlocked(ContinueFuture* /* unused */) override { + return BlockingReason::kNotBlocked; + } + + std::string + ToString() const override { + return "PhyElementFilterNode"; + } + + private: + std::unique_ptr element_exprs_; + QueryContext* query_context_; + std::string struct_name_; + bool is_finished_{false}; +}; + +} // namespace exec +} // namespace milvus diff --git a/internal/core/src/exec/operator/IterativeFilterNode.cpp b/internal/core/src/exec/operator/IterativeFilterNode.cpp index e77c875d86..1a329a7bc0 100644 --- a/internal/core/src/exec/operator/IterativeFilterNode.cpp +++ b/internal/core/src/exec/operator/IterativeFilterNode.cpp @@ -88,7 +88,8 @@ insert_helper(milvus::SearchResult& search_result, const FixedVector& offsets, const int64_t nq_index, const int64_t unity_topk, - const int i) { + const int i, + const IArrayOffsets* array_offsets = nullptr) { auto pos = large_is_better ? find_binsert_position(search_result.distances_, nq_index * unity_topk, @@ -98,6 +99,18 @@ insert_helper(milvus::SearchResult& search_result, nq_index * unity_topk, nq_index * unity_topk + topk, distances[i]); + + // For element-level: convert element_id to (doc_id, element_index) + int64_t doc_id; + int32_t elem_idx = -1; + if (array_offsets != nullptr) { + auto [doc, idx] = array_offsets->ElementIDToRowID(offsets[i]); + doc_id = doc; + elem_idx = idx; + } else { + doc_id = offsets[i]; + } + if (topk > pos) { std::memmove(&search_result.distances_[pos + 1], &search_result.distances_[pos], @@ -105,8 +118,16 @@ insert_helper(milvus::SearchResult& search_result, std::memmove(&search_result.seg_offsets_[pos + 1], &search_result.seg_offsets_[pos], (topk - pos) * sizeof(int64_t)); + if (array_offsets != nullptr) { + std::memmove(&search_result.element_indices_[pos + 1], + &search_result.element_indices_[pos], + (topk - pos) * sizeof(int32_t)); + } + } + search_result.seg_offsets_[pos] = doc_id; + if (array_offsets != nullptr) { + search_result.element_indices_[pos] = elem_idx; } - search_result.seg_offsets_[pos] = offsets[i]; search_result.distances_[pos] = distances[i]; ++topk; } @@ -178,10 +199,31 @@ PhyIterativeFilterNode::GetOutput() { search_result.total_nq_, "Vector Iterators' count must be equal to total_nq_, Check " "your code"); + + bool element_level = search_result.element_level_; + auto array_offsets = query_context_->get_array_offsets(); + + // For element-level, we need array_offsets to convert element_id → doc_id + if (element_level) { + AssertInfo( + array_offsets != nullptr, + "Array offsets required for element-level iterative filter"); + } + int nq_index = 0; search_result.seg_offsets_.resize(nq * unity_topk, INVALID_SEG_OFFSET); search_result.distances_.resize(nq * unity_topk); + if (element_level) { + search_result.element_indices_.resize(nq * unity_topk, -1); + } + + // Reuse memory allocation across batches and nqs + FixedVector doc_offsets; + std::vector element_to_doc_mapping; + std::unordered_map doc_eval_cache; + std::unordered_set unique_doc_ids; + for (auto& iterator : search_result.vector_iterators_.value()) { EvalCtx eval_ctx(operator_context_->get_exec_context(), exprs_.get()); @@ -208,8 +250,35 @@ PhyIterativeFilterNode::GetOutput() { break; } } + + // Clear but retain capacity + doc_offsets.clear(); + element_to_doc_mapping.clear(); + doc_eval_cache.clear(); + unique_doc_ids.clear(); + + if (element_level) { + // 1. Convert element_ids to doc_ids and do filter on those doc_ids + // 2. element_ids with doc_ids that pass the filter are what we interested in + element_to_doc_mapping.reserve(offsets.size()); + + for (auto element_id : offsets) { + auto [doc_id, elem_index] = + array_offsets->ElementIDToRowID(element_id); + element_to_doc_mapping.push_back(doc_id); + unique_doc_ids.insert(doc_id); + } + + doc_offsets.reserve(unique_doc_ids.size()); + for (auto doc_id : unique_doc_ids) { + doc_offsets.emplace_back(static_cast(doc_id)); + } + } else { + doc_offsets = offsets; + } + if (is_native_supported_) { - eval_ctx.set_offset_input(&offsets); + eval_ctx.set_offset_input(&doc_offsets); std::vector results; exprs_->Eval(0, 1, true, eval_ctx, results); AssertInfo( @@ -223,24 +292,52 @@ PhyIterativeFilterNode::GetOutput() { auto col_vec_size = col_vec->size(); TargetBitmapView bitsetview(col_vec->GetRawData(), col_vec_size); - Assert(bitsetview.size() <= batch_size); - Assert(bitsetview.size() == offsets.size()); - for (auto i = 0; i < offsets.size(); ++i) { - if (bitsetview[i] > 0) { - insert_helper(search_result, - topk, - large_is_better, - distances, - offsets, - nq_index, - unity_topk, - i); - if (topk == unity_topk) { - break; + + if (element_level) { + Assert(bitsetview.size() == doc_offsets.size()); + for (size_t i = 0; i < doc_offsets.size(); ++i) { + doc_eval_cache[doc_offsets[i]] = + (bitsetview[i] > 0); + } + + for (size_t i = 0; i < offsets.size(); ++i) { + int64_t doc_id = element_to_doc_mapping[i]; + if (doc_eval_cache[doc_id]) { + insert_helper(search_result, + topk, + large_is_better, + distances, + offsets, + nq_index, + unity_topk, + i, + array_offsets.get()); + if (topk == unity_topk) { + break; + } + } + } + } else { + Assert(bitsetview.size() <= batch_size); + Assert(bitsetview.size() == offsets.size()); + for (auto i = 0; i < offsets.size(); ++i) { + if (bitsetview[i]) { + insert_helper(search_result, + topk, + large_is_better, + distances, + offsets, + nq_index, + unity_topk, + i); + if (topk == unity_topk) { + break; + } } } } } else { + Assert(!element_level); for (auto i = 0; i < offsets.size(); ++i) { if (bitset[offsets[i]] > 0) { insert_helper(search_result, diff --git a/internal/core/src/exec/operator/VectorSearchNode.cpp b/internal/core/src/exec/operator/VectorSearchNode.cpp index 76ecbd84f1..ae1033bc1f 100644 --- a/internal/core/src/exec/operator/VectorSearchNode.cpp +++ b/internal/core/src/exec/operator/VectorSearchNode.cpp @@ -17,6 +17,8 @@ #include "VectorSearchNode.h" #include "common/Tracer.h" #include "fmt/format.h" +#include "common/ArrayOffsets.h" +#include "exec/operator/Utils.h" #include "monitor/Monitor.h" namespace milvus { @@ -80,10 +82,43 @@ PhyVectorSearchNode::GetOutput() { auto src_data = ph.get_blob(); auto src_offsets = ph.get_offsets(); auto num_queries = ph.num_of_queries_; + std::shared_ptr array_offsets = nullptr; + if (ph.element_level_) { + array_offsets = segment_->GetArrayOffsets(search_info_.field_id_); + AssertInfo(array_offsets != nullptr, "Array offsets not available"); + query_context_->set_array_offsets(array_offsets); + search_info_.array_offsets_ = array_offsets; + } + + // There are two types of execution: pre-filter and iterative filter + // For **pre-filter**, we have execution path: FilterBitsNode -> MvccNode -> ElementFilterBitsNode -> VectorSearchNode -> ... + // For **iterative filter**, we have execution path: MvccNode -> VectorSearchNode -> ElementFilterNode -> FilterNode -> ... + // + // When embedding search embedding on embedding list is used, which means element_level_ is true, we need to transform doc-level + // bitset to element-level bitset. In pre-filter path, ElementFilterBitsNode already transforms the bitset. We need to transform it + // in iterative filter path. + if (milvus::exec::UseVectorIterator(search_info_) && ph.element_level_) { + auto col_input = GetColumnVector(input_); + TargetBitmapView view(col_input->GetRawData(), col_input->size()); + TargetBitmapView valid_view(col_input->GetValidRawData(), + col_input->size()); + + auto [element_bitset, valid_element_bitset] = + array_offsets->RowBitsetToElementBitset(view, valid_view); + + query_context_->set_active_element_count(element_bitset.size()); + + std::vector col_res; + col_res.push_back(std::make_shared( + std::move(element_bitset), std::move(valid_element_bitset))); + input_ = std::make_shared(col_res); + } + milvus::SearchResult search_result; auto col_input = GetColumnVector(input_); TargetBitmapView view(col_input->GetRawData(), col_input->size()); + if (view.all()) { query_context_->set_search_result( std::move(empty_search_result(num_queries))); @@ -94,6 +129,7 @@ PhyVectorSearchNode::GetOutput() { milvus::BitsetView final_view((uint8_t*)col_input->GetRawData(), col_input->size()); auto op_context = query_context_->get_op_context(); + // todo(SpadeA): need to pass element_level to make check more rigorously? segment_->vector_search(search_info_, src_data, src_offsets, @@ -104,6 +140,7 @@ PhyVectorSearchNode::GetOutput() { search_result); search_result.total_data_cnt_ = final_view.size(); + search_result.element_level_ = ph.element_level_; span.GetSpan()->SetAttribute( "result_count", static_cast(search_result.seg_offsets_.size())); diff --git a/internal/core/src/expr/ITypeExpr.h b/internal/core/src/expr/ITypeExpr.h index 047977a424..27a7ddce62 100644 --- a/internal/core/src/expr/ITypeExpr.h +++ b/internal/core/src/expr/ITypeExpr.h @@ -118,6 +118,7 @@ struct ColumnInfo { DataType element_type_; std::vector nested_path_; bool nullable_; + bool element_level_; ColumnInfo(const proto::plan::ColumnInfo& column_info) : field_id_(column_info.field_id()), @@ -125,7 +126,8 @@ struct ColumnInfo { element_type_(static_cast(column_info.element_type())), nested_path_(column_info.nested_path().begin(), column_info.nested_path().end()), - nullable_(column_info.nullable()) { + nullable_(column_info.nullable()), + element_level_(column_info.is_element_level()) { } ColumnInfo(FieldId field_id, @@ -136,7 +138,8 @@ struct ColumnInfo { data_type_(data_type), element_type_(DataType::NONE), nested_path_(std::move(nested_path)), - nullable_(nullable) { + nullable_(nullable), + element_level_(false) { } ColumnInfo(FieldId field_id, @@ -148,7 +151,8 @@ struct ColumnInfo { data_type_(data_type), element_type_(element_type), nested_path_(std::move(nested_path)), - nullable_(nullable) { + nullable_(nullable), + element_level_(false) { } bool @@ -165,6 +169,10 @@ struct ColumnInfo { return false; } + if (element_level_ != other.element_level_) { + return false; + } + for (int i = 0; i < nested_path_.size(); ++i) { if (nested_path_[i] != other.nested_path_[i]) { return false; @@ -180,21 +188,25 @@ struct ColumnInfo { data_type_, element_type_, nested_path_, - nullable_) < std::tie(other.field_id_, - other.data_type_, - other.element_type_, - other.nested_path_, - other.nullable_); + nullable_, + element_level_) < std::tie(other.field_id_, + other.data_type_, + other.element_type_, + other.nested_path_, + other.nullable_, + other.element_level_); } std::string ToString() const { return fmt::format( - "[FieldId:{}, data_type:{}, element_type:{}, nested_path:{}]", + "[FieldId:{}, data_type:{}, element_type:{}, nested_path:{}, " + "element_level:{}]", std::to_string(field_id_.get()), data_type_, element_type_, - milvus::Join(nested_path_, ",")); + milvus::Join(nested_path_, ","), + element_level_); } }; diff --git a/internal/core/src/plan/PlanNode.h b/internal/core/src/plan/PlanNode.h index 0328ca522d..6dd6754799 100644 --- a/internal/core/src/plan/PlanNode.h +++ b/internal/core/src/plan/PlanNode.h @@ -183,6 +183,126 @@ class FilterBitsNode : public PlanNode { const expr::TypedExprPtr filter_; }; +class ElementFilterNode : public PlanNode { + public: + ElementFilterNode(const PlanNodeId& id, + expr::TypedExprPtr element_filter, + std::string struct_name, + std::vector sources) + : PlanNode(id), + sources_{std::move(sources)}, + element_filter_(std::move(element_filter)), + struct_name_(std::move(struct_name)) { + AssertInfo( + element_filter_->type() == DataType::BOOL, + fmt::format( + "Element filter expression must be of type BOOLEAN, Got {}", + element_filter_->type())); + } + + DataType + output_type() const override { + return DataType::NONE; + } + + std::vector + sources() const override { + return sources_; + } + + const expr::TypedExprPtr& + element_filter() const { + return element_filter_; + } + + const std::string& + struct_name() const { + return struct_name_; + } + + std::string_view + name() const override { + return "ElementFilter"; + } + + std::string + ToString() const override { + return fmt::format( + "ElementFilterNode:\n\t[struct_name:{}, element_filter:{}]", + struct_name_, + element_filter_->ToString()); + } + + private: + const std::vector sources_; + const expr::TypedExprPtr element_filter_; + const std::string struct_name_; +}; + +class ElementFilterBitsNode : public PlanNode { + public: + ElementFilterBitsNode( + const PlanNodeId& id, + expr::TypedExprPtr element_filter, + std::string struct_name, + std::vector sources = std::vector{}) + : PlanNode(id), + sources_{std::move(sources)}, + element_filter_(std::move(element_filter)), + struct_name_(std::move(struct_name)) { + AssertInfo( + element_filter_->type() == DataType::BOOL, + fmt::format( + "Element filter expression must be of type BOOLEAN, Got {}", + element_filter_->type())); + } + + DataType + output_type() const override { + return DataType::BOOL; + } + + std::vector + sources() const override { + return sources_; + } + + const expr::TypedExprPtr& + element_filter() const { + return element_filter_; + } + + const std::string& + struct_name() const { + return struct_name_; + } + + std::string_view + name() const override { + return "ElementFilterBits"; + } + + std::string + ToString() const override { + return fmt::format( + "ElementFilterBitsNode:\n\t[struct_name:{}, element_filter:{}]", + struct_name_, + element_filter_->ToString()); + } + + expr::ExprInfo + GatherInfo() const override { + expr::ExprInfo info; + element_filter_->GatherInfo(info); + return info; + } + + private: + const std::vector sources_; + const expr::TypedExprPtr element_filter_; + const std::string struct_name_; +}; + class MvccNode : public PlanNode { public: MvccNode(const PlanNodeId& id, diff --git a/internal/core/src/query/ExecPlanNodeVisitor.cpp b/internal/core/src/query/ExecPlanNodeVisitor.cpp index f918c475ec..87829aca72 100644 --- a/internal/core/src/query/ExecPlanNodeVisitor.cpp +++ b/internal/core/src/query/ExecPlanNodeVisitor.cpp @@ -55,7 +55,12 @@ ExecPlanNodeVisitor::ExecuteTask( for (;;) { auto result = task->Next(); if (!result) { - Assert(processed_num == query_context->get_active_count()); + if (query_context->get_active_element_count() > 0) { + Assert(processed_num == + query_context->get_active_element_count()); + } else { + Assert(processed_num == query_context->get_active_count()); + } break; } auto childrens = result->childrens(); diff --git a/internal/core/src/query/Plan.cpp b/internal/core/src/query/Plan.cpp index 00f300a061..81f133c269 100644 --- a/internal/core/src/query/Plan.cpp +++ b/internal/core/src/query/Plan.cpp @@ -31,29 +31,37 @@ ParsePlaceholderGroup(const Plan* plan, } bool -check_data_type(const FieldMeta& field_meta, - const milvus::proto::common::PlaceholderType type) { +check_data_type( + const FieldMeta& field_meta, + const milvus::proto::common::PlaceholderValue& placeholder_value) { if (field_meta.get_data_type() == DataType::VECTOR_ARRAY) { if (field_meta.get_element_type() == DataType::VECTOR_FLOAT) { - return type == - milvus::proto::common::PlaceholderType::EmbListFloatVector; + if (placeholder_value.element_level()) { + return placeholder_value.type() == + milvus::proto::common::PlaceholderType::FloatVector; + } else { + return placeholder_value.type() == + milvus::proto::common::PlaceholderType:: + EmbListFloatVector; + } } else if (field_meta.get_element_type() == DataType::VECTOR_FLOAT16) { - return type == + return placeholder_value.type() == milvus::proto::common::PlaceholderType::EmbListFloat16Vector; } else if (field_meta.get_element_type() == DataType::VECTOR_BFLOAT16) { - return type == milvus::proto::common::PlaceholderType:: - EmbListBFloat16Vector; + return placeholder_value.type() == + milvus::proto::common::PlaceholderType:: + EmbListBFloat16Vector; } else if (field_meta.get_element_type() == DataType::VECTOR_BINARY) { - return type == + return placeholder_value.type() == milvus::proto::common::PlaceholderType::EmbListBinaryVector; } else if (field_meta.get_element_type() == DataType::VECTOR_INT8) { - return type == + return placeholder_value.type() == milvus::proto::common::PlaceholderType::EmbListInt8Vector; } return false; } return static_cast(field_meta.get_data_type()) == - static_cast(type); + static_cast(placeholder_value.type()); } std::unique_ptr @@ -64,30 +72,33 @@ ParsePlaceholderGroup(const Plan* plan, milvus::proto::common::PlaceholderGroup ph_group; auto ok = ph_group.ParseFromArray(blob, blob_len); Assert(ok); - for (auto& info : ph_group.placeholders()) { + for (auto& ph : ph_group.placeholders()) { Placeholder element; - element.tag_ = info.tag(); + element.tag_ = ph.tag(); + element.element_level_ = ph.element_level(); Assert(plan->tag2field_.count(element.tag_)); auto field_id = plan->tag2field_.at(element.tag_); auto& field_meta = plan->schema_->operator[](field_id); - AssertInfo(check_data_type(field_meta, info.type()), + AssertInfo(check_data_type(field_meta, ph), "vector type must be the same, field {} - type {}, search " - "info type {}", + "ph type {}", field_meta.get_name().get(), field_meta.get_data_type(), - static_cast(info.type())); - element.num_of_queries_ = info.values_size(); + static_cast(ph.type())); + element.num_of_queries_ = ph.values_size(); AssertInfo(element.num_of_queries_ > 0, "must have queries"); - if (info.type() == + if (ph.type() == milvus::proto::common::PlaceholderType::SparseFloatVector) { element.sparse_matrix_ = - SparseBytesToRows(info.values(), /*validate=*/true); + SparseBytesToRows(ph.values(), /*validate=*/true); } else { - auto line_size = info.values().Get(0).size(); + auto line_size = ph.values().Get(0).size(); auto& target = element.blob_; - if (field_meta.get_data_type() != DataType::VECTOR_ARRAY) { - if (field_meta.get_sizeof() != line_size) { + if (field_meta.get_data_type() != DataType::VECTOR_ARRAY || + ph.element_level()) { + if (field_meta.get_sizeof() != line_size && + !ph.element_level()) { ThrowInfo(DimNotMatch, fmt::format( "vector dimension mismatch, expected vector " @@ -96,7 +107,7 @@ ParsePlaceholderGroup(const Plan* plan, line_size)); } target.reserve(line_size * element.num_of_queries_); - for (auto& line : info.values()) { + for (auto& line : ph.values()) { AssertInfo(line_size == line.size(), "vector dimension mismatch, expected vector " "size(byte) {}, actual {}.", @@ -118,7 +129,7 @@ ParsePlaceholderGroup(const Plan* plan, auto bytes_per_vec = milvus::vector_bytes_per_element( field_meta.get_element_type(), dim); - for (auto& line : info.values()) { + for (auto& line : ph.values()) { target.insert(target.end(), line.begin(), line.end()); AssertInfo( line.size() % bytes_per_vec == 0, diff --git a/internal/core/src/query/PlanImpl.h b/internal/core/src/query/PlanImpl.h index 1ade71c335..c0c7b7ff86 100644 --- a/internal/core/src/query/PlanImpl.h +++ b/internal/core/src/query/PlanImpl.h @@ -85,6 +85,7 @@ struct Placeholder { sparse_matrix_; // offsets for embedding list aligned_vector offsets_; + bool element_level_{false}; const void* get_blob() const { diff --git a/internal/core/src/query/PlanProto.cpp b/internal/core/src/query/PlanProto.cpp index b2cd65f4e2..f63259f633 100644 --- a/internal/core/src/query/PlanProto.cpp +++ b/internal/core/src/query/PlanProto.cpp @@ -63,162 +63,201 @@ MergeExprWithNamespace(const SchemaPtr schema, return and_expr; } +SearchInfo +ProtoParser::ParseSearchInfo(const planpb::VectorANNS& anns_proto) { + SearchInfo search_info; + auto& query_info_proto = anns_proto.query_info(); + auto field_id = FieldId(anns_proto.field_id()); + search_info.field_id_ = field_id; + + search_info.metric_type_ = query_info_proto.metric_type(); + search_info.topk_ = query_info_proto.topk(); + search_info.round_decimal_ = query_info_proto.round_decimal(); + search_info.search_params_ = + nlohmann::json::parse(query_info_proto.search_params()); + search_info.materialized_view_involved = + query_info_proto.materialized_view_involved(); + // currently, iterative filter does not support range search + if (!search_info.search_params_.contains(RADIUS)) { + if (query_info_proto.hints() != "") { + if (query_info_proto.hints() == "disable") { + search_info.iterative_filter_execution = false; + } else if (query_info_proto.hints() == ITERATIVE_FILTER) { + search_info.iterative_filter_execution = true; + } else { + // check if hints is valid + ThrowInfo(ConfigInvalid, + "hints: {} not supported", + query_info_proto.hints()); + } + } else if (search_info.search_params_.contains(HINTS)) { + if (search_info.search_params_[HINTS] == ITERATIVE_FILTER) { + search_info.iterative_filter_execution = true; + } else { + // check if hints is valid + ThrowInfo(ConfigInvalid, + "hints: {} not supported", + search_info.search_params_[HINTS]); + } + } + } + + if (query_info_proto.bm25_avgdl() > 0) { + search_info.search_params_[knowhere::meta::BM25_AVGDL] = + query_info_proto.bm25_avgdl(); + } + + if (query_info_proto.group_by_field_id() > 0) { + auto group_by_field_id = FieldId(query_info_proto.group_by_field_id()); + search_info.group_by_field_id_ = group_by_field_id; + search_info.group_size_ = query_info_proto.group_size() > 0 + ? query_info_proto.group_size() + : 1; + search_info.strict_group_size_ = query_info_proto.strict_group_size(); + // Always set json_path to distinguish between unset and empty string + // Empty string means accessing the entire JSON object + search_info.json_path_ = query_info_proto.json_path(); + if (query_info_proto.json_type() != + milvus::proto::schema::DataType::None) { + search_info.json_type_ = + static_cast(query_info_proto.json_type()); + } + search_info.strict_cast_ = query_info_proto.strict_cast(); + } + + if (query_info_proto.has_search_iterator_v2_info()) { + auto& iterator_v2_info_proto = + query_info_proto.search_iterator_v2_info(); + search_info.iterator_v2_info_ = SearchIteratorV2Info{ + .token = iterator_v2_info_proto.token(), + .batch_size = iterator_v2_info_proto.batch_size(), + }; + if (iterator_v2_info_proto.has_last_bound()) { + search_info.iterator_v2_info_->last_bound = + iterator_v2_info_proto.last_bound(); + } + } + + return search_info; +} + std::unique_ptr ProtoParser::PlanNodeFromProto(const planpb::PlanNode& plan_node_proto) { Assert(plan_node_proto.has_vector_anns()); auto& anns_proto = plan_node_proto.vector_anns(); - auto expr_parser = [&]() -> plan::PlanNodePtr { - auto expr = ParseExprs(anns_proto.predicates()); - if (plan_node_proto.has_namespace_()) { - expr = MergeExprWithNamespace( - schema, expr, plan_node_proto.namespace_()); - } - return std::make_shared( - milvus::plan::GetNextPlanNodeId(), expr); - }; - - auto search_info_parser = [&]() -> SearchInfo { - SearchInfo search_info; - auto& query_info_proto = anns_proto.query_info(); - auto field_id = FieldId(anns_proto.field_id()); - search_info.field_id_ = field_id; - - search_info.metric_type_ = query_info_proto.metric_type(); - search_info.topk_ = query_info_proto.topk(); - search_info.round_decimal_ = query_info_proto.round_decimal(); - search_info.search_params_ = - nlohmann::json::parse(query_info_proto.search_params()); - search_info.materialized_view_involved = - query_info_proto.materialized_view_involved(); - // currently, iterative filter does not support range search - if (!search_info.search_params_.contains(RADIUS)) { - if (query_info_proto.hints() != "") { - if (query_info_proto.hints() == "disable") { - search_info.iterative_filter_execution = false; - } else if (query_info_proto.hints() == ITERATIVE_FILTER) { - search_info.iterative_filter_execution = true; - } else { - // check if hints is valid - ThrowInfo(ConfigInvalid, - "hints: {} not supported", - query_info_proto.hints()); - } - } else if (search_info.search_params_.contains(HINTS)) { - if (search_info.search_params_[HINTS] == ITERATIVE_FILTER) { - search_info.iterative_filter_execution = true; - } else { - // check if hints is valid - ThrowInfo(ConfigInvalid, - "hints: {} not supported", - search_info.search_params_[HINTS]); - } - } - } - - if (query_info_proto.bm25_avgdl() > 0) { - search_info.search_params_[knowhere::meta::BM25_AVGDL] = - query_info_proto.bm25_avgdl(); - } - - if (query_info_proto.group_by_field_id() > 0) { - auto group_by_field_id = - FieldId(query_info_proto.group_by_field_id()); - search_info.group_by_field_id_ = group_by_field_id; - search_info.group_size_ = query_info_proto.group_size() > 0 - ? query_info_proto.group_size() - : 1; - search_info.strict_group_size_ = - query_info_proto.strict_group_size(); - // Always set json_path to distinguish between unset and empty string - // Empty string means accessing the entire JSON object - search_info.json_path_ = query_info_proto.json_path(); - if (query_info_proto.json_type() != - milvus::proto::schema::DataType::None) { - search_info.json_type_ = - static_cast(query_info_proto.json_type()); - } - search_info.strict_cast_ = query_info_proto.strict_cast(); - } - - if (query_info_proto.has_search_iterator_v2_info()) { - auto& iterator_v2_info_proto = - query_info_proto.search_iterator_v2_info(); - search_info.iterator_v2_info_ = SearchIteratorV2Info{ - .token = iterator_v2_info_proto.token(), - .batch_size = iterator_v2_info_proto.batch_size(), - }; - if (iterator_v2_info_proto.has_last_bound()) { - search_info.iterator_v2_info_->last_bound = - iterator_v2_info_proto.last_bound(); - } - } - - return search_info; - }; - + // Parse search information from proto auto plan_node = std::make_unique(); plan_node->placeholder_tag_ = anns_proto.placeholder_tag(); - plan_node->search_info_ = std::move(search_info_parser()); + plan_node->search_info_ = ParseSearchInfo(anns_proto); milvus::plan::PlanNodePtr plannode; std::vector sources; - // mvcc node -> vector search node -> iterative filter node - auto iterative_filter_plan = [&]() { - plannode = std::make_shared( - milvus::plan::GetNextPlanNodeId()); - sources = std::vector{plannode}; - plannode = std::make_shared( - milvus::plan::GetNextPlanNodeId(), sources); - sources = std::vector{plannode}; - - auto expr = ParseExprs(anns_proto.predicates()); - if (plan_node_proto.has_namespace_()) { - expr = MergeExprWithNamespace( - schema, expr, plan_node_proto.namespace_()); - } - plannode = std::make_shared( - milvus::plan::GetNextPlanNodeId(), expr, sources); - sources = std::vector{plannode}; - }; - - // pre filter node -> mvcc node -> vector search node - auto pre_filter_plan = [&]() { - plannode = std::move(expr_parser()); - if (plan_node->search_info_.materialized_view_involved) { - const auto expr_info = plannode->GatherInfo(); - knowhere::MaterializedViewSearchInfo materialized_view_search_info; - for (const auto& [expr_field_id, vals] : - expr_info.field_id_to_values) { - materialized_view_search_info - .field_id_to_touched_categories_cnt[expr_field_id] = - vals.size(); - } - materialized_view_search_info.is_pure_and = expr_info.is_pure_and; - materialized_view_search_info.has_not = expr_info.has_not; - - plan_node->search_info_ - .search_params_[knowhere::meta::MATERIALIZED_VIEW_SEARCH_INFO] = - materialized_view_search_info; - } - sources = std::vector{plannode}; - plannode = std::make_shared( - milvus::plan::GetNextPlanNodeId(), sources); - sources = std::vector{plannode}; - - plannode = std::make_shared( - milvus::plan::GetNextPlanNodeId(), sources); - sources = std::vector{plannode}; - }; - + // Build plan node chain based on predicate and filter execution strategy if (anns_proto.has_predicates()) { - // currently limit iterative filter scope to search only - if (plan_node->search_info_.iterative_filter_execution && - plan_node->search_info_.group_by_field_id_ == std::nullopt) { - iterative_filter_plan(); + auto* predicate_proto = &anns_proto.predicates(); + bool is_element_level = predicate_proto->expr_case() == + proto::plan::Expr::kElementFilterExpr; + + // Parse expressions based on filter type (similar to RandomSampleExpr pattern) + expr::TypedExprPtr element_expr = nullptr; + expr::TypedExprPtr doc_expr = nullptr; + std::string struct_name; + + if (is_element_level) { + // Element-level query: extract both element_expr and optional doc-level predicate + auto& element_filter_expr = predicate_proto->element_filter_expr(); + element_expr = ParseExprs(element_filter_expr.element_expr()); + struct_name = element_filter_expr.struct_name(); + + if (element_filter_expr.has_predicate()) { + doc_expr = ParseExprs(element_filter_expr.predicate()); + if (plan_node_proto.has_namespace_()) { + doc_expr = MergeExprWithNamespace( + schema, doc_expr, plan_node_proto.namespace_()); + } + } } else { - pre_filter_plan(); + // Document-level query: only doc expr + doc_expr = ParseExprs(anns_proto.predicates()); + if (plan_node_proto.has_namespace_()) { + doc_expr = MergeExprWithNamespace( + schema, doc_expr, plan_node_proto.namespace_()); + } + } + + bool is_iterative = + plan_node->search_info_.iterative_filter_execution && + plan_node->search_info_.group_by_field_id_ == std::nullopt; + if (is_iterative) { + plannode = std::make_shared( + milvus::plan::GetNextPlanNodeId()); + sources = std::vector{plannode}; + + plannode = std::make_shared( + milvus::plan::GetNextPlanNodeId(), sources); + sources = std::vector{plannode}; + + // Add element-level filter if needed + if (is_element_level) { + plannode = std::make_shared( + milvus::plan::GetNextPlanNodeId(), + element_expr, + struct_name, + sources); + sources = std::vector{plannode}; + } + + // Add doc-level filter if present + if (doc_expr) { + plannode = std::make_shared( + milvus::plan::GetNextPlanNodeId(), doc_expr, sources); + sources = std::vector{plannode}; + } + } else { + if (doc_expr) { + plannode = std::make_shared( + milvus::plan::GetNextPlanNodeId(), doc_expr); + sources = std::vector{plannode}; + + if (!is_element_level && + plan_node->search_info_.materialized_view_involved) { + const auto expr_info = plannode->GatherInfo(); + knowhere::MaterializedViewSearchInfo + materialized_view_search_info; + for (const auto& [expr_field_id, vals] : + expr_info.field_id_to_values) { + materialized_view_search_info + .field_id_to_touched_categories_cnt[expr_field_id] = + vals.size(); + } + materialized_view_search_info.is_pure_and = + expr_info.is_pure_and; + materialized_view_search_info.has_not = expr_info.has_not; + + plan_node->search_info_.search_params_ + [knowhere::meta::MATERIALIZED_VIEW_SEARCH_INFO] = + materialized_view_search_info; + } + } + + plannode = std::make_shared( + milvus::plan::GetNextPlanNodeId(), sources); + sources = std::vector{plannode}; + + if (is_element_level) { + plannode = std::make_shared( + milvus::plan::GetNextPlanNodeId(), + element_expr, + struct_name, + sources); + sources = std::vector{plannode}; + } + + plannode = std::make_shared( + milvus::plan::GetNextPlanNodeId(), sources); + sources = std::vector{plannode}; } } else { // no filter, force set iterative filter hint to false, go with normal vector search path @@ -400,8 +439,16 @@ expr::TypedExprPtr ProtoParser::ParseUnaryRangeExprs(const proto::plan::UnaryRangeExpr& expr_pb) { auto& column_info = expr_pb.column_info(); auto field_id = FieldId(column_info.field_id()); - auto data_type = schema->operator[](field_id).get_data_type(); - Assert(data_type == static_cast(column_info.data_type())); + auto& field = schema->operator[](field_id); + auto data_type = field.get_data_type(); + + if (column_info.is_element_level()) { + Assert(data_type == DataType::ARRAY); + Assert(field.get_element_type() == + static_cast(column_info.data_type())); + } else { + Assert(data_type == static_cast(column_info.data_type())); + } std::vector<::milvus::proto::plan::GenericValue> extra_values; for (auto val : expr_pb.extra_values()) { extra_values.emplace_back(val); @@ -417,8 +464,16 @@ expr::TypedExprPtr ProtoParser::ParseNullExprs(const proto::plan::NullExpr& expr_pb) { auto& column_info = expr_pb.column_info(); auto field_id = FieldId(column_info.field_id()); - auto data_type = schema->operator[](field_id).get_data_type(); - Assert(data_type == static_cast(column_info.data_type())); + auto& field = schema->operator[](field_id); + auto data_type = field.get_data_type(); + + if (column_info.is_element_level()) { + Assert(data_type == DataType::ARRAY); + Assert(field.get_element_type() == + static_cast(column_info.data_type())); + } else { + Assert(data_type == static_cast(column_info.data_type())); + } return std::make_shared( expr::ColumnInfo(column_info), expr_pb.op()); } @@ -428,8 +483,15 @@ ProtoParser::ParseBinaryRangeExprs( const proto::plan::BinaryRangeExpr& expr_pb) { auto& columnInfo = expr_pb.column_info(); auto field_id = FieldId(columnInfo.field_id()); - auto data_type = schema->operator[](field_id).get_data_type(); - Assert(data_type == (DataType)columnInfo.data_type()); + auto& field = schema->operator[](field_id); + auto data_type = field.get_data_type(); + + if (columnInfo.is_element_level()) { + Assert(data_type == DataType::ARRAY); + Assert(field.get_element_type() == (DataType)columnInfo.data_type()); + } else { + Assert(data_type == (DataType)columnInfo.data_type()); + } return std::make_shared( columnInfo, expr_pb.lower_value(), @@ -443,8 +505,15 @@ ProtoParser::ParseTimestamptzArithCompareExprs( const proto::plan::TimestamptzArithCompareExpr& expr_pb) { auto& columnInfo = expr_pb.timestamptz_column(); auto field_id = FieldId(columnInfo.field_id()); - auto data_type = schema->operator[](field_id).get_data_type(); - Assert(data_type == (DataType)columnInfo.data_type()); + auto& field = schema->operator[](field_id); + auto data_type = field.get_data_type(); + + if (columnInfo.is_element_level()) { + Assert(data_type == DataType::ARRAY); + Assert(field.get_element_type() == (DataType)columnInfo.data_type()); + } else { + Assert(data_type == (DataType)columnInfo.data_type()); + } return std::make_shared( columnInfo, expr_pb.arith_op(), @@ -453,6 +522,17 @@ ProtoParser::ParseTimestamptzArithCompareExprs( expr_pb.compare_value()); } +expr::TypedExprPtr +ProtoParser::ParseElementFilterExprs( + const proto::plan::ElementFilterExpr& expr_pb) { + // ElementFilterExpr is not a regular expression that can be evaluated directly. + // It should be handled at the PlanNode level (in PlanNodeFromProto). + // This method should never be called. + ThrowInfo(ExprInvalid, + "ParseElementFilterExprs should not be called directly. " + "ElementFilterExpr must be handled at PlanNode level."); +} + expr::TypedExprPtr ProtoParser::ParseCallExprs(const proto::plan::CallExpr& expr_pb) { std::vector parameters; @@ -480,15 +560,31 @@ expr::TypedExprPtr ProtoParser::ParseCompareExprs(const proto::plan::CompareExpr& expr_pb) { auto& left_column_info = expr_pb.left_column_info(); auto left_field_id = FieldId(left_column_info.field_id()); - auto left_data_type = schema->operator[](left_field_id).get_data_type(); - Assert(left_data_type == - static_cast(left_column_info.data_type())); + auto& left_field = schema->operator[](left_field_id); + auto left_data_type = left_field.get_data_type(); + + if (left_column_info.is_element_level()) { + Assert(left_data_type == DataType::ARRAY); + Assert(left_field.get_element_type() == + static_cast(left_column_info.data_type())); + } else { + Assert(left_data_type == + static_cast(left_column_info.data_type())); + } auto& right_column_info = expr_pb.right_column_info(); auto right_field_id = FieldId(right_column_info.field_id()); - auto right_data_type = schema->operator[](right_field_id).get_data_type(); - Assert(right_data_type == - static_cast(right_column_info.data_type())); + auto& right_field = schema->operator[](right_field_id); + auto right_data_type = right_field.get_data_type(); + + if (right_column_info.is_element_level()) { + Assert(right_data_type == DataType::ARRAY); + Assert(right_field.get_element_type() == + static_cast(right_column_info.data_type())); + } else { + Assert(right_data_type == + static_cast(right_column_info.data_type())); + } return std::make_shared(left_field_id, right_field_id, @@ -501,8 +597,15 @@ expr::TypedExprPtr ProtoParser::ParseTermExprs(const proto::plan::TermExpr& expr_pb) { auto& columnInfo = expr_pb.column_info(); auto field_id = FieldId(columnInfo.field_id()); - auto data_type = schema->operator[](field_id).get_data_type(); - Assert(data_type == (DataType)columnInfo.data_type()); + auto& field = schema->operator[](field_id); + auto data_type = field.get_data_type(); + + if (columnInfo.is_element_level()) { + Assert(data_type == DataType::ARRAY); + Assert(field.get_element_type() == (DataType)columnInfo.data_type()); + } else { + Assert(data_type == (DataType)columnInfo.data_type()); + } std::vector<::milvus::proto::plan::GenericValue> values; for (size_t i = 0; i < expr_pb.values_size(); i++) { values.emplace_back(expr_pb.values(i)); @@ -532,8 +635,16 @@ ProtoParser::ParseBinaryArithOpEvalRangeExprs( const proto::plan::BinaryArithOpEvalRangeExpr& expr_pb) { auto& column_info = expr_pb.column_info(); auto field_id = FieldId(column_info.field_id()); - auto data_type = schema->operator[](field_id).get_data_type(); - Assert(data_type == static_cast(column_info.data_type())); + auto& field = schema->operator[](field_id); + auto data_type = field.get_data_type(); + + if (column_info.is_element_level()) { + Assert(data_type == DataType::ARRAY); + Assert(field.get_element_type() == + static_cast(column_info.data_type())); + } else { + Assert(data_type == static_cast(column_info.data_type())); + } return std::make_shared( column_info, expr_pb.op(), @@ -546,8 +657,16 @@ expr::TypedExprPtr ProtoParser::ParseExistExprs(const proto::plan::ExistsExpr& expr_pb) { auto& column_info = expr_pb.info(); auto field_id = FieldId(column_info.field_id()); - auto data_type = schema->operator[](field_id).get_data_type(); - Assert(data_type == static_cast(column_info.data_type())); + auto& field = schema->operator[](field_id); + auto data_type = field.get_data_type(); + + if (column_info.is_element_level()) { + Assert(data_type == DataType::ARRAY); + Assert(field.get_element_type() == + static_cast(column_info.data_type())); + } else { + Assert(data_type == static_cast(column_info.data_type())); + } return std::make_shared(column_info); } @@ -556,8 +675,15 @@ ProtoParser::ParseJsonContainsExprs( const proto::plan::JSONContainsExpr& expr_pb) { auto& columnInfo = expr_pb.column_info(); auto field_id = FieldId(columnInfo.field_id()); - auto data_type = schema->operator[](field_id).get_data_type(); - Assert(data_type == (DataType)columnInfo.data_type()); + auto& field = schema->operator[](field_id); + auto data_type = field.get_data_type(); + + if (columnInfo.is_element_level()) { + Assert(data_type == DataType::ARRAY); + Assert(field.get_element_type() == (DataType)columnInfo.data_type()); + } else { + Assert(data_type == (DataType)columnInfo.data_type()); + } std::vector<::milvus::proto::plan::GenericValue> values; for (size_t i = 0; i < expr_pb.elements_size(); i++) { values.emplace_back(expr_pb.elements(i)); @@ -584,8 +710,15 @@ ProtoParser::ParseGISFunctionFilterExprs( const proto::plan::GISFunctionFilterExpr& expr_pb) { auto& columnInfo = expr_pb.column_info(); auto field_id = FieldId(columnInfo.field_id()); - auto data_type = schema->operator[](field_id).get_data_type(); - Assert(data_type == (DataType)columnInfo.data_type()); + auto& field = schema->operator[](field_id); + auto data_type = field.get_data_type(); + + if (columnInfo.is_element_level()) { + Assert(data_type == DataType::ARRAY); + Assert(field.get_element_type() == (DataType)columnInfo.data_type()); + } else { + Assert(data_type == (DataType)columnInfo.data_type()); + } auto expr = std::make_shared( columnInfo, expr_pb.op(), expr_pb.wkt_string(), expr_pb.distance()); @@ -671,6 +804,11 @@ ProtoParser::ParseExprs(const proto::plan::Expr& expr_pb, expr_pb.timestamptz_arith_compare_expr()); break; } + case ppe::kElementFilterExpr: { + ThrowInfo(ExprInvalid, + "ElementFilterExpr should be handled at PlanNode level, " + "not in ParseExprs"); + } default: { std::string s; google::protobuf::TextFormat::PrintToString(expr_pb, &s); diff --git a/internal/core/src/query/PlanProto.h b/internal/core/src/query/PlanProto.h index 64643926d5..7471c1e63b 100644 --- a/internal/core/src/query/PlanProto.h +++ b/internal/core/src/query/PlanProto.h @@ -106,6 +106,9 @@ class ProtoParser { ParseTimestamptzArithCompareExprs( const proto::plan::TimestamptzArithCompareExpr& expr_pb); + expr::TypedExprPtr + ParseElementFilterExprs(const proto::plan::ElementFilterExpr& expr_pb); + expr::TypedExprPtr ParseValueExprs(const proto::plan::ValueExpr& expr_pb); @@ -113,6 +116,9 @@ class ProtoParser { PlanOptionsFromProto(const proto::plan::PlanOption& plan_option_proto, PlanOptions& plan_options); + SearchInfo + ParseSearchInfo(const proto::plan::VectorANNS& anns_proto); + private: const SchemaPtr schema; }; diff --git a/internal/core/src/query/SearchBruteForce.cpp b/internal/core/src/query/SearchBruteForce.cpp index ae1a332d40..95ff80aa72 100644 --- a/internal/core/src/query/SearchBruteForce.cpp +++ b/internal/core/src/query/SearchBruteForce.cpp @@ -140,7 +140,7 @@ BruteForceSearch(const dataset::SearchDataset& query_ds, // not gurantee to return exactly `range_search_k` results, which may be more or less. // set it to -1 will return all results in the range. search_cfg[knowhere::meta::RANGE_SEARCH_K] = topk; - sub_result.mutable_seg_offsets().resize(nq * topk); + sub_result.mutable_offsets().resize(nq * topk); sub_result.mutable_distances().resize(nq * topk); // For vector array (embedding list), element type is used to determine how to operate search. @@ -196,8 +196,7 @@ BruteForceSearch(const dataset::SearchDataset& query_ds, auto result = ReGenRangeSearchResult(res.value(), topk, nq, query_ds.metric_type); milvus::tracer::AddEvent("ReGenRangeSearchResult"); - std::copy_n( - GetDatasetIDs(result), nq * topk, sub_result.get_seg_offsets()); + std::copy_n(GetDatasetIDs(result), nq * topk, sub_result.get_offsets()); std::copy_n( GetDatasetDistance(result), nq * topk, sub_result.get_distances()); } else { @@ -206,7 +205,7 @@ BruteForceSearch(const dataset::SearchDataset& query_ds, stat = knowhere::BruteForce::SearchWithBuf( base_dataset, query_dataset, - sub_result.mutable_seg_offsets().data(), + sub_result.mutable_offsets().data(), sub_result.mutable_distances().data(), search_cfg, bitset, @@ -215,7 +214,7 @@ BruteForceSearch(const dataset::SearchDataset& query_ds, stat = knowhere::BruteForce::SearchWithBuf( base_dataset, query_dataset, - sub_result.mutable_seg_offsets().data(), + sub_result.mutable_offsets().data(), sub_result.mutable_distances().data(), search_cfg, bitset, @@ -224,7 +223,7 @@ BruteForceSearch(const dataset::SearchDataset& query_ds, stat = knowhere::BruteForce::SearchWithBuf( base_dataset, query_dataset, - sub_result.mutable_seg_offsets().data(), + sub_result.mutable_offsets().data(), sub_result.mutable_distances().data(), search_cfg, bitset, @@ -233,7 +232,7 @@ BruteForceSearch(const dataset::SearchDataset& query_ds, stat = knowhere::BruteForce::SearchWithBuf( base_dataset, query_dataset, - sub_result.mutable_seg_offsets().data(), + sub_result.mutable_offsets().data(), sub_result.mutable_distances().data(), search_cfg, bitset, @@ -242,7 +241,7 @@ BruteForceSearch(const dataset::SearchDataset& query_ds, stat = knowhere::BruteForce::SearchSparseWithBuf( base_dataset, query_dataset, - sub_result.mutable_seg_offsets().data(), + sub_result.mutable_offsets().data(), sub_result.mutable_distances().data(), search_cfg, bitset, @@ -251,7 +250,7 @@ BruteForceSearch(const dataset::SearchDataset& query_ds, stat = knowhere::BruteForce::SearchWithBuf( base_dataset, query_dataset, - sub_result.mutable_seg_offsets().data(), + sub_result.mutable_offsets().data(), sub_result.mutable_distances().data(), search_cfg, bitset, diff --git a/internal/core/src/query/SearchBruteForceSparseTest.cpp b/internal/core/src/query/SearchBruteForceSparseTest.cpp index d338235b11..4004076f3c 100644 --- a/internal/core/src/query/SearchBruteForceSparseTest.cpp +++ b/internal/core/src/query/SearchBruteForceSparseTest.cpp @@ -129,7 +129,7 @@ class TestSparseFloatSearchBruteForce : public ::testing::Test { nullptr); for (int i = 0; i < nq; i++) { auto ref = SearchRef(base.get(), *(query.get() + i), nb, topk); - auto ans = result.get_seg_offsets() + i * topk; + auto ans = result.get_offsets() + i * topk; AssertMatch(ref, ans); } @@ -146,7 +146,7 @@ class TestSparseFloatSearchBruteForce : public ::testing::Test { for (int i = 0; i < nq; i++) { auto ref = RangeSearchRef( base.get(), *(query.get() + i), nb, 0.1, 0.5, topk); - auto ans = result2.get_seg_offsets() + i * topk; + auto ans = result2.get_offsets() + i * topk; AssertMatch(ref, ans); } diff --git a/internal/core/src/query/SearchBruteForceTest.cpp b/internal/core/src/query/SearchBruteForceTest.cpp index 78d06a4ea0..abb945d10a 100644 --- a/internal/core/src/query/SearchBruteForceTest.cpp +++ b/internal/core/src/query/SearchBruteForceTest.cpp @@ -151,7 +151,7 @@ class TestFloatSearchBruteForce : public ::testing::Test { dim, topk, metric_type); - auto ans = result.get_seg_offsets() + i * topk; + auto ans = result.get_offsets() + i * topk; AssertMatch(ref, ans); } } diff --git a/internal/core/src/query/SearchOnGrowing.cpp b/internal/core/src/query/SearchOnGrowing.cpp index f3db538b81..11877c8437 100644 --- a/internal/core/src/query/SearchOnGrowing.cpp +++ b/internal/core/src/query/SearchOnGrowing.cpp @@ -81,7 +81,7 @@ SearchOnGrowing(const segcore::SegmentGrowingImpl& segment, SearchResult& search_result) { auto& schema = segment.get_schema(); auto& record = segment.get_insert_record(); - auto active_count = + auto active_row_count = std::min(int64_t(bitset.size()), segment.get_active_count(timestamp)); // step 1.1: get meta @@ -162,7 +162,7 @@ SearchOnGrowing(const segcore::SegmentGrowingImpl& segment, CachedSearchIterator cached_iter(search_dataset, vec_ptr, - active_count, + active_row_count, info, index_info, bitset, @@ -172,23 +172,30 @@ SearchOnGrowing(const segcore::SegmentGrowingImpl& segment, } auto vec_size_per_chunk = vec_ptr->get_size_per_chunk(); - auto max_chunk = upper_div(active_count, vec_size_per_chunk); + auto max_chunk = upper_div(active_row_count, vec_size_per_chunk); + + // embedding search embedding on embedding list + bool embedding_search = false; + if (data_type == DataType::VECTOR_ARRAY && + info.array_offsets_ != nullptr) { + embedding_search = true; + } for (int chunk_id = current_chunk_id; chunk_id < max_chunk; ++chunk_id) { auto chunk_data = vec_ptr->get_chunk_data(chunk_id); - auto element_begin = chunk_id * vec_size_per_chunk; - auto element_end = - std::min(active_count, (chunk_id + 1) * vec_size_per_chunk); - auto size_per_chunk = element_end - element_begin; + auto row_begin = chunk_id * vec_size_per_chunk; + auto row_end = + std::min(active_row_count, (chunk_id + 1) * vec_size_per_chunk); + auto size_per_chunk = row_end - row_begin; query::dataset::RawDataset sub_data; std::unique_ptr buf = nullptr; std::vector offsets; if (data_type != DataType::VECTOR_ARRAY) { sub_data = query::dataset::RawDataset{ - element_begin, dim, size_per_chunk, chunk_data}; + row_begin, dim, size_per_chunk, chunk_data}; } else { // TODO(SpadeA): For VectorArray(Embedding List), data is // discreted stored in FixedVector which means we will copy the @@ -201,43 +208,59 @@ SearchOnGrowing(const segcore::SegmentGrowingImpl& segment, } buf = std::make_unique(size); - offsets.reserve(size_per_chunk + 1); - offsets.push_back(0); - auto offset = 0; - auto ptr = buf.get(); - for (int i = 0; i < size_per_chunk; ++i) { - memcpy(ptr, vec_ptr[i].data(), vec_ptr[i].byte_size()); - ptr += vec_ptr[i].byte_size(); + if (embedding_search) { + auto count = 0; + auto ptr = buf.get(); + for (int i = 0; i < size_per_chunk; ++i) { + memcpy(ptr, vec_ptr[i].data(), vec_ptr[i].byte_size()); + ptr += vec_ptr[i].byte_size(); + count += vec_ptr[i].length(); + } + sub_data = query::dataset::RawDataset{ + row_begin, dim, count, buf.get()}; + } else { + offsets.reserve(size_per_chunk + 1); + offsets.push_back(0); - offset += vec_ptr[i].length(); - offsets.push_back(offset); + auto offset = 0; + auto ptr = buf.get(); + for (int i = 0; i < size_per_chunk; ++i) { + memcpy(ptr, vec_ptr[i].data(), vec_ptr[i].byte_size()); + ptr += vec_ptr[i].byte_size(); + + offset += vec_ptr[i].length(); + offsets.push_back(offset); + } + sub_data = query::dataset::RawDataset{row_begin, + dim, + size_per_chunk, + buf.get(), + offsets.data()}; } - sub_data = query::dataset::RawDataset{element_begin, - dim, - size_per_chunk, - buf.get(), - offsets.data()}; } - if (data_type == DataType::VECTOR_ARRAY) { - AssertInfo( - query_offsets != nullptr, - "query_offsets is nullptr, but data_type is vector array"); + auto vector_type = data_type; + if (embedding_search) { + vector_type = element_type; } if (milvus::exec::UseVectorIterator(info)) { - AssertInfo(data_type != DataType::VECTOR_ARRAY, + AssertInfo(vector_type != DataType::VECTOR_ARRAY, "vector array(embedding list) is not supported for " "vector iterator"); + if (buf != nullptr) { + search_result.chunk_buffers_.emplace_back(std::move(buf)); + } + auto sub_qr = PackBruteForceSearchIteratorsIntoSubResult(search_dataset, sub_data, info, index_info, bitset, - data_type); + vector_type); final_qr.merge(sub_qr); } else { auto sub_qr = BruteForceSearch(search_dataset, @@ -245,7 +268,7 @@ SearchOnGrowing(const segcore::SegmentGrowingImpl& segment, info, index_info, bitset, - data_type, + vector_type, element_type, op_context); final_qr.merge(sub_qr); @@ -259,9 +282,18 @@ SearchOnGrowing(const segcore::SegmentGrowingImpl& segment, search_result.AssembleChunkVectorIterators( num_queries, max_chunk, chunk_rows, final_qr.chunk_iterators()); } else { + if (info.array_offsets_ != nullptr) { + auto [seg_offsets, elem_indicies] = + final_qr.convert_to_element_offsets( + info.array_offsets_.get()); + search_result.seg_offsets_ = std::move(seg_offsets); + search_result.element_indices_ = std::move(elem_indicies); + search_result.element_level_ = true; + } else { + search_result.seg_offsets_ = + std::move(final_qr.mutable_offsets()); + } search_result.distances_ = std::move(final_qr.mutable_distances()); - search_result.seg_offsets_ = - std::move(final_qr.mutable_seg_offsets()); } search_result.unity_topK_ = topk; search_result.total_nq_ = num_queries; diff --git a/internal/core/src/query/SearchOnSealed.cpp b/internal/core/src/query/SearchOnSealed.cpp index 24b17d3686..ded92fadbe 100644 --- a/internal/core/src/query/SearchOnSealed.cpp +++ b/internal/core/src/query/SearchOnSealed.cpp @@ -96,6 +96,28 @@ SearchOnSealedIndex(const Schema& schema, std::round(distances[i] * multiplier) / multiplier; } } + + // Handle element-level conversion if needed + if (search_info.array_offsets_ != nullptr) { + std::vector element_ids = + std::move(search_result.seg_offsets_); + search_result.seg_offsets_.resize(element_ids.size()); + search_result.element_indices_.resize(element_ids.size()); + + for (size_t i = 0; i < element_ids.size(); i++) { + if (element_ids[i] == INVALID_SEG_OFFSET) { + search_result.seg_offsets_[i] = INVALID_SEG_OFFSET; + search_result.element_indices_[i] = -1; + } else { + auto [doc_id, elem_index] = + search_info.array_offsets_->ElementIDToRowID( + element_ids[i]); + search_result.seg_offsets_[i] = doc_id; + search_result.element_indices_[i] = elem_index; + } + } + search_result.element_level_ = true; + } } search_result.total_nq_ = num_queries; search_result.unity_topK_ = topK; @@ -150,6 +172,17 @@ SearchOnSealedColumn(const Schema& schema, search_info.metric_type_, search_info.round_decimal_); + // For element-level search (embedding-search-embedding), we need to use + // element count instead of row count + bool is_element_level_search = + field.get_data_type() == DataType::VECTOR_ARRAY && + query_offsets == nullptr; + + if (is_element_level_search) { + // embedding-search-embedding on embedding list pattern + data_type = element_type; + } + auto offset = 0; auto vector_chunks = column->GetAllChunks(op_context); @@ -157,6 +190,14 @@ SearchOnSealedColumn(const Schema& schema, auto pw = vector_chunks[i]; auto vec_data = pw.get()->Data(); auto chunk_size = column->chunk_row_nums(i); + + // For element-level search, get element count from VectorArrayOffsets + if (is_element_level_search) { + auto elem_offsets_pw = column->VectorArrayOffsets(op_context, i); + // offsets[row_count] gives total element count in this chunk + chunk_size = elem_offsets_pw.get()[chunk_size]; + } + auto raw_dataset = query::dataset::RawDataset{offset, dim, chunk_size, vec_data}; @@ -201,8 +242,17 @@ SearchOnSealedColumn(const Schema& schema, column->GetNumRowsUntilChunk(), final_qr.chunk_iterators()); } else { + if (search_info.array_offsets_ != nullptr) { + auto [seg_offsets, elem_indicies] = + final_qr.convert_to_element_offsets( + search_info.array_offsets_.get()); + result.seg_offsets_ = std::move(seg_offsets); + result.element_indices_ = std::move(elem_indicies); + result.element_level_ = true; + } else { + result.seg_offsets_ = std::move(final_qr.mutable_offsets()); + } result.distances_ = std::move(final_qr.mutable_distances()); - result.seg_offsets_ = std::move(final_qr.mutable_seg_offsets()); } result.unity_topK_ = query_dataset.topk; result.total_nq_ = query_dataset.num_queries; diff --git a/internal/core/src/query/SubSearchResult.cpp b/internal/core/src/query/SubSearchResult.cpp index 02afbcb478..7262f8dbf4 100644 --- a/internal/core/src/query/SubSearchResult.cpp +++ b/internal/core/src/query/SubSearchResult.cpp @@ -30,7 +30,7 @@ SubSearchResult::merge_impl(const SubSearchResult& right) { for (int64_t qn = 0; qn < num_queries_; ++qn) { auto offset = qn * topk_; - int64_t* __restrict__ left_ids = this->get_seg_offsets() + offset; + int64_t* __restrict__ left_ids = this->get_offsets() + offset; float* __restrict__ left_distances = this->get_distances() + offset; auto right_ids = right.get_ids() + offset; diff --git a/internal/core/src/query/SubSearchResult.h b/internal/core/src/query/SubSearchResult.h index 40fe913896..dca20c5862 100644 --- a/internal/core/src/query/SubSearchResult.h +++ b/internal/core/src/query/SubSearchResult.h @@ -18,6 +18,7 @@ #include "common/Types.h" #include "common/Utils.h" #include "knowhere/index/index_node.h" +#include "common/ArrayOffsets.h" namespace milvus::query { class SubSearchResult { @@ -31,7 +32,7 @@ class SubSearchResult { topk_(topk), round_decimal_(round_decimal), metric_type_(metric_type), - seg_offsets_(num_queries * topk, INVALID_SEG_OFFSET), + offsets_(num_queries * topk, INVALID_SEG_OFFSET), distances_(num_queries * topk, init_value(metric_type)), chunk_iterators_(std::move(iters)) { } @@ -52,7 +53,7 @@ class SubSearchResult { topk_(other.topk_), round_decimal_(other.round_decimal_), metric_type_(std::move(other.metric_type_)), - seg_offsets_(std::move(other.seg_offsets_)), + offsets_(std::move(other.offsets_)), distances_(std::move(other.distances_)), chunk_iterators_(std::move(other.chunk_iterators_)) { } @@ -77,12 +78,12 @@ class SubSearchResult { const int64_t* get_ids() const { - return seg_offsets_.data(); + return offsets_.data(); } int64_t* - get_seg_offsets() { - return seg_offsets_.data(); + get_offsets() { + return offsets_.data(); } const float* @@ -96,8 +97,8 @@ class SubSearchResult { } auto& - mutable_seg_offsets() { - return seg_offsets_; + mutable_offsets() { + return offsets_; } auto& @@ -116,6 +117,27 @@ class SubSearchResult { return this->chunk_iterators_; } + std::pair, std::vector> + convert_to_element_offsets(const IArrayOffsets* array_offsets) { + std::vector doc_offsets; + std::vector element_indices; + doc_offsets.reserve(offsets_.size()); + element_indices.reserve(offsets_.size()); + for (size_t i = 0; i < offsets_.size(); i++) { + if (offsets_[i] == INVALID_SEG_OFFSET) { + doc_offsets.push_back(INVALID_SEG_OFFSET); + element_indices.push_back(-1); + } else { + auto [doc_id, elem_index] = + array_offsets->ElementIDToRowID(offsets_[i]); + doc_offsets.push_back(doc_id); + element_indices.push_back(elem_index); + } + } + return std::make_pair(std::move(doc_offsets), + std::move(element_indices)); + } + private: template void @@ -126,7 +148,7 @@ class SubSearchResult { int64_t topk_; int64_t round_decimal_; knowhere::MetricType metric_type_; - std::vector seg_offsets_; + std::vector offsets_; std::vector distances_; std::vector chunk_iterators_; }; diff --git a/internal/core/src/query/SubSearchResultTest.cpp b/internal/core/src/query/SubSearchResultTest.cpp index 7fc15e24c8..228a722278 100644 --- a/internal/core/src/query/SubSearchResultTest.cpp +++ b/internal/core/src/query/SubSearchResultTest.cpp @@ -55,7 +55,7 @@ GenSubSearchResult(const int64_t nq, } } sub_result->mutable_distances() = std::move(distances); - sub_result->mutable_seg_offsets() = std::move(ids); + sub_result->mutable_offsets() = std::move(ids); return sub_result; } @@ -72,7 +72,7 @@ CheckSubSearchResult(const int64_t nq, auto ref_x = result_ref[n].top(); result_ref[n].pop(); auto index = n * topk + topk - 1 - k; - auto id = result.get_seg_offsets()[index]; + auto id = result.get_offsets()[index]; auto distance = result.get_distances()[index]; ASSERT_EQ(id, ref_x); ASSERT_EQ(distance, ref_x); diff --git a/internal/core/src/segcore/ChunkedSegmentSealedImpl.cpp b/internal/core/src/segcore/ChunkedSegmentSealedImpl.cpp index 1683e0d141..0b4f199a3a 100644 --- a/internal/core/src/segcore/ChunkedSegmentSealedImpl.cpp +++ b/internal/core/src/segcore/ChunkedSegmentSealedImpl.cpp @@ -2676,22 +2676,62 @@ ChunkedSegmentSealedImpl::load_field_data_common( bool generated_interim_index = generate_interim_index(field_id, num_rows); - std::unique_lock lck(mutex_); - AssertInfo(!get_bit(field_data_ready_bitset_, field_id), - "field {} data already loaded", - field_id.get()); - set_bit(field_data_ready_bitset_, field_id, true); - update_row_count(num_rows); - if (generated_interim_index) { - auto column = get_column(field_id); - if (column) { - column->ManualEvictCache(); + std::string struct_name; + const FieldMeta* field_meta_ptr = nullptr; + + { + std::unique_lock lck(mutex_); + AssertInfo(!get_bit(field_data_ready_bitset_, field_id), + "field {} data already loaded", + field_id.get()); + set_bit(field_data_ready_bitset_, field_id, true); + update_row_count(num_rows); + if (generated_interim_index) { + auto column = get_column(field_id); + if (column) { + column->ManualEvictCache(); + } + } + if (data_type == DataType::GEOMETRY && + segcore_config_.get_enable_geometry_cache()) { + // Construct GeometryCache for the entire field + LoadGeometryCache(field_id, column); + } + + // Check if need to build ArrayOffsetsSealed for struct array fields + if (data_type == DataType::ARRAY || + data_type == DataType::VECTOR_ARRAY) { + auto& field_meta = schema_->operator[](field_id); + const std::string& field_name = field_meta.get_name().get(); + + if (field_name.find('[') != std::string::npos && + field_name.find(']') != std::string::npos) { + struct_name = field_name.substr(0, field_name.find('[')); + + auto it = struct_to_array_offsets_.find(struct_name); + if (it != struct_to_array_offsets_.end()) { + array_offsets_map_[field_id] = it->second; + } else { + field_meta_ptr = &field_meta; // need to build + } + } } } - if (data_type == DataType::GEOMETRY && - segcore_config_.get_enable_geometry_cache()) { - // Construct GeometryCache for the entire field - LoadGeometryCache(field_id, column); + + // Build ArrayOffsetsSealed outside lock (expensive operation) + if (field_meta_ptr) { + auto new_offsets = + ArrayOffsetsSealed::BuildFromSegment(this, *field_meta_ptr); + + std::unique_lock lck(mutex_); + // Double-check after re-acquiring lock + auto it = struct_to_array_offsets_.find(struct_name); + if (it == struct_to_array_offsets_.end()) { + struct_to_array_offsets_[struct_name] = new_offsets; + array_offsets_map_[field_id] = new_offsets; + } else { + array_offsets_map_[field_id] = it->second; + } } } diff --git a/internal/core/src/segcore/ChunkedSegmentSealedImpl.h b/internal/core/src/segcore/ChunkedSegmentSealedImpl.h index bce6b6b462..2f3cffa72e 100644 --- a/internal/core/src/segcore/ChunkedSegmentSealedImpl.h +++ b/internal/core/src/segcore/ChunkedSegmentSealedImpl.h @@ -169,6 +169,15 @@ class ChunkedSegmentSealedImpl : public SegmentSealed { FieldId field_id, const std::string& nested_path) const override; + std::shared_ptr + GetArrayOffsets(FieldId field_id) const override { + auto it = array_offsets_map_.find(field_id); + if (it != array_offsets_map_.end()) { + return it->second; + } + return nullptr; + } + void BulkGetJsonData(milvus::OpContext* op_ctx, FieldId field_id, @@ -1049,6 +1058,14 @@ class ChunkedSegmentSealedImpl : public SegmentSealed { // milvus storage internal api reader instance std::unique_ptr reader_; + + // ArrayOffsetsSealed for element-level filtering on array fields + // field_id -> ArrayOffsetsSealed mapping + std::unordered_map> + array_offsets_map_; + // struct_name -> ArrayOffsetsSealed mapping (temporary during load) + std::unordered_map> + struct_to_array_offsets_; }; inline SegmentSealedUPtr diff --git a/internal/core/src/segcore/SegmentGrowingImpl.cpp b/internal/core/src/segcore/SegmentGrowingImpl.cpp index de65712b93..b9a6b31b69 100644 --- a/internal/core/src/segcore/SegmentGrowingImpl.cpp +++ b/internal/core/src/segcore/SegmentGrowingImpl.cpp @@ -56,6 +56,167 @@ namespace milvus::segcore { using namespace milvus::cachinglayer; +namespace { + +void +ExtractArrayLengthsFromFieldData(const std::vector& field_data, + const FieldMeta& field_meta, + int32_t* array_lengths) { + auto data_type = field_meta.get_data_type(); + int64_t offset = 0; + + for (const auto& data : field_data) { + auto num_rows = data->get_num_rows(); + + if (data_type == DataType::VECTOR_ARRAY) { + // Get raw pointer to VectorArray data + auto* raw_data = static_cast(data->Data()); + for (int64_t i = 0; i < num_rows; ++i) { + array_lengths[offset + i] = raw_data[i].length(); + } + } else { + // For regular array types (INT32, FLOAT, etc.) + auto* raw_data = static_cast(data->Data()); + for (int64_t i = 0; i < num_rows; ++i) { + array_lengths[offset + i] = raw_data[i].length(); + } + } + offset += num_rows; + } +} + +void +ExtractArrayLengths(const proto::schema::FieldData& field_data, + const FieldMeta& field_meta, + int64_t num_rows, + int32_t* array_lengths) { + auto data_type = field_meta.get_data_type(); + if (data_type == DataType::VECTOR_ARRAY) { + const auto& vector_array = field_data.vectors().vector_array(); + int64_t dim = field_meta.get_dim(); + auto element_type = field_meta.get_element_type(); + + for (int i = 0; i < num_rows; ++i) { + const auto& vec_field = vector_array.data(i); + int32_t array_len = 0; + + switch (element_type) { + case DataType::VECTOR_FLOAT: + array_len = vec_field.float_vector().data_size() / dim; + break; + case DataType::VECTOR_FLOAT16: + array_len = vec_field.float16_vector().size() / (dim * 2); + break; + case DataType::VECTOR_BFLOAT16: + array_len = vec_field.bfloat16_vector().size() / (dim * 2); + break; + case DataType::VECTOR_BINARY: + array_len = vec_field.binary_vector().size() / (dim / 8); + break; + case DataType::VECTOR_INT8: + array_len = vec_field.int8_vector().size() / dim; + break; + default: + ThrowInfo(ErrorCode::UnexpectedError, + "Unexpected VECTOR_ARRAY element type: {}", + element_type); + } + + array_lengths[i] = array_len; + } + } else { + // ARRAY: extract from scalars().array_data().data(i) + const auto& array_data = field_data.scalars().array_data(); + auto element_type = field_meta.get_element_type(); + + for (int i = 0; i < num_rows; ++i) { + int32_t array_len = 0; + + switch (element_type) { + case DataType::BOOL: + array_len = array_data.data(i).bool_data().data_size(); + break; + case DataType::INT8: + case DataType::INT16: + case DataType::INT32: + array_len = array_data.data(i).int_data().data_size(); + break; + case DataType::INT64: + array_len = array_data.data(i).long_data().data_size(); + break; + case DataType::FLOAT: + array_len = array_data.data(i).float_data().data_size(); + break; + case DataType::DOUBLE: + array_len = array_data.data(i).double_data().data_size(); + break; + case DataType::STRING: + case DataType::VARCHAR: + array_len = array_data.data(i).string_data().data_size(); + break; + default: + ThrowInfo(ErrorCode::UnexpectedError, + "Unexpected array type: {}", + element_type); + } + + array_lengths[i] = array_len; + } + } + + // Handle nullable fields + if (field_meta.is_nullable() && field_data.valid_data_size() > 0) { + const auto& valid_data = field_data.valid_data(); + for (int i = 0; i < num_rows; ++i) { + if (!valid_data[i]) { + array_lengths[i] = 0; // null → empty array + } + } + } +} + +} // anonymous namespace + +void +SegmentGrowingImpl::InitializeArrayOffsets() { + // Group fields by struct_name + std::unordered_map> struct_fields; + + for (const auto& [field_id, field_meta] : schema_->get_fields()) { + const auto& field_name = field_meta.get_name().get(); + + // Check if field belongs to a struct: format = "struct_name[field_name]" + size_t bracket_pos = field_name.find('['); + if (bracket_pos != std::string::npos && bracket_pos > 0) { + std::string struct_name = field_name.substr(0, bracket_pos); + struct_fields[struct_name].push_back(field_id); + } + } + + // Create one ArrayOffsetsGrowing per struct, shared by all its fields + for (const auto& [struct_name, field_ids] : struct_fields) { + auto array_offsets = std::make_shared(); + + // Pick the first field as representative (any field works since array lengths are identical) + FieldId representative_field = field_ids[0]; + + // Map all field_ids from this struct to the same ArrayOffsetsGrowing + for (auto field_id : field_ids) { + array_offsets_map_[field_id] = array_offsets; + } + + // Record representative field for Insert-time updates + struct_representative_fields_.insert(representative_field); + + LOG_INFO( + "Created ArrayOffsetsGrowing for struct '{}' with {} fields, " + "representative field_id={}", + struct_name, + field_ids.size(), + representative_field.get()); + } +} + int64_t SegmentGrowingImpl::PreInsert(int64_t size) { auto reserved_begin = insert_record_.reserved.fetch_add(size); @@ -174,6 +335,22 @@ SegmentGrowingImpl::Insert(int64_t reserved_offset, insert_record_); } + // update ArrayOffsetsGrowing for struct fields + if (struct_representative_fields_.count(field_id) > 0) { + const auto& field_data = + insert_record_proto->fields_data(data_offset); + + std::vector array_lengths(num_rows); + ExtractArrayLengths( + field_data, field_meta, num_rows, array_lengths.data()); + + auto offsets_it = array_offsets_map_.find(field_id); + if (offsets_it != array_offsets_map_.end()) { + offsets_it->second->Insert( + reserved_offset, array_lengths.data(), num_rows); + } + } + // index text. if (field_meta.enable_match()) { // TODO: iterate texts and call `AddText` instead of `AddTexts`. This may cost much more memory. @@ -381,6 +558,23 @@ SegmentGrowingImpl::load_field_data_common( index->Reload(); } + // update ArrayOffsetsGrowing for struct fields + if (struct_representative_fields_.count(field_id) > 0) { + std::vector array_lengths(num_rows); + ExtractArrayLengthsFromFieldData( + field_data, field_meta, array_lengths.data()); + + auto offsets_it = array_offsets_map_.find(field_id); + if (offsets_it != array_offsets_map_.end()) { + offsets_it->second->Insert( + reserved_offset, array_lengths.data(), num_rows); + } + + LOG_INFO("Updated ArrayOffsetsGrowing for field {} with {} rows", + field_id.get(), + num_rows); + } + // update the mem size stats_.mem_size += storage::GetByteSizeOfFieldDatas(field_data); diff --git a/internal/core/src/segcore/SegmentGrowingImpl.h b/internal/core/src/segcore/SegmentGrowingImpl.h index be372bb13f..212f1e31c5 100644 --- a/internal/core/src/segcore/SegmentGrowingImpl.h +++ b/internal/core/src/segcore/SegmentGrowingImpl.h @@ -34,6 +34,7 @@ #include "common/Types.h" #include "query/PlanNode.h" #include "common/GeometryCache.h" +#include "common/ArrayOffsets.h" namespace milvus::segcore { @@ -330,6 +331,7 @@ class SegmentGrowingImpl : public SegmentGrowing { }, segment_id) { this->CreateTextIndexes(); + this->InitializeArrayOffsets(); } ~SegmentGrowingImpl() { @@ -490,6 +492,15 @@ class SegmentGrowingImpl : public SegmentGrowing { "RemoveJsonStats not implemented for SegmentGrowingImpl"); } + std::shared_ptr + GetArrayOffsets(FieldId field_id) const override { + auto it = array_offsets_map_.find(field_id); + if (it != array_offsets_map_.end()) { + return it->second; + } + return nullptr; + } + protected: int64_t num_chunk(FieldId field_id) const override; @@ -586,6 +597,9 @@ class SegmentGrowingImpl : public SegmentGrowing { const std::shared_ptr& properties, int64_t index); + void + InitializeArrayOffsets(); + private: storage::MmapChunkDescriptorPtr mmap_descriptor_ = nullptr; SegcoreConfig segcore_config_; @@ -609,6 +623,15 @@ class SegmentGrowingImpl : public SegmentGrowing { // milvus storage internal api reader instance std::unique_ptr reader_; + + // field_id -> ArrayOffsetsGrowing (for fast lookup via GetArrayOffsets) + // Multiple field_ids from the same struct point to the same ArrayOffsetsGrowing + std::unordered_map> + array_offsets_map_; + + // Representative field_id for each struct (used to extract array lengths during Insert) + // One field_id per struct, since all fields in the same struct have identical array lengths + std::unordered_set struct_representative_fields_; }; inline SegmentGrowingPtr diff --git a/internal/core/src/segcore/SegmentInterface.h b/internal/core/src/segcore/SegmentInterface.h index 5ca96784c2..c78cc4c7c5 100644 --- a/internal/core/src/segcore/SegmentInterface.h +++ b/internal/core/src/segcore/SegmentInterface.h @@ -24,6 +24,7 @@ #include #include "cachinglayer/CacheSlot.h" +#include "common/ArrayOffsets.h" #include "common/EasyAssert.h" #include "common/Json.h" #include "common/OpContext.h" @@ -243,6 +244,11 @@ class SegmentInterface { virtual void Load(milvus::tracer::TraceContext& trace_ctx) = 0; + + // Get IArrayOffsets for element-level filtering on array fields + // Returns nullptr if the field doesn't have IArrayOffsets + virtual std::shared_ptr + GetArrayOffsets(FieldId field_id) const = 0; }; // internal API for DSL calculation diff --git a/internal/core/src/segcore/reduce/GroupReduce.cpp b/internal/core/src/segcore/reduce/GroupReduce.cpp index 005956dba3..08c61f5ee1 100644 --- a/internal/core/src/segcore/reduce/GroupReduce.cpp +++ b/internal/core/src/segcore/reduce/GroupReduce.cpp @@ -67,6 +67,10 @@ GroupReduceHelper::RefreshSingleSearchResult(SearchResult* search_result, std::vector distances(size); std::vector seg_offsets(size); std::vector group_by_values(size); + std::vector element_indices; + if (search_result->element_level_) { + element_indices.resize(size); + } uint32_t index = 0; for (int j = 0; j < total_nq_; j++) { @@ -76,6 +80,10 @@ GroupReduceHelper::RefreshSingleSearchResult(SearchResult* search_result, seg_offsets[index] = search_result->seg_offsets_[offset]; group_by_values[index] = search_result->group_by_values_.value()[offset]; + if (search_result->element_level_) { + element_indices[index] = + search_result->element_indices_[offset]; + } index++; real_topks[j]++; } @@ -84,6 +92,9 @@ GroupReduceHelper::RefreshSingleSearchResult(SearchResult* search_result, search_result->distances_.swap(distances); search_result->seg_offsets_.swap(seg_offsets); search_result->group_by_values_.value().swap(group_by_values); + if (search_result->element_level_) { + search_result->element_indices_.swap(element_indices); + } AssertInfo(search_result->primary_keys_.size() == search_result->group_by_values_.value().size(), "Wrong size for group_by_values size after refresh:{}, " diff --git a/internal/core/src/segcore/reduce/Reduce.cpp b/internal/core/src/segcore/reduce/Reduce.cpp index ef27eb7307..87363d70e0 100644 --- a/internal/core/src/segcore/reduce/Reduce.cpp +++ b/internal/core/src/segcore/reduce/Reduce.cpp @@ -116,12 +116,17 @@ ReduceHelper::FilterInvalidSearchResult(SearchResult* search_result) { real_topks[i]++; offsets[valid_index] = offsets[index]; distances[valid_index] = distances[index]; + if (search_result->element_level_) + search_result->element_indices_[valid_index] = + search_result->element_indices_[index]; valid_index++; } } } offsets.resize(valid_index); distances.resize(valid_index); + if (search_result->element_level_) + search_result->element_indices_.resize(valid_index); search_result->topk_per_nq_prefix_sum_.resize(nq + 1); std::partial_sum(real_topks.begin(), real_topks.end(), @@ -207,6 +212,10 @@ ReduceHelper::SortEqualScoresOneNQ(size_t nq_begin, PkType temp_pk = std::move(search_result->primary_keys_[start + i]); int64_t temp_offset = search_result->seg_offsets_[start + i]; + int32_t temp_elem_idx = + search_result->element_level_ + ? search_result->element_indices_[start + i] + : -1; size_t curr = i; while (indices[curr] != i) { @@ -215,12 +224,20 @@ ReduceHelper::SortEqualScoresOneNQ(size_t nq_begin, std::move(search_result->primary_keys_[start + next]); search_result->seg_offsets_[start + curr] = search_result->seg_offsets_[start + next]; + if (search_result->element_level_) { + search_result->element_indices_[start + curr] = + search_result->element_indices_[start + next]; + } indices[curr] = curr; // Mark as processed curr = next; } search_result->primary_keys_[start + curr] = std::move(temp_pk); search_result->seg_offsets_[start + curr] = temp_offset; + if (search_result->element_level_) { + search_result->element_indices_[start + curr] = + temp_elem_idx; + } indices[curr] = curr; } } @@ -258,6 +275,10 @@ ReduceHelper::RefreshSingleSearchResult(SearchResult* search_result, search_result->distances_[offset]; search_result->seg_offsets_[index] = search_result->seg_offsets_[offset]; + if (search_result->element_level_) { + search_result->element_indices_[index] = + search_result->element_indices_[offset]; + } index++; real_topks[j]++; } @@ -265,6 +286,9 @@ ReduceHelper::RefreshSingleSearchResult(SearchResult* search_result, search_result->primary_keys_.resize(index); search_result->distances_.resize(index); search_result->seg_offsets_.resize(index); + if (search_result->element_level_) { + search_result->element_indices_.resize(index); + } } void @@ -451,6 +475,15 @@ ReduceHelper::GetSearchResultDataSlice(const int slice_index, // reserve space for distances search_result_data->mutable_scores()->Resize(result_count, 0); + for (auto search_result : search_results_) { + if (search_result->element_level_) { + search_result_data->mutable_element_indices() + ->mutable_data() + ->Resize(result_count, -1); + break; + } + } + // fill pks and distances for (auto qi = nq_begin; qi < nq_end; qi++) { int64_t topk_count = 0; @@ -499,6 +532,13 @@ ReduceHelper::GetSearchResultDataSlice(const int slice_index, search_result_data->mutable_scores()->Set( loc, search_result->distances_[ki]); + + if (search_result->element_level_) { + search_result_data->mutable_element_indices() + ->mutable_data() + ->Set(loc, search_result->element_indices_[ki]); + } + // set result offset to fill output fields data result_pairs[loc] = {&search_result->output_fields_data_, ki}; } diff --git a/internal/core/unittest/CMakeLists.txt b/internal/core/unittest/CMakeLists.txt index 9da374daf3..818c93b79c 100644 --- a/internal/core/unittest/CMakeLists.txt +++ b/internal/core/unittest/CMakeLists.txt @@ -50,6 +50,7 @@ set(MILVUS_TEST_FILES test_rust_result.cpp test_storage_v2_index_raw_data.cpp test_group_by_json.cpp + test_element_filter.cpp ) if ( NOT (INDEX_ENGINE STREQUAL "cardinal") ) diff --git a/internal/core/unittest/test_element_filter.cpp b/internal/core/unittest/test_element_filter.cpp new file mode 100644 index 0000000000..6585a82e86 --- /dev/null +++ b/internal/core/unittest/test_element_filter.cpp @@ -0,0 +1,977 @@ +// Copyright (C) 2019-2020 Zilliz. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions and limitations under the License + +#include +#include +#include +#include + +#include "common/Schema.h" +#include "common/ArrayOffsets.h" +#include "query/Plan.h" +#include "test_utils/DataGen.h" +#include "test_utils/storage_test_utils.h" +#include "test_utils/cachinglayer_test_utils.h" + +using namespace milvus; +using namespace milvus::query; +using namespace milvus::segcore; + +class ElementFilterSealed + : public ::testing::TestWithParam> { + protected: + bool + use_hints() const { + return std::get<0>(GetParam()); + } + bool + load_index() const { + return std::get<1>(GetParam()); + } +}; + +TEST_P(ElementFilterSealed, RangeExpr) { + bool with_hints = use_hints(); + bool with_load_index = load_index(); + // Step 1: Prepare schema with array field + int dim = 4; + auto schema = std::make_shared(); + 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 = 500; + int array_len = 3; + + // Step 2: Generate test data + 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++) { + int value = row * array_len + elem + 1; + array_data->mutable_int_data()->mutable_data()->Add(value); + } + } + break; + } + } + + // Step 3: Create sealed segment with field data + auto segment = CreateSealedWithFieldDataLoaded(schema, raw_data); + + // Step 4: Load vector index for element-level search + auto array_vec_values = raw_data.get_col(vec_fid); + + // DataGen generates VECTOR_ARRAY with data in float_vector (flattened), + // not in vector_array (nested structure) + std::vector vector_data(dim * N * array_len); + for (int i = 0; i < N; i++) { + const auto& float_vec = array_vec_values[i].float_vector().data(); + // float_vec contains array_len * dim floats + for (int j = 0; j < array_len * dim; j++) { + vector_data[i * array_len * dim + j] = float_vec[j]; + } + } + + // For element-level search, index all elements (N * array_len vectors) + auto indexing = GenVecIndexing(N * array_len, + dim, + vector_data.data(), + knowhere::IndexEnum::INDEX_HNSW); + LoadIndexInfo load_index_info; + load_index_info.field_id = vec_fid.get(); + load_index_info.index_params = GenIndexParams(indexing.get()); + load_index_info.cache_index = + CreateTestCacheIndex("test", std::move(indexing)); + load_index_info.index_params["metric_type"] = knowhere::metric::L2; + load_index_info.field_type = DataType::VECTOR_ARRAY; + load_index_info.element_type = DataType::VECTOR_FLOAT; + if (with_load_index) { + segment->LoadIndex(load_index_info); + } + + int topK = 5; + + // Step 5: Test with element-level filter + // Query: Search array elements, filter by element_value in (100, 400) + { + std::string hints_line = + with_hints ? R"(hints: "iterative_filter")" : ""; + std::string raw_plan = boost::str(boost::format(R"(vector_anns: < + field_id: %1% + predicates: < + element_filter_expr: < + element_expr: < + binary_range_expr: < + column_info: < + field_id: %2% + data_type: Int32 + element_type: Int32 + is_element_level: true + > + lower_inclusive: false + upper_inclusive: false + lower_value: < + int64_val: 100 + > + upper_value: < + int64_val: 400 + > + > + > + predicate: < + binary_arith_op_eval_range_expr: < + column_info: < + field_id: %3% + data_type: Int64 + > + arith_op: Mod + right_operand: < + int64_val: 2 + > + op: Equal + value: < + int64_val: 0 + > + > + > + struct_name: "structA" + > + > + query_info: < + topk: 5 + round_decimal: 3 + metric_type: "L2" + %4% + search_params: "{\"ef\": 50}" + > + placeholder_tag: "$0">)") % + vec_fid.get() % int_array_fid.get() % + int64_fid.get() % hints_line); + + proto::plan::PlanNode plan_node; + auto ok = + google::protobuf::TextFormat::ParseFromString(raw_plan, &plan_node); + ASSERT_TRUE(ok) << "Failed to parse element-level filter plan"; + + auto plan = CreateSearchPlanFromPlanNode(schema, plan_node); + ASSERT_NE(plan, nullptr); + + auto num_queries = 1; + auto seed = 1024; + auto ph_group_raw = + CreatePlaceholderGroup(num_queries, dim, seed, true); + auto ph_group = + ParsePlaceholderGroup(plan.get(), ph_group_raw.SerializeAsString()); + + auto search_result = + segment->Search(plan.get(), ph_group.get(), 1L << 63); + + // Verify results + ASSERT_NE(search_result, nullptr); + + // In element-level mode, results should be element indices, not doc offsets + ASSERT_TRUE(search_result->element_level_); + ASSERT_FALSE(search_result->element_indices_.empty()); + // Also check seg_offsets_ which stores the doc IDs + ASSERT_FALSE(search_result->seg_offsets_.empty()); + ASSERT_EQ(search_result->element_indices_.size(), + search_result->seg_offsets_.size()); + + // Should have topK results per query + ASSERT_LE(search_result->element_indices_.size(), topK * num_queries); + + std::cout << "Element-level search returned:" << std::endl; + for (auto i = 0; i < search_result->seg_offsets_.size(); i++) { + int64_t doc_id = search_result->seg_offsets_[i]; + int32_t elem_idx = search_result->element_indices_[i]; + float distance = search_result->distances_[i]; + + std::cout << "doc_id: " << doc_id << ", element_index: " << elem_idx + << ", distance: " << distance << std::endl; + + // Verify the doc_id satisfies the predicate (id % 2 == 0) + ASSERT_EQ(doc_id % 2, 0) << "Result doc_id " << doc_id + << " should satisfy (id % 2 == 0)"; + + // Verify element value is in range (100, 400) + // Element value = doc_id * array_len + elem_idx + 1 + int element_value = doc_id * array_len + elem_idx + 1; + ASSERT_GT(element_value, 100) + << "Element value " << element_value << " should be > 100"; + ASSERT_LT(element_value, 400) + << "Element value " << element_value << " should be < 400"; + } + + // Verify distances are sorted (ascending for L2) + for (size_t i = 1; i < search_result->distances_.size(); ++i) { + ASSERT_LE(search_result->distances_[i - 1], + search_result->distances_[i]) + << "Distances should be sorted in ascending order"; + } + } +} + +TEST_P(ElementFilterSealed, UnaryExpr) { + bool with_hints = use_hints(); + bool with_load_index = load_index(); + // Step 1: Prepare schema with array field + int dim = 4; + auto schema = std::make_shared(); + 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 = 500; + int array_len = 3; + + // Step 2: Generate test data + 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++) { + int value = row * array_len + elem + 1; + array_data->mutable_int_data()->mutable_data()->Add(value); + } + } + break; + } + } + + // Step 3: Create sealed segment with field data + auto segment = CreateSealedWithFieldDataLoaded(schema, raw_data); + + // Step 4: Load vector index for element-level search + auto array_vec_values = raw_data.get_col(vec_fid); + + // DataGen generates VECTOR_ARRAY with data in float_vector (flattened), + // not in vector_array (nested structure) + std::vector vector_data(dim * N * array_len); + for (int i = 0; i < N; i++) { + const auto& float_vec = array_vec_values[i].float_vector().data(); + // float_vec contains array_len * dim floats + for (int j = 0; j < array_len * dim; j++) { + vector_data[i * array_len * dim + j] = float_vec[j]; + } + } + + // For element-level search, index all elements (N * array_len vectors) + auto indexing = GenVecIndexing(N * array_len, + dim, + vector_data.data(), + knowhere::IndexEnum::INDEX_HNSW); + LoadIndexInfo load_index_info; + load_index_info.field_id = vec_fid.get(); + load_index_info.index_params = GenIndexParams(indexing.get()); + load_index_info.cache_index = + CreateTestCacheIndex("test", std::move(indexing)); + load_index_info.index_params["metric_type"] = knowhere::metric::L2; + load_index_info.field_type = DataType::VECTOR_ARRAY; + load_index_info.element_type = DataType::VECTOR_FLOAT; + if (with_load_index) { + segment->LoadIndex(load_index_info); + } + + int topK = 5; + + // Step 5: Test with element-level filter + // Query: Search array elements, filter by element_value < 10 + { + std::string hints_line = + with_hints ? R"(hints: "iterative_filter")" : ""; + std::string raw_plan = boost::str(boost::format(R"(vector_anns: < + field_id: %1% + predicates: < + element_filter_expr: < + element_expr: < + unary_range_expr: < + column_info: < + field_id: %2% + data_type: Int32 + element_type: Int32 + is_element_level: true + > + op: GreaterThan + value: < + int64_val: 10 + > + > + > + predicate: < + binary_arith_op_eval_range_expr: < + column_info: < + field_id: %3% + data_type: Int64 + > + arith_op: Mod + right_operand: < + int64_val: 2 + > + op: Equal + value: < + int64_val: 0 + > + > + > + struct_name: "structA" + > + > + query_info: < + topk: 5 + round_decimal: 3 + metric_type: "L2" + %4% + search_params: "{\"ef\": 50}" + > + placeholder_tag: "$0">)") % + vec_fid.get() % int_array_fid.get() % + int64_fid.get() % hints_line); + + proto::plan::PlanNode plan_node; + auto ok = + google::protobuf::TextFormat::ParseFromString(raw_plan, &plan_node); + ASSERT_TRUE(ok) << "Failed to parse element-level filter plan"; + + auto plan = CreateSearchPlanFromPlanNode(schema, plan_node); + ASSERT_NE(plan, nullptr); + + auto num_queries = 1; + auto seed = 1024; + auto ph_group_raw = + CreatePlaceholderGroup(num_queries, dim, seed, true); + auto ph_group = + ParsePlaceholderGroup(plan.get(), ph_group_raw.SerializeAsString()); + + auto search_result = + segment->Search(plan.get(), ph_group.get(), 1L << 63); + + // Verify results + ASSERT_NE(search_result, nullptr); + + // In element-level mode, results should be element indices, not doc offsets + ASSERT_TRUE(search_result->element_level_); + ASSERT_FALSE(search_result->element_indices_.empty()); + // Also check seg_offsets_ which stores the doc IDs + ASSERT_FALSE(search_result->seg_offsets_.empty()); + ASSERT_EQ(search_result->element_indices_.size(), + search_result->seg_offsets_.size()); + + // Should have topK results per query + ASSERT_LE(search_result->element_indices_.size(), topK * num_queries); + + std::cout << "Element-level search returned:" << std::endl; + for (auto i = 0; i < search_result->seg_offsets_.size(); i++) { + std::cout << "doc_id: " << search_result->seg_offsets_[i] + << ", element_index: " + << search_result->element_indices_[i] << std::endl; + std::cout << "distance: " << search_result->distances_[i] + << std::endl; + } + + // Verify distances are sorted (ascending for L2) + for (size_t i = 1; i < search_result->distances_.size(); ++i) { + ASSERT_LE(search_result->distances_[i - 1], + search_result->distances_[i]) + << "Distances should be sorted in ascending order"; + } + } +} + +INSTANTIATE_TEST_SUITE_P( + ElementFilter, + ElementFilterSealed, + ::testing::Combine(::testing::Bool(), // with_hints: true/false + ::testing::Bool() // with_load_index: true/false + ), + [](const ::testing::TestParamInfo& info) { + bool with_hints = std::get<0>(info.param); + bool with_load_index = std::get<1>(info.param); + std::string name = ""; + name += with_hints ? "WithHints" : "WithoutHints"; + name += "_"; + name += with_load_index ? "WithLoadIndex" : "WithoutLoadIndex"; + return name; + }); + +TEST(ElementFilter, GrowingSegmentArrayOffsetsGrowing) { + int dim = 4; + auto schema = std::make_shared(); + 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 = 500; + int array_len = 3; + + auto raw_data = DataGen(schema, N, 42, 0, 1, array_len); + + // Customize int_array data: doc i has elements [i*3+1, i*3+2, i*3+3] + 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++) { + int value = row * array_len + elem + 1; + array_data->mutable_int_data()->mutable_data()->Add(value); + } + } + break; + } + } + + auto segment = CreateGrowingSegment(schema, empty_index_meta); + segment->PreInsert(N); + segment->Insert(0, + N, + raw_data.row_ids_.data(), + raw_data.timestamps_.data(), + raw_data.raw_); + + auto growing_impl = dynamic_cast(segment.get()); + ASSERT_NE(growing_impl, nullptr); + + // Both fields should share the same ArrayOffsetsGrowing + auto offsets_vec = growing_impl->GetArrayOffsets(vec_fid); + auto offsets_int = growing_impl->GetArrayOffsets(int_array_fid); + ASSERT_NE(offsets_vec, nullptr); + ASSERT_NE(offsets_int, nullptr); + + // Should point to the same object (shared) + ASSERT_EQ(offsets_vec, offsets_int) + << "Fields in same struct should share ArrayOffsetsGrowing"; + + // Verify counts + ASSERT_EQ(offsets_vec->GetRowCount(), N) + << "Should have " << N << " documents"; + ASSERT_EQ(offsets_vec->GetTotalElementCount(), N * array_len) + << "Should have " << N * array_len << " total elements"; + + for (int64_t doc_id = 0; doc_id < N; ++doc_id) { + for (int32_t elem_idx = 0; elem_idx < array_len; ++elem_idx) { + int64_t elem_id = doc_id * array_len + elem_idx; + auto [mapped_doc, mapped_idx] = + offsets_vec->ElementIDToRowID(elem_id); + + ASSERT_EQ(mapped_doc, doc_id) + << "Element " << elem_id << " should map to doc " << doc_id; + ASSERT_EQ(mapped_idx, elem_idx) + << "Element " << elem_id << " should have index " << elem_idx; + } + } +} + +TEST(ElementFilter, GrowingSegmentOutOfOrderInsert) { + // Test out-of-order Insert handling in ArrayOffsetsGrowing + int dim = 4; + auto schema = std::make_shared(); + 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); + + int array_len = 3; + + // Create growing segment + auto segment = CreateGrowingSegment(schema, empty_index_meta); + + // Simulate out-of-order inserts + // Insert docs [10-19], [0-9], [20-29] + auto gen_batch = [&](int64_t start, int64_t count) { + auto batch = DataGen(schema, count, 42 + start, start, 1, array_len); + + // Customize int_array data + for (int i = 0; i < batch.raw_->fields_data_size(); i++) { + auto* field_data = batch.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 < count; row++) { + int64_t global_row = start + row; + auto* array_data = field_data->mutable_scalars() + ->mutable_array_data() + ->mutable_data() + ->Add(); + + for (int elem = 0; elem < array_len; elem++) { + int value = global_row * array_len + elem + 1; + array_data->mutable_int_data()->mutable_data()->Add( + value); + } + } + break; + } + } + + return batch; + }; + + // Insert batch 2 first (docs 10-19) - should be cached + auto batch2 = gen_batch(10, 10); + segment->PreInsert(10); + segment->Insert( + 10, 10, batch2.row_ids_.data(), batch2.timestamps_.data(), batch2.raw_); + + // Insert batch 1 (docs 0-9) - should trigger drain of batch 2 + auto batch1 = gen_batch(0, 10); + segment->PreInsert(10); + segment->Insert( + 0, 10, batch1.row_ids_.data(), batch1.timestamps_.data(), batch1.raw_); + + // Insert batch 3 (docs 25-34) - should be cached (gap at 20-24) + auto batch3 = gen_batch(25, 10); + segment->PreInsert(10); + segment->Insert( + 25, 10, batch3.row_ids_.data(), batch3.timestamps_.data(), batch3.raw_); + + // Verify ArrayOffsetsGrowing + auto growing_impl = dynamic_cast(segment.get()); + ASSERT_NE(growing_impl, nullptr); + + auto offsets = growing_impl->GetArrayOffsets(vec_fid); + ASSERT_NE(offsets, nullptr); + + // After inserting docs [0-19] (batch3 cached due to gap), committed count should be 20 + ASSERT_EQ(offsets->GetRowCount(), 20) + << "Should have committed docs 0-19, batch3 cached"; + ASSERT_EQ(offsets->GetTotalElementCount(), 20 * array_len) + << "Should have 20 docs worth of elements"; + + // Verify mapping for committed docs + for (int64_t doc_id = 0; doc_id < 20; ++doc_id) { + for (int32_t elem_idx = 0; elem_idx < array_len; ++elem_idx) { + int64_t elem_id = doc_id * array_len + elem_idx; + auto [mapped_doc, mapped_idx] = offsets->ElementIDToRowID(elem_id); + + ASSERT_EQ(mapped_doc, doc_id) + << "Element " << elem_id << " should map to doc " << doc_id; + ASSERT_EQ(mapped_idx, elem_idx); + } + } +} + +// Parameterized test fixture for GrowingIterativeRangeExpr +class ElementFilterGrowing : public ::testing::TestWithParam { + protected: + bool + use_hints() const { + return GetParam(); + } +}; + +TEST_P(ElementFilterGrowing, RangeExpr) { + bool with_hints = use_hints(); + int dim = 4; + auto schema = std::make_shared(); + 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 = 500; + int array_len = 3; + + // Generate test data + auto raw_data = DataGen(schema, N, 42, 0, 1, array_len); + + // Customize int_array data: doc i has elements [i*3+1, i*3+2, i*3+3] + 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++) { + int value = row * array_len + elem + 1; + array_data->mutable_int_data()->mutable_data()->Add(value); + } + } + break; + } + } + + // Create growing segment and insert data + auto segment = CreateGrowingSegment(schema, empty_index_meta); + segment->PreInsert(N); + segment->Insert(0, + N, + raw_data.row_ids_.data(), + raw_data.timestamps_.data(), + raw_data.raw_); + + // Verify ArrayOffsetsGrowing was built + auto growing_impl = dynamic_cast(segment.get()); + ASSERT_NE(growing_impl, nullptr); + auto offsets = growing_impl->GetArrayOffsets(vec_fid); + ASSERT_NE(offsets, nullptr); + ASSERT_EQ(offsets->GetRowCount(), N); + ASSERT_EQ(offsets->GetTotalElementCount(), N * array_len); + + int topK = 5; + + // Execute element-level search with iterative filter + // Query: Search array elements where (id % 2 == 0) AND (price_array element in range (100, 400)) + { + std::string hints_line = + with_hints ? R"(hints: "iterative_filter")" : ""; + std::string raw_plan = boost::str(boost::format(R"(vector_anns: < + field_id: %1% + predicates: < + element_filter_expr: < + element_expr: < + binary_range_expr: < + column_info: < + field_id: %2% + data_type: Int32 + element_type: Int32 + is_element_level: true + > + lower_inclusive: false + upper_inclusive: false + lower_value: < + int64_val: 100 + > + upper_value: < + int64_val: 400 + > + > + > + predicate: < + binary_arith_op_eval_range_expr: < + column_info: < + field_id: %3% + data_type: Int64 + > + arith_op: Mod + right_operand: < + int64_val: 2 + > + op: Equal + value: < + int64_val: 0 + > + > + > + struct_name: "structA" + > + > + query_info: < + topk: 5 + round_decimal: 3 + metric_type: "L2" + %4% + search_params: "{\"ef\": 50}" + > + placeholder_tag: "$0">)") % + vec_fid.get() % int_array_fid.get() % + int64_fid.get() % hints_line); + + proto::plan::PlanNode plan_node; + auto ok = + google::protobuf::TextFormat::ParseFromString(raw_plan, &plan_node); + ASSERT_TRUE(ok) << "Failed to parse element-level filter plan"; + + auto plan = CreateSearchPlanFromPlanNode(schema, plan_node); + ASSERT_NE(plan, nullptr); + + auto num_queries = 1; + auto seed = 1024; + auto ph_group_raw = + CreatePlaceholderGroup(num_queries, dim, seed, true); + auto ph_group = + ParsePlaceholderGroup(plan.get(), ph_group_raw.SerializeAsString()); + + auto search_result = + segment->Search(plan.get(), ph_group.get(), 1L << 63); + + // Verify results + ASSERT_NE(search_result, nullptr); + + // In element-level mode, results should contain element indices + ASSERT_TRUE(search_result->element_level_) + << "Search should be in element-level mode"; + ASSERT_FALSE(search_result->element_indices_.empty()) + << "Should have element indices"; + ASSERT_FALSE(search_result->seg_offsets_.empty()) + << "Should have doc offsets"; + ASSERT_EQ(search_result->element_indices_.size(), + search_result->seg_offsets_.size()) + << "Element indices and doc offsets should match in size"; + + // Should have topK results per query + ASSERT_LE(search_result->element_indices_.size(), topK * num_queries) + << "Should not exceed topK results"; + + std::cout << "Growing segment element-level search results:" + << std::endl; + for (size_t i = 0; i < search_result->seg_offsets_.size(); i++) { + int64_t doc_id = search_result->seg_offsets_[i]; + int32_t elem_idx = search_result->element_indices_[i]; + float distance = search_result->distances_[i]; + + std::cout << " [" << i << "] doc_id=" << doc_id + << ", element_index=" << elem_idx + << ", distance=" << distance << std::endl; + + // Verify the doc_id satisfies the predicate (id % 2 == 0) + ASSERT_EQ(doc_id % 2, 0) << "Result doc_id " << doc_id + << " should satisfy (id % 2 == 0)"; + + // Verify element_idx is valid + ASSERT_GE(elem_idx, 0) << "Element index should be >= 0"; + ASSERT_LT(elem_idx, array_len) + << "Element index should be < array_len"; + + // Verify element value is in range (100, 400) + // Element value = doc_id * array_len + elem_idx + 1 + int element_value = doc_id * array_len + elem_idx + 1; + ASSERT_GT(element_value, 100) + << "Element value " << element_value << " should be > 100"; + ASSERT_LT(element_value, 400) + << "Element value " << element_value << " should be < 400"; + } + + // Verify distances are sorted (ascending for L2) + for (size_t i = 1; i < search_result->distances_.size(); ++i) { + ASSERT_LE(search_result->distances_[i - 1], + search_result->distances_[i]) + << "Distances should be sorted in ascending order"; + } + } +} + +INSTANTIATE_TEST_SUITE_P( + ElementFilter, + ElementFilterGrowing, + ::testing::Bool(), // with_hints: true/false + [](const ::testing::TestParamInfo& info) { + bool with_hints = info.param; + return with_hints ? "WithHints" : "WithoutHints"; + }); + +// Unit tests for ArrayOffsetsGrowing +TEST(ArrayOffsetsGrowing, PurePendingThenDrain) { + // Test: first insert goes entirely to pending, second insert triggers drain + ArrayOffsetsGrowing offsets; + + // First insert: rows 2-4, all go to pending (committed_row_count_ = 0) + std::vector lens1 = { + 3, 2, 4}; // row 2: 3 elems, row 3: 2 elems, row 4: 4 elems + offsets.Insert(2, lens1.data(), 3); + + ASSERT_EQ(offsets.GetRowCount(), 0) << "No rows should be committed yet"; + ASSERT_EQ(offsets.GetTotalElementCount(), 0) + << "No elements should exist yet"; + + // Second insert: rows 0-1, triggers drain of pending rows 2-4 + std::vector lens2 = {2, 3}; // row 0: 2 elems, row 1: 3 elems + offsets.Insert(0, lens2.data(), 2); + + ASSERT_EQ(offsets.GetRowCount(), 5) << "All 5 rows should be committed"; + // Total elements: 2 + 3 + 3 + 2 + 4 = 14 + ASSERT_EQ(offsets.GetTotalElementCount(), 14); + + // Verify ElementIDToRowID mapping + // Row 0: elem 0-1, Row 1: elem 2-4, Row 2: elem 5-7, Row 3: elem 8-9, Row 4: elem 10-13 + std::vector> expected = { + {0, 0}, + {0, 1}, // row 0 + {1, 0}, + {1, 1}, + {1, 2}, // row 1 + {2, 0}, + {2, 1}, + {2, 2}, // row 2 + {3, 0}, + {3, 1}, // row 3 + {4, 0}, + {4, 1}, + {4, 2}, + {4, 3} // row 4 + }; + + for (int32_t elem_id = 0; elem_id < 14; ++elem_id) { + auto [row_id, elem_idx] = offsets.ElementIDToRowID(elem_id); + ASSERT_EQ(row_id, expected[elem_id].first) + << "elem_id " << elem_id << " should map to row " + << expected[elem_id].first; + ASSERT_EQ(elem_idx, expected[elem_id].second) + << "elem_id " << elem_id << " should have elem_idx " + << expected[elem_id].second; + } +} + +TEST(ArrayOffsetsGrowing, ElementIDRangeOfRow) { + ArrayOffsetsGrowing offsets; + + // Insert 4 rows with varying element counts + std::vector lens = {3, 0, 2, 5}; // includes empty array + offsets.Insert(0, lens.data(), 4); + + ASSERT_EQ(offsets.GetRowCount(), 4); + ASSERT_EQ(offsets.GetTotalElementCount(), 10); // 3 + 0 + 2 + 5 + + // Verify ElementIDRangeOfRow + auto [start0, end0] = offsets.ElementIDRangeOfRow(0); + ASSERT_EQ(start0, 0); + ASSERT_EQ(end0, 3); + + auto [start1, end1] = offsets.ElementIDRangeOfRow(1); + ASSERT_EQ(start1, 3); + ASSERT_EQ(end1, 3); // empty array + + auto [start2, end2] = offsets.ElementIDRangeOfRow(2); + ASSERT_EQ(start2, 3); + ASSERT_EQ(end2, 5); + + auto [start3, end3] = offsets.ElementIDRangeOfRow(3); + ASSERT_EQ(start3, 5); + ASSERT_EQ(end3, 10); + + // Boundary: row_id == row_count returns (total, total) + auto [start4, end4] = offsets.ElementIDRangeOfRow(4); + ASSERT_EQ(start4, 10); + ASSERT_EQ(end4, 10); +} + +TEST(ArrayOffsetsGrowing, MultiplePendingBatches) { + // Test multiple pending batches being drained in order + ArrayOffsetsGrowing offsets; + + // Insert row 5 first + std::vector lens5 = {2}; + offsets.Insert(5, lens5.data(), 1); + ASSERT_EQ(offsets.GetRowCount(), 0); + + // Insert row 3 + std::vector lens3 = {3}; + offsets.Insert(3, lens3.data(), 1); + ASSERT_EQ(offsets.GetRowCount(), 0); + + // Insert row 1 + std::vector lens1 = {1}; + offsets.Insert(1, lens1.data(), 1); + ASSERT_EQ(offsets.GetRowCount(), 0); + + // Insert row 0 - should drain row 1, but not 3 or 5 (gap at 2) + std::vector lens0 = {2}; + offsets.Insert(0, lens0.data(), 1); + ASSERT_EQ(offsets.GetRowCount(), 2) << "Should commit rows 0-1"; + ASSERT_EQ(offsets.GetTotalElementCount(), 3); // 2 + 1 + + // Insert row 2 - should drain rows 3, but not 5 (gap at 4) + std::vector lens2 = {1}; + offsets.Insert(2, lens2.data(), 1); + ASSERT_EQ(offsets.GetRowCount(), 4) << "Should commit rows 0-3"; + ASSERT_EQ(offsets.GetTotalElementCount(), 7); // 2 + 1 + 1 + 3 + + // Insert row 4 - should drain row 5 + std::vector lens4 = {2}; + offsets.Insert(4, lens4.data(), 1); + ASSERT_EQ(offsets.GetRowCount(), 6) << "Should commit rows 0-5"; + ASSERT_EQ(offsets.GetTotalElementCount(), 11); // 2 + 1 + 1 + 3 + 2 + 2 + + // Verify final mapping + // Row 0: elem 0-1, Row 1: elem 2, Row 2: elem 3, Row 3: elem 4-6, Row 4: elem 7-8, Row 5: elem 9-10 + auto [r0, i0] = offsets.ElementIDToRowID(0); + ASSERT_EQ(r0, 0); + ASSERT_EQ(i0, 0); + + auto [r2, i2] = offsets.ElementIDToRowID(2); + ASSERT_EQ(r2, 1); + ASSERT_EQ(i2, 0); + + auto [r4, i4] = offsets.ElementIDToRowID(4); + ASSERT_EQ(r4, 3); + ASSERT_EQ(i4, 0); + + auto [r7, i7] = offsets.ElementIDToRowID(7); + ASSERT_EQ(r7, 4); + ASSERT_EQ(i7, 0); + + auto [r10, i10] = offsets.ElementIDToRowID(10); + ASSERT_EQ(r10, 5); + ASSERT_EQ(i10, 1); +} diff --git a/internal/core/unittest/test_indexing.cpp b/internal/core/unittest/test_indexing.cpp index 2400ea4276..994c1ce72a 100644 --- a/internal/core/unittest/test_indexing.cpp +++ b/internal/core/unittest/test_indexing.cpp @@ -191,7 +191,7 @@ TEST(Indexing, BinaryBruteForce) { SearchResult sr; sr.total_nq_ = num_queries; sr.unity_topK_ = topk; - sr.seg_offsets_ = std::move(sub_result.mutable_seg_offsets()); + sr.seg_offsets_ = std::move(sub_result.mutable_offsets()); sr.distances_ = std::move(sub_result.mutable_distances()); auto json = SearchResultToJson(sr); diff --git a/internal/core/unittest/test_string_expr.cpp b/internal/core/unittest/test_string_expr.cpp index 8f1150d824..75c43a9d25 100644 --- a/internal/core/unittest/test_string_expr.cpp +++ b/internal/core/unittest/test_string_expr.cpp @@ -1579,7 +1579,7 @@ TEST(AlwaysTrueStringPlan, SearchWithOutputFields) { for (auto q = 0; q < num_queries; q++) { for (auto k = 0; k < topk; k++) { auto offset = q * topk + k; - auto seg_offset = sub_result.get_seg_offsets()[offset]; + auto seg_offset = sub_result.get_offsets()[offset]; ASSERT_EQ(std::get(sr->primary_keys_[offset]), str_col[seg_offset]); ASSERT_EQ(retrieved_str_col[offset], str_col[seg_offset]); diff --git a/internal/core/unittest/test_utils/DataGen.h b/internal/core/unittest/test_utils/DataGen.h index 8bf2ddd5c7..7ec8187a71 100644 --- a/internal/core/unittest/test_utils/DataGen.h +++ b/internal/core/unittest/test_utils/DataGen.h @@ -1151,7 +1151,10 @@ CreatePlaceholderGroup(int64_t num_queries, template auto -CreatePlaceholderGroup(int64_t num_queries, int dim, int64_t seed = 42) { +CreatePlaceholderGroup(int64_t num_queries, + int dim, + int64_t seed = 42, + bool element_level = false) { if (std::is_same_v) { assert(dim % 8 == 0); } @@ -1162,6 +1165,7 @@ CreatePlaceholderGroup(int64_t num_queries, int dim, int64_t seed = 42) { auto value = raw_group.add_placeholders(); value->set_tag("$0"); value->set_type(TraitType::placeholder_type); + value->set_element_level(element_level); // TODO caiyd: need update for Int8Vector std::normal_distribution dis(0, 1); std::default_random_engine e(seed); diff --git a/internal/parser/planparserv2/Plan.g4 b/internal/parser/planparserv2/Plan.g4 index d73ed2f597..0bfd2633db 100644 --- a/internal/parser/planparserv2/Plan.g4 +++ b/internal/parser/planparserv2/Plan.g4 @@ -3,53 +3,55 @@ grammar Plan; expr: Identifier (op1=(ADD | SUB) INTERVAL interval_string=StringLiteral)? op2=(LT | LE | GT | GE | EQ | NE) ISO compare_string=StringLiteral # TimestamptzCompareForward | ISO compare_string=StringLiteral op2=(LT | LE | GT | GE | EQ | NE) Identifier (op1=(ADD | SUB) INTERVAL interval_string=StringLiteral)? # TimestamptzCompareReverse - | IntegerConstant # Integer - | FloatingConstant # Floating - | BooleanConstant # Boolean - | StringLiteral # String - | (Identifier|Meta) # Identifier - | JSONIdentifier # JSONIdentifier - | LBRACE Identifier RBRACE # TemplateVariable - | '(' expr ')' # Parens - | '[' expr (',' expr)* ','? ']' # Array - | EmptyArray # EmptyArray - | EXISTS expr # Exists - | expr LIKE StringLiteral # Like - | TEXTMATCH'('Identifier',' StringLiteral (',' textMatchOption)? ')' # TextMatch - | PHRASEMATCH'('Identifier',' StringLiteral (',' expr)? ')' # PhraseMatch - | RANDOMSAMPLE'(' expr ')' # RandomSample - | expr POW expr # Power - | op = (ADD | SUB | BNOT | NOT) expr # Unary -// | '(' typeName ')' expr # Cast - | expr op = (MUL | DIV | MOD) expr # MulDivMod - | expr op = (ADD | SUB) expr # AddSub - | expr op = (SHL | SHR) expr # Shift - | expr op = NOT? IN expr # Term - | (JSONContains | ArrayContains)'('expr',' expr')' # JSONContains - | (JSONContainsAll | ArrayContainsAll)'('expr',' expr')' # JSONContainsAll - | (JSONContainsAny | ArrayContainsAny)'('expr',' expr')' # JSONContainsAny - | STEuqals'('Identifier','StringLiteral')' # STEuqals - | STTouches'('Identifier','StringLiteral')' # STTouches - | STOverlaps'('Identifier','StringLiteral')' # STOverlaps - | STCrosses'('Identifier','StringLiteral')' # STCrosses - | STContains'('Identifier','StringLiteral')' # STContains - | STIntersects'('Identifier','StringLiteral')' # STIntersects - | STWithin'('Identifier','StringLiteral')' # STWithin - | STDWithin'('Identifier','StringLiteral',' expr')' # STDWithin - | STIsValid'('Identifier')' # STIsValid - | ArrayLength'('(Identifier | JSONIdentifier)')' # ArrayLength - | Identifier '(' ( expr (',' expr )* ','? )? ')' # Call - | expr op1 = (LT | LE) (Identifier | JSONIdentifier) op2 = (LT | LE) expr # Range - | expr op1 = (GT | GE) (Identifier | JSONIdentifier) op2 = (GT | GE) expr # ReverseRange - | expr op = (LT | LE | GT | GE) expr # Relational - | expr op = (EQ | NE) expr # Equality - | expr BAND expr # BitAnd - | expr BXOR expr # BitXor - | expr BOR expr # BitOr - | expr AND expr # LogicalAnd - | expr OR expr # LogicalOr - | (Identifier | JSONIdentifier) ISNULL # IsNull - | (Identifier | JSONIdentifier) ISNOTNULL # IsNotNull; + | IntegerConstant # Integer + | FloatingConstant # Floating + | BooleanConstant # Boolean + | StringLiteral # String + | (Identifier|Meta) # Identifier + | JSONIdentifier # JSONIdentifier + | StructSubFieldIdentifier # StructSubField + | LBRACE Identifier RBRACE # TemplateVariable + | '(' expr ')' # Parens + | '[' expr (',' expr)* ','? ']' # Array + | EmptyArray # EmptyArray + | EXISTS expr # Exists + | expr LIKE StringLiteral # Like + | TEXTMATCH'('Identifier',' StringLiteral (',' textMatchOption)? ')' # TextMatch + | PHRASEMATCH'('Identifier',' StringLiteral (',' expr)? ')' # PhraseMatch + | RANDOMSAMPLE'(' expr ')' # RandomSample + | ElementFilter'('Identifier',' expr')' # ElementFilter + | expr POW expr # Power + | op = (ADD | SUB | BNOT | NOT) expr # Unary +// | '(' typeName ')' expr # Cast + | expr op = (MUL | DIV | MOD) expr # MulDivMod + | expr op = (ADD | SUB) expr # AddSub + | expr op = (SHL | SHR) expr # Shift + | expr op = NOT? IN expr # Term + | (JSONContains | ArrayContains)'('expr',' expr')' # JSONContains + | (JSONContainsAll | ArrayContainsAll)'('expr',' expr')' # JSONContainsAll + | (JSONContainsAny | ArrayContainsAny)'('expr',' expr')' # JSONContainsAny + | STEuqals'('Identifier','StringLiteral')' # STEuqals + | STTouches'('Identifier','StringLiteral')' # STTouches + | STOverlaps'('Identifier','StringLiteral')' # STOverlaps + | STCrosses'('Identifier','StringLiteral')' # STCrosses + | STContains'('Identifier','StringLiteral')' # STContains + | STIntersects'('Identifier','StringLiteral')' # STIntersects + | STWithin'('Identifier','StringLiteral')' # STWithin + | STDWithin'('Identifier','StringLiteral',' expr')' # STDWithin + | STIsValid'('Identifier')' # STIsValid + | ArrayLength'('(Identifier | JSONIdentifier)')' # ArrayLength + | Identifier '(' ( expr (',' expr )* ','? )? ')' # Call + | expr op1 = (LT | LE) (Identifier | JSONIdentifier | StructSubFieldIdentifier) op2 = (LT | LE) expr # Range + | expr op1 = (GT | GE) (Identifier | JSONIdentifier | StructSubFieldIdentifier) op2 = (GT | GE) expr # ReverseRange + | expr op = (LT | LE | GT | GE) expr # Relational + | expr op = (EQ | NE) expr # Equality + | expr BAND expr # BitAnd + | expr BXOR expr # BitXor + | expr BOR expr # BitOr + | expr AND expr # LogicalAnd + | expr OR expr # LogicalOr + | (Identifier | JSONIdentifier) ISNULL # IsNull + | (Identifier | JSONIdentifier) ISNOTNULL # IsNotNull; textMatchOption: MINIMUM_SHOULD_MATCH ASSIGN IntegerConstant; @@ -115,6 +117,7 @@ ArrayContains: 'array_contains' | 'ARRAY_CONTAINS'; ArrayContainsAll: 'array_contains_all' | 'ARRAY_CONTAINS_ALL'; ArrayContainsAny: 'array_contains_any' | 'ARRAY_CONTAINS_ANY'; ArrayLength: 'array_length' | 'ARRAY_LENGTH'; +ElementFilter: 'element_filter' | 'ELEMENT_FILTER'; STEuqals:'st_equals' | 'ST_EQUALS'; STTouches:'st_touches' | 'ST_TOUCHES'; @@ -143,6 +146,7 @@ Meta: '$meta'; StringLiteral: EncodingPrefix? ('"' DoubleSCharSequence? '"' | '\'' SingleSCharSequence? '\''); JSONIdentifier: (Identifier | Meta)('[' (StringLiteral | DecimalConstant) ']')+; +StructSubFieldIdentifier: '$[' Identifier ']'; fragment EncodingPrefix: 'u8' | 'u' | 'U' | 'L'; diff --git a/internal/parser/planparserv2/fill_expression_value.go b/internal/parser/planparserv2/fill_expression_value.go index 282b00c7d6..75a08fa0b8 100644 --- a/internal/parser/planparserv2/fill_expression_value.go +++ b/internal/parser/planparserv2/fill_expression_value.go @@ -40,6 +40,14 @@ func FillExpressionValue(expr *planpb.Expr, templateValues map[string]*planpb.Ge return FillJSONContainsExpressionValue(e.JsonContainsExpr, templateValues) case *planpb.Expr_RandomSampleExpr: return FillExpressionValue(expr.GetExpr().(*planpb.Expr_RandomSampleExpr).RandomSampleExpr.GetPredicate(), templateValues) + case *planpb.Expr_ElementFilterExpr: + if err := FillExpressionValue(e.ElementFilterExpr.GetElementExpr(), templateValues); err != nil { + return err + } + if e.ElementFilterExpr.GetPredicate() != nil { + return FillExpressionValue(e.ElementFilterExpr.GetPredicate(), templateValues) + } + return nil default: return fmt.Errorf("this expression no need to fill placeholder with expr type: %T", e) } diff --git a/internal/parser/planparserv2/generated/Plan.interp b/internal/parser/planparserv2/generated/Plan.interp index e65a0ca6d4..6134d27abf 100644 --- a/internal/parser/planparserv2/generated/Plan.interp +++ b/internal/parser/planparserv2/generated/Plan.interp @@ -61,11 +61,13 @@ null null null null +null '$meta' null null null null +null token symbolic names: null @@ -117,6 +119,7 @@ ArrayContains ArrayContainsAll ArrayContainsAny ArrayLength +ElementFilter STEuqals STTouches STOverlaps @@ -133,6 +136,7 @@ Identifier Meta StringLiteral JSONIdentifier +StructSubFieldIdentifier Whitespace Newline @@ -142,4 +146,4 @@ textMatchOption atn: -[4, 1, 66, 244, 2, 0, 7, 0, 2, 1, 7, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 10, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 22, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 41, 8, 0, 10, 0, 12, 0, 44, 9, 0, 1, 0, 3, 0, 47, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 61, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 71, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 166, 8, 0, 10, 0, 12, 0, 169, 9, 0, 1, 0, 3, 0, 172, 8, 0, 3, 0, 174, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 181, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 197, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 235, 8, 0, 10, 0, 12, 0, 238, 9, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 2, 0, 2, 0, 14, 1, 0, 23, 24, 1, 0, 8, 13, 1, 0, 61, 62, 2, 0, 23, 24, 38, 39, 2, 0, 42, 42, 45, 45, 2, 0, 43, 43, 46, 46, 2, 0, 44, 44, 47, 47, 2, 0, 61, 61, 64, 64, 1, 0, 25, 27, 1, 0, 29, 30, 1, 0, 8, 9, 1, 0, 10, 11, 1, 0, 8, 11, 1, 0, 12, 13, 298, 0, 180, 1, 0, 0, 0, 2, 239, 1, 0, 0, 0, 4, 5, 6, 0, -1, 0, 5, 9, 5, 61, 0, 0, 6, 7, 7, 0, 0, 0, 7, 8, 5, 19, 0, 0, 8, 10, 5, 63, 0, 0, 9, 6, 1, 0, 0, 0, 9, 10, 1, 0, 0, 0, 10, 11, 1, 0, 0, 0, 11, 12, 7, 1, 0, 0, 12, 13, 5, 20, 0, 0, 13, 181, 5, 63, 0, 0, 14, 15, 5, 20, 0, 0, 15, 16, 5, 63, 0, 0, 16, 17, 7, 1, 0, 0, 17, 21, 5, 61, 0, 0, 18, 19, 7, 0, 0, 0, 19, 20, 5, 19, 0, 0, 20, 22, 5, 63, 0, 0, 21, 18, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 181, 1, 0, 0, 0, 23, 181, 5, 59, 0, 0, 24, 181, 5, 60, 0, 0, 25, 181, 5, 58, 0, 0, 26, 181, 5, 63, 0, 0, 27, 181, 7, 2, 0, 0, 28, 181, 5, 64, 0, 0, 29, 30, 5, 6, 0, 0, 30, 31, 5, 61, 0, 0, 31, 181, 5, 7, 0, 0, 32, 33, 5, 1, 0, 0, 33, 34, 3, 0, 0, 0, 34, 35, 5, 2, 0, 0, 35, 181, 1, 0, 0, 0, 36, 37, 5, 3, 0, 0, 37, 42, 3, 0, 0, 0, 38, 39, 5, 4, 0, 0, 39, 41, 3, 0, 0, 0, 40, 38, 1, 0, 0, 0, 41, 44, 1, 0, 0, 0, 42, 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 46, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 45, 47, 5, 4, 0, 0, 46, 45, 1, 0, 0, 0, 46, 47, 1, 0, 0, 0, 47, 48, 1, 0, 0, 0, 48, 49, 5, 5, 0, 0, 49, 181, 1, 0, 0, 0, 50, 181, 5, 41, 0, 0, 51, 52, 5, 15, 0, 0, 52, 181, 3, 0, 0, 36, 53, 54, 5, 16, 0, 0, 54, 55, 5, 1, 0, 0, 55, 56, 5, 61, 0, 0, 56, 57, 5, 4, 0, 0, 57, 60, 5, 63, 0, 0, 58, 59, 5, 4, 0, 0, 59, 61, 3, 2, 1, 0, 60, 58, 1, 0, 0, 0, 60, 61, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 181, 5, 2, 0, 0, 63, 64, 5, 17, 0, 0, 64, 65, 5, 1, 0, 0, 65, 66, 5, 61, 0, 0, 66, 67, 5, 4, 0, 0, 67, 70, 5, 63, 0, 0, 68, 69, 5, 4, 0, 0, 69, 71, 3, 0, 0, 0, 70, 68, 1, 0, 0, 0, 70, 71, 1, 0, 0, 0, 71, 72, 1, 0, 0, 0, 72, 181, 5, 2, 0, 0, 73, 74, 5, 18, 0, 0, 74, 75, 5, 1, 0, 0, 75, 76, 3, 0, 0, 0, 76, 77, 5, 2, 0, 0, 77, 181, 1, 0, 0, 0, 78, 79, 7, 3, 0, 0, 79, 181, 3, 0, 0, 30, 80, 81, 7, 4, 0, 0, 81, 82, 5, 1, 0, 0, 82, 83, 3, 0, 0, 0, 83, 84, 5, 4, 0, 0, 84, 85, 3, 0, 0, 0, 85, 86, 5, 2, 0, 0, 86, 181, 1, 0, 0, 0, 87, 88, 7, 5, 0, 0, 88, 89, 5, 1, 0, 0, 89, 90, 3, 0, 0, 0, 90, 91, 5, 4, 0, 0, 91, 92, 3, 0, 0, 0, 92, 93, 5, 2, 0, 0, 93, 181, 1, 0, 0, 0, 94, 95, 7, 6, 0, 0, 95, 96, 5, 1, 0, 0, 96, 97, 3, 0, 0, 0, 97, 98, 5, 4, 0, 0, 98, 99, 3, 0, 0, 0, 99, 100, 5, 2, 0, 0, 100, 181, 1, 0, 0, 0, 101, 102, 5, 49, 0, 0, 102, 103, 5, 1, 0, 0, 103, 104, 5, 61, 0, 0, 104, 105, 5, 4, 0, 0, 105, 106, 5, 63, 0, 0, 106, 181, 5, 2, 0, 0, 107, 108, 5, 50, 0, 0, 108, 109, 5, 1, 0, 0, 109, 110, 5, 61, 0, 0, 110, 111, 5, 4, 0, 0, 111, 112, 5, 63, 0, 0, 112, 181, 5, 2, 0, 0, 113, 114, 5, 51, 0, 0, 114, 115, 5, 1, 0, 0, 115, 116, 5, 61, 0, 0, 116, 117, 5, 4, 0, 0, 117, 118, 5, 63, 0, 0, 118, 181, 5, 2, 0, 0, 119, 120, 5, 52, 0, 0, 120, 121, 5, 1, 0, 0, 121, 122, 5, 61, 0, 0, 122, 123, 5, 4, 0, 0, 123, 124, 5, 63, 0, 0, 124, 181, 5, 2, 0, 0, 125, 126, 5, 53, 0, 0, 126, 127, 5, 1, 0, 0, 127, 128, 5, 61, 0, 0, 128, 129, 5, 4, 0, 0, 129, 130, 5, 63, 0, 0, 130, 181, 5, 2, 0, 0, 131, 132, 5, 54, 0, 0, 132, 133, 5, 1, 0, 0, 133, 134, 5, 61, 0, 0, 134, 135, 5, 4, 0, 0, 135, 136, 5, 63, 0, 0, 136, 181, 5, 2, 0, 0, 137, 138, 5, 55, 0, 0, 138, 139, 5, 1, 0, 0, 139, 140, 5, 61, 0, 0, 140, 141, 5, 4, 0, 0, 141, 142, 5, 63, 0, 0, 142, 181, 5, 2, 0, 0, 143, 144, 5, 56, 0, 0, 144, 145, 5, 1, 0, 0, 145, 146, 5, 61, 0, 0, 146, 147, 5, 4, 0, 0, 147, 148, 5, 63, 0, 0, 148, 149, 5, 4, 0, 0, 149, 150, 3, 0, 0, 0, 150, 151, 5, 2, 0, 0, 151, 181, 1, 0, 0, 0, 152, 153, 5, 57, 0, 0, 153, 154, 5, 1, 0, 0, 154, 155, 5, 61, 0, 0, 155, 181, 5, 2, 0, 0, 156, 157, 5, 48, 0, 0, 157, 158, 5, 1, 0, 0, 158, 159, 7, 7, 0, 0, 159, 181, 5, 2, 0, 0, 160, 161, 5, 61, 0, 0, 161, 173, 5, 1, 0, 0, 162, 167, 3, 0, 0, 0, 163, 164, 5, 4, 0, 0, 164, 166, 3, 0, 0, 0, 165, 163, 1, 0, 0, 0, 166, 169, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 167, 168, 1, 0, 0, 0, 168, 171, 1, 0, 0, 0, 169, 167, 1, 0, 0, 0, 170, 172, 5, 4, 0, 0, 171, 170, 1, 0, 0, 0, 171, 172, 1, 0, 0, 0, 172, 174, 1, 0, 0, 0, 173, 162, 1, 0, 0, 0, 173, 174, 1, 0, 0, 0, 174, 175, 1, 0, 0, 0, 175, 181, 5, 2, 0, 0, 176, 177, 7, 7, 0, 0, 177, 181, 5, 36, 0, 0, 178, 179, 7, 7, 0, 0, 179, 181, 5, 37, 0, 0, 180, 4, 1, 0, 0, 0, 180, 14, 1, 0, 0, 0, 180, 23, 1, 0, 0, 0, 180, 24, 1, 0, 0, 0, 180, 25, 1, 0, 0, 0, 180, 26, 1, 0, 0, 0, 180, 27, 1, 0, 0, 0, 180, 28, 1, 0, 0, 0, 180, 29, 1, 0, 0, 0, 180, 32, 1, 0, 0, 0, 180, 36, 1, 0, 0, 0, 180, 50, 1, 0, 0, 0, 180, 51, 1, 0, 0, 0, 180, 53, 1, 0, 0, 0, 180, 63, 1, 0, 0, 0, 180, 73, 1, 0, 0, 0, 180, 78, 1, 0, 0, 0, 180, 80, 1, 0, 0, 0, 180, 87, 1, 0, 0, 0, 180, 94, 1, 0, 0, 0, 180, 101, 1, 0, 0, 0, 180, 107, 1, 0, 0, 0, 180, 113, 1, 0, 0, 0, 180, 119, 1, 0, 0, 0, 180, 125, 1, 0, 0, 0, 180, 131, 1, 0, 0, 0, 180, 137, 1, 0, 0, 0, 180, 143, 1, 0, 0, 0, 180, 152, 1, 0, 0, 0, 180, 156, 1, 0, 0, 0, 180, 160, 1, 0, 0, 0, 180, 176, 1, 0, 0, 0, 180, 178, 1, 0, 0, 0, 181, 236, 1, 0, 0, 0, 182, 183, 10, 31, 0, 0, 183, 184, 5, 28, 0, 0, 184, 235, 3, 0, 0, 32, 185, 186, 10, 29, 0, 0, 186, 187, 7, 8, 0, 0, 187, 235, 3, 0, 0, 30, 188, 189, 10, 28, 0, 0, 189, 190, 7, 0, 0, 0, 190, 235, 3, 0, 0, 29, 191, 192, 10, 27, 0, 0, 192, 193, 7, 9, 0, 0, 193, 235, 3, 0, 0, 28, 194, 196, 10, 26, 0, 0, 195, 197, 5, 39, 0, 0, 196, 195, 1, 0, 0, 0, 196, 197, 1, 0, 0, 0, 197, 198, 1, 0, 0, 0, 198, 199, 5, 40, 0, 0, 199, 235, 3, 0, 0, 27, 200, 201, 10, 11, 0, 0, 201, 202, 7, 10, 0, 0, 202, 203, 7, 7, 0, 0, 203, 204, 7, 10, 0, 0, 204, 235, 3, 0, 0, 12, 205, 206, 10, 10, 0, 0, 206, 207, 7, 11, 0, 0, 207, 208, 7, 7, 0, 0, 208, 209, 7, 11, 0, 0, 209, 235, 3, 0, 0, 11, 210, 211, 10, 9, 0, 0, 211, 212, 7, 12, 0, 0, 212, 235, 3, 0, 0, 10, 213, 214, 10, 8, 0, 0, 214, 215, 7, 13, 0, 0, 215, 235, 3, 0, 0, 9, 216, 217, 10, 7, 0, 0, 217, 218, 5, 31, 0, 0, 218, 235, 3, 0, 0, 8, 219, 220, 10, 6, 0, 0, 220, 221, 5, 33, 0, 0, 221, 235, 3, 0, 0, 7, 222, 223, 10, 5, 0, 0, 223, 224, 5, 32, 0, 0, 224, 235, 3, 0, 0, 6, 225, 226, 10, 4, 0, 0, 226, 227, 5, 34, 0, 0, 227, 235, 3, 0, 0, 5, 228, 229, 10, 3, 0, 0, 229, 230, 5, 35, 0, 0, 230, 235, 3, 0, 0, 4, 231, 232, 10, 35, 0, 0, 232, 233, 5, 14, 0, 0, 233, 235, 5, 63, 0, 0, 234, 182, 1, 0, 0, 0, 234, 185, 1, 0, 0, 0, 234, 188, 1, 0, 0, 0, 234, 191, 1, 0, 0, 0, 234, 194, 1, 0, 0, 0, 234, 200, 1, 0, 0, 0, 234, 205, 1, 0, 0, 0, 234, 210, 1, 0, 0, 0, 234, 213, 1, 0, 0, 0, 234, 216, 1, 0, 0, 0, 234, 219, 1, 0, 0, 0, 234, 222, 1, 0, 0, 0, 234, 225, 1, 0, 0, 0, 234, 228, 1, 0, 0, 0, 234, 231, 1, 0, 0, 0, 235, 238, 1, 0, 0, 0, 236, 234, 1, 0, 0, 0, 236, 237, 1, 0, 0, 0, 237, 1, 1, 0, 0, 0, 238, 236, 1, 0, 0, 0, 239, 240, 5, 21, 0, 0, 240, 241, 5, 22, 0, 0, 241, 242, 5, 59, 0, 0, 242, 3, 1, 0, 0, 0, 13, 9, 21, 42, 46, 60, 70, 167, 171, 173, 180, 196, 234, 236] \ No newline at end of file +[4, 1, 68, 252, 2, 0, 7, 0, 2, 1, 7, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 10, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 22, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 42, 8, 0, 10, 0, 12, 0, 45, 9, 0, 1, 0, 3, 0, 48, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 62, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 72, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 174, 8, 0, 10, 0, 12, 0, 177, 9, 0, 1, 0, 3, 0, 180, 8, 0, 3, 0, 182, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 189, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 205, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 243, 8, 0, 10, 0, 12, 0, 246, 9, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 2, 0, 2, 0, 15, 1, 0, 23, 24, 1, 0, 8, 13, 1, 0, 62, 63, 2, 0, 23, 24, 38, 39, 2, 0, 42, 42, 45, 45, 2, 0, 43, 43, 46, 46, 2, 0, 44, 44, 47, 47, 2, 0, 62, 62, 65, 65, 1, 0, 25, 27, 1, 0, 29, 30, 1, 0, 8, 9, 2, 0, 62, 62, 65, 66, 1, 0, 10, 11, 1, 0, 8, 11, 1, 0, 12, 13, 308, 0, 188, 1, 0, 0, 0, 2, 247, 1, 0, 0, 0, 4, 5, 6, 0, -1, 0, 5, 9, 5, 62, 0, 0, 6, 7, 7, 0, 0, 0, 7, 8, 5, 19, 0, 0, 8, 10, 5, 64, 0, 0, 9, 6, 1, 0, 0, 0, 9, 10, 1, 0, 0, 0, 10, 11, 1, 0, 0, 0, 11, 12, 7, 1, 0, 0, 12, 13, 5, 20, 0, 0, 13, 189, 5, 64, 0, 0, 14, 15, 5, 20, 0, 0, 15, 16, 5, 64, 0, 0, 16, 17, 7, 1, 0, 0, 17, 21, 5, 62, 0, 0, 18, 19, 7, 0, 0, 0, 19, 20, 5, 19, 0, 0, 20, 22, 5, 64, 0, 0, 21, 18, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 189, 1, 0, 0, 0, 23, 189, 5, 60, 0, 0, 24, 189, 5, 61, 0, 0, 25, 189, 5, 59, 0, 0, 26, 189, 5, 64, 0, 0, 27, 189, 7, 2, 0, 0, 28, 189, 5, 65, 0, 0, 29, 189, 5, 66, 0, 0, 30, 31, 5, 6, 0, 0, 31, 32, 5, 62, 0, 0, 32, 189, 5, 7, 0, 0, 33, 34, 5, 1, 0, 0, 34, 35, 3, 0, 0, 0, 35, 36, 5, 2, 0, 0, 36, 189, 1, 0, 0, 0, 37, 38, 5, 3, 0, 0, 38, 43, 3, 0, 0, 0, 39, 40, 5, 4, 0, 0, 40, 42, 3, 0, 0, 0, 41, 39, 1, 0, 0, 0, 42, 45, 1, 0, 0, 0, 43, 41, 1, 0, 0, 0, 43, 44, 1, 0, 0, 0, 44, 47, 1, 0, 0, 0, 45, 43, 1, 0, 0, 0, 46, 48, 5, 4, 0, 0, 47, 46, 1, 0, 0, 0, 47, 48, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 50, 5, 5, 0, 0, 50, 189, 1, 0, 0, 0, 51, 189, 5, 41, 0, 0, 52, 53, 5, 15, 0, 0, 53, 189, 3, 0, 0, 37, 54, 55, 5, 16, 0, 0, 55, 56, 5, 1, 0, 0, 56, 57, 5, 62, 0, 0, 57, 58, 5, 4, 0, 0, 58, 61, 5, 64, 0, 0, 59, 60, 5, 4, 0, 0, 60, 62, 3, 2, 1, 0, 61, 59, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 63, 1, 0, 0, 0, 63, 189, 5, 2, 0, 0, 64, 65, 5, 17, 0, 0, 65, 66, 5, 1, 0, 0, 66, 67, 5, 62, 0, 0, 67, 68, 5, 4, 0, 0, 68, 71, 5, 64, 0, 0, 69, 70, 5, 4, 0, 0, 70, 72, 3, 0, 0, 0, 71, 69, 1, 0, 0, 0, 71, 72, 1, 0, 0, 0, 72, 73, 1, 0, 0, 0, 73, 189, 5, 2, 0, 0, 74, 75, 5, 18, 0, 0, 75, 76, 5, 1, 0, 0, 76, 77, 3, 0, 0, 0, 77, 78, 5, 2, 0, 0, 78, 189, 1, 0, 0, 0, 79, 80, 5, 49, 0, 0, 80, 81, 5, 1, 0, 0, 81, 82, 5, 62, 0, 0, 82, 83, 5, 4, 0, 0, 83, 84, 3, 0, 0, 0, 84, 85, 5, 2, 0, 0, 85, 189, 1, 0, 0, 0, 86, 87, 7, 3, 0, 0, 87, 189, 3, 0, 0, 30, 88, 89, 7, 4, 0, 0, 89, 90, 5, 1, 0, 0, 90, 91, 3, 0, 0, 0, 91, 92, 5, 4, 0, 0, 92, 93, 3, 0, 0, 0, 93, 94, 5, 2, 0, 0, 94, 189, 1, 0, 0, 0, 95, 96, 7, 5, 0, 0, 96, 97, 5, 1, 0, 0, 97, 98, 3, 0, 0, 0, 98, 99, 5, 4, 0, 0, 99, 100, 3, 0, 0, 0, 100, 101, 5, 2, 0, 0, 101, 189, 1, 0, 0, 0, 102, 103, 7, 6, 0, 0, 103, 104, 5, 1, 0, 0, 104, 105, 3, 0, 0, 0, 105, 106, 5, 4, 0, 0, 106, 107, 3, 0, 0, 0, 107, 108, 5, 2, 0, 0, 108, 189, 1, 0, 0, 0, 109, 110, 5, 50, 0, 0, 110, 111, 5, 1, 0, 0, 111, 112, 5, 62, 0, 0, 112, 113, 5, 4, 0, 0, 113, 114, 5, 64, 0, 0, 114, 189, 5, 2, 0, 0, 115, 116, 5, 51, 0, 0, 116, 117, 5, 1, 0, 0, 117, 118, 5, 62, 0, 0, 118, 119, 5, 4, 0, 0, 119, 120, 5, 64, 0, 0, 120, 189, 5, 2, 0, 0, 121, 122, 5, 52, 0, 0, 122, 123, 5, 1, 0, 0, 123, 124, 5, 62, 0, 0, 124, 125, 5, 4, 0, 0, 125, 126, 5, 64, 0, 0, 126, 189, 5, 2, 0, 0, 127, 128, 5, 53, 0, 0, 128, 129, 5, 1, 0, 0, 129, 130, 5, 62, 0, 0, 130, 131, 5, 4, 0, 0, 131, 132, 5, 64, 0, 0, 132, 189, 5, 2, 0, 0, 133, 134, 5, 54, 0, 0, 134, 135, 5, 1, 0, 0, 135, 136, 5, 62, 0, 0, 136, 137, 5, 4, 0, 0, 137, 138, 5, 64, 0, 0, 138, 189, 5, 2, 0, 0, 139, 140, 5, 55, 0, 0, 140, 141, 5, 1, 0, 0, 141, 142, 5, 62, 0, 0, 142, 143, 5, 4, 0, 0, 143, 144, 5, 64, 0, 0, 144, 189, 5, 2, 0, 0, 145, 146, 5, 56, 0, 0, 146, 147, 5, 1, 0, 0, 147, 148, 5, 62, 0, 0, 148, 149, 5, 4, 0, 0, 149, 150, 5, 64, 0, 0, 150, 189, 5, 2, 0, 0, 151, 152, 5, 57, 0, 0, 152, 153, 5, 1, 0, 0, 153, 154, 5, 62, 0, 0, 154, 155, 5, 4, 0, 0, 155, 156, 5, 64, 0, 0, 156, 157, 5, 4, 0, 0, 157, 158, 3, 0, 0, 0, 158, 159, 5, 2, 0, 0, 159, 189, 1, 0, 0, 0, 160, 161, 5, 58, 0, 0, 161, 162, 5, 1, 0, 0, 162, 163, 5, 62, 0, 0, 163, 189, 5, 2, 0, 0, 164, 165, 5, 48, 0, 0, 165, 166, 5, 1, 0, 0, 166, 167, 7, 7, 0, 0, 167, 189, 5, 2, 0, 0, 168, 169, 5, 62, 0, 0, 169, 181, 5, 1, 0, 0, 170, 175, 3, 0, 0, 0, 171, 172, 5, 4, 0, 0, 172, 174, 3, 0, 0, 0, 173, 171, 1, 0, 0, 0, 174, 177, 1, 0, 0, 0, 175, 173, 1, 0, 0, 0, 175, 176, 1, 0, 0, 0, 176, 179, 1, 0, 0, 0, 177, 175, 1, 0, 0, 0, 178, 180, 5, 4, 0, 0, 179, 178, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 182, 1, 0, 0, 0, 181, 170, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 183, 1, 0, 0, 0, 183, 189, 5, 2, 0, 0, 184, 185, 7, 7, 0, 0, 185, 189, 5, 36, 0, 0, 186, 187, 7, 7, 0, 0, 187, 189, 5, 37, 0, 0, 188, 4, 1, 0, 0, 0, 188, 14, 1, 0, 0, 0, 188, 23, 1, 0, 0, 0, 188, 24, 1, 0, 0, 0, 188, 25, 1, 0, 0, 0, 188, 26, 1, 0, 0, 0, 188, 27, 1, 0, 0, 0, 188, 28, 1, 0, 0, 0, 188, 29, 1, 0, 0, 0, 188, 30, 1, 0, 0, 0, 188, 33, 1, 0, 0, 0, 188, 37, 1, 0, 0, 0, 188, 51, 1, 0, 0, 0, 188, 52, 1, 0, 0, 0, 188, 54, 1, 0, 0, 0, 188, 64, 1, 0, 0, 0, 188, 74, 1, 0, 0, 0, 188, 79, 1, 0, 0, 0, 188, 86, 1, 0, 0, 0, 188, 88, 1, 0, 0, 0, 188, 95, 1, 0, 0, 0, 188, 102, 1, 0, 0, 0, 188, 109, 1, 0, 0, 0, 188, 115, 1, 0, 0, 0, 188, 121, 1, 0, 0, 0, 188, 127, 1, 0, 0, 0, 188, 133, 1, 0, 0, 0, 188, 139, 1, 0, 0, 0, 188, 145, 1, 0, 0, 0, 188, 151, 1, 0, 0, 0, 188, 160, 1, 0, 0, 0, 188, 164, 1, 0, 0, 0, 188, 168, 1, 0, 0, 0, 188, 184, 1, 0, 0, 0, 188, 186, 1, 0, 0, 0, 189, 244, 1, 0, 0, 0, 190, 191, 10, 31, 0, 0, 191, 192, 5, 28, 0, 0, 192, 243, 3, 0, 0, 32, 193, 194, 10, 29, 0, 0, 194, 195, 7, 8, 0, 0, 195, 243, 3, 0, 0, 30, 196, 197, 10, 28, 0, 0, 197, 198, 7, 0, 0, 0, 198, 243, 3, 0, 0, 29, 199, 200, 10, 27, 0, 0, 200, 201, 7, 9, 0, 0, 201, 243, 3, 0, 0, 28, 202, 204, 10, 26, 0, 0, 203, 205, 5, 39, 0, 0, 204, 203, 1, 0, 0, 0, 204, 205, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 207, 5, 40, 0, 0, 207, 243, 3, 0, 0, 27, 208, 209, 10, 11, 0, 0, 209, 210, 7, 10, 0, 0, 210, 211, 7, 11, 0, 0, 211, 212, 7, 10, 0, 0, 212, 243, 3, 0, 0, 12, 213, 214, 10, 10, 0, 0, 214, 215, 7, 12, 0, 0, 215, 216, 7, 11, 0, 0, 216, 217, 7, 12, 0, 0, 217, 243, 3, 0, 0, 11, 218, 219, 10, 9, 0, 0, 219, 220, 7, 13, 0, 0, 220, 243, 3, 0, 0, 10, 221, 222, 10, 8, 0, 0, 222, 223, 7, 14, 0, 0, 223, 243, 3, 0, 0, 9, 224, 225, 10, 7, 0, 0, 225, 226, 5, 31, 0, 0, 226, 243, 3, 0, 0, 8, 227, 228, 10, 6, 0, 0, 228, 229, 5, 33, 0, 0, 229, 243, 3, 0, 0, 7, 230, 231, 10, 5, 0, 0, 231, 232, 5, 32, 0, 0, 232, 243, 3, 0, 0, 6, 233, 234, 10, 4, 0, 0, 234, 235, 5, 34, 0, 0, 235, 243, 3, 0, 0, 5, 236, 237, 10, 3, 0, 0, 237, 238, 5, 35, 0, 0, 238, 243, 3, 0, 0, 4, 239, 240, 10, 36, 0, 0, 240, 241, 5, 14, 0, 0, 241, 243, 5, 64, 0, 0, 242, 190, 1, 0, 0, 0, 242, 193, 1, 0, 0, 0, 242, 196, 1, 0, 0, 0, 242, 199, 1, 0, 0, 0, 242, 202, 1, 0, 0, 0, 242, 208, 1, 0, 0, 0, 242, 213, 1, 0, 0, 0, 242, 218, 1, 0, 0, 0, 242, 221, 1, 0, 0, 0, 242, 224, 1, 0, 0, 0, 242, 227, 1, 0, 0, 0, 242, 230, 1, 0, 0, 0, 242, 233, 1, 0, 0, 0, 242, 236, 1, 0, 0, 0, 242, 239, 1, 0, 0, 0, 243, 246, 1, 0, 0, 0, 244, 242, 1, 0, 0, 0, 244, 245, 1, 0, 0, 0, 245, 1, 1, 0, 0, 0, 246, 244, 1, 0, 0, 0, 247, 248, 5, 21, 0, 0, 248, 249, 5, 22, 0, 0, 249, 250, 5, 60, 0, 0, 250, 3, 1, 0, 0, 0, 13, 9, 21, 43, 47, 61, 71, 175, 179, 181, 188, 204, 242, 244] \ No newline at end of file diff --git a/internal/parser/planparserv2/generated/Plan.tokens b/internal/parser/planparserv2/generated/Plan.tokens index f834707a5d..374477f781 100644 --- a/internal/parser/planparserv2/generated/Plan.tokens +++ b/internal/parser/planparserv2/generated/Plan.tokens @@ -46,24 +46,26 @@ ArrayContains=45 ArrayContainsAll=46 ArrayContainsAny=47 ArrayLength=48 -STEuqals=49 -STTouches=50 -STOverlaps=51 -STCrosses=52 -STContains=53 -STIntersects=54 -STWithin=55 -STDWithin=56 -STIsValid=57 -BooleanConstant=58 -IntegerConstant=59 -FloatingConstant=60 -Identifier=61 -Meta=62 -StringLiteral=63 -JSONIdentifier=64 -Whitespace=65 -Newline=66 +ElementFilter=49 +STEuqals=50 +STTouches=51 +STOverlaps=52 +STCrosses=53 +STContains=54 +STIntersects=55 +STWithin=56 +STDWithin=57 +STIsValid=58 +BooleanConstant=59 +IntegerConstant=60 +FloatingConstant=61 +Identifier=62 +Meta=63 +StringLiteral=64 +JSONIdentifier=65 +StructSubFieldIdentifier=66 +Whitespace=67 +Newline=68 '('=1 ')'=2 '['=3 @@ -90,4 +92,4 @@ Newline=66 '|'=32 '^'=33 '~'=38 -'$meta'=62 +'$meta'=63 diff --git a/internal/parser/planparserv2/generated/PlanLexer.interp b/internal/parser/planparserv2/generated/PlanLexer.interp index 4718ffd2ae..343557898e 100644 --- a/internal/parser/planparserv2/generated/PlanLexer.interp +++ b/internal/parser/planparserv2/generated/PlanLexer.interp @@ -61,11 +61,13 @@ null null null null +null '$meta' null null null null +null token symbolic names: null @@ -117,6 +119,7 @@ ArrayContains ArrayContainsAll ArrayContainsAny ArrayLength +ElementFilter STEuqals STTouches STOverlaps @@ -133,6 +136,7 @@ Identifier Meta StringLiteral JSONIdentifier +StructSubFieldIdentifier Whitespace Newline @@ -185,6 +189,7 @@ ArrayContains ArrayContainsAll ArrayContainsAny ArrayLength +ElementFilter STEuqals STTouches STOverlaps @@ -201,6 +206,7 @@ Identifier Meta StringLiteral JSONIdentifier +StructSubFieldIdentifier EncodingPrefix DoubleSCharSequence SingleSCharSequence @@ -237,4 +243,4 @@ mode names: DEFAULT_MODE atn: -[4, 0, 66, 1192, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 222, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 236, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 258, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 284, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 312, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 3, 18, 330, 8, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 3, 19, 338, 8, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 380, 8, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 417, 8, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 425, 8, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 3, 35, 441, 8, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 465, 8, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 476, 8, 38, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 482, 8, 39, 1, 40, 1, 40, 1, 40, 5, 40, 487, 8, 40, 10, 40, 12, 40, 490, 9, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 520, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 556, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 592, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 622, 8, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 3, 45, 660, 8, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 698, 8, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 3, 47, 724, 8, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, 744, 8, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 3, 49, 766, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 3, 50, 790, 8, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 812, 8, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 3, 52, 836, 8, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 864, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 884, 8, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 3, 55, 906, 8, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 928, 8, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 957, 8, 57, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 963, 8, 58, 1, 59, 1, 59, 3, 59, 967, 8, 59, 1, 60, 1, 60, 1, 60, 5, 60, 972, 8, 60, 10, 60, 12, 60, 975, 9, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 3, 62, 984, 8, 62, 1, 62, 1, 62, 3, 62, 988, 8, 62, 1, 62, 1, 62, 1, 62, 3, 62, 993, 8, 62, 1, 62, 3, 62, 996, 8, 62, 1, 63, 1, 63, 3, 63, 1000, 8, 63, 1, 63, 1, 63, 1, 63, 3, 63, 1005, 8, 63, 1, 63, 1, 63, 4, 63, 1009, 8, 63, 11, 63, 12, 63, 1010, 1, 64, 1, 64, 1, 64, 3, 64, 1016, 8, 64, 1, 65, 4, 65, 1019, 8, 65, 11, 65, 12, 65, 1020, 1, 66, 4, 66, 1024, 8, 66, 11, 66, 12, 66, 1025, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 1035, 8, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1044, 8, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 4, 71, 1053, 8, 71, 11, 71, 12, 71, 1054, 1, 72, 1, 72, 5, 72, 1059, 8, 72, 10, 72, 12, 72, 1062, 9, 72, 1, 72, 3, 72, 1065, 8, 72, 1, 73, 1, 73, 5, 73, 1069, 8, 73, 10, 73, 12, 73, 1072, 9, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 3, 79, 1099, 8, 79, 1, 80, 1, 80, 3, 80, 1103, 8, 80, 1, 80, 1, 80, 1, 80, 3, 80, 1108, 8, 80, 1, 81, 1, 81, 1, 81, 1, 81, 3, 81, 1114, 8, 81, 1, 81, 1, 81, 1, 82, 3, 82, 1119, 8, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 3, 82, 1126, 8, 82, 1, 83, 1, 83, 3, 83, 1130, 8, 83, 1, 83, 1, 83, 1, 84, 4, 84, 1135, 8, 84, 11, 84, 12, 84, 1136, 1, 85, 3, 85, 1140, 8, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 3, 85, 1147, 8, 85, 1, 86, 4, 86, 1150, 8, 86, 11, 86, 12, 86, 1151, 1, 87, 1, 87, 3, 87, 1156, 8, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 3, 88, 1165, 8, 88, 1, 88, 3, 88, 1168, 8, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 3, 88, 1175, 8, 88, 1, 89, 4, 89, 1178, 8, 89, 11, 89, 12, 89, 1179, 1, 89, 1, 89, 1, 90, 1, 90, 3, 90, 1186, 8, 90, 1, 90, 3, 90, 1189, 8, 90, 1, 90, 1, 90, 0, 0, 91, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 56, 113, 57, 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, 64, 129, 0, 131, 0, 133, 0, 135, 0, 137, 0, 139, 0, 141, 0, 143, 0, 145, 0, 147, 0, 149, 0, 151, 0, 153, 0, 155, 0, 157, 0, 159, 0, 161, 0, 163, 0, 165, 0, 167, 0, 169, 0, 171, 0, 173, 0, 175, 0, 177, 0, 179, 65, 181, 66, 1, 0, 16, 3, 0, 76, 76, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 3, 0, 65, 90, 95, 95, 97, 122, 1, 0, 48, 57, 2, 0, 66, 66, 98, 98, 1, 0, 48, 49, 2, 0, 88, 88, 120, 120, 1, 0, 49, 57, 1, 0, 48, 55, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 80, 80, 112, 112, 10, 0, 34, 34, 39, 39, 63, 63, 92, 92, 97, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, 0, 9, 9, 32, 32, 1252, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 179, 1, 0, 0, 0, 0, 181, 1, 0, 0, 0, 1, 183, 1, 0, 0, 0, 3, 185, 1, 0, 0, 0, 5, 187, 1, 0, 0, 0, 7, 189, 1, 0, 0, 0, 9, 191, 1, 0, 0, 0, 11, 193, 1, 0, 0, 0, 13, 195, 1, 0, 0, 0, 15, 197, 1, 0, 0, 0, 17, 199, 1, 0, 0, 0, 19, 202, 1, 0, 0, 0, 21, 204, 1, 0, 0, 0, 23, 207, 1, 0, 0, 0, 25, 210, 1, 0, 0, 0, 27, 221, 1, 0, 0, 0, 29, 235, 1, 0, 0, 0, 31, 257, 1, 0, 0, 0, 33, 283, 1, 0, 0, 0, 35, 311, 1, 0, 0, 0, 37, 329, 1, 0, 0, 0, 39, 337, 1, 0, 0, 0, 41, 379, 1, 0, 0, 0, 43, 381, 1, 0, 0, 0, 45, 383, 1, 0, 0, 0, 47, 385, 1, 0, 0, 0, 49, 387, 1, 0, 0, 0, 51, 389, 1, 0, 0, 0, 53, 391, 1, 0, 0, 0, 55, 393, 1, 0, 0, 0, 57, 396, 1, 0, 0, 0, 59, 399, 1, 0, 0, 0, 61, 402, 1, 0, 0, 0, 63, 404, 1, 0, 0, 0, 65, 406, 1, 0, 0, 0, 67, 416, 1, 0, 0, 0, 69, 424, 1, 0, 0, 0, 71, 440, 1, 0, 0, 0, 73, 464, 1, 0, 0, 0, 75, 466, 1, 0, 0, 0, 77, 475, 1, 0, 0, 0, 79, 481, 1, 0, 0, 0, 81, 483, 1, 0, 0, 0, 83, 519, 1, 0, 0, 0, 85, 555, 1, 0, 0, 0, 87, 591, 1, 0, 0, 0, 89, 621, 1, 0, 0, 0, 91, 659, 1, 0, 0, 0, 93, 697, 1, 0, 0, 0, 95, 723, 1, 0, 0, 0, 97, 743, 1, 0, 0, 0, 99, 765, 1, 0, 0, 0, 101, 789, 1, 0, 0, 0, 103, 811, 1, 0, 0, 0, 105, 835, 1, 0, 0, 0, 107, 863, 1, 0, 0, 0, 109, 883, 1, 0, 0, 0, 111, 905, 1, 0, 0, 0, 113, 927, 1, 0, 0, 0, 115, 956, 1, 0, 0, 0, 117, 962, 1, 0, 0, 0, 119, 966, 1, 0, 0, 0, 121, 968, 1, 0, 0, 0, 123, 976, 1, 0, 0, 0, 125, 983, 1, 0, 0, 0, 127, 999, 1, 0, 0, 0, 129, 1015, 1, 0, 0, 0, 131, 1018, 1, 0, 0, 0, 133, 1023, 1, 0, 0, 0, 135, 1034, 1, 0, 0, 0, 137, 1043, 1, 0, 0, 0, 139, 1045, 1, 0, 0, 0, 141, 1047, 1, 0, 0, 0, 143, 1049, 1, 0, 0, 0, 145, 1064, 1, 0, 0, 0, 147, 1066, 1, 0, 0, 0, 149, 1073, 1, 0, 0, 0, 151, 1077, 1, 0, 0, 0, 153, 1079, 1, 0, 0, 0, 155, 1081, 1, 0, 0, 0, 157, 1083, 1, 0, 0, 0, 159, 1098, 1, 0, 0, 0, 161, 1107, 1, 0, 0, 0, 163, 1109, 1, 0, 0, 0, 165, 1125, 1, 0, 0, 0, 167, 1127, 1, 0, 0, 0, 169, 1134, 1, 0, 0, 0, 171, 1146, 1, 0, 0, 0, 173, 1149, 1, 0, 0, 0, 175, 1153, 1, 0, 0, 0, 177, 1174, 1, 0, 0, 0, 179, 1177, 1, 0, 0, 0, 181, 1188, 1, 0, 0, 0, 183, 184, 5, 40, 0, 0, 184, 2, 1, 0, 0, 0, 185, 186, 5, 41, 0, 0, 186, 4, 1, 0, 0, 0, 187, 188, 5, 91, 0, 0, 188, 6, 1, 0, 0, 0, 189, 190, 5, 44, 0, 0, 190, 8, 1, 0, 0, 0, 191, 192, 5, 93, 0, 0, 192, 10, 1, 0, 0, 0, 193, 194, 5, 123, 0, 0, 194, 12, 1, 0, 0, 0, 195, 196, 5, 125, 0, 0, 196, 14, 1, 0, 0, 0, 197, 198, 5, 60, 0, 0, 198, 16, 1, 0, 0, 0, 199, 200, 5, 60, 0, 0, 200, 201, 5, 61, 0, 0, 201, 18, 1, 0, 0, 0, 202, 203, 5, 62, 0, 0, 203, 20, 1, 0, 0, 0, 204, 205, 5, 62, 0, 0, 205, 206, 5, 61, 0, 0, 206, 22, 1, 0, 0, 0, 207, 208, 5, 61, 0, 0, 208, 209, 5, 61, 0, 0, 209, 24, 1, 0, 0, 0, 210, 211, 5, 33, 0, 0, 211, 212, 5, 61, 0, 0, 212, 26, 1, 0, 0, 0, 213, 214, 5, 108, 0, 0, 214, 215, 5, 105, 0, 0, 215, 216, 5, 107, 0, 0, 216, 222, 5, 101, 0, 0, 217, 218, 5, 76, 0, 0, 218, 219, 5, 73, 0, 0, 219, 220, 5, 75, 0, 0, 220, 222, 5, 69, 0, 0, 221, 213, 1, 0, 0, 0, 221, 217, 1, 0, 0, 0, 222, 28, 1, 0, 0, 0, 223, 224, 5, 101, 0, 0, 224, 225, 5, 120, 0, 0, 225, 226, 5, 105, 0, 0, 226, 227, 5, 115, 0, 0, 227, 228, 5, 116, 0, 0, 228, 236, 5, 115, 0, 0, 229, 230, 5, 69, 0, 0, 230, 231, 5, 88, 0, 0, 231, 232, 5, 73, 0, 0, 232, 233, 5, 83, 0, 0, 233, 234, 5, 84, 0, 0, 234, 236, 5, 83, 0, 0, 235, 223, 1, 0, 0, 0, 235, 229, 1, 0, 0, 0, 236, 30, 1, 0, 0, 0, 237, 238, 5, 116, 0, 0, 238, 239, 5, 101, 0, 0, 239, 240, 5, 120, 0, 0, 240, 241, 5, 116, 0, 0, 241, 242, 5, 95, 0, 0, 242, 243, 5, 109, 0, 0, 243, 244, 5, 97, 0, 0, 244, 245, 5, 116, 0, 0, 245, 246, 5, 99, 0, 0, 246, 258, 5, 104, 0, 0, 247, 248, 5, 84, 0, 0, 248, 249, 5, 69, 0, 0, 249, 250, 5, 88, 0, 0, 250, 251, 5, 84, 0, 0, 251, 252, 5, 95, 0, 0, 252, 253, 5, 77, 0, 0, 253, 254, 5, 65, 0, 0, 254, 255, 5, 84, 0, 0, 255, 256, 5, 67, 0, 0, 256, 258, 5, 72, 0, 0, 257, 237, 1, 0, 0, 0, 257, 247, 1, 0, 0, 0, 258, 32, 1, 0, 0, 0, 259, 260, 5, 112, 0, 0, 260, 261, 5, 104, 0, 0, 261, 262, 5, 114, 0, 0, 262, 263, 5, 97, 0, 0, 263, 264, 5, 115, 0, 0, 264, 265, 5, 101, 0, 0, 265, 266, 5, 95, 0, 0, 266, 267, 5, 109, 0, 0, 267, 268, 5, 97, 0, 0, 268, 269, 5, 116, 0, 0, 269, 270, 5, 99, 0, 0, 270, 284, 5, 104, 0, 0, 271, 272, 5, 80, 0, 0, 272, 273, 5, 72, 0, 0, 273, 274, 5, 82, 0, 0, 274, 275, 5, 65, 0, 0, 275, 276, 5, 83, 0, 0, 276, 277, 5, 69, 0, 0, 277, 278, 5, 95, 0, 0, 278, 279, 5, 77, 0, 0, 279, 280, 5, 65, 0, 0, 280, 281, 5, 84, 0, 0, 281, 282, 5, 67, 0, 0, 282, 284, 5, 72, 0, 0, 283, 259, 1, 0, 0, 0, 283, 271, 1, 0, 0, 0, 284, 34, 1, 0, 0, 0, 285, 286, 5, 114, 0, 0, 286, 287, 5, 97, 0, 0, 287, 288, 5, 110, 0, 0, 288, 289, 5, 100, 0, 0, 289, 290, 5, 111, 0, 0, 290, 291, 5, 109, 0, 0, 291, 292, 5, 95, 0, 0, 292, 293, 5, 115, 0, 0, 293, 294, 5, 97, 0, 0, 294, 295, 5, 109, 0, 0, 295, 296, 5, 112, 0, 0, 296, 297, 5, 108, 0, 0, 297, 312, 5, 101, 0, 0, 298, 299, 5, 82, 0, 0, 299, 300, 5, 65, 0, 0, 300, 301, 5, 78, 0, 0, 301, 302, 5, 68, 0, 0, 302, 303, 5, 79, 0, 0, 303, 304, 5, 77, 0, 0, 304, 305, 5, 95, 0, 0, 305, 306, 5, 83, 0, 0, 306, 307, 5, 65, 0, 0, 307, 308, 5, 77, 0, 0, 308, 309, 5, 80, 0, 0, 309, 310, 5, 76, 0, 0, 310, 312, 5, 69, 0, 0, 311, 285, 1, 0, 0, 0, 311, 298, 1, 0, 0, 0, 312, 36, 1, 0, 0, 0, 313, 314, 5, 105, 0, 0, 314, 315, 5, 110, 0, 0, 315, 316, 5, 116, 0, 0, 316, 317, 5, 101, 0, 0, 317, 318, 5, 114, 0, 0, 318, 319, 5, 118, 0, 0, 319, 320, 5, 97, 0, 0, 320, 330, 5, 108, 0, 0, 321, 322, 5, 73, 0, 0, 322, 323, 5, 78, 0, 0, 323, 324, 5, 84, 0, 0, 324, 325, 5, 69, 0, 0, 325, 326, 5, 82, 0, 0, 326, 327, 5, 86, 0, 0, 327, 328, 5, 65, 0, 0, 328, 330, 5, 76, 0, 0, 329, 313, 1, 0, 0, 0, 329, 321, 1, 0, 0, 0, 330, 38, 1, 0, 0, 0, 331, 332, 5, 105, 0, 0, 332, 333, 5, 115, 0, 0, 333, 338, 5, 111, 0, 0, 334, 335, 5, 73, 0, 0, 335, 336, 5, 83, 0, 0, 336, 338, 5, 79, 0, 0, 337, 331, 1, 0, 0, 0, 337, 334, 1, 0, 0, 0, 338, 40, 1, 0, 0, 0, 339, 340, 5, 109, 0, 0, 340, 341, 5, 105, 0, 0, 341, 342, 5, 110, 0, 0, 342, 343, 5, 105, 0, 0, 343, 344, 5, 109, 0, 0, 344, 345, 5, 117, 0, 0, 345, 346, 5, 109, 0, 0, 346, 347, 5, 95, 0, 0, 347, 348, 5, 115, 0, 0, 348, 349, 5, 104, 0, 0, 349, 350, 5, 111, 0, 0, 350, 351, 5, 117, 0, 0, 351, 352, 5, 108, 0, 0, 352, 353, 5, 100, 0, 0, 353, 354, 5, 95, 0, 0, 354, 355, 5, 109, 0, 0, 355, 356, 5, 97, 0, 0, 356, 357, 5, 116, 0, 0, 357, 358, 5, 99, 0, 0, 358, 380, 5, 104, 0, 0, 359, 360, 5, 77, 0, 0, 360, 361, 5, 73, 0, 0, 361, 362, 5, 78, 0, 0, 362, 363, 5, 73, 0, 0, 363, 364, 5, 77, 0, 0, 364, 365, 5, 85, 0, 0, 365, 366, 5, 77, 0, 0, 366, 367, 5, 95, 0, 0, 367, 368, 5, 83, 0, 0, 368, 369, 5, 72, 0, 0, 369, 370, 5, 79, 0, 0, 370, 371, 5, 85, 0, 0, 371, 372, 5, 76, 0, 0, 372, 373, 5, 68, 0, 0, 373, 374, 5, 95, 0, 0, 374, 375, 5, 77, 0, 0, 375, 376, 5, 65, 0, 0, 376, 377, 5, 84, 0, 0, 377, 378, 5, 67, 0, 0, 378, 380, 5, 72, 0, 0, 379, 339, 1, 0, 0, 0, 379, 359, 1, 0, 0, 0, 380, 42, 1, 0, 0, 0, 381, 382, 5, 61, 0, 0, 382, 44, 1, 0, 0, 0, 383, 384, 5, 43, 0, 0, 384, 46, 1, 0, 0, 0, 385, 386, 5, 45, 0, 0, 386, 48, 1, 0, 0, 0, 387, 388, 5, 42, 0, 0, 388, 50, 1, 0, 0, 0, 389, 390, 5, 47, 0, 0, 390, 52, 1, 0, 0, 0, 391, 392, 5, 37, 0, 0, 392, 54, 1, 0, 0, 0, 393, 394, 5, 42, 0, 0, 394, 395, 5, 42, 0, 0, 395, 56, 1, 0, 0, 0, 396, 397, 5, 60, 0, 0, 397, 398, 5, 60, 0, 0, 398, 58, 1, 0, 0, 0, 399, 400, 5, 62, 0, 0, 400, 401, 5, 62, 0, 0, 401, 60, 1, 0, 0, 0, 402, 403, 5, 38, 0, 0, 403, 62, 1, 0, 0, 0, 404, 405, 5, 124, 0, 0, 405, 64, 1, 0, 0, 0, 406, 407, 5, 94, 0, 0, 407, 66, 1, 0, 0, 0, 408, 409, 5, 38, 0, 0, 409, 417, 5, 38, 0, 0, 410, 411, 5, 97, 0, 0, 411, 412, 5, 110, 0, 0, 412, 417, 5, 100, 0, 0, 413, 414, 5, 65, 0, 0, 414, 415, 5, 78, 0, 0, 415, 417, 5, 68, 0, 0, 416, 408, 1, 0, 0, 0, 416, 410, 1, 0, 0, 0, 416, 413, 1, 0, 0, 0, 417, 68, 1, 0, 0, 0, 418, 419, 5, 124, 0, 0, 419, 425, 5, 124, 0, 0, 420, 421, 5, 111, 0, 0, 421, 425, 5, 114, 0, 0, 422, 423, 5, 79, 0, 0, 423, 425, 5, 82, 0, 0, 424, 418, 1, 0, 0, 0, 424, 420, 1, 0, 0, 0, 424, 422, 1, 0, 0, 0, 425, 70, 1, 0, 0, 0, 426, 427, 5, 105, 0, 0, 427, 428, 5, 115, 0, 0, 428, 429, 5, 32, 0, 0, 429, 430, 5, 110, 0, 0, 430, 431, 5, 117, 0, 0, 431, 432, 5, 108, 0, 0, 432, 441, 5, 108, 0, 0, 433, 434, 5, 73, 0, 0, 434, 435, 5, 83, 0, 0, 435, 436, 5, 32, 0, 0, 436, 437, 5, 78, 0, 0, 437, 438, 5, 85, 0, 0, 438, 439, 5, 76, 0, 0, 439, 441, 5, 76, 0, 0, 440, 426, 1, 0, 0, 0, 440, 433, 1, 0, 0, 0, 441, 72, 1, 0, 0, 0, 442, 443, 5, 105, 0, 0, 443, 444, 5, 115, 0, 0, 444, 445, 5, 32, 0, 0, 445, 446, 5, 110, 0, 0, 446, 447, 5, 111, 0, 0, 447, 448, 5, 116, 0, 0, 448, 449, 5, 32, 0, 0, 449, 450, 5, 110, 0, 0, 450, 451, 5, 117, 0, 0, 451, 452, 5, 108, 0, 0, 452, 465, 5, 108, 0, 0, 453, 454, 5, 73, 0, 0, 454, 455, 5, 83, 0, 0, 455, 456, 5, 32, 0, 0, 456, 457, 5, 78, 0, 0, 457, 458, 5, 79, 0, 0, 458, 459, 5, 84, 0, 0, 459, 460, 5, 32, 0, 0, 460, 461, 5, 78, 0, 0, 461, 462, 5, 85, 0, 0, 462, 463, 5, 76, 0, 0, 463, 465, 5, 76, 0, 0, 464, 442, 1, 0, 0, 0, 464, 453, 1, 0, 0, 0, 465, 74, 1, 0, 0, 0, 466, 467, 5, 126, 0, 0, 467, 76, 1, 0, 0, 0, 468, 476, 5, 33, 0, 0, 469, 470, 5, 110, 0, 0, 470, 471, 5, 111, 0, 0, 471, 476, 5, 116, 0, 0, 472, 473, 5, 78, 0, 0, 473, 474, 5, 79, 0, 0, 474, 476, 5, 84, 0, 0, 475, 468, 1, 0, 0, 0, 475, 469, 1, 0, 0, 0, 475, 472, 1, 0, 0, 0, 476, 78, 1, 0, 0, 0, 477, 478, 5, 105, 0, 0, 478, 482, 5, 110, 0, 0, 479, 480, 5, 73, 0, 0, 480, 482, 5, 78, 0, 0, 481, 477, 1, 0, 0, 0, 481, 479, 1, 0, 0, 0, 482, 80, 1, 0, 0, 0, 483, 488, 5, 91, 0, 0, 484, 487, 3, 179, 89, 0, 485, 487, 3, 181, 90, 0, 486, 484, 1, 0, 0, 0, 486, 485, 1, 0, 0, 0, 487, 490, 1, 0, 0, 0, 488, 486, 1, 0, 0, 0, 488, 489, 1, 0, 0, 0, 489, 491, 1, 0, 0, 0, 490, 488, 1, 0, 0, 0, 491, 492, 5, 93, 0, 0, 492, 82, 1, 0, 0, 0, 493, 494, 5, 106, 0, 0, 494, 495, 5, 115, 0, 0, 495, 496, 5, 111, 0, 0, 496, 497, 5, 110, 0, 0, 497, 498, 5, 95, 0, 0, 498, 499, 5, 99, 0, 0, 499, 500, 5, 111, 0, 0, 500, 501, 5, 110, 0, 0, 501, 502, 5, 116, 0, 0, 502, 503, 5, 97, 0, 0, 503, 504, 5, 105, 0, 0, 504, 505, 5, 110, 0, 0, 505, 520, 5, 115, 0, 0, 506, 507, 5, 74, 0, 0, 507, 508, 5, 83, 0, 0, 508, 509, 5, 79, 0, 0, 509, 510, 5, 78, 0, 0, 510, 511, 5, 95, 0, 0, 511, 512, 5, 67, 0, 0, 512, 513, 5, 79, 0, 0, 513, 514, 5, 78, 0, 0, 514, 515, 5, 84, 0, 0, 515, 516, 5, 65, 0, 0, 516, 517, 5, 73, 0, 0, 517, 518, 5, 78, 0, 0, 518, 520, 5, 83, 0, 0, 519, 493, 1, 0, 0, 0, 519, 506, 1, 0, 0, 0, 520, 84, 1, 0, 0, 0, 521, 522, 5, 106, 0, 0, 522, 523, 5, 115, 0, 0, 523, 524, 5, 111, 0, 0, 524, 525, 5, 110, 0, 0, 525, 526, 5, 95, 0, 0, 526, 527, 5, 99, 0, 0, 527, 528, 5, 111, 0, 0, 528, 529, 5, 110, 0, 0, 529, 530, 5, 116, 0, 0, 530, 531, 5, 97, 0, 0, 531, 532, 5, 105, 0, 0, 532, 533, 5, 110, 0, 0, 533, 534, 5, 115, 0, 0, 534, 535, 5, 95, 0, 0, 535, 536, 5, 97, 0, 0, 536, 537, 5, 108, 0, 0, 537, 556, 5, 108, 0, 0, 538, 539, 5, 74, 0, 0, 539, 540, 5, 83, 0, 0, 540, 541, 5, 79, 0, 0, 541, 542, 5, 78, 0, 0, 542, 543, 5, 95, 0, 0, 543, 544, 5, 67, 0, 0, 544, 545, 5, 79, 0, 0, 545, 546, 5, 78, 0, 0, 546, 547, 5, 84, 0, 0, 547, 548, 5, 65, 0, 0, 548, 549, 5, 73, 0, 0, 549, 550, 5, 78, 0, 0, 550, 551, 5, 83, 0, 0, 551, 552, 5, 95, 0, 0, 552, 553, 5, 65, 0, 0, 553, 554, 5, 76, 0, 0, 554, 556, 5, 76, 0, 0, 555, 521, 1, 0, 0, 0, 555, 538, 1, 0, 0, 0, 556, 86, 1, 0, 0, 0, 557, 558, 5, 106, 0, 0, 558, 559, 5, 115, 0, 0, 559, 560, 5, 111, 0, 0, 560, 561, 5, 110, 0, 0, 561, 562, 5, 95, 0, 0, 562, 563, 5, 99, 0, 0, 563, 564, 5, 111, 0, 0, 564, 565, 5, 110, 0, 0, 565, 566, 5, 116, 0, 0, 566, 567, 5, 97, 0, 0, 567, 568, 5, 105, 0, 0, 568, 569, 5, 110, 0, 0, 569, 570, 5, 115, 0, 0, 570, 571, 5, 95, 0, 0, 571, 572, 5, 97, 0, 0, 572, 573, 5, 110, 0, 0, 573, 592, 5, 121, 0, 0, 574, 575, 5, 74, 0, 0, 575, 576, 5, 83, 0, 0, 576, 577, 5, 79, 0, 0, 577, 578, 5, 78, 0, 0, 578, 579, 5, 95, 0, 0, 579, 580, 5, 67, 0, 0, 580, 581, 5, 79, 0, 0, 581, 582, 5, 78, 0, 0, 582, 583, 5, 84, 0, 0, 583, 584, 5, 65, 0, 0, 584, 585, 5, 73, 0, 0, 585, 586, 5, 78, 0, 0, 586, 587, 5, 83, 0, 0, 587, 588, 5, 95, 0, 0, 588, 589, 5, 65, 0, 0, 589, 590, 5, 78, 0, 0, 590, 592, 5, 89, 0, 0, 591, 557, 1, 0, 0, 0, 591, 574, 1, 0, 0, 0, 592, 88, 1, 0, 0, 0, 593, 594, 5, 97, 0, 0, 594, 595, 5, 114, 0, 0, 595, 596, 5, 114, 0, 0, 596, 597, 5, 97, 0, 0, 597, 598, 5, 121, 0, 0, 598, 599, 5, 95, 0, 0, 599, 600, 5, 99, 0, 0, 600, 601, 5, 111, 0, 0, 601, 602, 5, 110, 0, 0, 602, 603, 5, 116, 0, 0, 603, 604, 5, 97, 0, 0, 604, 605, 5, 105, 0, 0, 605, 606, 5, 110, 0, 0, 606, 622, 5, 115, 0, 0, 607, 608, 5, 65, 0, 0, 608, 609, 5, 82, 0, 0, 609, 610, 5, 82, 0, 0, 610, 611, 5, 65, 0, 0, 611, 612, 5, 89, 0, 0, 612, 613, 5, 95, 0, 0, 613, 614, 5, 67, 0, 0, 614, 615, 5, 79, 0, 0, 615, 616, 5, 78, 0, 0, 616, 617, 5, 84, 0, 0, 617, 618, 5, 65, 0, 0, 618, 619, 5, 73, 0, 0, 619, 620, 5, 78, 0, 0, 620, 622, 5, 83, 0, 0, 621, 593, 1, 0, 0, 0, 621, 607, 1, 0, 0, 0, 622, 90, 1, 0, 0, 0, 623, 624, 5, 97, 0, 0, 624, 625, 5, 114, 0, 0, 625, 626, 5, 114, 0, 0, 626, 627, 5, 97, 0, 0, 627, 628, 5, 121, 0, 0, 628, 629, 5, 95, 0, 0, 629, 630, 5, 99, 0, 0, 630, 631, 5, 111, 0, 0, 631, 632, 5, 110, 0, 0, 632, 633, 5, 116, 0, 0, 633, 634, 5, 97, 0, 0, 634, 635, 5, 105, 0, 0, 635, 636, 5, 110, 0, 0, 636, 637, 5, 115, 0, 0, 637, 638, 5, 95, 0, 0, 638, 639, 5, 97, 0, 0, 639, 640, 5, 108, 0, 0, 640, 660, 5, 108, 0, 0, 641, 642, 5, 65, 0, 0, 642, 643, 5, 82, 0, 0, 643, 644, 5, 82, 0, 0, 644, 645, 5, 65, 0, 0, 645, 646, 5, 89, 0, 0, 646, 647, 5, 95, 0, 0, 647, 648, 5, 67, 0, 0, 648, 649, 5, 79, 0, 0, 649, 650, 5, 78, 0, 0, 650, 651, 5, 84, 0, 0, 651, 652, 5, 65, 0, 0, 652, 653, 5, 73, 0, 0, 653, 654, 5, 78, 0, 0, 654, 655, 5, 83, 0, 0, 655, 656, 5, 95, 0, 0, 656, 657, 5, 65, 0, 0, 657, 658, 5, 76, 0, 0, 658, 660, 5, 76, 0, 0, 659, 623, 1, 0, 0, 0, 659, 641, 1, 0, 0, 0, 660, 92, 1, 0, 0, 0, 661, 662, 5, 97, 0, 0, 662, 663, 5, 114, 0, 0, 663, 664, 5, 114, 0, 0, 664, 665, 5, 97, 0, 0, 665, 666, 5, 121, 0, 0, 666, 667, 5, 95, 0, 0, 667, 668, 5, 99, 0, 0, 668, 669, 5, 111, 0, 0, 669, 670, 5, 110, 0, 0, 670, 671, 5, 116, 0, 0, 671, 672, 5, 97, 0, 0, 672, 673, 5, 105, 0, 0, 673, 674, 5, 110, 0, 0, 674, 675, 5, 115, 0, 0, 675, 676, 5, 95, 0, 0, 676, 677, 5, 97, 0, 0, 677, 678, 5, 110, 0, 0, 678, 698, 5, 121, 0, 0, 679, 680, 5, 65, 0, 0, 680, 681, 5, 82, 0, 0, 681, 682, 5, 82, 0, 0, 682, 683, 5, 65, 0, 0, 683, 684, 5, 89, 0, 0, 684, 685, 5, 95, 0, 0, 685, 686, 5, 67, 0, 0, 686, 687, 5, 79, 0, 0, 687, 688, 5, 78, 0, 0, 688, 689, 5, 84, 0, 0, 689, 690, 5, 65, 0, 0, 690, 691, 5, 73, 0, 0, 691, 692, 5, 78, 0, 0, 692, 693, 5, 83, 0, 0, 693, 694, 5, 95, 0, 0, 694, 695, 5, 65, 0, 0, 695, 696, 5, 78, 0, 0, 696, 698, 5, 89, 0, 0, 697, 661, 1, 0, 0, 0, 697, 679, 1, 0, 0, 0, 698, 94, 1, 0, 0, 0, 699, 700, 5, 97, 0, 0, 700, 701, 5, 114, 0, 0, 701, 702, 5, 114, 0, 0, 702, 703, 5, 97, 0, 0, 703, 704, 5, 121, 0, 0, 704, 705, 5, 95, 0, 0, 705, 706, 5, 108, 0, 0, 706, 707, 5, 101, 0, 0, 707, 708, 5, 110, 0, 0, 708, 709, 5, 103, 0, 0, 709, 710, 5, 116, 0, 0, 710, 724, 5, 104, 0, 0, 711, 712, 5, 65, 0, 0, 712, 713, 5, 82, 0, 0, 713, 714, 5, 82, 0, 0, 714, 715, 5, 65, 0, 0, 715, 716, 5, 89, 0, 0, 716, 717, 5, 95, 0, 0, 717, 718, 5, 76, 0, 0, 718, 719, 5, 69, 0, 0, 719, 720, 5, 78, 0, 0, 720, 721, 5, 71, 0, 0, 721, 722, 5, 84, 0, 0, 722, 724, 5, 72, 0, 0, 723, 699, 1, 0, 0, 0, 723, 711, 1, 0, 0, 0, 724, 96, 1, 0, 0, 0, 725, 726, 5, 115, 0, 0, 726, 727, 5, 116, 0, 0, 727, 728, 5, 95, 0, 0, 728, 729, 5, 101, 0, 0, 729, 730, 5, 113, 0, 0, 730, 731, 5, 117, 0, 0, 731, 732, 5, 97, 0, 0, 732, 733, 5, 108, 0, 0, 733, 744, 5, 115, 0, 0, 734, 735, 5, 83, 0, 0, 735, 736, 5, 84, 0, 0, 736, 737, 5, 95, 0, 0, 737, 738, 5, 69, 0, 0, 738, 739, 5, 81, 0, 0, 739, 740, 5, 85, 0, 0, 740, 741, 5, 65, 0, 0, 741, 742, 5, 76, 0, 0, 742, 744, 5, 83, 0, 0, 743, 725, 1, 0, 0, 0, 743, 734, 1, 0, 0, 0, 744, 98, 1, 0, 0, 0, 745, 746, 5, 115, 0, 0, 746, 747, 5, 116, 0, 0, 747, 748, 5, 95, 0, 0, 748, 749, 5, 116, 0, 0, 749, 750, 5, 111, 0, 0, 750, 751, 5, 117, 0, 0, 751, 752, 5, 99, 0, 0, 752, 753, 5, 104, 0, 0, 753, 754, 5, 101, 0, 0, 754, 766, 5, 115, 0, 0, 755, 756, 5, 83, 0, 0, 756, 757, 5, 84, 0, 0, 757, 758, 5, 95, 0, 0, 758, 759, 5, 84, 0, 0, 759, 760, 5, 79, 0, 0, 760, 761, 5, 85, 0, 0, 761, 762, 5, 67, 0, 0, 762, 763, 5, 72, 0, 0, 763, 764, 5, 69, 0, 0, 764, 766, 5, 83, 0, 0, 765, 745, 1, 0, 0, 0, 765, 755, 1, 0, 0, 0, 766, 100, 1, 0, 0, 0, 767, 768, 5, 115, 0, 0, 768, 769, 5, 116, 0, 0, 769, 770, 5, 95, 0, 0, 770, 771, 5, 111, 0, 0, 771, 772, 5, 118, 0, 0, 772, 773, 5, 101, 0, 0, 773, 774, 5, 114, 0, 0, 774, 775, 5, 108, 0, 0, 775, 776, 5, 97, 0, 0, 776, 777, 5, 112, 0, 0, 777, 790, 5, 115, 0, 0, 778, 779, 5, 83, 0, 0, 779, 780, 5, 84, 0, 0, 780, 781, 5, 95, 0, 0, 781, 782, 5, 79, 0, 0, 782, 783, 5, 86, 0, 0, 783, 784, 5, 69, 0, 0, 784, 785, 5, 82, 0, 0, 785, 786, 5, 76, 0, 0, 786, 787, 5, 65, 0, 0, 787, 788, 5, 80, 0, 0, 788, 790, 5, 83, 0, 0, 789, 767, 1, 0, 0, 0, 789, 778, 1, 0, 0, 0, 790, 102, 1, 0, 0, 0, 791, 792, 5, 115, 0, 0, 792, 793, 5, 116, 0, 0, 793, 794, 5, 95, 0, 0, 794, 795, 5, 99, 0, 0, 795, 796, 5, 114, 0, 0, 796, 797, 5, 111, 0, 0, 797, 798, 5, 115, 0, 0, 798, 799, 5, 115, 0, 0, 799, 800, 5, 101, 0, 0, 800, 812, 5, 115, 0, 0, 801, 802, 5, 83, 0, 0, 802, 803, 5, 84, 0, 0, 803, 804, 5, 95, 0, 0, 804, 805, 5, 67, 0, 0, 805, 806, 5, 82, 0, 0, 806, 807, 5, 79, 0, 0, 807, 808, 5, 83, 0, 0, 808, 809, 5, 83, 0, 0, 809, 810, 5, 69, 0, 0, 810, 812, 5, 83, 0, 0, 811, 791, 1, 0, 0, 0, 811, 801, 1, 0, 0, 0, 812, 104, 1, 0, 0, 0, 813, 814, 5, 115, 0, 0, 814, 815, 5, 116, 0, 0, 815, 816, 5, 95, 0, 0, 816, 817, 5, 99, 0, 0, 817, 818, 5, 111, 0, 0, 818, 819, 5, 110, 0, 0, 819, 820, 5, 116, 0, 0, 820, 821, 5, 97, 0, 0, 821, 822, 5, 105, 0, 0, 822, 823, 5, 110, 0, 0, 823, 836, 5, 115, 0, 0, 824, 825, 5, 83, 0, 0, 825, 826, 5, 84, 0, 0, 826, 827, 5, 95, 0, 0, 827, 828, 5, 67, 0, 0, 828, 829, 5, 79, 0, 0, 829, 830, 5, 78, 0, 0, 830, 831, 5, 84, 0, 0, 831, 832, 5, 65, 0, 0, 832, 833, 5, 73, 0, 0, 833, 834, 5, 78, 0, 0, 834, 836, 5, 83, 0, 0, 835, 813, 1, 0, 0, 0, 835, 824, 1, 0, 0, 0, 836, 106, 1, 0, 0, 0, 837, 838, 5, 115, 0, 0, 838, 839, 5, 116, 0, 0, 839, 840, 5, 95, 0, 0, 840, 841, 5, 105, 0, 0, 841, 842, 5, 110, 0, 0, 842, 843, 5, 116, 0, 0, 843, 844, 5, 101, 0, 0, 844, 845, 5, 114, 0, 0, 845, 846, 5, 115, 0, 0, 846, 847, 5, 101, 0, 0, 847, 848, 5, 99, 0, 0, 848, 849, 5, 116, 0, 0, 849, 864, 5, 115, 0, 0, 850, 851, 5, 83, 0, 0, 851, 852, 5, 84, 0, 0, 852, 853, 5, 95, 0, 0, 853, 854, 5, 73, 0, 0, 854, 855, 5, 78, 0, 0, 855, 856, 5, 84, 0, 0, 856, 857, 5, 69, 0, 0, 857, 858, 5, 82, 0, 0, 858, 859, 5, 83, 0, 0, 859, 860, 5, 69, 0, 0, 860, 861, 5, 67, 0, 0, 861, 862, 5, 84, 0, 0, 862, 864, 5, 83, 0, 0, 863, 837, 1, 0, 0, 0, 863, 850, 1, 0, 0, 0, 864, 108, 1, 0, 0, 0, 865, 866, 5, 115, 0, 0, 866, 867, 5, 116, 0, 0, 867, 868, 5, 95, 0, 0, 868, 869, 5, 119, 0, 0, 869, 870, 5, 105, 0, 0, 870, 871, 5, 116, 0, 0, 871, 872, 5, 104, 0, 0, 872, 873, 5, 105, 0, 0, 873, 884, 5, 110, 0, 0, 874, 875, 5, 83, 0, 0, 875, 876, 5, 84, 0, 0, 876, 877, 5, 95, 0, 0, 877, 878, 5, 87, 0, 0, 878, 879, 5, 73, 0, 0, 879, 880, 5, 84, 0, 0, 880, 881, 5, 72, 0, 0, 881, 882, 5, 73, 0, 0, 882, 884, 5, 78, 0, 0, 883, 865, 1, 0, 0, 0, 883, 874, 1, 0, 0, 0, 884, 110, 1, 0, 0, 0, 885, 886, 5, 115, 0, 0, 886, 887, 5, 116, 0, 0, 887, 888, 5, 95, 0, 0, 888, 889, 5, 100, 0, 0, 889, 890, 5, 119, 0, 0, 890, 891, 5, 105, 0, 0, 891, 892, 5, 116, 0, 0, 892, 893, 5, 104, 0, 0, 893, 894, 5, 105, 0, 0, 894, 906, 5, 110, 0, 0, 895, 896, 5, 83, 0, 0, 896, 897, 5, 84, 0, 0, 897, 898, 5, 95, 0, 0, 898, 899, 5, 68, 0, 0, 899, 900, 5, 87, 0, 0, 900, 901, 5, 73, 0, 0, 901, 902, 5, 84, 0, 0, 902, 903, 5, 72, 0, 0, 903, 904, 5, 73, 0, 0, 904, 906, 5, 78, 0, 0, 905, 885, 1, 0, 0, 0, 905, 895, 1, 0, 0, 0, 906, 112, 1, 0, 0, 0, 907, 908, 5, 115, 0, 0, 908, 909, 5, 116, 0, 0, 909, 910, 5, 95, 0, 0, 910, 911, 5, 105, 0, 0, 911, 912, 5, 115, 0, 0, 912, 913, 5, 118, 0, 0, 913, 914, 5, 97, 0, 0, 914, 915, 5, 108, 0, 0, 915, 916, 5, 105, 0, 0, 916, 928, 5, 100, 0, 0, 917, 918, 5, 83, 0, 0, 918, 919, 5, 84, 0, 0, 919, 920, 5, 95, 0, 0, 920, 921, 5, 73, 0, 0, 921, 922, 5, 83, 0, 0, 922, 923, 5, 86, 0, 0, 923, 924, 5, 65, 0, 0, 924, 925, 5, 76, 0, 0, 925, 926, 5, 73, 0, 0, 926, 928, 5, 68, 0, 0, 927, 907, 1, 0, 0, 0, 927, 917, 1, 0, 0, 0, 928, 114, 1, 0, 0, 0, 929, 930, 5, 116, 0, 0, 930, 931, 5, 114, 0, 0, 931, 932, 5, 117, 0, 0, 932, 957, 5, 101, 0, 0, 933, 934, 5, 84, 0, 0, 934, 935, 5, 114, 0, 0, 935, 936, 5, 117, 0, 0, 936, 957, 5, 101, 0, 0, 937, 938, 5, 84, 0, 0, 938, 939, 5, 82, 0, 0, 939, 940, 5, 85, 0, 0, 940, 957, 5, 69, 0, 0, 941, 942, 5, 102, 0, 0, 942, 943, 5, 97, 0, 0, 943, 944, 5, 108, 0, 0, 944, 945, 5, 115, 0, 0, 945, 957, 5, 101, 0, 0, 946, 947, 5, 70, 0, 0, 947, 948, 5, 97, 0, 0, 948, 949, 5, 108, 0, 0, 949, 950, 5, 115, 0, 0, 950, 957, 5, 101, 0, 0, 951, 952, 5, 70, 0, 0, 952, 953, 5, 65, 0, 0, 953, 954, 5, 76, 0, 0, 954, 955, 5, 83, 0, 0, 955, 957, 5, 69, 0, 0, 956, 929, 1, 0, 0, 0, 956, 933, 1, 0, 0, 0, 956, 937, 1, 0, 0, 0, 956, 941, 1, 0, 0, 0, 956, 946, 1, 0, 0, 0, 956, 951, 1, 0, 0, 0, 957, 116, 1, 0, 0, 0, 958, 963, 3, 145, 72, 0, 959, 963, 3, 147, 73, 0, 960, 963, 3, 149, 74, 0, 961, 963, 3, 143, 71, 0, 962, 958, 1, 0, 0, 0, 962, 959, 1, 0, 0, 0, 962, 960, 1, 0, 0, 0, 962, 961, 1, 0, 0, 0, 963, 118, 1, 0, 0, 0, 964, 967, 3, 161, 80, 0, 965, 967, 3, 163, 81, 0, 966, 964, 1, 0, 0, 0, 966, 965, 1, 0, 0, 0, 967, 120, 1, 0, 0, 0, 968, 973, 3, 139, 69, 0, 969, 972, 3, 139, 69, 0, 970, 972, 3, 141, 70, 0, 971, 969, 1, 0, 0, 0, 971, 970, 1, 0, 0, 0, 972, 975, 1, 0, 0, 0, 973, 971, 1, 0, 0, 0, 973, 974, 1, 0, 0, 0, 974, 122, 1, 0, 0, 0, 975, 973, 1, 0, 0, 0, 976, 977, 5, 36, 0, 0, 977, 978, 5, 109, 0, 0, 978, 979, 5, 101, 0, 0, 979, 980, 5, 116, 0, 0, 980, 981, 5, 97, 0, 0, 981, 124, 1, 0, 0, 0, 982, 984, 3, 129, 64, 0, 983, 982, 1, 0, 0, 0, 983, 984, 1, 0, 0, 0, 984, 995, 1, 0, 0, 0, 985, 987, 5, 34, 0, 0, 986, 988, 3, 131, 65, 0, 987, 986, 1, 0, 0, 0, 987, 988, 1, 0, 0, 0, 988, 989, 1, 0, 0, 0, 989, 996, 5, 34, 0, 0, 990, 992, 5, 39, 0, 0, 991, 993, 3, 133, 66, 0, 992, 991, 1, 0, 0, 0, 992, 993, 1, 0, 0, 0, 993, 994, 1, 0, 0, 0, 994, 996, 5, 39, 0, 0, 995, 985, 1, 0, 0, 0, 995, 990, 1, 0, 0, 0, 996, 126, 1, 0, 0, 0, 997, 1000, 3, 121, 60, 0, 998, 1000, 3, 123, 61, 0, 999, 997, 1, 0, 0, 0, 999, 998, 1, 0, 0, 0, 1000, 1008, 1, 0, 0, 0, 1001, 1004, 5, 91, 0, 0, 1002, 1005, 3, 125, 62, 0, 1003, 1005, 3, 145, 72, 0, 1004, 1002, 1, 0, 0, 0, 1004, 1003, 1, 0, 0, 0, 1005, 1006, 1, 0, 0, 0, 1006, 1007, 5, 93, 0, 0, 1007, 1009, 1, 0, 0, 0, 1008, 1001, 1, 0, 0, 0, 1009, 1010, 1, 0, 0, 0, 1010, 1008, 1, 0, 0, 0, 1010, 1011, 1, 0, 0, 0, 1011, 128, 1, 0, 0, 0, 1012, 1013, 5, 117, 0, 0, 1013, 1016, 5, 56, 0, 0, 1014, 1016, 7, 0, 0, 0, 1015, 1012, 1, 0, 0, 0, 1015, 1014, 1, 0, 0, 0, 1016, 130, 1, 0, 0, 0, 1017, 1019, 3, 135, 67, 0, 1018, 1017, 1, 0, 0, 0, 1019, 1020, 1, 0, 0, 0, 1020, 1018, 1, 0, 0, 0, 1020, 1021, 1, 0, 0, 0, 1021, 132, 1, 0, 0, 0, 1022, 1024, 3, 137, 68, 0, 1023, 1022, 1, 0, 0, 0, 1024, 1025, 1, 0, 0, 0, 1025, 1023, 1, 0, 0, 0, 1025, 1026, 1, 0, 0, 0, 1026, 134, 1, 0, 0, 0, 1027, 1035, 8, 1, 0, 0, 1028, 1035, 3, 177, 88, 0, 1029, 1030, 5, 92, 0, 0, 1030, 1035, 5, 10, 0, 0, 1031, 1032, 5, 92, 0, 0, 1032, 1033, 5, 13, 0, 0, 1033, 1035, 5, 10, 0, 0, 1034, 1027, 1, 0, 0, 0, 1034, 1028, 1, 0, 0, 0, 1034, 1029, 1, 0, 0, 0, 1034, 1031, 1, 0, 0, 0, 1035, 136, 1, 0, 0, 0, 1036, 1044, 8, 2, 0, 0, 1037, 1044, 3, 177, 88, 0, 1038, 1039, 5, 92, 0, 0, 1039, 1044, 5, 10, 0, 0, 1040, 1041, 5, 92, 0, 0, 1041, 1042, 5, 13, 0, 0, 1042, 1044, 5, 10, 0, 0, 1043, 1036, 1, 0, 0, 0, 1043, 1037, 1, 0, 0, 0, 1043, 1038, 1, 0, 0, 0, 1043, 1040, 1, 0, 0, 0, 1044, 138, 1, 0, 0, 0, 1045, 1046, 7, 3, 0, 0, 1046, 140, 1, 0, 0, 0, 1047, 1048, 7, 4, 0, 0, 1048, 142, 1, 0, 0, 0, 1049, 1050, 5, 48, 0, 0, 1050, 1052, 7, 5, 0, 0, 1051, 1053, 7, 6, 0, 0, 1052, 1051, 1, 0, 0, 0, 1053, 1054, 1, 0, 0, 0, 1054, 1052, 1, 0, 0, 0, 1054, 1055, 1, 0, 0, 0, 1055, 144, 1, 0, 0, 0, 1056, 1060, 3, 151, 75, 0, 1057, 1059, 3, 141, 70, 0, 1058, 1057, 1, 0, 0, 0, 1059, 1062, 1, 0, 0, 0, 1060, 1058, 1, 0, 0, 0, 1060, 1061, 1, 0, 0, 0, 1061, 1065, 1, 0, 0, 0, 1062, 1060, 1, 0, 0, 0, 1063, 1065, 5, 48, 0, 0, 1064, 1056, 1, 0, 0, 0, 1064, 1063, 1, 0, 0, 0, 1065, 146, 1, 0, 0, 0, 1066, 1070, 5, 48, 0, 0, 1067, 1069, 3, 153, 76, 0, 1068, 1067, 1, 0, 0, 0, 1069, 1072, 1, 0, 0, 0, 1070, 1068, 1, 0, 0, 0, 1070, 1071, 1, 0, 0, 0, 1071, 148, 1, 0, 0, 0, 1072, 1070, 1, 0, 0, 0, 1073, 1074, 5, 48, 0, 0, 1074, 1075, 7, 7, 0, 0, 1075, 1076, 3, 173, 86, 0, 1076, 150, 1, 0, 0, 0, 1077, 1078, 7, 8, 0, 0, 1078, 152, 1, 0, 0, 0, 1079, 1080, 7, 9, 0, 0, 1080, 154, 1, 0, 0, 0, 1081, 1082, 7, 10, 0, 0, 1082, 156, 1, 0, 0, 0, 1083, 1084, 3, 155, 77, 0, 1084, 1085, 3, 155, 77, 0, 1085, 1086, 3, 155, 77, 0, 1086, 1087, 3, 155, 77, 0, 1087, 158, 1, 0, 0, 0, 1088, 1089, 5, 92, 0, 0, 1089, 1090, 5, 117, 0, 0, 1090, 1091, 1, 0, 0, 0, 1091, 1099, 3, 157, 78, 0, 1092, 1093, 5, 92, 0, 0, 1093, 1094, 5, 85, 0, 0, 1094, 1095, 1, 0, 0, 0, 1095, 1096, 3, 157, 78, 0, 1096, 1097, 3, 157, 78, 0, 1097, 1099, 1, 0, 0, 0, 1098, 1088, 1, 0, 0, 0, 1098, 1092, 1, 0, 0, 0, 1099, 160, 1, 0, 0, 0, 1100, 1102, 3, 165, 82, 0, 1101, 1103, 3, 167, 83, 0, 1102, 1101, 1, 0, 0, 0, 1102, 1103, 1, 0, 0, 0, 1103, 1108, 1, 0, 0, 0, 1104, 1105, 3, 169, 84, 0, 1105, 1106, 3, 167, 83, 0, 1106, 1108, 1, 0, 0, 0, 1107, 1100, 1, 0, 0, 0, 1107, 1104, 1, 0, 0, 0, 1108, 162, 1, 0, 0, 0, 1109, 1110, 5, 48, 0, 0, 1110, 1113, 7, 7, 0, 0, 1111, 1114, 3, 171, 85, 0, 1112, 1114, 3, 173, 86, 0, 1113, 1111, 1, 0, 0, 0, 1113, 1112, 1, 0, 0, 0, 1114, 1115, 1, 0, 0, 0, 1115, 1116, 3, 175, 87, 0, 1116, 164, 1, 0, 0, 0, 1117, 1119, 3, 169, 84, 0, 1118, 1117, 1, 0, 0, 0, 1118, 1119, 1, 0, 0, 0, 1119, 1120, 1, 0, 0, 0, 1120, 1121, 5, 46, 0, 0, 1121, 1126, 3, 169, 84, 0, 1122, 1123, 3, 169, 84, 0, 1123, 1124, 5, 46, 0, 0, 1124, 1126, 1, 0, 0, 0, 1125, 1118, 1, 0, 0, 0, 1125, 1122, 1, 0, 0, 0, 1126, 166, 1, 0, 0, 0, 1127, 1129, 7, 11, 0, 0, 1128, 1130, 7, 12, 0, 0, 1129, 1128, 1, 0, 0, 0, 1129, 1130, 1, 0, 0, 0, 1130, 1131, 1, 0, 0, 0, 1131, 1132, 3, 169, 84, 0, 1132, 168, 1, 0, 0, 0, 1133, 1135, 3, 141, 70, 0, 1134, 1133, 1, 0, 0, 0, 1135, 1136, 1, 0, 0, 0, 1136, 1134, 1, 0, 0, 0, 1136, 1137, 1, 0, 0, 0, 1137, 170, 1, 0, 0, 0, 1138, 1140, 3, 173, 86, 0, 1139, 1138, 1, 0, 0, 0, 1139, 1140, 1, 0, 0, 0, 1140, 1141, 1, 0, 0, 0, 1141, 1142, 5, 46, 0, 0, 1142, 1147, 3, 173, 86, 0, 1143, 1144, 3, 173, 86, 0, 1144, 1145, 5, 46, 0, 0, 1145, 1147, 1, 0, 0, 0, 1146, 1139, 1, 0, 0, 0, 1146, 1143, 1, 0, 0, 0, 1147, 172, 1, 0, 0, 0, 1148, 1150, 3, 155, 77, 0, 1149, 1148, 1, 0, 0, 0, 1150, 1151, 1, 0, 0, 0, 1151, 1149, 1, 0, 0, 0, 1151, 1152, 1, 0, 0, 0, 1152, 174, 1, 0, 0, 0, 1153, 1155, 7, 13, 0, 0, 1154, 1156, 7, 12, 0, 0, 1155, 1154, 1, 0, 0, 0, 1155, 1156, 1, 0, 0, 0, 1156, 1157, 1, 0, 0, 0, 1157, 1158, 3, 169, 84, 0, 1158, 176, 1, 0, 0, 0, 1159, 1160, 5, 92, 0, 0, 1160, 1175, 7, 14, 0, 0, 1161, 1162, 5, 92, 0, 0, 1162, 1164, 3, 153, 76, 0, 1163, 1165, 3, 153, 76, 0, 1164, 1163, 1, 0, 0, 0, 1164, 1165, 1, 0, 0, 0, 1165, 1167, 1, 0, 0, 0, 1166, 1168, 3, 153, 76, 0, 1167, 1166, 1, 0, 0, 0, 1167, 1168, 1, 0, 0, 0, 1168, 1175, 1, 0, 0, 0, 1169, 1170, 5, 92, 0, 0, 1170, 1171, 5, 120, 0, 0, 1171, 1172, 1, 0, 0, 0, 1172, 1175, 3, 173, 86, 0, 1173, 1175, 3, 159, 79, 0, 1174, 1159, 1, 0, 0, 0, 1174, 1161, 1, 0, 0, 0, 1174, 1169, 1, 0, 0, 0, 1174, 1173, 1, 0, 0, 0, 1175, 178, 1, 0, 0, 0, 1176, 1178, 7, 15, 0, 0, 1177, 1176, 1, 0, 0, 0, 1178, 1179, 1, 0, 0, 0, 1179, 1177, 1, 0, 0, 0, 1179, 1180, 1, 0, 0, 0, 1180, 1181, 1, 0, 0, 0, 1181, 1182, 6, 89, 0, 0, 1182, 180, 1, 0, 0, 0, 1183, 1185, 5, 13, 0, 0, 1184, 1186, 5, 10, 0, 0, 1185, 1184, 1, 0, 0, 0, 1185, 1186, 1, 0, 0, 0, 1186, 1189, 1, 0, 0, 0, 1187, 1189, 5, 10, 0, 0, 1188, 1183, 1, 0, 0, 0, 1188, 1187, 1, 0, 0, 0, 1189, 1190, 1, 0, 0, 0, 1190, 1191, 6, 90, 0, 0, 1191, 182, 1, 0, 0, 0, 72, 0, 221, 235, 257, 283, 311, 329, 337, 379, 416, 424, 440, 464, 475, 481, 486, 488, 519, 555, 591, 621, 659, 697, 723, 743, 765, 789, 811, 835, 863, 883, 905, 927, 956, 962, 966, 971, 973, 983, 987, 992, 995, 999, 1004, 1010, 1015, 1020, 1025, 1034, 1043, 1054, 1060, 1064, 1070, 1098, 1102, 1107, 1113, 1118, 1125, 1129, 1136, 1139, 1146, 1151, 1155, 1164, 1167, 1174, 1179, 1185, 1188, 1, 6, 0, 0] \ No newline at end of file +[4, 0, 68, 1232, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 226, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 240, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 262, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 288, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 316, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 3, 18, 334, 8, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 3, 19, 342, 8, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 384, 8, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 421, 8, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 429, 8, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 3, 35, 445, 8, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 469, 8, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 480, 8, 38, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 486, 8, 39, 1, 40, 1, 40, 1, 40, 5, 40, 491, 8, 40, 10, 40, 12, 40, 494, 9, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 524, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 560, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 596, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 626, 8, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 3, 45, 664, 8, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 702, 8, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 3, 47, 728, 8, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, 758, 8, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 3, 49, 778, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 3, 50, 800, 8, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 824, 8, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 3, 52, 846, 8, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 870, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 898, 8, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 3, 55, 918, 8, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 940, 8, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 962, 8, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 991, 8, 58, 1, 59, 1, 59, 1, 59, 1, 59, 3, 59, 997, 8, 59, 1, 60, 1, 60, 3, 60, 1001, 8, 60, 1, 61, 1, 61, 1, 61, 5, 61, 1006, 8, 61, 10, 61, 12, 61, 1009, 9, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 3, 63, 1018, 8, 63, 1, 63, 1, 63, 3, 63, 1022, 8, 63, 1, 63, 1, 63, 1, 63, 3, 63, 1027, 8, 63, 1, 63, 3, 63, 1030, 8, 63, 1, 64, 1, 64, 3, 64, 1034, 8, 64, 1, 64, 1, 64, 1, 64, 3, 64, 1039, 8, 64, 1, 64, 1, 64, 4, 64, 1043, 8, 64, 11, 64, 12, 64, 1044, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 3, 66, 1056, 8, 66, 1, 67, 4, 67, 1059, 8, 67, 11, 67, 12, 67, 1060, 1, 68, 4, 68, 1064, 8, 68, 11, 68, 12, 68, 1065, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 3, 69, 1075, 8, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 3, 70, 1084, 8, 70, 1, 71, 1, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 4, 73, 1093, 8, 73, 11, 73, 12, 73, 1094, 1, 74, 1, 74, 5, 74, 1099, 8, 74, 10, 74, 12, 74, 1102, 9, 74, 1, 74, 3, 74, 1105, 8, 74, 1, 75, 1, 75, 5, 75, 1109, 8, 75, 10, 75, 12, 75, 1112, 9, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 3, 81, 1139, 8, 81, 1, 82, 1, 82, 3, 82, 1143, 8, 82, 1, 82, 1, 82, 1, 82, 3, 82, 1148, 8, 82, 1, 83, 1, 83, 1, 83, 1, 83, 3, 83, 1154, 8, 83, 1, 83, 1, 83, 1, 84, 3, 84, 1159, 8, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 3, 84, 1166, 8, 84, 1, 85, 1, 85, 3, 85, 1170, 8, 85, 1, 85, 1, 85, 1, 86, 4, 86, 1175, 8, 86, 11, 86, 12, 86, 1176, 1, 87, 3, 87, 1180, 8, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 3, 87, 1187, 8, 87, 1, 88, 4, 88, 1190, 8, 88, 11, 88, 12, 88, 1191, 1, 89, 1, 89, 3, 89, 1196, 8, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 3, 90, 1205, 8, 90, 1, 90, 3, 90, 1208, 8, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 3, 90, 1215, 8, 90, 1, 91, 4, 91, 1218, 8, 91, 11, 91, 12, 91, 1219, 1, 91, 1, 91, 1, 92, 1, 92, 3, 92, 1226, 8, 92, 1, 92, 3, 92, 1229, 8, 92, 1, 92, 1, 92, 0, 0, 93, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 56, 113, 57, 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, 64, 129, 65, 131, 66, 133, 0, 135, 0, 137, 0, 139, 0, 141, 0, 143, 0, 145, 0, 147, 0, 149, 0, 151, 0, 153, 0, 155, 0, 157, 0, 159, 0, 161, 0, 163, 0, 165, 0, 167, 0, 169, 0, 171, 0, 173, 0, 175, 0, 177, 0, 179, 0, 181, 0, 183, 67, 185, 68, 1, 0, 16, 3, 0, 76, 76, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 3, 0, 65, 90, 95, 95, 97, 122, 1, 0, 48, 57, 2, 0, 66, 66, 98, 98, 1, 0, 48, 49, 2, 0, 88, 88, 120, 120, 1, 0, 49, 57, 1, 0, 48, 55, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 80, 80, 112, 112, 10, 0, 34, 34, 39, 39, 63, 63, 92, 92, 97, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 2, 0, 9, 9, 32, 32, 1293, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, 0, 0, 0, 183, 1, 0, 0, 0, 0, 185, 1, 0, 0, 0, 1, 187, 1, 0, 0, 0, 3, 189, 1, 0, 0, 0, 5, 191, 1, 0, 0, 0, 7, 193, 1, 0, 0, 0, 9, 195, 1, 0, 0, 0, 11, 197, 1, 0, 0, 0, 13, 199, 1, 0, 0, 0, 15, 201, 1, 0, 0, 0, 17, 203, 1, 0, 0, 0, 19, 206, 1, 0, 0, 0, 21, 208, 1, 0, 0, 0, 23, 211, 1, 0, 0, 0, 25, 214, 1, 0, 0, 0, 27, 225, 1, 0, 0, 0, 29, 239, 1, 0, 0, 0, 31, 261, 1, 0, 0, 0, 33, 287, 1, 0, 0, 0, 35, 315, 1, 0, 0, 0, 37, 333, 1, 0, 0, 0, 39, 341, 1, 0, 0, 0, 41, 383, 1, 0, 0, 0, 43, 385, 1, 0, 0, 0, 45, 387, 1, 0, 0, 0, 47, 389, 1, 0, 0, 0, 49, 391, 1, 0, 0, 0, 51, 393, 1, 0, 0, 0, 53, 395, 1, 0, 0, 0, 55, 397, 1, 0, 0, 0, 57, 400, 1, 0, 0, 0, 59, 403, 1, 0, 0, 0, 61, 406, 1, 0, 0, 0, 63, 408, 1, 0, 0, 0, 65, 410, 1, 0, 0, 0, 67, 420, 1, 0, 0, 0, 69, 428, 1, 0, 0, 0, 71, 444, 1, 0, 0, 0, 73, 468, 1, 0, 0, 0, 75, 470, 1, 0, 0, 0, 77, 479, 1, 0, 0, 0, 79, 485, 1, 0, 0, 0, 81, 487, 1, 0, 0, 0, 83, 523, 1, 0, 0, 0, 85, 559, 1, 0, 0, 0, 87, 595, 1, 0, 0, 0, 89, 625, 1, 0, 0, 0, 91, 663, 1, 0, 0, 0, 93, 701, 1, 0, 0, 0, 95, 727, 1, 0, 0, 0, 97, 757, 1, 0, 0, 0, 99, 777, 1, 0, 0, 0, 101, 799, 1, 0, 0, 0, 103, 823, 1, 0, 0, 0, 105, 845, 1, 0, 0, 0, 107, 869, 1, 0, 0, 0, 109, 897, 1, 0, 0, 0, 111, 917, 1, 0, 0, 0, 113, 939, 1, 0, 0, 0, 115, 961, 1, 0, 0, 0, 117, 990, 1, 0, 0, 0, 119, 996, 1, 0, 0, 0, 121, 1000, 1, 0, 0, 0, 123, 1002, 1, 0, 0, 0, 125, 1010, 1, 0, 0, 0, 127, 1017, 1, 0, 0, 0, 129, 1033, 1, 0, 0, 0, 131, 1046, 1, 0, 0, 0, 133, 1055, 1, 0, 0, 0, 135, 1058, 1, 0, 0, 0, 137, 1063, 1, 0, 0, 0, 139, 1074, 1, 0, 0, 0, 141, 1083, 1, 0, 0, 0, 143, 1085, 1, 0, 0, 0, 145, 1087, 1, 0, 0, 0, 147, 1089, 1, 0, 0, 0, 149, 1104, 1, 0, 0, 0, 151, 1106, 1, 0, 0, 0, 153, 1113, 1, 0, 0, 0, 155, 1117, 1, 0, 0, 0, 157, 1119, 1, 0, 0, 0, 159, 1121, 1, 0, 0, 0, 161, 1123, 1, 0, 0, 0, 163, 1138, 1, 0, 0, 0, 165, 1147, 1, 0, 0, 0, 167, 1149, 1, 0, 0, 0, 169, 1165, 1, 0, 0, 0, 171, 1167, 1, 0, 0, 0, 173, 1174, 1, 0, 0, 0, 175, 1186, 1, 0, 0, 0, 177, 1189, 1, 0, 0, 0, 179, 1193, 1, 0, 0, 0, 181, 1214, 1, 0, 0, 0, 183, 1217, 1, 0, 0, 0, 185, 1228, 1, 0, 0, 0, 187, 188, 5, 40, 0, 0, 188, 2, 1, 0, 0, 0, 189, 190, 5, 41, 0, 0, 190, 4, 1, 0, 0, 0, 191, 192, 5, 91, 0, 0, 192, 6, 1, 0, 0, 0, 193, 194, 5, 44, 0, 0, 194, 8, 1, 0, 0, 0, 195, 196, 5, 93, 0, 0, 196, 10, 1, 0, 0, 0, 197, 198, 5, 123, 0, 0, 198, 12, 1, 0, 0, 0, 199, 200, 5, 125, 0, 0, 200, 14, 1, 0, 0, 0, 201, 202, 5, 60, 0, 0, 202, 16, 1, 0, 0, 0, 203, 204, 5, 60, 0, 0, 204, 205, 5, 61, 0, 0, 205, 18, 1, 0, 0, 0, 206, 207, 5, 62, 0, 0, 207, 20, 1, 0, 0, 0, 208, 209, 5, 62, 0, 0, 209, 210, 5, 61, 0, 0, 210, 22, 1, 0, 0, 0, 211, 212, 5, 61, 0, 0, 212, 213, 5, 61, 0, 0, 213, 24, 1, 0, 0, 0, 214, 215, 5, 33, 0, 0, 215, 216, 5, 61, 0, 0, 216, 26, 1, 0, 0, 0, 217, 218, 5, 108, 0, 0, 218, 219, 5, 105, 0, 0, 219, 220, 5, 107, 0, 0, 220, 226, 5, 101, 0, 0, 221, 222, 5, 76, 0, 0, 222, 223, 5, 73, 0, 0, 223, 224, 5, 75, 0, 0, 224, 226, 5, 69, 0, 0, 225, 217, 1, 0, 0, 0, 225, 221, 1, 0, 0, 0, 226, 28, 1, 0, 0, 0, 227, 228, 5, 101, 0, 0, 228, 229, 5, 120, 0, 0, 229, 230, 5, 105, 0, 0, 230, 231, 5, 115, 0, 0, 231, 232, 5, 116, 0, 0, 232, 240, 5, 115, 0, 0, 233, 234, 5, 69, 0, 0, 234, 235, 5, 88, 0, 0, 235, 236, 5, 73, 0, 0, 236, 237, 5, 83, 0, 0, 237, 238, 5, 84, 0, 0, 238, 240, 5, 83, 0, 0, 239, 227, 1, 0, 0, 0, 239, 233, 1, 0, 0, 0, 240, 30, 1, 0, 0, 0, 241, 242, 5, 116, 0, 0, 242, 243, 5, 101, 0, 0, 243, 244, 5, 120, 0, 0, 244, 245, 5, 116, 0, 0, 245, 246, 5, 95, 0, 0, 246, 247, 5, 109, 0, 0, 247, 248, 5, 97, 0, 0, 248, 249, 5, 116, 0, 0, 249, 250, 5, 99, 0, 0, 250, 262, 5, 104, 0, 0, 251, 252, 5, 84, 0, 0, 252, 253, 5, 69, 0, 0, 253, 254, 5, 88, 0, 0, 254, 255, 5, 84, 0, 0, 255, 256, 5, 95, 0, 0, 256, 257, 5, 77, 0, 0, 257, 258, 5, 65, 0, 0, 258, 259, 5, 84, 0, 0, 259, 260, 5, 67, 0, 0, 260, 262, 5, 72, 0, 0, 261, 241, 1, 0, 0, 0, 261, 251, 1, 0, 0, 0, 262, 32, 1, 0, 0, 0, 263, 264, 5, 112, 0, 0, 264, 265, 5, 104, 0, 0, 265, 266, 5, 114, 0, 0, 266, 267, 5, 97, 0, 0, 267, 268, 5, 115, 0, 0, 268, 269, 5, 101, 0, 0, 269, 270, 5, 95, 0, 0, 270, 271, 5, 109, 0, 0, 271, 272, 5, 97, 0, 0, 272, 273, 5, 116, 0, 0, 273, 274, 5, 99, 0, 0, 274, 288, 5, 104, 0, 0, 275, 276, 5, 80, 0, 0, 276, 277, 5, 72, 0, 0, 277, 278, 5, 82, 0, 0, 278, 279, 5, 65, 0, 0, 279, 280, 5, 83, 0, 0, 280, 281, 5, 69, 0, 0, 281, 282, 5, 95, 0, 0, 282, 283, 5, 77, 0, 0, 283, 284, 5, 65, 0, 0, 284, 285, 5, 84, 0, 0, 285, 286, 5, 67, 0, 0, 286, 288, 5, 72, 0, 0, 287, 263, 1, 0, 0, 0, 287, 275, 1, 0, 0, 0, 288, 34, 1, 0, 0, 0, 289, 290, 5, 114, 0, 0, 290, 291, 5, 97, 0, 0, 291, 292, 5, 110, 0, 0, 292, 293, 5, 100, 0, 0, 293, 294, 5, 111, 0, 0, 294, 295, 5, 109, 0, 0, 295, 296, 5, 95, 0, 0, 296, 297, 5, 115, 0, 0, 297, 298, 5, 97, 0, 0, 298, 299, 5, 109, 0, 0, 299, 300, 5, 112, 0, 0, 300, 301, 5, 108, 0, 0, 301, 316, 5, 101, 0, 0, 302, 303, 5, 82, 0, 0, 303, 304, 5, 65, 0, 0, 304, 305, 5, 78, 0, 0, 305, 306, 5, 68, 0, 0, 306, 307, 5, 79, 0, 0, 307, 308, 5, 77, 0, 0, 308, 309, 5, 95, 0, 0, 309, 310, 5, 83, 0, 0, 310, 311, 5, 65, 0, 0, 311, 312, 5, 77, 0, 0, 312, 313, 5, 80, 0, 0, 313, 314, 5, 76, 0, 0, 314, 316, 5, 69, 0, 0, 315, 289, 1, 0, 0, 0, 315, 302, 1, 0, 0, 0, 316, 36, 1, 0, 0, 0, 317, 318, 5, 105, 0, 0, 318, 319, 5, 110, 0, 0, 319, 320, 5, 116, 0, 0, 320, 321, 5, 101, 0, 0, 321, 322, 5, 114, 0, 0, 322, 323, 5, 118, 0, 0, 323, 324, 5, 97, 0, 0, 324, 334, 5, 108, 0, 0, 325, 326, 5, 73, 0, 0, 326, 327, 5, 78, 0, 0, 327, 328, 5, 84, 0, 0, 328, 329, 5, 69, 0, 0, 329, 330, 5, 82, 0, 0, 330, 331, 5, 86, 0, 0, 331, 332, 5, 65, 0, 0, 332, 334, 5, 76, 0, 0, 333, 317, 1, 0, 0, 0, 333, 325, 1, 0, 0, 0, 334, 38, 1, 0, 0, 0, 335, 336, 5, 105, 0, 0, 336, 337, 5, 115, 0, 0, 337, 342, 5, 111, 0, 0, 338, 339, 5, 73, 0, 0, 339, 340, 5, 83, 0, 0, 340, 342, 5, 79, 0, 0, 341, 335, 1, 0, 0, 0, 341, 338, 1, 0, 0, 0, 342, 40, 1, 0, 0, 0, 343, 344, 5, 109, 0, 0, 344, 345, 5, 105, 0, 0, 345, 346, 5, 110, 0, 0, 346, 347, 5, 105, 0, 0, 347, 348, 5, 109, 0, 0, 348, 349, 5, 117, 0, 0, 349, 350, 5, 109, 0, 0, 350, 351, 5, 95, 0, 0, 351, 352, 5, 115, 0, 0, 352, 353, 5, 104, 0, 0, 353, 354, 5, 111, 0, 0, 354, 355, 5, 117, 0, 0, 355, 356, 5, 108, 0, 0, 356, 357, 5, 100, 0, 0, 357, 358, 5, 95, 0, 0, 358, 359, 5, 109, 0, 0, 359, 360, 5, 97, 0, 0, 360, 361, 5, 116, 0, 0, 361, 362, 5, 99, 0, 0, 362, 384, 5, 104, 0, 0, 363, 364, 5, 77, 0, 0, 364, 365, 5, 73, 0, 0, 365, 366, 5, 78, 0, 0, 366, 367, 5, 73, 0, 0, 367, 368, 5, 77, 0, 0, 368, 369, 5, 85, 0, 0, 369, 370, 5, 77, 0, 0, 370, 371, 5, 95, 0, 0, 371, 372, 5, 83, 0, 0, 372, 373, 5, 72, 0, 0, 373, 374, 5, 79, 0, 0, 374, 375, 5, 85, 0, 0, 375, 376, 5, 76, 0, 0, 376, 377, 5, 68, 0, 0, 377, 378, 5, 95, 0, 0, 378, 379, 5, 77, 0, 0, 379, 380, 5, 65, 0, 0, 380, 381, 5, 84, 0, 0, 381, 382, 5, 67, 0, 0, 382, 384, 5, 72, 0, 0, 383, 343, 1, 0, 0, 0, 383, 363, 1, 0, 0, 0, 384, 42, 1, 0, 0, 0, 385, 386, 5, 61, 0, 0, 386, 44, 1, 0, 0, 0, 387, 388, 5, 43, 0, 0, 388, 46, 1, 0, 0, 0, 389, 390, 5, 45, 0, 0, 390, 48, 1, 0, 0, 0, 391, 392, 5, 42, 0, 0, 392, 50, 1, 0, 0, 0, 393, 394, 5, 47, 0, 0, 394, 52, 1, 0, 0, 0, 395, 396, 5, 37, 0, 0, 396, 54, 1, 0, 0, 0, 397, 398, 5, 42, 0, 0, 398, 399, 5, 42, 0, 0, 399, 56, 1, 0, 0, 0, 400, 401, 5, 60, 0, 0, 401, 402, 5, 60, 0, 0, 402, 58, 1, 0, 0, 0, 403, 404, 5, 62, 0, 0, 404, 405, 5, 62, 0, 0, 405, 60, 1, 0, 0, 0, 406, 407, 5, 38, 0, 0, 407, 62, 1, 0, 0, 0, 408, 409, 5, 124, 0, 0, 409, 64, 1, 0, 0, 0, 410, 411, 5, 94, 0, 0, 411, 66, 1, 0, 0, 0, 412, 413, 5, 38, 0, 0, 413, 421, 5, 38, 0, 0, 414, 415, 5, 97, 0, 0, 415, 416, 5, 110, 0, 0, 416, 421, 5, 100, 0, 0, 417, 418, 5, 65, 0, 0, 418, 419, 5, 78, 0, 0, 419, 421, 5, 68, 0, 0, 420, 412, 1, 0, 0, 0, 420, 414, 1, 0, 0, 0, 420, 417, 1, 0, 0, 0, 421, 68, 1, 0, 0, 0, 422, 423, 5, 124, 0, 0, 423, 429, 5, 124, 0, 0, 424, 425, 5, 111, 0, 0, 425, 429, 5, 114, 0, 0, 426, 427, 5, 79, 0, 0, 427, 429, 5, 82, 0, 0, 428, 422, 1, 0, 0, 0, 428, 424, 1, 0, 0, 0, 428, 426, 1, 0, 0, 0, 429, 70, 1, 0, 0, 0, 430, 431, 5, 105, 0, 0, 431, 432, 5, 115, 0, 0, 432, 433, 5, 32, 0, 0, 433, 434, 5, 110, 0, 0, 434, 435, 5, 117, 0, 0, 435, 436, 5, 108, 0, 0, 436, 445, 5, 108, 0, 0, 437, 438, 5, 73, 0, 0, 438, 439, 5, 83, 0, 0, 439, 440, 5, 32, 0, 0, 440, 441, 5, 78, 0, 0, 441, 442, 5, 85, 0, 0, 442, 443, 5, 76, 0, 0, 443, 445, 5, 76, 0, 0, 444, 430, 1, 0, 0, 0, 444, 437, 1, 0, 0, 0, 445, 72, 1, 0, 0, 0, 446, 447, 5, 105, 0, 0, 447, 448, 5, 115, 0, 0, 448, 449, 5, 32, 0, 0, 449, 450, 5, 110, 0, 0, 450, 451, 5, 111, 0, 0, 451, 452, 5, 116, 0, 0, 452, 453, 5, 32, 0, 0, 453, 454, 5, 110, 0, 0, 454, 455, 5, 117, 0, 0, 455, 456, 5, 108, 0, 0, 456, 469, 5, 108, 0, 0, 457, 458, 5, 73, 0, 0, 458, 459, 5, 83, 0, 0, 459, 460, 5, 32, 0, 0, 460, 461, 5, 78, 0, 0, 461, 462, 5, 79, 0, 0, 462, 463, 5, 84, 0, 0, 463, 464, 5, 32, 0, 0, 464, 465, 5, 78, 0, 0, 465, 466, 5, 85, 0, 0, 466, 467, 5, 76, 0, 0, 467, 469, 5, 76, 0, 0, 468, 446, 1, 0, 0, 0, 468, 457, 1, 0, 0, 0, 469, 74, 1, 0, 0, 0, 470, 471, 5, 126, 0, 0, 471, 76, 1, 0, 0, 0, 472, 480, 5, 33, 0, 0, 473, 474, 5, 110, 0, 0, 474, 475, 5, 111, 0, 0, 475, 480, 5, 116, 0, 0, 476, 477, 5, 78, 0, 0, 477, 478, 5, 79, 0, 0, 478, 480, 5, 84, 0, 0, 479, 472, 1, 0, 0, 0, 479, 473, 1, 0, 0, 0, 479, 476, 1, 0, 0, 0, 480, 78, 1, 0, 0, 0, 481, 482, 5, 105, 0, 0, 482, 486, 5, 110, 0, 0, 483, 484, 5, 73, 0, 0, 484, 486, 5, 78, 0, 0, 485, 481, 1, 0, 0, 0, 485, 483, 1, 0, 0, 0, 486, 80, 1, 0, 0, 0, 487, 492, 5, 91, 0, 0, 488, 491, 3, 183, 91, 0, 489, 491, 3, 185, 92, 0, 490, 488, 1, 0, 0, 0, 490, 489, 1, 0, 0, 0, 491, 494, 1, 0, 0, 0, 492, 490, 1, 0, 0, 0, 492, 493, 1, 0, 0, 0, 493, 495, 1, 0, 0, 0, 494, 492, 1, 0, 0, 0, 495, 496, 5, 93, 0, 0, 496, 82, 1, 0, 0, 0, 497, 498, 5, 106, 0, 0, 498, 499, 5, 115, 0, 0, 499, 500, 5, 111, 0, 0, 500, 501, 5, 110, 0, 0, 501, 502, 5, 95, 0, 0, 502, 503, 5, 99, 0, 0, 503, 504, 5, 111, 0, 0, 504, 505, 5, 110, 0, 0, 505, 506, 5, 116, 0, 0, 506, 507, 5, 97, 0, 0, 507, 508, 5, 105, 0, 0, 508, 509, 5, 110, 0, 0, 509, 524, 5, 115, 0, 0, 510, 511, 5, 74, 0, 0, 511, 512, 5, 83, 0, 0, 512, 513, 5, 79, 0, 0, 513, 514, 5, 78, 0, 0, 514, 515, 5, 95, 0, 0, 515, 516, 5, 67, 0, 0, 516, 517, 5, 79, 0, 0, 517, 518, 5, 78, 0, 0, 518, 519, 5, 84, 0, 0, 519, 520, 5, 65, 0, 0, 520, 521, 5, 73, 0, 0, 521, 522, 5, 78, 0, 0, 522, 524, 5, 83, 0, 0, 523, 497, 1, 0, 0, 0, 523, 510, 1, 0, 0, 0, 524, 84, 1, 0, 0, 0, 525, 526, 5, 106, 0, 0, 526, 527, 5, 115, 0, 0, 527, 528, 5, 111, 0, 0, 528, 529, 5, 110, 0, 0, 529, 530, 5, 95, 0, 0, 530, 531, 5, 99, 0, 0, 531, 532, 5, 111, 0, 0, 532, 533, 5, 110, 0, 0, 533, 534, 5, 116, 0, 0, 534, 535, 5, 97, 0, 0, 535, 536, 5, 105, 0, 0, 536, 537, 5, 110, 0, 0, 537, 538, 5, 115, 0, 0, 538, 539, 5, 95, 0, 0, 539, 540, 5, 97, 0, 0, 540, 541, 5, 108, 0, 0, 541, 560, 5, 108, 0, 0, 542, 543, 5, 74, 0, 0, 543, 544, 5, 83, 0, 0, 544, 545, 5, 79, 0, 0, 545, 546, 5, 78, 0, 0, 546, 547, 5, 95, 0, 0, 547, 548, 5, 67, 0, 0, 548, 549, 5, 79, 0, 0, 549, 550, 5, 78, 0, 0, 550, 551, 5, 84, 0, 0, 551, 552, 5, 65, 0, 0, 552, 553, 5, 73, 0, 0, 553, 554, 5, 78, 0, 0, 554, 555, 5, 83, 0, 0, 555, 556, 5, 95, 0, 0, 556, 557, 5, 65, 0, 0, 557, 558, 5, 76, 0, 0, 558, 560, 5, 76, 0, 0, 559, 525, 1, 0, 0, 0, 559, 542, 1, 0, 0, 0, 560, 86, 1, 0, 0, 0, 561, 562, 5, 106, 0, 0, 562, 563, 5, 115, 0, 0, 563, 564, 5, 111, 0, 0, 564, 565, 5, 110, 0, 0, 565, 566, 5, 95, 0, 0, 566, 567, 5, 99, 0, 0, 567, 568, 5, 111, 0, 0, 568, 569, 5, 110, 0, 0, 569, 570, 5, 116, 0, 0, 570, 571, 5, 97, 0, 0, 571, 572, 5, 105, 0, 0, 572, 573, 5, 110, 0, 0, 573, 574, 5, 115, 0, 0, 574, 575, 5, 95, 0, 0, 575, 576, 5, 97, 0, 0, 576, 577, 5, 110, 0, 0, 577, 596, 5, 121, 0, 0, 578, 579, 5, 74, 0, 0, 579, 580, 5, 83, 0, 0, 580, 581, 5, 79, 0, 0, 581, 582, 5, 78, 0, 0, 582, 583, 5, 95, 0, 0, 583, 584, 5, 67, 0, 0, 584, 585, 5, 79, 0, 0, 585, 586, 5, 78, 0, 0, 586, 587, 5, 84, 0, 0, 587, 588, 5, 65, 0, 0, 588, 589, 5, 73, 0, 0, 589, 590, 5, 78, 0, 0, 590, 591, 5, 83, 0, 0, 591, 592, 5, 95, 0, 0, 592, 593, 5, 65, 0, 0, 593, 594, 5, 78, 0, 0, 594, 596, 5, 89, 0, 0, 595, 561, 1, 0, 0, 0, 595, 578, 1, 0, 0, 0, 596, 88, 1, 0, 0, 0, 597, 598, 5, 97, 0, 0, 598, 599, 5, 114, 0, 0, 599, 600, 5, 114, 0, 0, 600, 601, 5, 97, 0, 0, 601, 602, 5, 121, 0, 0, 602, 603, 5, 95, 0, 0, 603, 604, 5, 99, 0, 0, 604, 605, 5, 111, 0, 0, 605, 606, 5, 110, 0, 0, 606, 607, 5, 116, 0, 0, 607, 608, 5, 97, 0, 0, 608, 609, 5, 105, 0, 0, 609, 610, 5, 110, 0, 0, 610, 626, 5, 115, 0, 0, 611, 612, 5, 65, 0, 0, 612, 613, 5, 82, 0, 0, 613, 614, 5, 82, 0, 0, 614, 615, 5, 65, 0, 0, 615, 616, 5, 89, 0, 0, 616, 617, 5, 95, 0, 0, 617, 618, 5, 67, 0, 0, 618, 619, 5, 79, 0, 0, 619, 620, 5, 78, 0, 0, 620, 621, 5, 84, 0, 0, 621, 622, 5, 65, 0, 0, 622, 623, 5, 73, 0, 0, 623, 624, 5, 78, 0, 0, 624, 626, 5, 83, 0, 0, 625, 597, 1, 0, 0, 0, 625, 611, 1, 0, 0, 0, 626, 90, 1, 0, 0, 0, 627, 628, 5, 97, 0, 0, 628, 629, 5, 114, 0, 0, 629, 630, 5, 114, 0, 0, 630, 631, 5, 97, 0, 0, 631, 632, 5, 121, 0, 0, 632, 633, 5, 95, 0, 0, 633, 634, 5, 99, 0, 0, 634, 635, 5, 111, 0, 0, 635, 636, 5, 110, 0, 0, 636, 637, 5, 116, 0, 0, 637, 638, 5, 97, 0, 0, 638, 639, 5, 105, 0, 0, 639, 640, 5, 110, 0, 0, 640, 641, 5, 115, 0, 0, 641, 642, 5, 95, 0, 0, 642, 643, 5, 97, 0, 0, 643, 644, 5, 108, 0, 0, 644, 664, 5, 108, 0, 0, 645, 646, 5, 65, 0, 0, 646, 647, 5, 82, 0, 0, 647, 648, 5, 82, 0, 0, 648, 649, 5, 65, 0, 0, 649, 650, 5, 89, 0, 0, 650, 651, 5, 95, 0, 0, 651, 652, 5, 67, 0, 0, 652, 653, 5, 79, 0, 0, 653, 654, 5, 78, 0, 0, 654, 655, 5, 84, 0, 0, 655, 656, 5, 65, 0, 0, 656, 657, 5, 73, 0, 0, 657, 658, 5, 78, 0, 0, 658, 659, 5, 83, 0, 0, 659, 660, 5, 95, 0, 0, 660, 661, 5, 65, 0, 0, 661, 662, 5, 76, 0, 0, 662, 664, 5, 76, 0, 0, 663, 627, 1, 0, 0, 0, 663, 645, 1, 0, 0, 0, 664, 92, 1, 0, 0, 0, 665, 666, 5, 97, 0, 0, 666, 667, 5, 114, 0, 0, 667, 668, 5, 114, 0, 0, 668, 669, 5, 97, 0, 0, 669, 670, 5, 121, 0, 0, 670, 671, 5, 95, 0, 0, 671, 672, 5, 99, 0, 0, 672, 673, 5, 111, 0, 0, 673, 674, 5, 110, 0, 0, 674, 675, 5, 116, 0, 0, 675, 676, 5, 97, 0, 0, 676, 677, 5, 105, 0, 0, 677, 678, 5, 110, 0, 0, 678, 679, 5, 115, 0, 0, 679, 680, 5, 95, 0, 0, 680, 681, 5, 97, 0, 0, 681, 682, 5, 110, 0, 0, 682, 702, 5, 121, 0, 0, 683, 684, 5, 65, 0, 0, 684, 685, 5, 82, 0, 0, 685, 686, 5, 82, 0, 0, 686, 687, 5, 65, 0, 0, 687, 688, 5, 89, 0, 0, 688, 689, 5, 95, 0, 0, 689, 690, 5, 67, 0, 0, 690, 691, 5, 79, 0, 0, 691, 692, 5, 78, 0, 0, 692, 693, 5, 84, 0, 0, 693, 694, 5, 65, 0, 0, 694, 695, 5, 73, 0, 0, 695, 696, 5, 78, 0, 0, 696, 697, 5, 83, 0, 0, 697, 698, 5, 95, 0, 0, 698, 699, 5, 65, 0, 0, 699, 700, 5, 78, 0, 0, 700, 702, 5, 89, 0, 0, 701, 665, 1, 0, 0, 0, 701, 683, 1, 0, 0, 0, 702, 94, 1, 0, 0, 0, 703, 704, 5, 97, 0, 0, 704, 705, 5, 114, 0, 0, 705, 706, 5, 114, 0, 0, 706, 707, 5, 97, 0, 0, 707, 708, 5, 121, 0, 0, 708, 709, 5, 95, 0, 0, 709, 710, 5, 108, 0, 0, 710, 711, 5, 101, 0, 0, 711, 712, 5, 110, 0, 0, 712, 713, 5, 103, 0, 0, 713, 714, 5, 116, 0, 0, 714, 728, 5, 104, 0, 0, 715, 716, 5, 65, 0, 0, 716, 717, 5, 82, 0, 0, 717, 718, 5, 82, 0, 0, 718, 719, 5, 65, 0, 0, 719, 720, 5, 89, 0, 0, 720, 721, 5, 95, 0, 0, 721, 722, 5, 76, 0, 0, 722, 723, 5, 69, 0, 0, 723, 724, 5, 78, 0, 0, 724, 725, 5, 71, 0, 0, 725, 726, 5, 84, 0, 0, 726, 728, 5, 72, 0, 0, 727, 703, 1, 0, 0, 0, 727, 715, 1, 0, 0, 0, 728, 96, 1, 0, 0, 0, 729, 730, 5, 101, 0, 0, 730, 731, 5, 108, 0, 0, 731, 732, 5, 101, 0, 0, 732, 733, 5, 109, 0, 0, 733, 734, 5, 101, 0, 0, 734, 735, 5, 110, 0, 0, 735, 736, 5, 116, 0, 0, 736, 737, 5, 95, 0, 0, 737, 738, 5, 102, 0, 0, 738, 739, 5, 105, 0, 0, 739, 740, 5, 108, 0, 0, 740, 741, 5, 116, 0, 0, 741, 742, 5, 101, 0, 0, 742, 758, 5, 114, 0, 0, 743, 744, 5, 69, 0, 0, 744, 745, 5, 76, 0, 0, 745, 746, 5, 69, 0, 0, 746, 747, 5, 77, 0, 0, 747, 748, 5, 69, 0, 0, 748, 749, 5, 78, 0, 0, 749, 750, 5, 84, 0, 0, 750, 751, 5, 95, 0, 0, 751, 752, 5, 70, 0, 0, 752, 753, 5, 73, 0, 0, 753, 754, 5, 76, 0, 0, 754, 755, 5, 84, 0, 0, 755, 756, 5, 69, 0, 0, 756, 758, 5, 82, 0, 0, 757, 729, 1, 0, 0, 0, 757, 743, 1, 0, 0, 0, 758, 98, 1, 0, 0, 0, 759, 760, 5, 115, 0, 0, 760, 761, 5, 116, 0, 0, 761, 762, 5, 95, 0, 0, 762, 763, 5, 101, 0, 0, 763, 764, 5, 113, 0, 0, 764, 765, 5, 117, 0, 0, 765, 766, 5, 97, 0, 0, 766, 767, 5, 108, 0, 0, 767, 778, 5, 115, 0, 0, 768, 769, 5, 83, 0, 0, 769, 770, 5, 84, 0, 0, 770, 771, 5, 95, 0, 0, 771, 772, 5, 69, 0, 0, 772, 773, 5, 81, 0, 0, 773, 774, 5, 85, 0, 0, 774, 775, 5, 65, 0, 0, 775, 776, 5, 76, 0, 0, 776, 778, 5, 83, 0, 0, 777, 759, 1, 0, 0, 0, 777, 768, 1, 0, 0, 0, 778, 100, 1, 0, 0, 0, 779, 780, 5, 115, 0, 0, 780, 781, 5, 116, 0, 0, 781, 782, 5, 95, 0, 0, 782, 783, 5, 116, 0, 0, 783, 784, 5, 111, 0, 0, 784, 785, 5, 117, 0, 0, 785, 786, 5, 99, 0, 0, 786, 787, 5, 104, 0, 0, 787, 788, 5, 101, 0, 0, 788, 800, 5, 115, 0, 0, 789, 790, 5, 83, 0, 0, 790, 791, 5, 84, 0, 0, 791, 792, 5, 95, 0, 0, 792, 793, 5, 84, 0, 0, 793, 794, 5, 79, 0, 0, 794, 795, 5, 85, 0, 0, 795, 796, 5, 67, 0, 0, 796, 797, 5, 72, 0, 0, 797, 798, 5, 69, 0, 0, 798, 800, 5, 83, 0, 0, 799, 779, 1, 0, 0, 0, 799, 789, 1, 0, 0, 0, 800, 102, 1, 0, 0, 0, 801, 802, 5, 115, 0, 0, 802, 803, 5, 116, 0, 0, 803, 804, 5, 95, 0, 0, 804, 805, 5, 111, 0, 0, 805, 806, 5, 118, 0, 0, 806, 807, 5, 101, 0, 0, 807, 808, 5, 114, 0, 0, 808, 809, 5, 108, 0, 0, 809, 810, 5, 97, 0, 0, 810, 811, 5, 112, 0, 0, 811, 824, 5, 115, 0, 0, 812, 813, 5, 83, 0, 0, 813, 814, 5, 84, 0, 0, 814, 815, 5, 95, 0, 0, 815, 816, 5, 79, 0, 0, 816, 817, 5, 86, 0, 0, 817, 818, 5, 69, 0, 0, 818, 819, 5, 82, 0, 0, 819, 820, 5, 76, 0, 0, 820, 821, 5, 65, 0, 0, 821, 822, 5, 80, 0, 0, 822, 824, 5, 83, 0, 0, 823, 801, 1, 0, 0, 0, 823, 812, 1, 0, 0, 0, 824, 104, 1, 0, 0, 0, 825, 826, 5, 115, 0, 0, 826, 827, 5, 116, 0, 0, 827, 828, 5, 95, 0, 0, 828, 829, 5, 99, 0, 0, 829, 830, 5, 114, 0, 0, 830, 831, 5, 111, 0, 0, 831, 832, 5, 115, 0, 0, 832, 833, 5, 115, 0, 0, 833, 834, 5, 101, 0, 0, 834, 846, 5, 115, 0, 0, 835, 836, 5, 83, 0, 0, 836, 837, 5, 84, 0, 0, 837, 838, 5, 95, 0, 0, 838, 839, 5, 67, 0, 0, 839, 840, 5, 82, 0, 0, 840, 841, 5, 79, 0, 0, 841, 842, 5, 83, 0, 0, 842, 843, 5, 83, 0, 0, 843, 844, 5, 69, 0, 0, 844, 846, 5, 83, 0, 0, 845, 825, 1, 0, 0, 0, 845, 835, 1, 0, 0, 0, 846, 106, 1, 0, 0, 0, 847, 848, 5, 115, 0, 0, 848, 849, 5, 116, 0, 0, 849, 850, 5, 95, 0, 0, 850, 851, 5, 99, 0, 0, 851, 852, 5, 111, 0, 0, 852, 853, 5, 110, 0, 0, 853, 854, 5, 116, 0, 0, 854, 855, 5, 97, 0, 0, 855, 856, 5, 105, 0, 0, 856, 857, 5, 110, 0, 0, 857, 870, 5, 115, 0, 0, 858, 859, 5, 83, 0, 0, 859, 860, 5, 84, 0, 0, 860, 861, 5, 95, 0, 0, 861, 862, 5, 67, 0, 0, 862, 863, 5, 79, 0, 0, 863, 864, 5, 78, 0, 0, 864, 865, 5, 84, 0, 0, 865, 866, 5, 65, 0, 0, 866, 867, 5, 73, 0, 0, 867, 868, 5, 78, 0, 0, 868, 870, 5, 83, 0, 0, 869, 847, 1, 0, 0, 0, 869, 858, 1, 0, 0, 0, 870, 108, 1, 0, 0, 0, 871, 872, 5, 115, 0, 0, 872, 873, 5, 116, 0, 0, 873, 874, 5, 95, 0, 0, 874, 875, 5, 105, 0, 0, 875, 876, 5, 110, 0, 0, 876, 877, 5, 116, 0, 0, 877, 878, 5, 101, 0, 0, 878, 879, 5, 114, 0, 0, 879, 880, 5, 115, 0, 0, 880, 881, 5, 101, 0, 0, 881, 882, 5, 99, 0, 0, 882, 883, 5, 116, 0, 0, 883, 898, 5, 115, 0, 0, 884, 885, 5, 83, 0, 0, 885, 886, 5, 84, 0, 0, 886, 887, 5, 95, 0, 0, 887, 888, 5, 73, 0, 0, 888, 889, 5, 78, 0, 0, 889, 890, 5, 84, 0, 0, 890, 891, 5, 69, 0, 0, 891, 892, 5, 82, 0, 0, 892, 893, 5, 83, 0, 0, 893, 894, 5, 69, 0, 0, 894, 895, 5, 67, 0, 0, 895, 896, 5, 84, 0, 0, 896, 898, 5, 83, 0, 0, 897, 871, 1, 0, 0, 0, 897, 884, 1, 0, 0, 0, 898, 110, 1, 0, 0, 0, 899, 900, 5, 115, 0, 0, 900, 901, 5, 116, 0, 0, 901, 902, 5, 95, 0, 0, 902, 903, 5, 119, 0, 0, 903, 904, 5, 105, 0, 0, 904, 905, 5, 116, 0, 0, 905, 906, 5, 104, 0, 0, 906, 907, 5, 105, 0, 0, 907, 918, 5, 110, 0, 0, 908, 909, 5, 83, 0, 0, 909, 910, 5, 84, 0, 0, 910, 911, 5, 95, 0, 0, 911, 912, 5, 87, 0, 0, 912, 913, 5, 73, 0, 0, 913, 914, 5, 84, 0, 0, 914, 915, 5, 72, 0, 0, 915, 916, 5, 73, 0, 0, 916, 918, 5, 78, 0, 0, 917, 899, 1, 0, 0, 0, 917, 908, 1, 0, 0, 0, 918, 112, 1, 0, 0, 0, 919, 920, 5, 115, 0, 0, 920, 921, 5, 116, 0, 0, 921, 922, 5, 95, 0, 0, 922, 923, 5, 100, 0, 0, 923, 924, 5, 119, 0, 0, 924, 925, 5, 105, 0, 0, 925, 926, 5, 116, 0, 0, 926, 927, 5, 104, 0, 0, 927, 928, 5, 105, 0, 0, 928, 940, 5, 110, 0, 0, 929, 930, 5, 83, 0, 0, 930, 931, 5, 84, 0, 0, 931, 932, 5, 95, 0, 0, 932, 933, 5, 68, 0, 0, 933, 934, 5, 87, 0, 0, 934, 935, 5, 73, 0, 0, 935, 936, 5, 84, 0, 0, 936, 937, 5, 72, 0, 0, 937, 938, 5, 73, 0, 0, 938, 940, 5, 78, 0, 0, 939, 919, 1, 0, 0, 0, 939, 929, 1, 0, 0, 0, 940, 114, 1, 0, 0, 0, 941, 942, 5, 115, 0, 0, 942, 943, 5, 116, 0, 0, 943, 944, 5, 95, 0, 0, 944, 945, 5, 105, 0, 0, 945, 946, 5, 115, 0, 0, 946, 947, 5, 118, 0, 0, 947, 948, 5, 97, 0, 0, 948, 949, 5, 108, 0, 0, 949, 950, 5, 105, 0, 0, 950, 962, 5, 100, 0, 0, 951, 952, 5, 83, 0, 0, 952, 953, 5, 84, 0, 0, 953, 954, 5, 95, 0, 0, 954, 955, 5, 73, 0, 0, 955, 956, 5, 83, 0, 0, 956, 957, 5, 86, 0, 0, 957, 958, 5, 65, 0, 0, 958, 959, 5, 76, 0, 0, 959, 960, 5, 73, 0, 0, 960, 962, 5, 68, 0, 0, 961, 941, 1, 0, 0, 0, 961, 951, 1, 0, 0, 0, 962, 116, 1, 0, 0, 0, 963, 964, 5, 116, 0, 0, 964, 965, 5, 114, 0, 0, 965, 966, 5, 117, 0, 0, 966, 991, 5, 101, 0, 0, 967, 968, 5, 84, 0, 0, 968, 969, 5, 114, 0, 0, 969, 970, 5, 117, 0, 0, 970, 991, 5, 101, 0, 0, 971, 972, 5, 84, 0, 0, 972, 973, 5, 82, 0, 0, 973, 974, 5, 85, 0, 0, 974, 991, 5, 69, 0, 0, 975, 976, 5, 102, 0, 0, 976, 977, 5, 97, 0, 0, 977, 978, 5, 108, 0, 0, 978, 979, 5, 115, 0, 0, 979, 991, 5, 101, 0, 0, 980, 981, 5, 70, 0, 0, 981, 982, 5, 97, 0, 0, 982, 983, 5, 108, 0, 0, 983, 984, 5, 115, 0, 0, 984, 991, 5, 101, 0, 0, 985, 986, 5, 70, 0, 0, 986, 987, 5, 65, 0, 0, 987, 988, 5, 76, 0, 0, 988, 989, 5, 83, 0, 0, 989, 991, 5, 69, 0, 0, 990, 963, 1, 0, 0, 0, 990, 967, 1, 0, 0, 0, 990, 971, 1, 0, 0, 0, 990, 975, 1, 0, 0, 0, 990, 980, 1, 0, 0, 0, 990, 985, 1, 0, 0, 0, 991, 118, 1, 0, 0, 0, 992, 997, 3, 149, 74, 0, 993, 997, 3, 151, 75, 0, 994, 997, 3, 153, 76, 0, 995, 997, 3, 147, 73, 0, 996, 992, 1, 0, 0, 0, 996, 993, 1, 0, 0, 0, 996, 994, 1, 0, 0, 0, 996, 995, 1, 0, 0, 0, 997, 120, 1, 0, 0, 0, 998, 1001, 3, 165, 82, 0, 999, 1001, 3, 167, 83, 0, 1000, 998, 1, 0, 0, 0, 1000, 999, 1, 0, 0, 0, 1001, 122, 1, 0, 0, 0, 1002, 1007, 3, 143, 71, 0, 1003, 1006, 3, 143, 71, 0, 1004, 1006, 3, 145, 72, 0, 1005, 1003, 1, 0, 0, 0, 1005, 1004, 1, 0, 0, 0, 1006, 1009, 1, 0, 0, 0, 1007, 1005, 1, 0, 0, 0, 1007, 1008, 1, 0, 0, 0, 1008, 124, 1, 0, 0, 0, 1009, 1007, 1, 0, 0, 0, 1010, 1011, 5, 36, 0, 0, 1011, 1012, 5, 109, 0, 0, 1012, 1013, 5, 101, 0, 0, 1013, 1014, 5, 116, 0, 0, 1014, 1015, 5, 97, 0, 0, 1015, 126, 1, 0, 0, 0, 1016, 1018, 3, 133, 66, 0, 1017, 1016, 1, 0, 0, 0, 1017, 1018, 1, 0, 0, 0, 1018, 1029, 1, 0, 0, 0, 1019, 1021, 5, 34, 0, 0, 1020, 1022, 3, 135, 67, 0, 1021, 1020, 1, 0, 0, 0, 1021, 1022, 1, 0, 0, 0, 1022, 1023, 1, 0, 0, 0, 1023, 1030, 5, 34, 0, 0, 1024, 1026, 5, 39, 0, 0, 1025, 1027, 3, 137, 68, 0, 1026, 1025, 1, 0, 0, 0, 1026, 1027, 1, 0, 0, 0, 1027, 1028, 1, 0, 0, 0, 1028, 1030, 5, 39, 0, 0, 1029, 1019, 1, 0, 0, 0, 1029, 1024, 1, 0, 0, 0, 1030, 128, 1, 0, 0, 0, 1031, 1034, 3, 123, 61, 0, 1032, 1034, 3, 125, 62, 0, 1033, 1031, 1, 0, 0, 0, 1033, 1032, 1, 0, 0, 0, 1034, 1042, 1, 0, 0, 0, 1035, 1038, 5, 91, 0, 0, 1036, 1039, 3, 127, 63, 0, 1037, 1039, 3, 149, 74, 0, 1038, 1036, 1, 0, 0, 0, 1038, 1037, 1, 0, 0, 0, 1039, 1040, 1, 0, 0, 0, 1040, 1041, 5, 93, 0, 0, 1041, 1043, 1, 0, 0, 0, 1042, 1035, 1, 0, 0, 0, 1043, 1044, 1, 0, 0, 0, 1044, 1042, 1, 0, 0, 0, 1044, 1045, 1, 0, 0, 0, 1045, 130, 1, 0, 0, 0, 1046, 1047, 5, 36, 0, 0, 1047, 1048, 5, 91, 0, 0, 1048, 1049, 1, 0, 0, 0, 1049, 1050, 3, 123, 61, 0, 1050, 1051, 5, 93, 0, 0, 1051, 132, 1, 0, 0, 0, 1052, 1053, 5, 117, 0, 0, 1053, 1056, 5, 56, 0, 0, 1054, 1056, 7, 0, 0, 0, 1055, 1052, 1, 0, 0, 0, 1055, 1054, 1, 0, 0, 0, 1056, 134, 1, 0, 0, 0, 1057, 1059, 3, 139, 69, 0, 1058, 1057, 1, 0, 0, 0, 1059, 1060, 1, 0, 0, 0, 1060, 1058, 1, 0, 0, 0, 1060, 1061, 1, 0, 0, 0, 1061, 136, 1, 0, 0, 0, 1062, 1064, 3, 141, 70, 0, 1063, 1062, 1, 0, 0, 0, 1064, 1065, 1, 0, 0, 0, 1065, 1063, 1, 0, 0, 0, 1065, 1066, 1, 0, 0, 0, 1066, 138, 1, 0, 0, 0, 1067, 1075, 8, 1, 0, 0, 1068, 1075, 3, 181, 90, 0, 1069, 1070, 5, 92, 0, 0, 1070, 1075, 5, 10, 0, 0, 1071, 1072, 5, 92, 0, 0, 1072, 1073, 5, 13, 0, 0, 1073, 1075, 5, 10, 0, 0, 1074, 1067, 1, 0, 0, 0, 1074, 1068, 1, 0, 0, 0, 1074, 1069, 1, 0, 0, 0, 1074, 1071, 1, 0, 0, 0, 1075, 140, 1, 0, 0, 0, 1076, 1084, 8, 2, 0, 0, 1077, 1084, 3, 181, 90, 0, 1078, 1079, 5, 92, 0, 0, 1079, 1084, 5, 10, 0, 0, 1080, 1081, 5, 92, 0, 0, 1081, 1082, 5, 13, 0, 0, 1082, 1084, 5, 10, 0, 0, 1083, 1076, 1, 0, 0, 0, 1083, 1077, 1, 0, 0, 0, 1083, 1078, 1, 0, 0, 0, 1083, 1080, 1, 0, 0, 0, 1084, 142, 1, 0, 0, 0, 1085, 1086, 7, 3, 0, 0, 1086, 144, 1, 0, 0, 0, 1087, 1088, 7, 4, 0, 0, 1088, 146, 1, 0, 0, 0, 1089, 1090, 5, 48, 0, 0, 1090, 1092, 7, 5, 0, 0, 1091, 1093, 7, 6, 0, 0, 1092, 1091, 1, 0, 0, 0, 1093, 1094, 1, 0, 0, 0, 1094, 1092, 1, 0, 0, 0, 1094, 1095, 1, 0, 0, 0, 1095, 148, 1, 0, 0, 0, 1096, 1100, 3, 155, 77, 0, 1097, 1099, 3, 145, 72, 0, 1098, 1097, 1, 0, 0, 0, 1099, 1102, 1, 0, 0, 0, 1100, 1098, 1, 0, 0, 0, 1100, 1101, 1, 0, 0, 0, 1101, 1105, 1, 0, 0, 0, 1102, 1100, 1, 0, 0, 0, 1103, 1105, 5, 48, 0, 0, 1104, 1096, 1, 0, 0, 0, 1104, 1103, 1, 0, 0, 0, 1105, 150, 1, 0, 0, 0, 1106, 1110, 5, 48, 0, 0, 1107, 1109, 3, 157, 78, 0, 1108, 1107, 1, 0, 0, 0, 1109, 1112, 1, 0, 0, 0, 1110, 1108, 1, 0, 0, 0, 1110, 1111, 1, 0, 0, 0, 1111, 152, 1, 0, 0, 0, 1112, 1110, 1, 0, 0, 0, 1113, 1114, 5, 48, 0, 0, 1114, 1115, 7, 7, 0, 0, 1115, 1116, 3, 177, 88, 0, 1116, 154, 1, 0, 0, 0, 1117, 1118, 7, 8, 0, 0, 1118, 156, 1, 0, 0, 0, 1119, 1120, 7, 9, 0, 0, 1120, 158, 1, 0, 0, 0, 1121, 1122, 7, 10, 0, 0, 1122, 160, 1, 0, 0, 0, 1123, 1124, 3, 159, 79, 0, 1124, 1125, 3, 159, 79, 0, 1125, 1126, 3, 159, 79, 0, 1126, 1127, 3, 159, 79, 0, 1127, 162, 1, 0, 0, 0, 1128, 1129, 5, 92, 0, 0, 1129, 1130, 5, 117, 0, 0, 1130, 1131, 1, 0, 0, 0, 1131, 1139, 3, 161, 80, 0, 1132, 1133, 5, 92, 0, 0, 1133, 1134, 5, 85, 0, 0, 1134, 1135, 1, 0, 0, 0, 1135, 1136, 3, 161, 80, 0, 1136, 1137, 3, 161, 80, 0, 1137, 1139, 1, 0, 0, 0, 1138, 1128, 1, 0, 0, 0, 1138, 1132, 1, 0, 0, 0, 1139, 164, 1, 0, 0, 0, 1140, 1142, 3, 169, 84, 0, 1141, 1143, 3, 171, 85, 0, 1142, 1141, 1, 0, 0, 0, 1142, 1143, 1, 0, 0, 0, 1143, 1148, 1, 0, 0, 0, 1144, 1145, 3, 173, 86, 0, 1145, 1146, 3, 171, 85, 0, 1146, 1148, 1, 0, 0, 0, 1147, 1140, 1, 0, 0, 0, 1147, 1144, 1, 0, 0, 0, 1148, 166, 1, 0, 0, 0, 1149, 1150, 5, 48, 0, 0, 1150, 1153, 7, 7, 0, 0, 1151, 1154, 3, 175, 87, 0, 1152, 1154, 3, 177, 88, 0, 1153, 1151, 1, 0, 0, 0, 1153, 1152, 1, 0, 0, 0, 1154, 1155, 1, 0, 0, 0, 1155, 1156, 3, 179, 89, 0, 1156, 168, 1, 0, 0, 0, 1157, 1159, 3, 173, 86, 0, 1158, 1157, 1, 0, 0, 0, 1158, 1159, 1, 0, 0, 0, 1159, 1160, 1, 0, 0, 0, 1160, 1161, 5, 46, 0, 0, 1161, 1166, 3, 173, 86, 0, 1162, 1163, 3, 173, 86, 0, 1163, 1164, 5, 46, 0, 0, 1164, 1166, 1, 0, 0, 0, 1165, 1158, 1, 0, 0, 0, 1165, 1162, 1, 0, 0, 0, 1166, 170, 1, 0, 0, 0, 1167, 1169, 7, 11, 0, 0, 1168, 1170, 7, 12, 0, 0, 1169, 1168, 1, 0, 0, 0, 1169, 1170, 1, 0, 0, 0, 1170, 1171, 1, 0, 0, 0, 1171, 1172, 3, 173, 86, 0, 1172, 172, 1, 0, 0, 0, 1173, 1175, 3, 145, 72, 0, 1174, 1173, 1, 0, 0, 0, 1175, 1176, 1, 0, 0, 0, 1176, 1174, 1, 0, 0, 0, 1176, 1177, 1, 0, 0, 0, 1177, 174, 1, 0, 0, 0, 1178, 1180, 3, 177, 88, 0, 1179, 1178, 1, 0, 0, 0, 1179, 1180, 1, 0, 0, 0, 1180, 1181, 1, 0, 0, 0, 1181, 1182, 5, 46, 0, 0, 1182, 1187, 3, 177, 88, 0, 1183, 1184, 3, 177, 88, 0, 1184, 1185, 5, 46, 0, 0, 1185, 1187, 1, 0, 0, 0, 1186, 1179, 1, 0, 0, 0, 1186, 1183, 1, 0, 0, 0, 1187, 176, 1, 0, 0, 0, 1188, 1190, 3, 159, 79, 0, 1189, 1188, 1, 0, 0, 0, 1190, 1191, 1, 0, 0, 0, 1191, 1189, 1, 0, 0, 0, 1191, 1192, 1, 0, 0, 0, 1192, 178, 1, 0, 0, 0, 1193, 1195, 7, 13, 0, 0, 1194, 1196, 7, 12, 0, 0, 1195, 1194, 1, 0, 0, 0, 1195, 1196, 1, 0, 0, 0, 1196, 1197, 1, 0, 0, 0, 1197, 1198, 3, 173, 86, 0, 1198, 180, 1, 0, 0, 0, 1199, 1200, 5, 92, 0, 0, 1200, 1215, 7, 14, 0, 0, 1201, 1202, 5, 92, 0, 0, 1202, 1204, 3, 157, 78, 0, 1203, 1205, 3, 157, 78, 0, 1204, 1203, 1, 0, 0, 0, 1204, 1205, 1, 0, 0, 0, 1205, 1207, 1, 0, 0, 0, 1206, 1208, 3, 157, 78, 0, 1207, 1206, 1, 0, 0, 0, 1207, 1208, 1, 0, 0, 0, 1208, 1215, 1, 0, 0, 0, 1209, 1210, 5, 92, 0, 0, 1210, 1211, 5, 120, 0, 0, 1211, 1212, 1, 0, 0, 0, 1212, 1215, 3, 177, 88, 0, 1213, 1215, 3, 163, 81, 0, 1214, 1199, 1, 0, 0, 0, 1214, 1201, 1, 0, 0, 0, 1214, 1209, 1, 0, 0, 0, 1214, 1213, 1, 0, 0, 0, 1215, 182, 1, 0, 0, 0, 1216, 1218, 7, 15, 0, 0, 1217, 1216, 1, 0, 0, 0, 1218, 1219, 1, 0, 0, 0, 1219, 1217, 1, 0, 0, 0, 1219, 1220, 1, 0, 0, 0, 1220, 1221, 1, 0, 0, 0, 1221, 1222, 6, 91, 0, 0, 1222, 184, 1, 0, 0, 0, 1223, 1225, 5, 13, 0, 0, 1224, 1226, 5, 10, 0, 0, 1225, 1224, 1, 0, 0, 0, 1225, 1226, 1, 0, 0, 0, 1226, 1229, 1, 0, 0, 0, 1227, 1229, 5, 10, 0, 0, 1228, 1223, 1, 0, 0, 0, 1228, 1227, 1, 0, 0, 0, 1229, 1230, 1, 0, 0, 0, 1230, 1231, 6, 92, 0, 0, 1231, 186, 1, 0, 0, 0, 73, 0, 225, 239, 261, 287, 315, 333, 341, 383, 420, 428, 444, 468, 479, 485, 490, 492, 523, 559, 595, 625, 663, 701, 727, 757, 777, 799, 823, 845, 869, 897, 917, 939, 961, 990, 996, 1000, 1005, 1007, 1017, 1021, 1026, 1029, 1033, 1038, 1044, 1055, 1060, 1065, 1074, 1083, 1094, 1100, 1104, 1110, 1138, 1142, 1147, 1153, 1158, 1165, 1169, 1176, 1179, 1186, 1191, 1195, 1204, 1207, 1214, 1219, 1225, 1228, 1, 6, 0, 0] \ No newline at end of file diff --git a/internal/parser/planparserv2/generated/PlanLexer.tokens b/internal/parser/planparserv2/generated/PlanLexer.tokens index f834707a5d..374477f781 100644 --- a/internal/parser/planparserv2/generated/PlanLexer.tokens +++ b/internal/parser/planparserv2/generated/PlanLexer.tokens @@ -46,24 +46,26 @@ ArrayContains=45 ArrayContainsAll=46 ArrayContainsAny=47 ArrayLength=48 -STEuqals=49 -STTouches=50 -STOverlaps=51 -STCrosses=52 -STContains=53 -STIntersects=54 -STWithin=55 -STDWithin=56 -STIsValid=57 -BooleanConstant=58 -IntegerConstant=59 -FloatingConstant=60 -Identifier=61 -Meta=62 -StringLiteral=63 -JSONIdentifier=64 -Whitespace=65 -Newline=66 +ElementFilter=49 +STEuqals=50 +STTouches=51 +STOverlaps=52 +STCrosses=53 +STContains=54 +STIntersects=55 +STWithin=56 +STDWithin=57 +STIsValid=58 +BooleanConstant=59 +IntegerConstant=60 +FloatingConstant=61 +Identifier=62 +Meta=63 +StringLiteral=64 +JSONIdentifier=65 +StructSubFieldIdentifier=66 +Whitespace=67 +Newline=68 '('=1 ')'=2 '['=3 @@ -90,4 +92,4 @@ Newline=66 '|'=32 '^'=33 '~'=38 -'$meta'=62 +'$meta'=63 diff --git a/internal/parser/planparserv2/generated/plan_base_visitor.go b/internal/parser/planparserv2/generated/plan_base_visitor.go index c4a4e5a632..eb1708aece 100644 --- a/internal/parser/planparserv2/generated/plan_base_visitor.go +++ b/internal/parser/planparserv2/generated/plan_base_visitor.go @@ -7,18 +7,6 @@ type BasePlanVisitor struct { *antlr.BaseParseTreeVisitor } -func (v *BasePlanVisitor) VisitJSONIdentifier(ctx *JSONIdentifierContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BasePlanVisitor) VisitRandomSample(ctx *RandomSampleContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BasePlanVisitor) VisitParens(ctx *ParensContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitString(ctx *StringContext) interface{} { return v.VisitChildren(ctx) } @@ -27,22 +15,10 @@ func (v *BasePlanVisitor) VisitFloating(ctx *FloatingContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitJSONContainsAll(ctx *JSONContainsAllContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BasePlanVisitor) VisitLogicalOr(ctx *LogicalOrContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitIsNotNull(ctx *IsNotNullContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitMulDivMod(ctx *MulDivModContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitIdentifier(ctx *IdentifierContext) interface{} { return v.VisitChildren(ctx) } @@ -55,14 +31,6 @@ func (v *BasePlanVisitor) VisitLike(ctx *LikeContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitLogicalAnd(ctx *LogicalAndContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BasePlanVisitor) VisitTemplateVariable(ctx *TemplateVariableContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitEquality(ctx *EqualityContext) interface{} { return v.VisitChildren(ctx) } @@ -71,14 +39,6 @@ func (v *BasePlanVisitor) VisitBoolean(ctx *BooleanContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitTimestamptzCompareReverse(ctx *TimestamptzCompareReverseContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BasePlanVisitor) VisitSTDWithin(ctx *STDWithinContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitShift(ctx *ShiftContext) interface{} { return v.VisitChildren(ctx) } @@ -87,54 +47,26 @@ func (v *BasePlanVisitor) VisitTimestamptzCompareForward(ctx *TimestamptzCompare return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitCall(ctx *CallContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BasePlanVisitor) VisitSTCrosses(ctx *STCrossesContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitReverseRange(ctx *ReverseRangeContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitBitOr(ctx *BitOrContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitEmptyArray(ctx *EmptyArrayContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitAddSub(ctx *AddSubContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitPhraseMatch(ctx *PhraseMatchContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitRelational(ctx *RelationalContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitArrayLength(ctx *ArrayLengthContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitTextMatch(ctx *TextMatchContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitSTTouches(ctx *STTouchesContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitSTContains(ctx *STContainsContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitTerm(ctx *TermContext) interface{} { return v.VisitChildren(ctx) } @@ -151,6 +83,94 @@ func (v *BasePlanVisitor) VisitRange(ctx *RangeContext) interface{} { return v.VisitChildren(ctx) } +func (v *BasePlanVisitor) VisitSTIsValid(ctx *STIsValidContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitBitXor(ctx *BitXorContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitElementFilter(ctx *ElementFilterContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitBitAnd(ctx *BitAndContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitSTOverlaps(ctx *STOverlapsContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitJSONIdentifier(ctx *JSONIdentifierContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitRandomSample(ctx *RandomSampleContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitParens(ctx *ParensContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitJSONContainsAll(ctx *JSONContainsAllContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitLogicalOr(ctx *LogicalOrContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitMulDivMod(ctx *MulDivModContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitLogicalAnd(ctx *LogicalAndContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitTemplateVariable(ctx *TemplateVariableContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitTimestamptzCompareReverse(ctx *TimestamptzCompareReverseContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitSTDWithin(ctx *STDWithinContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitCall(ctx *CallContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitSTCrosses(ctx *STCrossesContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitBitOr(ctx *BitOrContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitAddSub(ctx *AddSubContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitRelational(ctx *RelationalContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitTextMatch(ctx *TextMatchContext) interface{} { + return v.VisitChildren(ctx) +} + +func (v *BasePlanVisitor) VisitSTContains(ctx *STContainsContext) interface{} { + return v.VisitChildren(ctx) +} + func (v *BasePlanVisitor) VisitUnary(ctx *UnaryContext) interface{} { return v.VisitChildren(ctx) } @@ -167,22 +187,10 @@ func (v *BasePlanVisitor) VisitJSONContainsAny(ctx *JSONContainsAnyContext) inte return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitSTIsValid(ctx *STIsValidContext) interface{} { - return v.VisitChildren(ctx) -} - -func (v *BasePlanVisitor) VisitBitXor(ctx *BitXorContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitExists(ctx *ExistsContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitBitAnd(ctx *BitAndContext) interface{} { - return v.VisitChildren(ctx) -} - func (v *BasePlanVisitor) VisitSTEuqals(ctx *STEuqalsContext) interface{} { return v.VisitChildren(ctx) } @@ -191,11 +199,11 @@ func (v *BasePlanVisitor) VisitIsNull(ctx *IsNullContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitPower(ctx *PowerContext) interface{} { +func (v *BasePlanVisitor) VisitStructSubField(ctx *StructSubFieldContext) interface{} { return v.VisitChildren(ctx) } -func (v *BasePlanVisitor) VisitSTOverlaps(ctx *STOverlapsContext) interface{} { +func (v *BasePlanVisitor) VisitPower(ctx *PowerContext) interface{} { return v.VisitChildren(ctx) } diff --git a/internal/parser/planparserv2/generated/plan_lexer.go b/internal/parser/planparserv2/generated/plan_lexer.go index 8f32975426..ab794760f6 100644 --- a/internal/parser/planparserv2/generated/plan_lexer.go +++ b/internal/parser/planparserv2/generated/plan_lexer.go @@ -47,7 +47,7 @@ func planlexerLexerInit() { "'>'", "'>='", "'=='", "'!='", "", "", "", "", "", "", "", "", "'='", "'+'", "'-'", "'*'", "'/'", "'%'", "'**'", "'<<'", "'>>'", "'&'", "'|'", "'^'", "", "", "", "", "'~'", "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", "", "", "", "'$meta'", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "'$meta'", } staticData.SymbolicNames = []string{ "", "", "", "", "", "", "LBRACE", "RBRACE", "LT", "LE", "GT", "GE", @@ -56,11 +56,11 @@ func planlexerLexerInit() { "DIV", "MOD", "POW", "SHL", "SHR", "BAND", "BOR", "BXOR", "AND", "OR", "ISNULL", "ISNOTNULL", "BNOT", "NOT", "IN", "EmptyArray", "JSONContains", "JSONContainsAll", "JSONContainsAny", "ArrayContains", "ArrayContainsAll", - "ArrayContainsAny", "ArrayLength", "STEuqals", "STTouches", "STOverlaps", - "STCrosses", "STContains", "STIntersects", "STWithin", "STDWithin", - "STIsValid", "BooleanConstant", "IntegerConstant", "FloatingConstant", - "Identifier", "Meta", "StringLiteral", "JSONIdentifier", "Whitespace", - "Newline", + "ArrayContainsAny", "ArrayLength", "ElementFilter", "STEuqals", "STTouches", + "STOverlaps", "STCrosses", "STContains", "STIntersects", "STWithin", + "STDWithin", "STIsValid", "BooleanConstant", "IntegerConstant", "FloatingConstant", + "Identifier", "Meta", "StringLiteral", "JSONIdentifier", "StructSubFieldIdentifier", + "Whitespace", "Newline", } staticData.RuleNames = []string{ "T__0", "T__1", "T__2", "T__3", "T__4", "LBRACE", "RBRACE", "LT", "LE", @@ -69,21 +69,21 @@ func planlexerLexerInit() { "ADD", "SUB", "MUL", "DIV", "MOD", "POW", "SHL", "SHR", "BAND", "BOR", "BXOR", "AND", "OR", "ISNULL", "ISNOTNULL", "BNOT", "NOT", "IN", "EmptyArray", "JSONContains", "JSONContainsAll", "JSONContainsAny", "ArrayContains", - "ArrayContainsAll", "ArrayContainsAny", "ArrayLength", "STEuqals", "STTouches", - "STOverlaps", "STCrosses", "STContains", "STIntersects", "STWithin", - "STDWithin", "STIsValid", "BooleanConstant", "IntegerConstant", "FloatingConstant", - "Identifier", "Meta", "StringLiteral", "JSONIdentifier", "EncodingPrefix", - "DoubleSCharSequence", "SingleSCharSequence", "DoubleSChar", "SingleSChar", - "Nondigit", "Digit", "BinaryConstant", "DecimalConstant", "OctalConstant", - "HexadecimalConstant", "NonzeroDigit", "OctalDigit", "HexadecimalDigit", - "HexQuad", "UniversalCharacterName", "DecimalFloatingConstant", "HexadecimalFloatingConstant", - "FractionalConstant", "ExponentPart", "DigitSequence", "HexadecimalFractionalConstant", - "HexadecimalDigitSequence", "BinaryExponentPart", "EscapeSequence", - "Whitespace", "Newline", + "ArrayContainsAll", "ArrayContainsAny", "ArrayLength", "ElementFilter", + "STEuqals", "STTouches", "STOverlaps", "STCrosses", "STContains", "STIntersects", + "STWithin", "STDWithin", "STIsValid", "BooleanConstant", "IntegerConstant", + "FloatingConstant", "Identifier", "Meta", "StringLiteral", "JSONIdentifier", + "StructSubFieldIdentifier", "EncodingPrefix", "DoubleSCharSequence", + "SingleSCharSequence", "DoubleSChar", "SingleSChar", "Nondigit", "Digit", + "BinaryConstant", "DecimalConstant", "OctalConstant", "HexadecimalConstant", + "NonzeroDigit", "OctalDigit", "HexadecimalDigit", "HexQuad", "UniversalCharacterName", + "DecimalFloatingConstant", "HexadecimalFloatingConstant", "FractionalConstant", + "ExponentPart", "DigitSequence", "HexadecimalFractionalConstant", "HexadecimalDigitSequence", + "BinaryExponentPart", "EscapeSequence", "Whitespace", "Newline", } staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ - 4, 0, 66, 1192, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, + 4, 0, 68, 1232, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, @@ -100,531 +100,549 @@ func planlexerLexerInit() { 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, - 88, 2, 89, 7, 89, 2, 90, 7, 90, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, - 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, - 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, - 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 222, - 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, - 14, 1, 14, 1, 14, 3, 14, 236, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, + 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 1, 0, 1, 0, + 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, + 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, + 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, + 1, 13, 1, 13, 3, 13, 226, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, + 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 240, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, - 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 258, 8, 15, 1, 16, 1, 16, 1, 16, - 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, + 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 262, + 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, - 3, 16, 284, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, + 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 288, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, - 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 312, 8, - 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, - 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 3, 18, 330, 8, 18, 1, 19, 1, - 19, 1, 19, 1, 19, 1, 19, 1, 19, 3, 19, 338, 8, 19, 1, 20, 1, 20, 1, 20, + 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, + 17, 1, 17, 3, 17, 316, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, + 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 3, + 18, 334, 8, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 3, 19, 342, 8, + 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, - 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, - 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 380, 8, 20, 1, 21, 1, 21, - 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, - 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, - 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, - 33, 1, 33, 3, 33, 417, 8, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, - 3, 34, 425, 8, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, - 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 3, 35, 441, 8, 35, 1, 36, - 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, + 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 384, + 8, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, + 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, + 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, + 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 421, 8, 33, 1, 34, 1, 34, 1, 34, + 1, 34, 1, 34, 1, 34, 3, 34, 429, 8, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, + 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 3, 35, + 445, 8, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, - 3, 36, 465, 8, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, - 38, 1, 38, 3, 38, 476, 8, 38, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 482, 8, - 39, 1, 40, 1, 40, 1, 40, 5, 40, 487, 8, 40, 10, 40, 12, 40, 490, 9, 40, - 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, + 1, 36, 1, 36, 1, 36, 3, 36, 469, 8, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, + 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 480, 8, 38, 1, 39, 1, 39, 1, 39, + 1, 39, 3, 39, 486, 8, 39, 1, 40, 1, 40, 1, 40, 5, 40, 491, 8, 40, 10, 40, + 12, 40, 494, 9, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, - 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 520, 8, 41, 1, - 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, + 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, + 41, 524, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, - 1, 42, 1, 42, 3, 42, 556, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, + 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 560, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, - 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 592, 8, 43, - 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, + 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, + 3, 43, 596, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, - 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 622, 8, 44, 1, - 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, + 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, + 44, 626, 8, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, - 1, 45, 1, 45, 1, 45, 1, 45, 3, 45, 660, 8, 45, 1, 46, 1, 46, 1, 46, 1, + 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 3, 45, 664, 8, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, - 1, 46, 3, 46, 698, 8, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, + 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 702, 8, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, - 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 3, 47, 724, 8, 47, 1, - 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, - 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, 744, 8, 48, 1, - 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, - 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 3, 49, 766, - 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, + 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 3, + 47, 728, 8, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, + 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, + 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, + 758, 8, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, + 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 3, 49, + 778, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, - 1, 50, 1, 50, 3, 50, 790, 8, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, + 1, 50, 3, 50, 800, 8, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, - 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 812, 8, 51, 1, 52, 1, 52, 1, 52, 1, + 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 824, 8, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, - 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 3, 52, 836, 8, - 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, + 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 3, 52, 846, 8, 52, 1, + 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, - 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 864, 8, 53, 1, 54, 1, 54, + 53, 3, 53, 870, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, - 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 884, 8, 54, 1, 55, 1, 55, - 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, - 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 3, 55, 906, 8, 55, - 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, - 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, - 928, 8, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, + 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 898, + 8, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, + 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 3, 55, 918, + 8, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, + 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, + 3, 56, 940, 8, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, - 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 957, 8, - 57, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 963, 8, 58, 1, 59, 1, 59, 3, 59, - 967, 8, 59, 1, 60, 1, 60, 1, 60, 5, 60, 972, 8, 60, 10, 60, 12, 60, 975, - 9, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 3, 62, 984, 8, - 62, 1, 62, 1, 62, 3, 62, 988, 8, 62, 1, 62, 1, 62, 1, 62, 3, 62, 993, 8, - 62, 1, 62, 3, 62, 996, 8, 62, 1, 63, 1, 63, 3, 63, 1000, 8, 63, 1, 63, - 1, 63, 1, 63, 3, 63, 1005, 8, 63, 1, 63, 1, 63, 4, 63, 1009, 8, 63, 11, - 63, 12, 63, 1010, 1, 64, 1, 64, 1, 64, 3, 64, 1016, 8, 64, 1, 65, 4, 65, - 1019, 8, 65, 11, 65, 12, 65, 1020, 1, 66, 4, 66, 1024, 8, 66, 11, 66, 12, - 66, 1025, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 1035, - 8, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1044, 8, - 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 4, 71, 1053, 8, 71, - 11, 71, 12, 71, 1054, 1, 72, 1, 72, 5, 72, 1059, 8, 72, 10, 72, 12, 72, - 1062, 9, 72, 1, 72, 3, 72, 1065, 8, 72, 1, 73, 1, 73, 5, 73, 1069, 8, 73, - 10, 73, 12, 73, 1072, 9, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, - 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, - 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 3, 79, 1099, - 8, 79, 1, 80, 1, 80, 3, 80, 1103, 8, 80, 1, 80, 1, 80, 1, 80, 3, 80, 1108, - 8, 80, 1, 81, 1, 81, 1, 81, 1, 81, 3, 81, 1114, 8, 81, 1, 81, 1, 81, 1, - 82, 3, 82, 1119, 8, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 3, 82, 1126, - 8, 82, 1, 83, 1, 83, 3, 83, 1130, 8, 83, 1, 83, 1, 83, 1, 84, 4, 84, 1135, - 8, 84, 11, 84, 12, 84, 1136, 1, 85, 3, 85, 1140, 8, 85, 1, 85, 1, 85, 1, - 85, 1, 85, 1, 85, 3, 85, 1147, 8, 85, 1, 86, 4, 86, 1150, 8, 86, 11, 86, - 12, 86, 1151, 1, 87, 1, 87, 3, 87, 1156, 8, 87, 1, 87, 1, 87, 1, 88, 1, - 88, 1, 88, 1, 88, 1, 88, 3, 88, 1165, 8, 88, 1, 88, 3, 88, 1168, 8, 88, - 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 3, 88, 1175, 8, 88, 1, 89, 4, 89, 1178, - 8, 89, 11, 89, 12, 89, 1179, 1, 89, 1, 89, 1, 90, 1, 90, 3, 90, 1186, 8, - 90, 1, 90, 3, 90, 1189, 8, 90, 1, 90, 1, 90, 0, 0, 91, 1, 1, 3, 2, 5, 3, + 1, 57, 1, 57, 3, 57, 962, 8, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, + 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, + 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, + 58, 3, 58, 991, 8, 58, 1, 59, 1, 59, 1, 59, 1, 59, 3, 59, 997, 8, 59, 1, + 60, 1, 60, 3, 60, 1001, 8, 60, 1, 61, 1, 61, 1, 61, 5, 61, 1006, 8, 61, + 10, 61, 12, 61, 1009, 9, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, + 1, 63, 3, 63, 1018, 8, 63, 1, 63, 1, 63, 3, 63, 1022, 8, 63, 1, 63, 1, + 63, 1, 63, 3, 63, 1027, 8, 63, 1, 63, 3, 63, 1030, 8, 63, 1, 64, 1, 64, + 3, 64, 1034, 8, 64, 1, 64, 1, 64, 1, 64, 3, 64, 1039, 8, 64, 1, 64, 1, + 64, 4, 64, 1043, 8, 64, 11, 64, 12, 64, 1044, 1, 65, 1, 65, 1, 65, 1, 65, + 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 3, 66, 1056, 8, 66, 1, 67, 4, 67, 1059, + 8, 67, 11, 67, 12, 67, 1060, 1, 68, 4, 68, 1064, 8, 68, 11, 68, 12, 68, + 1065, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 3, 69, 1075, 8, + 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 3, 70, 1084, 8, 70, + 1, 71, 1, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 4, 73, 1093, 8, 73, 11, + 73, 12, 73, 1094, 1, 74, 1, 74, 5, 74, 1099, 8, 74, 10, 74, 12, 74, 1102, + 9, 74, 1, 74, 3, 74, 1105, 8, 74, 1, 75, 1, 75, 5, 75, 1109, 8, 75, 10, + 75, 12, 75, 1112, 9, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, + 1, 78, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, + 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 3, 81, 1139, 8, 81, + 1, 82, 1, 82, 3, 82, 1143, 8, 82, 1, 82, 1, 82, 1, 82, 3, 82, 1148, 8, + 82, 1, 83, 1, 83, 1, 83, 1, 83, 3, 83, 1154, 8, 83, 1, 83, 1, 83, 1, 84, + 3, 84, 1159, 8, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 3, 84, 1166, 8, + 84, 1, 85, 1, 85, 3, 85, 1170, 8, 85, 1, 85, 1, 85, 1, 86, 4, 86, 1175, + 8, 86, 11, 86, 12, 86, 1176, 1, 87, 3, 87, 1180, 8, 87, 1, 87, 1, 87, 1, + 87, 1, 87, 1, 87, 3, 87, 1187, 8, 87, 1, 88, 4, 88, 1190, 8, 88, 11, 88, + 12, 88, 1191, 1, 89, 1, 89, 3, 89, 1196, 8, 89, 1, 89, 1, 89, 1, 90, 1, + 90, 1, 90, 1, 90, 1, 90, 3, 90, 1205, 8, 90, 1, 90, 3, 90, 1208, 8, 90, + 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 3, 90, 1215, 8, 90, 1, 91, 4, 91, 1218, + 8, 91, 11, 91, 12, 91, 1219, 1, 91, 1, 91, 1, 92, 1, 92, 3, 92, 1226, 8, + 92, 1, 92, 3, 92, 1229, 8, 92, 1, 92, 1, 92, 0, 0, 93, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 56, 113, 57, - 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, 64, 129, 0, - 131, 0, 133, 0, 135, 0, 137, 0, 139, 0, 141, 0, 143, 0, 145, 0, 147, 0, + 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, 64, 129, 65, + 131, 66, 133, 0, 135, 0, 137, 0, 139, 0, 141, 0, 143, 0, 145, 0, 147, 0, 149, 0, 151, 0, 153, 0, 155, 0, 157, 0, 159, 0, 161, 0, 163, 0, 165, 0, - 167, 0, 169, 0, 171, 0, 173, 0, 175, 0, 177, 0, 179, 65, 181, 66, 1, 0, - 16, 3, 0, 76, 76, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, - 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 3, 0, 65, 90, 95, 95, 97, 122, 1, - 0, 48, 57, 2, 0, 66, 66, 98, 98, 1, 0, 48, 49, 2, 0, 88, 88, 120, 120, - 1, 0, 49, 57, 1, 0, 48, 55, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 69, 69, - 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 80, 80, 112, 112, 10, 0, 34, 34, - 39, 39, 63, 63, 92, 92, 97, 98, 102, 102, 110, 110, 114, 114, 116, 116, - 118, 118, 2, 0, 9, 9, 32, 32, 1252, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, - 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, - 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, - 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, - 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, - 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, - 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, - 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, - 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, - 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, - 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, - 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, - 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, - 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, - 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, - 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, - 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, - 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 179, 1, 0, 0, 0, 0, 181, 1, 0, 0, 0, 1, - 183, 1, 0, 0, 0, 3, 185, 1, 0, 0, 0, 5, 187, 1, 0, 0, 0, 7, 189, 1, 0, - 0, 0, 9, 191, 1, 0, 0, 0, 11, 193, 1, 0, 0, 0, 13, 195, 1, 0, 0, 0, 15, - 197, 1, 0, 0, 0, 17, 199, 1, 0, 0, 0, 19, 202, 1, 0, 0, 0, 21, 204, 1, - 0, 0, 0, 23, 207, 1, 0, 0, 0, 25, 210, 1, 0, 0, 0, 27, 221, 1, 0, 0, 0, - 29, 235, 1, 0, 0, 0, 31, 257, 1, 0, 0, 0, 33, 283, 1, 0, 0, 0, 35, 311, - 1, 0, 0, 0, 37, 329, 1, 0, 0, 0, 39, 337, 1, 0, 0, 0, 41, 379, 1, 0, 0, - 0, 43, 381, 1, 0, 0, 0, 45, 383, 1, 0, 0, 0, 47, 385, 1, 0, 0, 0, 49, 387, - 1, 0, 0, 0, 51, 389, 1, 0, 0, 0, 53, 391, 1, 0, 0, 0, 55, 393, 1, 0, 0, - 0, 57, 396, 1, 0, 0, 0, 59, 399, 1, 0, 0, 0, 61, 402, 1, 0, 0, 0, 63, 404, - 1, 0, 0, 0, 65, 406, 1, 0, 0, 0, 67, 416, 1, 0, 0, 0, 69, 424, 1, 0, 0, - 0, 71, 440, 1, 0, 0, 0, 73, 464, 1, 0, 0, 0, 75, 466, 1, 0, 0, 0, 77, 475, - 1, 0, 0, 0, 79, 481, 1, 0, 0, 0, 81, 483, 1, 0, 0, 0, 83, 519, 1, 0, 0, - 0, 85, 555, 1, 0, 0, 0, 87, 591, 1, 0, 0, 0, 89, 621, 1, 0, 0, 0, 91, 659, - 1, 0, 0, 0, 93, 697, 1, 0, 0, 0, 95, 723, 1, 0, 0, 0, 97, 743, 1, 0, 0, - 0, 99, 765, 1, 0, 0, 0, 101, 789, 1, 0, 0, 0, 103, 811, 1, 0, 0, 0, 105, - 835, 1, 0, 0, 0, 107, 863, 1, 0, 0, 0, 109, 883, 1, 0, 0, 0, 111, 905, - 1, 0, 0, 0, 113, 927, 1, 0, 0, 0, 115, 956, 1, 0, 0, 0, 117, 962, 1, 0, - 0, 0, 119, 966, 1, 0, 0, 0, 121, 968, 1, 0, 0, 0, 123, 976, 1, 0, 0, 0, - 125, 983, 1, 0, 0, 0, 127, 999, 1, 0, 0, 0, 129, 1015, 1, 0, 0, 0, 131, - 1018, 1, 0, 0, 0, 133, 1023, 1, 0, 0, 0, 135, 1034, 1, 0, 0, 0, 137, 1043, - 1, 0, 0, 0, 139, 1045, 1, 0, 0, 0, 141, 1047, 1, 0, 0, 0, 143, 1049, 1, - 0, 0, 0, 145, 1064, 1, 0, 0, 0, 147, 1066, 1, 0, 0, 0, 149, 1073, 1, 0, - 0, 0, 151, 1077, 1, 0, 0, 0, 153, 1079, 1, 0, 0, 0, 155, 1081, 1, 0, 0, - 0, 157, 1083, 1, 0, 0, 0, 159, 1098, 1, 0, 0, 0, 161, 1107, 1, 0, 0, 0, - 163, 1109, 1, 0, 0, 0, 165, 1125, 1, 0, 0, 0, 167, 1127, 1, 0, 0, 0, 169, - 1134, 1, 0, 0, 0, 171, 1146, 1, 0, 0, 0, 173, 1149, 1, 0, 0, 0, 175, 1153, - 1, 0, 0, 0, 177, 1174, 1, 0, 0, 0, 179, 1177, 1, 0, 0, 0, 181, 1188, 1, - 0, 0, 0, 183, 184, 5, 40, 0, 0, 184, 2, 1, 0, 0, 0, 185, 186, 5, 41, 0, - 0, 186, 4, 1, 0, 0, 0, 187, 188, 5, 91, 0, 0, 188, 6, 1, 0, 0, 0, 189, - 190, 5, 44, 0, 0, 190, 8, 1, 0, 0, 0, 191, 192, 5, 93, 0, 0, 192, 10, 1, - 0, 0, 0, 193, 194, 5, 123, 0, 0, 194, 12, 1, 0, 0, 0, 195, 196, 5, 125, - 0, 0, 196, 14, 1, 0, 0, 0, 197, 198, 5, 60, 0, 0, 198, 16, 1, 0, 0, 0, - 199, 200, 5, 60, 0, 0, 200, 201, 5, 61, 0, 0, 201, 18, 1, 0, 0, 0, 202, - 203, 5, 62, 0, 0, 203, 20, 1, 0, 0, 0, 204, 205, 5, 62, 0, 0, 205, 206, - 5, 61, 0, 0, 206, 22, 1, 0, 0, 0, 207, 208, 5, 61, 0, 0, 208, 209, 5, 61, - 0, 0, 209, 24, 1, 0, 0, 0, 210, 211, 5, 33, 0, 0, 211, 212, 5, 61, 0, 0, - 212, 26, 1, 0, 0, 0, 213, 214, 5, 108, 0, 0, 214, 215, 5, 105, 0, 0, 215, - 216, 5, 107, 0, 0, 216, 222, 5, 101, 0, 0, 217, 218, 5, 76, 0, 0, 218, - 219, 5, 73, 0, 0, 219, 220, 5, 75, 0, 0, 220, 222, 5, 69, 0, 0, 221, 213, - 1, 0, 0, 0, 221, 217, 1, 0, 0, 0, 222, 28, 1, 0, 0, 0, 223, 224, 5, 101, - 0, 0, 224, 225, 5, 120, 0, 0, 225, 226, 5, 105, 0, 0, 226, 227, 5, 115, - 0, 0, 227, 228, 5, 116, 0, 0, 228, 236, 5, 115, 0, 0, 229, 230, 5, 69, - 0, 0, 230, 231, 5, 88, 0, 0, 231, 232, 5, 73, 0, 0, 232, 233, 5, 83, 0, - 0, 233, 234, 5, 84, 0, 0, 234, 236, 5, 83, 0, 0, 235, 223, 1, 0, 0, 0, - 235, 229, 1, 0, 0, 0, 236, 30, 1, 0, 0, 0, 237, 238, 5, 116, 0, 0, 238, - 239, 5, 101, 0, 0, 239, 240, 5, 120, 0, 0, 240, 241, 5, 116, 0, 0, 241, - 242, 5, 95, 0, 0, 242, 243, 5, 109, 0, 0, 243, 244, 5, 97, 0, 0, 244, 245, - 5, 116, 0, 0, 245, 246, 5, 99, 0, 0, 246, 258, 5, 104, 0, 0, 247, 248, - 5, 84, 0, 0, 248, 249, 5, 69, 0, 0, 249, 250, 5, 88, 0, 0, 250, 251, 5, - 84, 0, 0, 251, 252, 5, 95, 0, 0, 252, 253, 5, 77, 0, 0, 253, 254, 5, 65, - 0, 0, 254, 255, 5, 84, 0, 0, 255, 256, 5, 67, 0, 0, 256, 258, 5, 72, 0, - 0, 257, 237, 1, 0, 0, 0, 257, 247, 1, 0, 0, 0, 258, 32, 1, 0, 0, 0, 259, - 260, 5, 112, 0, 0, 260, 261, 5, 104, 0, 0, 261, 262, 5, 114, 0, 0, 262, - 263, 5, 97, 0, 0, 263, 264, 5, 115, 0, 0, 264, 265, 5, 101, 0, 0, 265, - 266, 5, 95, 0, 0, 266, 267, 5, 109, 0, 0, 267, 268, 5, 97, 0, 0, 268, 269, - 5, 116, 0, 0, 269, 270, 5, 99, 0, 0, 270, 284, 5, 104, 0, 0, 271, 272, - 5, 80, 0, 0, 272, 273, 5, 72, 0, 0, 273, 274, 5, 82, 0, 0, 274, 275, 5, - 65, 0, 0, 275, 276, 5, 83, 0, 0, 276, 277, 5, 69, 0, 0, 277, 278, 5, 95, - 0, 0, 278, 279, 5, 77, 0, 0, 279, 280, 5, 65, 0, 0, 280, 281, 5, 84, 0, - 0, 281, 282, 5, 67, 0, 0, 282, 284, 5, 72, 0, 0, 283, 259, 1, 0, 0, 0, - 283, 271, 1, 0, 0, 0, 284, 34, 1, 0, 0, 0, 285, 286, 5, 114, 0, 0, 286, - 287, 5, 97, 0, 0, 287, 288, 5, 110, 0, 0, 288, 289, 5, 100, 0, 0, 289, - 290, 5, 111, 0, 0, 290, 291, 5, 109, 0, 0, 291, 292, 5, 95, 0, 0, 292, - 293, 5, 115, 0, 0, 293, 294, 5, 97, 0, 0, 294, 295, 5, 109, 0, 0, 295, - 296, 5, 112, 0, 0, 296, 297, 5, 108, 0, 0, 297, 312, 5, 101, 0, 0, 298, - 299, 5, 82, 0, 0, 299, 300, 5, 65, 0, 0, 300, 301, 5, 78, 0, 0, 301, 302, - 5, 68, 0, 0, 302, 303, 5, 79, 0, 0, 303, 304, 5, 77, 0, 0, 304, 305, 5, - 95, 0, 0, 305, 306, 5, 83, 0, 0, 306, 307, 5, 65, 0, 0, 307, 308, 5, 77, - 0, 0, 308, 309, 5, 80, 0, 0, 309, 310, 5, 76, 0, 0, 310, 312, 5, 69, 0, - 0, 311, 285, 1, 0, 0, 0, 311, 298, 1, 0, 0, 0, 312, 36, 1, 0, 0, 0, 313, - 314, 5, 105, 0, 0, 314, 315, 5, 110, 0, 0, 315, 316, 5, 116, 0, 0, 316, - 317, 5, 101, 0, 0, 317, 318, 5, 114, 0, 0, 318, 319, 5, 118, 0, 0, 319, - 320, 5, 97, 0, 0, 320, 330, 5, 108, 0, 0, 321, 322, 5, 73, 0, 0, 322, 323, - 5, 78, 0, 0, 323, 324, 5, 84, 0, 0, 324, 325, 5, 69, 0, 0, 325, 326, 5, - 82, 0, 0, 326, 327, 5, 86, 0, 0, 327, 328, 5, 65, 0, 0, 328, 330, 5, 76, - 0, 0, 329, 313, 1, 0, 0, 0, 329, 321, 1, 0, 0, 0, 330, 38, 1, 0, 0, 0, - 331, 332, 5, 105, 0, 0, 332, 333, 5, 115, 0, 0, 333, 338, 5, 111, 0, 0, - 334, 335, 5, 73, 0, 0, 335, 336, 5, 83, 0, 0, 336, 338, 5, 79, 0, 0, 337, - 331, 1, 0, 0, 0, 337, 334, 1, 0, 0, 0, 338, 40, 1, 0, 0, 0, 339, 340, 5, - 109, 0, 0, 340, 341, 5, 105, 0, 0, 341, 342, 5, 110, 0, 0, 342, 343, 5, - 105, 0, 0, 343, 344, 5, 109, 0, 0, 344, 345, 5, 117, 0, 0, 345, 346, 5, - 109, 0, 0, 346, 347, 5, 95, 0, 0, 347, 348, 5, 115, 0, 0, 348, 349, 5, - 104, 0, 0, 349, 350, 5, 111, 0, 0, 350, 351, 5, 117, 0, 0, 351, 352, 5, - 108, 0, 0, 352, 353, 5, 100, 0, 0, 353, 354, 5, 95, 0, 0, 354, 355, 5, - 109, 0, 0, 355, 356, 5, 97, 0, 0, 356, 357, 5, 116, 0, 0, 357, 358, 5, - 99, 0, 0, 358, 380, 5, 104, 0, 0, 359, 360, 5, 77, 0, 0, 360, 361, 5, 73, - 0, 0, 361, 362, 5, 78, 0, 0, 362, 363, 5, 73, 0, 0, 363, 364, 5, 77, 0, - 0, 364, 365, 5, 85, 0, 0, 365, 366, 5, 77, 0, 0, 366, 367, 5, 95, 0, 0, - 367, 368, 5, 83, 0, 0, 368, 369, 5, 72, 0, 0, 369, 370, 5, 79, 0, 0, 370, - 371, 5, 85, 0, 0, 371, 372, 5, 76, 0, 0, 372, 373, 5, 68, 0, 0, 373, 374, - 5, 95, 0, 0, 374, 375, 5, 77, 0, 0, 375, 376, 5, 65, 0, 0, 376, 377, 5, - 84, 0, 0, 377, 378, 5, 67, 0, 0, 378, 380, 5, 72, 0, 0, 379, 339, 1, 0, - 0, 0, 379, 359, 1, 0, 0, 0, 380, 42, 1, 0, 0, 0, 381, 382, 5, 61, 0, 0, - 382, 44, 1, 0, 0, 0, 383, 384, 5, 43, 0, 0, 384, 46, 1, 0, 0, 0, 385, 386, - 5, 45, 0, 0, 386, 48, 1, 0, 0, 0, 387, 388, 5, 42, 0, 0, 388, 50, 1, 0, - 0, 0, 389, 390, 5, 47, 0, 0, 390, 52, 1, 0, 0, 0, 391, 392, 5, 37, 0, 0, - 392, 54, 1, 0, 0, 0, 393, 394, 5, 42, 0, 0, 394, 395, 5, 42, 0, 0, 395, - 56, 1, 0, 0, 0, 396, 397, 5, 60, 0, 0, 397, 398, 5, 60, 0, 0, 398, 58, - 1, 0, 0, 0, 399, 400, 5, 62, 0, 0, 400, 401, 5, 62, 0, 0, 401, 60, 1, 0, - 0, 0, 402, 403, 5, 38, 0, 0, 403, 62, 1, 0, 0, 0, 404, 405, 5, 124, 0, - 0, 405, 64, 1, 0, 0, 0, 406, 407, 5, 94, 0, 0, 407, 66, 1, 0, 0, 0, 408, - 409, 5, 38, 0, 0, 409, 417, 5, 38, 0, 0, 410, 411, 5, 97, 0, 0, 411, 412, - 5, 110, 0, 0, 412, 417, 5, 100, 0, 0, 413, 414, 5, 65, 0, 0, 414, 415, - 5, 78, 0, 0, 415, 417, 5, 68, 0, 0, 416, 408, 1, 0, 0, 0, 416, 410, 1, - 0, 0, 0, 416, 413, 1, 0, 0, 0, 417, 68, 1, 0, 0, 0, 418, 419, 5, 124, 0, - 0, 419, 425, 5, 124, 0, 0, 420, 421, 5, 111, 0, 0, 421, 425, 5, 114, 0, - 0, 422, 423, 5, 79, 0, 0, 423, 425, 5, 82, 0, 0, 424, 418, 1, 0, 0, 0, - 424, 420, 1, 0, 0, 0, 424, 422, 1, 0, 0, 0, 425, 70, 1, 0, 0, 0, 426, 427, - 5, 105, 0, 0, 427, 428, 5, 115, 0, 0, 428, 429, 5, 32, 0, 0, 429, 430, - 5, 110, 0, 0, 430, 431, 5, 117, 0, 0, 431, 432, 5, 108, 0, 0, 432, 441, - 5, 108, 0, 0, 433, 434, 5, 73, 0, 0, 434, 435, 5, 83, 0, 0, 435, 436, 5, - 32, 0, 0, 436, 437, 5, 78, 0, 0, 437, 438, 5, 85, 0, 0, 438, 439, 5, 76, - 0, 0, 439, 441, 5, 76, 0, 0, 440, 426, 1, 0, 0, 0, 440, 433, 1, 0, 0, 0, - 441, 72, 1, 0, 0, 0, 442, 443, 5, 105, 0, 0, 443, 444, 5, 115, 0, 0, 444, - 445, 5, 32, 0, 0, 445, 446, 5, 110, 0, 0, 446, 447, 5, 111, 0, 0, 447, - 448, 5, 116, 0, 0, 448, 449, 5, 32, 0, 0, 449, 450, 5, 110, 0, 0, 450, - 451, 5, 117, 0, 0, 451, 452, 5, 108, 0, 0, 452, 465, 5, 108, 0, 0, 453, - 454, 5, 73, 0, 0, 454, 455, 5, 83, 0, 0, 455, 456, 5, 32, 0, 0, 456, 457, - 5, 78, 0, 0, 457, 458, 5, 79, 0, 0, 458, 459, 5, 84, 0, 0, 459, 460, 5, - 32, 0, 0, 460, 461, 5, 78, 0, 0, 461, 462, 5, 85, 0, 0, 462, 463, 5, 76, - 0, 0, 463, 465, 5, 76, 0, 0, 464, 442, 1, 0, 0, 0, 464, 453, 1, 0, 0, 0, - 465, 74, 1, 0, 0, 0, 466, 467, 5, 126, 0, 0, 467, 76, 1, 0, 0, 0, 468, - 476, 5, 33, 0, 0, 469, 470, 5, 110, 0, 0, 470, 471, 5, 111, 0, 0, 471, - 476, 5, 116, 0, 0, 472, 473, 5, 78, 0, 0, 473, 474, 5, 79, 0, 0, 474, 476, - 5, 84, 0, 0, 475, 468, 1, 0, 0, 0, 475, 469, 1, 0, 0, 0, 475, 472, 1, 0, - 0, 0, 476, 78, 1, 0, 0, 0, 477, 478, 5, 105, 0, 0, 478, 482, 5, 110, 0, - 0, 479, 480, 5, 73, 0, 0, 480, 482, 5, 78, 0, 0, 481, 477, 1, 0, 0, 0, - 481, 479, 1, 0, 0, 0, 482, 80, 1, 0, 0, 0, 483, 488, 5, 91, 0, 0, 484, - 487, 3, 179, 89, 0, 485, 487, 3, 181, 90, 0, 486, 484, 1, 0, 0, 0, 486, - 485, 1, 0, 0, 0, 487, 490, 1, 0, 0, 0, 488, 486, 1, 0, 0, 0, 488, 489, - 1, 0, 0, 0, 489, 491, 1, 0, 0, 0, 490, 488, 1, 0, 0, 0, 491, 492, 5, 93, - 0, 0, 492, 82, 1, 0, 0, 0, 493, 494, 5, 106, 0, 0, 494, 495, 5, 115, 0, - 0, 495, 496, 5, 111, 0, 0, 496, 497, 5, 110, 0, 0, 497, 498, 5, 95, 0, - 0, 498, 499, 5, 99, 0, 0, 499, 500, 5, 111, 0, 0, 500, 501, 5, 110, 0, - 0, 501, 502, 5, 116, 0, 0, 502, 503, 5, 97, 0, 0, 503, 504, 5, 105, 0, - 0, 504, 505, 5, 110, 0, 0, 505, 520, 5, 115, 0, 0, 506, 507, 5, 74, 0, - 0, 507, 508, 5, 83, 0, 0, 508, 509, 5, 79, 0, 0, 509, 510, 5, 78, 0, 0, - 510, 511, 5, 95, 0, 0, 511, 512, 5, 67, 0, 0, 512, 513, 5, 79, 0, 0, 513, - 514, 5, 78, 0, 0, 514, 515, 5, 84, 0, 0, 515, 516, 5, 65, 0, 0, 516, 517, - 5, 73, 0, 0, 517, 518, 5, 78, 0, 0, 518, 520, 5, 83, 0, 0, 519, 493, 1, - 0, 0, 0, 519, 506, 1, 0, 0, 0, 520, 84, 1, 0, 0, 0, 521, 522, 5, 106, 0, - 0, 522, 523, 5, 115, 0, 0, 523, 524, 5, 111, 0, 0, 524, 525, 5, 110, 0, - 0, 525, 526, 5, 95, 0, 0, 526, 527, 5, 99, 0, 0, 527, 528, 5, 111, 0, 0, - 528, 529, 5, 110, 0, 0, 529, 530, 5, 116, 0, 0, 530, 531, 5, 97, 0, 0, - 531, 532, 5, 105, 0, 0, 532, 533, 5, 110, 0, 0, 533, 534, 5, 115, 0, 0, - 534, 535, 5, 95, 0, 0, 535, 536, 5, 97, 0, 0, 536, 537, 5, 108, 0, 0, 537, - 556, 5, 108, 0, 0, 538, 539, 5, 74, 0, 0, 539, 540, 5, 83, 0, 0, 540, 541, - 5, 79, 0, 0, 541, 542, 5, 78, 0, 0, 542, 543, 5, 95, 0, 0, 543, 544, 5, - 67, 0, 0, 544, 545, 5, 79, 0, 0, 545, 546, 5, 78, 0, 0, 546, 547, 5, 84, - 0, 0, 547, 548, 5, 65, 0, 0, 548, 549, 5, 73, 0, 0, 549, 550, 5, 78, 0, - 0, 550, 551, 5, 83, 0, 0, 551, 552, 5, 95, 0, 0, 552, 553, 5, 65, 0, 0, - 553, 554, 5, 76, 0, 0, 554, 556, 5, 76, 0, 0, 555, 521, 1, 0, 0, 0, 555, - 538, 1, 0, 0, 0, 556, 86, 1, 0, 0, 0, 557, 558, 5, 106, 0, 0, 558, 559, - 5, 115, 0, 0, 559, 560, 5, 111, 0, 0, 560, 561, 5, 110, 0, 0, 561, 562, - 5, 95, 0, 0, 562, 563, 5, 99, 0, 0, 563, 564, 5, 111, 0, 0, 564, 565, 5, - 110, 0, 0, 565, 566, 5, 116, 0, 0, 566, 567, 5, 97, 0, 0, 567, 568, 5, - 105, 0, 0, 568, 569, 5, 110, 0, 0, 569, 570, 5, 115, 0, 0, 570, 571, 5, - 95, 0, 0, 571, 572, 5, 97, 0, 0, 572, 573, 5, 110, 0, 0, 573, 592, 5, 121, - 0, 0, 574, 575, 5, 74, 0, 0, 575, 576, 5, 83, 0, 0, 576, 577, 5, 79, 0, - 0, 577, 578, 5, 78, 0, 0, 578, 579, 5, 95, 0, 0, 579, 580, 5, 67, 0, 0, - 580, 581, 5, 79, 0, 0, 581, 582, 5, 78, 0, 0, 582, 583, 5, 84, 0, 0, 583, - 584, 5, 65, 0, 0, 584, 585, 5, 73, 0, 0, 585, 586, 5, 78, 0, 0, 586, 587, - 5, 83, 0, 0, 587, 588, 5, 95, 0, 0, 588, 589, 5, 65, 0, 0, 589, 590, 5, - 78, 0, 0, 590, 592, 5, 89, 0, 0, 591, 557, 1, 0, 0, 0, 591, 574, 1, 0, - 0, 0, 592, 88, 1, 0, 0, 0, 593, 594, 5, 97, 0, 0, 594, 595, 5, 114, 0, - 0, 595, 596, 5, 114, 0, 0, 596, 597, 5, 97, 0, 0, 597, 598, 5, 121, 0, - 0, 598, 599, 5, 95, 0, 0, 599, 600, 5, 99, 0, 0, 600, 601, 5, 111, 0, 0, - 601, 602, 5, 110, 0, 0, 602, 603, 5, 116, 0, 0, 603, 604, 5, 97, 0, 0, - 604, 605, 5, 105, 0, 0, 605, 606, 5, 110, 0, 0, 606, 622, 5, 115, 0, 0, - 607, 608, 5, 65, 0, 0, 608, 609, 5, 82, 0, 0, 609, 610, 5, 82, 0, 0, 610, - 611, 5, 65, 0, 0, 611, 612, 5, 89, 0, 0, 612, 613, 5, 95, 0, 0, 613, 614, - 5, 67, 0, 0, 614, 615, 5, 79, 0, 0, 615, 616, 5, 78, 0, 0, 616, 617, 5, - 84, 0, 0, 617, 618, 5, 65, 0, 0, 618, 619, 5, 73, 0, 0, 619, 620, 5, 78, - 0, 0, 620, 622, 5, 83, 0, 0, 621, 593, 1, 0, 0, 0, 621, 607, 1, 0, 0, 0, - 622, 90, 1, 0, 0, 0, 623, 624, 5, 97, 0, 0, 624, 625, 5, 114, 0, 0, 625, - 626, 5, 114, 0, 0, 626, 627, 5, 97, 0, 0, 627, 628, 5, 121, 0, 0, 628, - 629, 5, 95, 0, 0, 629, 630, 5, 99, 0, 0, 630, 631, 5, 111, 0, 0, 631, 632, - 5, 110, 0, 0, 632, 633, 5, 116, 0, 0, 633, 634, 5, 97, 0, 0, 634, 635, - 5, 105, 0, 0, 635, 636, 5, 110, 0, 0, 636, 637, 5, 115, 0, 0, 637, 638, - 5, 95, 0, 0, 638, 639, 5, 97, 0, 0, 639, 640, 5, 108, 0, 0, 640, 660, 5, - 108, 0, 0, 641, 642, 5, 65, 0, 0, 642, 643, 5, 82, 0, 0, 643, 644, 5, 82, - 0, 0, 644, 645, 5, 65, 0, 0, 645, 646, 5, 89, 0, 0, 646, 647, 5, 95, 0, - 0, 647, 648, 5, 67, 0, 0, 648, 649, 5, 79, 0, 0, 649, 650, 5, 78, 0, 0, - 650, 651, 5, 84, 0, 0, 651, 652, 5, 65, 0, 0, 652, 653, 5, 73, 0, 0, 653, - 654, 5, 78, 0, 0, 654, 655, 5, 83, 0, 0, 655, 656, 5, 95, 0, 0, 656, 657, - 5, 65, 0, 0, 657, 658, 5, 76, 0, 0, 658, 660, 5, 76, 0, 0, 659, 623, 1, - 0, 0, 0, 659, 641, 1, 0, 0, 0, 660, 92, 1, 0, 0, 0, 661, 662, 5, 97, 0, - 0, 662, 663, 5, 114, 0, 0, 663, 664, 5, 114, 0, 0, 664, 665, 5, 97, 0, - 0, 665, 666, 5, 121, 0, 0, 666, 667, 5, 95, 0, 0, 667, 668, 5, 99, 0, 0, - 668, 669, 5, 111, 0, 0, 669, 670, 5, 110, 0, 0, 670, 671, 5, 116, 0, 0, - 671, 672, 5, 97, 0, 0, 672, 673, 5, 105, 0, 0, 673, 674, 5, 110, 0, 0, - 674, 675, 5, 115, 0, 0, 675, 676, 5, 95, 0, 0, 676, 677, 5, 97, 0, 0, 677, - 678, 5, 110, 0, 0, 678, 698, 5, 121, 0, 0, 679, 680, 5, 65, 0, 0, 680, - 681, 5, 82, 0, 0, 681, 682, 5, 82, 0, 0, 682, 683, 5, 65, 0, 0, 683, 684, - 5, 89, 0, 0, 684, 685, 5, 95, 0, 0, 685, 686, 5, 67, 0, 0, 686, 687, 5, - 79, 0, 0, 687, 688, 5, 78, 0, 0, 688, 689, 5, 84, 0, 0, 689, 690, 5, 65, - 0, 0, 690, 691, 5, 73, 0, 0, 691, 692, 5, 78, 0, 0, 692, 693, 5, 83, 0, - 0, 693, 694, 5, 95, 0, 0, 694, 695, 5, 65, 0, 0, 695, 696, 5, 78, 0, 0, - 696, 698, 5, 89, 0, 0, 697, 661, 1, 0, 0, 0, 697, 679, 1, 0, 0, 0, 698, - 94, 1, 0, 0, 0, 699, 700, 5, 97, 0, 0, 700, 701, 5, 114, 0, 0, 701, 702, - 5, 114, 0, 0, 702, 703, 5, 97, 0, 0, 703, 704, 5, 121, 0, 0, 704, 705, - 5, 95, 0, 0, 705, 706, 5, 108, 0, 0, 706, 707, 5, 101, 0, 0, 707, 708, - 5, 110, 0, 0, 708, 709, 5, 103, 0, 0, 709, 710, 5, 116, 0, 0, 710, 724, - 5, 104, 0, 0, 711, 712, 5, 65, 0, 0, 712, 713, 5, 82, 0, 0, 713, 714, 5, - 82, 0, 0, 714, 715, 5, 65, 0, 0, 715, 716, 5, 89, 0, 0, 716, 717, 5, 95, - 0, 0, 717, 718, 5, 76, 0, 0, 718, 719, 5, 69, 0, 0, 719, 720, 5, 78, 0, - 0, 720, 721, 5, 71, 0, 0, 721, 722, 5, 84, 0, 0, 722, 724, 5, 72, 0, 0, - 723, 699, 1, 0, 0, 0, 723, 711, 1, 0, 0, 0, 724, 96, 1, 0, 0, 0, 725, 726, - 5, 115, 0, 0, 726, 727, 5, 116, 0, 0, 727, 728, 5, 95, 0, 0, 728, 729, - 5, 101, 0, 0, 729, 730, 5, 113, 0, 0, 730, 731, 5, 117, 0, 0, 731, 732, - 5, 97, 0, 0, 732, 733, 5, 108, 0, 0, 733, 744, 5, 115, 0, 0, 734, 735, - 5, 83, 0, 0, 735, 736, 5, 84, 0, 0, 736, 737, 5, 95, 0, 0, 737, 738, 5, - 69, 0, 0, 738, 739, 5, 81, 0, 0, 739, 740, 5, 85, 0, 0, 740, 741, 5, 65, - 0, 0, 741, 742, 5, 76, 0, 0, 742, 744, 5, 83, 0, 0, 743, 725, 1, 0, 0, - 0, 743, 734, 1, 0, 0, 0, 744, 98, 1, 0, 0, 0, 745, 746, 5, 115, 0, 0, 746, - 747, 5, 116, 0, 0, 747, 748, 5, 95, 0, 0, 748, 749, 5, 116, 0, 0, 749, - 750, 5, 111, 0, 0, 750, 751, 5, 117, 0, 0, 751, 752, 5, 99, 0, 0, 752, - 753, 5, 104, 0, 0, 753, 754, 5, 101, 0, 0, 754, 766, 5, 115, 0, 0, 755, - 756, 5, 83, 0, 0, 756, 757, 5, 84, 0, 0, 757, 758, 5, 95, 0, 0, 758, 759, - 5, 84, 0, 0, 759, 760, 5, 79, 0, 0, 760, 761, 5, 85, 0, 0, 761, 762, 5, - 67, 0, 0, 762, 763, 5, 72, 0, 0, 763, 764, 5, 69, 0, 0, 764, 766, 5, 83, - 0, 0, 765, 745, 1, 0, 0, 0, 765, 755, 1, 0, 0, 0, 766, 100, 1, 0, 0, 0, - 767, 768, 5, 115, 0, 0, 768, 769, 5, 116, 0, 0, 769, 770, 5, 95, 0, 0, - 770, 771, 5, 111, 0, 0, 771, 772, 5, 118, 0, 0, 772, 773, 5, 101, 0, 0, - 773, 774, 5, 114, 0, 0, 774, 775, 5, 108, 0, 0, 775, 776, 5, 97, 0, 0, - 776, 777, 5, 112, 0, 0, 777, 790, 5, 115, 0, 0, 778, 779, 5, 83, 0, 0, - 779, 780, 5, 84, 0, 0, 780, 781, 5, 95, 0, 0, 781, 782, 5, 79, 0, 0, 782, - 783, 5, 86, 0, 0, 783, 784, 5, 69, 0, 0, 784, 785, 5, 82, 0, 0, 785, 786, - 5, 76, 0, 0, 786, 787, 5, 65, 0, 0, 787, 788, 5, 80, 0, 0, 788, 790, 5, - 83, 0, 0, 789, 767, 1, 0, 0, 0, 789, 778, 1, 0, 0, 0, 790, 102, 1, 0, 0, - 0, 791, 792, 5, 115, 0, 0, 792, 793, 5, 116, 0, 0, 793, 794, 5, 95, 0, - 0, 794, 795, 5, 99, 0, 0, 795, 796, 5, 114, 0, 0, 796, 797, 5, 111, 0, - 0, 797, 798, 5, 115, 0, 0, 798, 799, 5, 115, 0, 0, 799, 800, 5, 101, 0, - 0, 800, 812, 5, 115, 0, 0, 801, 802, 5, 83, 0, 0, 802, 803, 5, 84, 0, 0, - 803, 804, 5, 95, 0, 0, 804, 805, 5, 67, 0, 0, 805, 806, 5, 82, 0, 0, 806, - 807, 5, 79, 0, 0, 807, 808, 5, 83, 0, 0, 808, 809, 5, 83, 0, 0, 809, 810, - 5, 69, 0, 0, 810, 812, 5, 83, 0, 0, 811, 791, 1, 0, 0, 0, 811, 801, 1, - 0, 0, 0, 812, 104, 1, 0, 0, 0, 813, 814, 5, 115, 0, 0, 814, 815, 5, 116, - 0, 0, 815, 816, 5, 95, 0, 0, 816, 817, 5, 99, 0, 0, 817, 818, 5, 111, 0, - 0, 818, 819, 5, 110, 0, 0, 819, 820, 5, 116, 0, 0, 820, 821, 5, 97, 0, - 0, 821, 822, 5, 105, 0, 0, 822, 823, 5, 110, 0, 0, 823, 836, 5, 115, 0, - 0, 824, 825, 5, 83, 0, 0, 825, 826, 5, 84, 0, 0, 826, 827, 5, 95, 0, 0, - 827, 828, 5, 67, 0, 0, 828, 829, 5, 79, 0, 0, 829, 830, 5, 78, 0, 0, 830, - 831, 5, 84, 0, 0, 831, 832, 5, 65, 0, 0, 832, 833, 5, 73, 0, 0, 833, 834, - 5, 78, 0, 0, 834, 836, 5, 83, 0, 0, 835, 813, 1, 0, 0, 0, 835, 824, 1, - 0, 0, 0, 836, 106, 1, 0, 0, 0, 837, 838, 5, 115, 0, 0, 838, 839, 5, 116, - 0, 0, 839, 840, 5, 95, 0, 0, 840, 841, 5, 105, 0, 0, 841, 842, 5, 110, - 0, 0, 842, 843, 5, 116, 0, 0, 843, 844, 5, 101, 0, 0, 844, 845, 5, 114, - 0, 0, 845, 846, 5, 115, 0, 0, 846, 847, 5, 101, 0, 0, 847, 848, 5, 99, - 0, 0, 848, 849, 5, 116, 0, 0, 849, 864, 5, 115, 0, 0, 850, 851, 5, 83, - 0, 0, 851, 852, 5, 84, 0, 0, 852, 853, 5, 95, 0, 0, 853, 854, 5, 73, 0, - 0, 854, 855, 5, 78, 0, 0, 855, 856, 5, 84, 0, 0, 856, 857, 5, 69, 0, 0, - 857, 858, 5, 82, 0, 0, 858, 859, 5, 83, 0, 0, 859, 860, 5, 69, 0, 0, 860, - 861, 5, 67, 0, 0, 861, 862, 5, 84, 0, 0, 862, 864, 5, 83, 0, 0, 863, 837, - 1, 0, 0, 0, 863, 850, 1, 0, 0, 0, 864, 108, 1, 0, 0, 0, 865, 866, 5, 115, - 0, 0, 866, 867, 5, 116, 0, 0, 867, 868, 5, 95, 0, 0, 868, 869, 5, 119, - 0, 0, 869, 870, 5, 105, 0, 0, 870, 871, 5, 116, 0, 0, 871, 872, 5, 104, - 0, 0, 872, 873, 5, 105, 0, 0, 873, 884, 5, 110, 0, 0, 874, 875, 5, 83, - 0, 0, 875, 876, 5, 84, 0, 0, 876, 877, 5, 95, 0, 0, 877, 878, 5, 87, 0, - 0, 878, 879, 5, 73, 0, 0, 879, 880, 5, 84, 0, 0, 880, 881, 5, 72, 0, 0, - 881, 882, 5, 73, 0, 0, 882, 884, 5, 78, 0, 0, 883, 865, 1, 0, 0, 0, 883, - 874, 1, 0, 0, 0, 884, 110, 1, 0, 0, 0, 885, 886, 5, 115, 0, 0, 886, 887, - 5, 116, 0, 0, 887, 888, 5, 95, 0, 0, 888, 889, 5, 100, 0, 0, 889, 890, - 5, 119, 0, 0, 890, 891, 5, 105, 0, 0, 891, 892, 5, 116, 0, 0, 892, 893, - 5, 104, 0, 0, 893, 894, 5, 105, 0, 0, 894, 906, 5, 110, 0, 0, 895, 896, - 5, 83, 0, 0, 896, 897, 5, 84, 0, 0, 897, 898, 5, 95, 0, 0, 898, 899, 5, - 68, 0, 0, 899, 900, 5, 87, 0, 0, 900, 901, 5, 73, 0, 0, 901, 902, 5, 84, - 0, 0, 902, 903, 5, 72, 0, 0, 903, 904, 5, 73, 0, 0, 904, 906, 5, 78, 0, - 0, 905, 885, 1, 0, 0, 0, 905, 895, 1, 0, 0, 0, 906, 112, 1, 0, 0, 0, 907, - 908, 5, 115, 0, 0, 908, 909, 5, 116, 0, 0, 909, 910, 5, 95, 0, 0, 910, - 911, 5, 105, 0, 0, 911, 912, 5, 115, 0, 0, 912, 913, 5, 118, 0, 0, 913, - 914, 5, 97, 0, 0, 914, 915, 5, 108, 0, 0, 915, 916, 5, 105, 0, 0, 916, - 928, 5, 100, 0, 0, 917, 918, 5, 83, 0, 0, 918, 919, 5, 84, 0, 0, 919, 920, - 5, 95, 0, 0, 920, 921, 5, 73, 0, 0, 921, 922, 5, 83, 0, 0, 922, 923, 5, - 86, 0, 0, 923, 924, 5, 65, 0, 0, 924, 925, 5, 76, 0, 0, 925, 926, 5, 73, - 0, 0, 926, 928, 5, 68, 0, 0, 927, 907, 1, 0, 0, 0, 927, 917, 1, 0, 0, 0, - 928, 114, 1, 0, 0, 0, 929, 930, 5, 116, 0, 0, 930, 931, 5, 114, 0, 0, 931, - 932, 5, 117, 0, 0, 932, 957, 5, 101, 0, 0, 933, 934, 5, 84, 0, 0, 934, - 935, 5, 114, 0, 0, 935, 936, 5, 117, 0, 0, 936, 957, 5, 101, 0, 0, 937, - 938, 5, 84, 0, 0, 938, 939, 5, 82, 0, 0, 939, 940, 5, 85, 0, 0, 940, 957, - 5, 69, 0, 0, 941, 942, 5, 102, 0, 0, 942, 943, 5, 97, 0, 0, 943, 944, 5, - 108, 0, 0, 944, 945, 5, 115, 0, 0, 945, 957, 5, 101, 0, 0, 946, 947, 5, - 70, 0, 0, 947, 948, 5, 97, 0, 0, 948, 949, 5, 108, 0, 0, 949, 950, 5, 115, - 0, 0, 950, 957, 5, 101, 0, 0, 951, 952, 5, 70, 0, 0, 952, 953, 5, 65, 0, - 0, 953, 954, 5, 76, 0, 0, 954, 955, 5, 83, 0, 0, 955, 957, 5, 69, 0, 0, - 956, 929, 1, 0, 0, 0, 956, 933, 1, 0, 0, 0, 956, 937, 1, 0, 0, 0, 956, - 941, 1, 0, 0, 0, 956, 946, 1, 0, 0, 0, 956, 951, 1, 0, 0, 0, 957, 116, - 1, 0, 0, 0, 958, 963, 3, 145, 72, 0, 959, 963, 3, 147, 73, 0, 960, 963, - 3, 149, 74, 0, 961, 963, 3, 143, 71, 0, 962, 958, 1, 0, 0, 0, 962, 959, - 1, 0, 0, 0, 962, 960, 1, 0, 0, 0, 962, 961, 1, 0, 0, 0, 963, 118, 1, 0, - 0, 0, 964, 967, 3, 161, 80, 0, 965, 967, 3, 163, 81, 0, 966, 964, 1, 0, - 0, 0, 966, 965, 1, 0, 0, 0, 967, 120, 1, 0, 0, 0, 968, 973, 3, 139, 69, - 0, 969, 972, 3, 139, 69, 0, 970, 972, 3, 141, 70, 0, 971, 969, 1, 0, 0, - 0, 971, 970, 1, 0, 0, 0, 972, 975, 1, 0, 0, 0, 973, 971, 1, 0, 0, 0, 973, - 974, 1, 0, 0, 0, 974, 122, 1, 0, 0, 0, 975, 973, 1, 0, 0, 0, 976, 977, - 5, 36, 0, 0, 977, 978, 5, 109, 0, 0, 978, 979, 5, 101, 0, 0, 979, 980, - 5, 116, 0, 0, 980, 981, 5, 97, 0, 0, 981, 124, 1, 0, 0, 0, 982, 984, 3, - 129, 64, 0, 983, 982, 1, 0, 0, 0, 983, 984, 1, 0, 0, 0, 984, 995, 1, 0, - 0, 0, 985, 987, 5, 34, 0, 0, 986, 988, 3, 131, 65, 0, 987, 986, 1, 0, 0, - 0, 987, 988, 1, 0, 0, 0, 988, 989, 1, 0, 0, 0, 989, 996, 5, 34, 0, 0, 990, - 992, 5, 39, 0, 0, 991, 993, 3, 133, 66, 0, 992, 991, 1, 0, 0, 0, 992, 993, - 1, 0, 0, 0, 993, 994, 1, 0, 0, 0, 994, 996, 5, 39, 0, 0, 995, 985, 1, 0, - 0, 0, 995, 990, 1, 0, 0, 0, 996, 126, 1, 0, 0, 0, 997, 1000, 3, 121, 60, - 0, 998, 1000, 3, 123, 61, 0, 999, 997, 1, 0, 0, 0, 999, 998, 1, 0, 0, 0, - 1000, 1008, 1, 0, 0, 0, 1001, 1004, 5, 91, 0, 0, 1002, 1005, 3, 125, 62, - 0, 1003, 1005, 3, 145, 72, 0, 1004, 1002, 1, 0, 0, 0, 1004, 1003, 1, 0, - 0, 0, 1005, 1006, 1, 0, 0, 0, 1006, 1007, 5, 93, 0, 0, 1007, 1009, 1, 0, - 0, 0, 1008, 1001, 1, 0, 0, 0, 1009, 1010, 1, 0, 0, 0, 1010, 1008, 1, 0, - 0, 0, 1010, 1011, 1, 0, 0, 0, 1011, 128, 1, 0, 0, 0, 1012, 1013, 5, 117, - 0, 0, 1013, 1016, 5, 56, 0, 0, 1014, 1016, 7, 0, 0, 0, 1015, 1012, 1, 0, - 0, 0, 1015, 1014, 1, 0, 0, 0, 1016, 130, 1, 0, 0, 0, 1017, 1019, 3, 135, - 67, 0, 1018, 1017, 1, 0, 0, 0, 1019, 1020, 1, 0, 0, 0, 1020, 1018, 1, 0, - 0, 0, 1020, 1021, 1, 0, 0, 0, 1021, 132, 1, 0, 0, 0, 1022, 1024, 3, 137, - 68, 0, 1023, 1022, 1, 0, 0, 0, 1024, 1025, 1, 0, 0, 0, 1025, 1023, 1, 0, - 0, 0, 1025, 1026, 1, 0, 0, 0, 1026, 134, 1, 0, 0, 0, 1027, 1035, 8, 1, - 0, 0, 1028, 1035, 3, 177, 88, 0, 1029, 1030, 5, 92, 0, 0, 1030, 1035, 5, - 10, 0, 0, 1031, 1032, 5, 92, 0, 0, 1032, 1033, 5, 13, 0, 0, 1033, 1035, - 5, 10, 0, 0, 1034, 1027, 1, 0, 0, 0, 1034, 1028, 1, 0, 0, 0, 1034, 1029, - 1, 0, 0, 0, 1034, 1031, 1, 0, 0, 0, 1035, 136, 1, 0, 0, 0, 1036, 1044, - 8, 2, 0, 0, 1037, 1044, 3, 177, 88, 0, 1038, 1039, 5, 92, 0, 0, 1039, 1044, - 5, 10, 0, 0, 1040, 1041, 5, 92, 0, 0, 1041, 1042, 5, 13, 0, 0, 1042, 1044, - 5, 10, 0, 0, 1043, 1036, 1, 0, 0, 0, 1043, 1037, 1, 0, 0, 0, 1043, 1038, - 1, 0, 0, 0, 1043, 1040, 1, 0, 0, 0, 1044, 138, 1, 0, 0, 0, 1045, 1046, - 7, 3, 0, 0, 1046, 140, 1, 0, 0, 0, 1047, 1048, 7, 4, 0, 0, 1048, 142, 1, - 0, 0, 0, 1049, 1050, 5, 48, 0, 0, 1050, 1052, 7, 5, 0, 0, 1051, 1053, 7, - 6, 0, 0, 1052, 1051, 1, 0, 0, 0, 1053, 1054, 1, 0, 0, 0, 1054, 1052, 1, - 0, 0, 0, 1054, 1055, 1, 0, 0, 0, 1055, 144, 1, 0, 0, 0, 1056, 1060, 3, - 151, 75, 0, 1057, 1059, 3, 141, 70, 0, 1058, 1057, 1, 0, 0, 0, 1059, 1062, - 1, 0, 0, 0, 1060, 1058, 1, 0, 0, 0, 1060, 1061, 1, 0, 0, 0, 1061, 1065, - 1, 0, 0, 0, 1062, 1060, 1, 0, 0, 0, 1063, 1065, 5, 48, 0, 0, 1064, 1056, - 1, 0, 0, 0, 1064, 1063, 1, 0, 0, 0, 1065, 146, 1, 0, 0, 0, 1066, 1070, - 5, 48, 0, 0, 1067, 1069, 3, 153, 76, 0, 1068, 1067, 1, 0, 0, 0, 1069, 1072, - 1, 0, 0, 0, 1070, 1068, 1, 0, 0, 0, 1070, 1071, 1, 0, 0, 0, 1071, 148, - 1, 0, 0, 0, 1072, 1070, 1, 0, 0, 0, 1073, 1074, 5, 48, 0, 0, 1074, 1075, - 7, 7, 0, 0, 1075, 1076, 3, 173, 86, 0, 1076, 150, 1, 0, 0, 0, 1077, 1078, - 7, 8, 0, 0, 1078, 152, 1, 0, 0, 0, 1079, 1080, 7, 9, 0, 0, 1080, 154, 1, - 0, 0, 0, 1081, 1082, 7, 10, 0, 0, 1082, 156, 1, 0, 0, 0, 1083, 1084, 3, - 155, 77, 0, 1084, 1085, 3, 155, 77, 0, 1085, 1086, 3, 155, 77, 0, 1086, - 1087, 3, 155, 77, 0, 1087, 158, 1, 0, 0, 0, 1088, 1089, 5, 92, 0, 0, 1089, - 1090, 5, 117, 0, 0, 1090, 1091, 1, 0, 0, 0, 1091, 1099, 3, 157, 78, 0, - 1092, 1093, 5, 92, 0, 0, 1093, 1094, 5, 85, 0, 0, 1094, 1095, 1, 0, 0, - 0, 1095, 1096, 3, 157, 78, 0, 1096, 1097, 3, 157, 78, 0, 1097, 1099, 1, - 0, 0, 0, 1098, 1088, 1, 0, 0, 0, 1098, 1092, 1, 0, 0, 0, 1099, 160, 1, - 0, 0, 0, 1100, 1102, 3, 165, 82, 0, 1101, 1103, 3, 167, 83, 0, 1102, 1101, - 1, 0, 0, 0, 1102, 1103, 1, 0, 0, 0, 1103, 1108, 1, 0, 0, 0, 1104, 1105, - 3, 169, 84, 0, 1105, 1106, 3, 167, 83, 0, 1106, 1108, 1, 0, 0, 0, 1107, - 1100, 1, 0, 0, 0, 1107, 1104, 1, 0, 0, 0, 1108, 162, 1, 0, 0, 0, 1109, - 1110, 5, 48, 0, 0, 1110, 1113, 7, 7, 0, 0, 1111, 1114, 3, 171, 85, 0, 1112, - 1114, 3, 173, 86, 0, 1113, 1111, 1, 0, 0, 0, 1113, 1112, 1, 0, 0, 0, 1114, - 1115, 1, 0, 0, 0, 1115, 1116, 3, 175, 87, 0, 1116, 164, 1, 0, 0, 0, 1117, - 1119, 3, 169, 84, 0, 1118, 1117, 1, 0, 0, 0, 1118, 1119, 1, 0, 0, 0, 1119, - 1120, 1, 0, 0, 0, 1120, 1121, 5, 46, 0, 0, 1121, 1126, 3, 169, 84, 0, 1122, - 1123, 3, 169, 84, 0, 1123, 1124, 5, 46, 0, 0, 1124, 1126, 1, 0, 0, 0, 1125, - 1118, 1, 0, 0, 0, 1125, 1122, 1, 0, 0, 0, 1126, 166, 1, 0, 0, 0, 1127, - 1129, 7, 11, 0, 0, 1128, 1130, 7, 12, 0, 0, 1129, 1128, 1, 0, 0, 0, 1129, - 1130, 1, 0, 0, 0, 1130, 1131, 1, 0, 0, 0, 1131, 1132, 3, 169, 84, 0, 1132, - 168, 1, 0, 0, 0, 1133, 1135, 3, 141, 70, 0, 1134, 1133, 1, 0, 0, 0, 1135, - 1136, 1, 0, 0, 0, 1136, 1134, 1, 0, 0, 0, 1136, 1137, 1, 0, 0, 0, 1137, - 170, 1, 0, 0, 0, 1138, 1140, 3, 173, 86, 0, 1139, 1138, 1, 0, 0, 0, 1139, - 1140, 1, 0, 0, 0, 1140, 1141, 1, 0, 0, 0, 1141, 1142, 5, 46, 0, 0, 1142, - 1147, 3, 173, 86, 0, 1143, 1144, 3, 173, 86, 0, 1144, 1145, 5, 46, 0, 0, - 1145, 1147, 1, 0, 0, 0, 1146, 1139, 1, 0, 0, 0, 1146, 1143, 1, 0, 0, 0, - 1147, 172, 1, 0, 0, 0, 1148, 1150, 3, 155, 77, 0, 1149, 1148, 1, 0, 0, - 0, 1150, 1151, 1, 0, 0, 0, 1151, 1149, 1, 0, 0, 0, 1151, 1152, 1, 0, 0, - 0, 1152, 174, 1, 0, 0, 0, 1153, 1155, 7, 13, 0, 0, 1154, 1156, 7, 12, 0, - 0, 1155, 1154, 1, 0, 0, 0, 1155, 1156, 1, 0, 0, 0, 1156, 1157, 1, 0, 0, - 0, 1157, 1158, 3, 169, 84, 0, 1158, 176, 1, 0, 0, 0, 1159, 1160, 5, 92, - 0, 0, 1160, 1175, 7, 14, 0, 0, 1161, 1162, 5, 92, 0, 0, 1162, 1164, 3, - 153, 76, 0, 1163, 1165, 3, 153, 76, 0, 1164, 1163, 1, 0, 0, 0, 1164, 1165, - 1, 0, 0, 0, 1165, 1167, 1, 0, 0, 0, 1166, 1168, 3, 153, 76, 0, 1167, 1166, - 1, 0, 0, 0, 1167, 1168, 1, 0, 0, 0, 1168, 1175, 1, 0, 0, 0, 1169, 1170, - 5, 92, 0, 0, 1170, 1171, 5, 120, 0, 0, 1171, 1172, 1, 0, 0, 0, 1172, 1175, - 3, 173, 86, 0, 1173, 1175, 3, 159, 79, 0, 1174, 1159, 1, 0, 0, 0, 1174, - 1161, 1, 0, 0, 0, 1174, 1169, 1, 0, 0, 0, 1174, 1173, 1, 0, 0, 0, 1175, - 178, 1, 0, 0, 0, 1176, 1178, 7, 15, 0, 0, 1177, 1176, 1, 0, 0, 0, 1178, - 1179, 1, 0, 0, 0, 1179, 1177, 1, 0, 0, 0, 1179, 1180, 1, 0, 0, 0, 1180, - 1181, 1, 0, 0, 0, 1181, 1182, 6, 89, 0, 0, 1182, 180, 1, 0, 0, 0, 1183, - 1185, 5, 13, 0, 0, 1184, 1186, 5, 10, 0, 0, 1185, 1184, 1, 0, 0, 0, 1185, - 1186, 1, 0, 0, 0, 1186, 1189, 1, 0, 0, 0, 1187, 1189, 5, 10, 0, 0, 1188, - 1183, 1, 0, 0, 0, 1188, 1187, 1, 0, 0, 0, 1189, 1190, 1, 0, 0, 0, 1190, - 1191, 6, 90, 0, 0, 1191, 182, 1, 0, 0, 0, 72, 0, 221, 235, 257, 283, 311, - 329, 337, 379, 416, 424, 440, 464, 475, 481, 486, 488, 519, 555, 591, 621, - 659, 697, 723, 743, 765, 789, 811, 835, 863, 883, 905, 927, 956, 962, 966, - 971, 973, 983, 987, 992, 995, 999, 1004, 1010, 1015, 1020, 1025, 1034, - 1043, 1054, 1060, 1064, 1070, 1098, 1102, 1107, 1113, 1118, 1125, 1129, - 1136, 1139, 1146, 1151, 1155, 1164, 1167, 1174, 1179, 1185, 1188, 1, 6, - 0, 0, + 167, 0, 169, 0, 171, 0, 173, 0, 175, 0, 177, 0, 179, 0, 181, 0, 183, 67, + 185, 68, 1, 0, 16, 3, 0, 76, 76, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, + 34, 34, 92, 92, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 3, 0, 65, 90, 95, + 95, 97, 122, 1, 0, 48, 57, 2, 0, 66, 66, 98, 98, 1, 0, 48, 49, 2, 0, 88, + 88, 120, 120, 1, 0, 49, 57, 1, 0, 48, 55, 3, 0, 48, 57, 65, 70, 97, 102, + 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 80, 80, 112, 112, 10, + 0, 34, 34, 39, 39, 63, 63, 92, 92, 97, 98, 102, 102, 110, 110, 114, 114, + 116, 116, 118, 118, 2, 0, 9, 9, 32, 32, 1293, 0, 1, 1, 0, 0, 0, 0, 3, 1, + 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, + 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, + 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, + 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, + 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, + 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, + 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, + 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, + 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, + 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, + 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, + 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, + 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, + 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, + 0, 111, 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, + 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, + 125, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, + 0, 0, 0, 183, 1, 0, 0, 0, 0, 185, 1, 0, 0, 0, 1, 187, 1, 0, 0, 0, 3, 189, + 1, 0, 0, 0, 5, 191, 1, 0, 0, 0, 7, 193, 1, 0, 0, 0, 9, 195, 1, 0, 0, 0, + 11, 197, 1, 0, 0, 0, 13, 199, 1, 0, 0, 0, 15, 201, 1, 0, 0, 0, 17, 203, + 1, 0, 0, 0, 19, 206, 1, 0, 0, 0, 21, 208, 1, 0, 0, 0, 23, 211, 1, 0, 0, + 0, 25, 214, 1, 0, 0, 0, 27, 225, 1, 0, 0, 0, 29, 239, 1, 0, 0, 0, 31, 261, + 1, 0, 0, 0, 33, 287, 1, 0, 0, 0, 35, 315, 1, 0, 0, 0, 37, 333, 1, 0, 0, + 0, 39, 341, 1, 0, 0, 0, 41, 383, 1, 0, 0, 0, 43, 385, 1, 0, 0, 0, 45, 387, + 1, 0, 0, 0, 47, 389, 1, 0, 0, 0, 49, 391, 1, 0, 0, 0, 51, 393, 1, 0, 0, + 0, 53, 395, 1, 0, 0, 0, 55, 397, 1, 0, 0, 0, 57, 400, 1, 0, 0, 0, 59, 403, + 1, 0, 0, 0, 61, 406, 1, 0, 0, 0, 63, 408, 1, 0, 0, 0, 65, 410, 1, 0, 0, + 0, 67, 420, 1, 0, 0, 0, 69, 428, 1, 0, 0, 0, 71, 444, 1, 0, 0, 0, 73, 468, + 1, 0, 0, 0, 75, 470, 1, 0, 0, 0, 77, 479, 1, 0, 0, 0, 79, 485, 1, 0, 0, + 0, 81, 487, 1, 0, 0, 0, 83, 523, 1, 0, 0, 0, 85, 559, 1, 0, 0, 0, 87, 595, + 1, 0, 0, 0, 89, 625, 1, 0, 0, 0, 91, 663, 1, 0, 0, 0, 93, 701, 1, 0, 0, + 0, 95, 727, 1, 0, 0, 0, 97, 757, 1, 0, 0, 0, 99, 777, 1, 0, 0, 0, 101, + 799, 1, 0, 0, 0, 103, 823, 1, 0, 0, 0, 105, 845, 1, 0, 0, 0, 107, 869, + 1, 0, 0, 0, 109, 897, 1, 0, 0, 0, 111, 917, 1, 0, 0, 0, 113, 939, 1, 0, + 0, 0, 115, 961, 1, 0, 0, 0, 117, 990, 1, 0, 0, 0, 119, 996, 1, 0, 0, 0, + 121, 1000, 1, 0, 0, 0, 123, 1002, 1, 0, 0, 0, 125, 1010, 1, 0, 0, 0, 127, + 1017, 1, 0, 0, 0, 129, 1033, 1, 0, 0, 0, 131, 1046, 1, 0, 0, 0, 133, 1055, + 1, 0, 0, 0, 135, 1058, 1, 0, 0, 0, 137, 1063, 1, 0, 0, 0, 139, 1074, 1, + 0, 0, 0, 141, 1083, 1, 0, 0, 0, 143, 1085, 1, 0, 0, 0, 145, 1087, 1, 0, + 0, 0, 147, 1089, 1, 0, 0, 0, 149, 1104, 1, 0, 0, 0, 151, 1106, 1, 0, 0, + 0, 153, 1113, 1, 0, 0, 0, 155, 1117, 1, 0, 0, 0, 157, 1119, 1, 0, 0, 0, + 159, 1121, 1, 0, 0, 0, 161, 1123, 1, 0, 0, 0, 163, 1138, 1, 0, 0, 0, 165, + 1147, 1, 0, 0, 0, 167, 1149, 1, 0, 0, 0, 169, 1165, 1, 0, 0, 0, 171, 1167, + 1, 0, 0, 0, 173, 1174, 1, 0, 0, 0, 175, 1186, 1, 0, 0, 0, 177, 1189, 1, + 0, 0, 0, 179, 1193, 1, 0, 0, 0, 181, 1214, 1, 0, 0, 0, 183, 1217, 1, 0, + 0, 0, 185, 1228, 1, 0, 0, 0, 187, 188, 5, 40, 0, 0, 188, 2, 1, 0, 0, 0, + 189, 190, 5, 41, 0, 0, 190, 4, 1, 0, 0, 0, 191, 192, 5, 91, 0, 0, 192, + 6, 1, 0, 0, 0, 193, 194, 5, 44, 0, 0, 194, 8, 1, 0, 0, 0, 195, 196, 5, + 93, 0, 0, 196, 10, 1, 0, 0, 0, 197, 198, 5, 123, 0, 0, 198, 12, 1, 0, 0, + 0, 199, 200, 5, 125, 0, 0, 200, 14, 1, 0, 0, 0, 201, 202, 5, 60, 0, 0, + 202, 16, 1, 0, 0, 0, 203, 204, 5, 60, 0, 0, 204, 205, 5, 61, 0, 0, 205, + 18, 1, 0, 0, 0, 206, 207, 5, 62, 0, 0, 207, 20, 1, 0, 0, 0, 208, 209, 5, + 62, 0, 0, 209, 210, 5, 61, 0, 0, 210, 22, 1, 0, 0, 0, 211, 212, 5, 61, + 0, 0, 212, 213, 5, 61, 0, 0, 213, 24, 1, 0, 0, 0, 214, 215, 5, 33, 0, 0, + 215, 216, 5, 61, 0, 0, 216, 26, 1, 0, 0, 0, 217, 218, 5, 108, 0, 0, 218, + 219, 5, 105, 0, 0, 219, 220, 5, 107, 0, 0, 220, 226, 5, 101, 0, 0, 221, + 222, 5, 76, 0, 0, 222, 223, 5, 73, 0, 0, 223, 224, 5, 75, 0, 0, 224, 226, + 5, 69, 0, 0, 225, 217, 1, 0, 0, 0, 225, 221, 1, 0, 0, 0, 226, 28, 1, 0, + 0, 0, 227, 228, 5, 101, 0, 0, 228, 229, 5, 120, 0, 0, 229, 230, 5, 105, + 0, 0, 230, 231, 5, 115, 0, 0, 231, 232, 5, 116, 0, 0, 232, 240, 5, 115, + 0, 0, 233, 234, 5, 69, 0, 0, 234, 235, 5, 88, 0, 0, 235, 236, 5, 73, 0, + 0, 236, 237, 5, 83, 0, 0, 237, 238, 5, 84, 0, 0, 238, 240, 5, 83, 0, 0, + 239, 227, 1, 0, 0, 0, 239, 233, 1, 0, 0, 0, 240, 30, 1, 0, 0, 0, 241, 242, + 5, 116, 0, 0, 242, 243, 5, 101, 0, 0, 243, 244, 5, 120, 0, 0, 244, 245, + 5, 116, 0, 0, 245, 246, 5, 95, 0, 0, 246, 247, 5, 109, 0, 0, 247, 248, + 5, 97, 0, 0, 248, 249, 5, 116, 0, 0, 249, 250, 5, 99, 0, 0, 250, 262, 5, + 104, 0, 0, 251, 252, 5, 84, 0, 0, 252, 253, 5, 69, 0, 0, 253, 254, 5, 88, + 0, 0, 254, 255, 5, 84, 0, 0, 255, 256, 5, 95, 0, 0, 256, 257, 5, 77, 0, + 0, 257, 258, 5, 65, 0, 0, 258, 259, 5, 84, 0, 0, 259, 260, 5, 67, 0, 0, + 260, 262, 5, 72, 0, 0, 261, 241, 1, 0, 0, 0, 261, 251, 1, 0, 0, 0, 262, + 32, 1, 0, 0, 0, 263, 264, 5, 112, 0, 0, 264, 265, 5, 104, 0, 0, 265, 266, + 5, 114, 0, 0, 266, 267, 5, 97, 0, 0, 267, 268, 5, 115, 0, 0, 268, 269, + 5, 101, 0, 0, 269, 270, 5, 95, 0, 0, 270, 271, 5, 109, 0, 0, 271, 272, + 5, 97, 0, 0, 272, 273, 5, 116, 0, 0, 273, 274, 5, 99, 0, 0, 274, 288, 5, + 104, 0, 0, 275, 276, 5, 80, 0, 0, 276, 277, 5, 72, 0, 0, 277, 278, 5, 82, + 0, 0, 278, 279, 5, 65, 0, 0, 279, 280, 5, 83, 0, 0, 280, 281, 5, 69, 0, + 0, 281, 282, 5, 95, 0, 0, 282, 283, 5, 77, 0, 0, 283, 284, 5, 65, 0, 0, + 284, 285, 5, 84, 0, 0, 285, 286, 5, 67, 0, 0, 286, 288, 5, 72, 0, 0, 287, + 263, 1, 0, 0, 0, 287, 275, 1, 0, 0, 0, 288, 34, 1, 0, 0, 0, 289, 290, 5, + 114, 0, 0, 290, 291, 5, 97, 0, 0, 291, 292, 5, 110, 0, 0, 292, 293, 5, + 100, 0, 0, 293, 294, 5, 111, 0, 0, 294, 295, 5, 109, 0, 0, 295, 296, 5, + 95, 0, 0, 296, 297, 5, 115, 0, 0, 297, 298, 5, 97, 0, 0, 298, 299, 5, 109, + 0, 0, 299, 300, 5, 112, 0, 0, 300, 301, 5, 108, 0, 0, 301, 316, 5, 101, + 0, 0, 302, 303, 5, 82, 0, 0, 303, 304, 5, 65, 0, 0, 304, 305, 5, 78, 0, + 0, 305, 306, 5, 68, 0, 0, 306, 307, 5, 79, 0, 0, 307, 308, 5, 77, 0, 0, + 308, 309, 5, 95, 0, 0, 309, 310, 5, 83, 0, 0, 310, 311, 5, 65, 0, 0, 311, + 312, 5, 77, 0, 0, 312, 313, 5, 80, 0, 0, 313, 314, 5, 76, 0, 0, 314, 316, + 5, 69, 0, 0, 315, 289, 1, 0, 0, 0, 315, 302, 1, 0, 0, 0, 316, 36, 1, 0, + 0, 0, 317, 318, 5, 105, 0, 0, 318, 319, 5, 110, 0, 0, 319, 320, 5, 116, + 0, 0, 320, 321, 5, 101, 0, 0, 321, 322, 5, 114, 0, 0, 322, 323, 5, 118, + 0, 0, 323, 324, 5, 97, 0, 0, 324, 334, 5, 108, 0, 0, 325, 326, 5, 73, 0, + 0, 326, 327, 5, 78, 0, 0, 327, 328, 5, 84, 0, 0, 328, 329, 5, 69, 0, 0, + 329, 330, 5, 82, 0, 0, 330, 331, 5, 86, 0, 0, 331, 332, 5, 65, 0, 0, 332, + 334, 5, 76, 0, 0, 333, 317, 1, 0, 0, 0, 333, 325, 1, 0, 0, 0, 334, 38, + 1, 0, 0, 0, 335, 336, 5, 105, 0, 0, 336, 337, 5, 115, 0, 0, 337, 342, 5, + 111, 0, 0, 338, 339, 5, 73, 0, 0, 339, 340, 5, 83, 0, 0, 340, 342, 5, 79, + 0, 0, 341, 335, 1, 0, 0, 0, 341, 338, 1, 0, 0, 0, 342, 40, 1, 0, 0, 0, + 343, 344, 5, 109, 0, 0, 344, 345, 5, 105, 0, 0, 345, 346, 5, 110, 0, 0, + 346, 347, 5, 105, 0, 0, 347, 348, 5, 109, 0, 0, 348, 349, 5, 117, 0, 0, + 349, 350, 5, 109, 0, 0, 350, 351, 5, 95, 0, 0, 351, 352, 5, 115, 0, 0, + 352, 353, 5, 104, 0, 0, 353, 354, 5, 111, 0, 0, 354, 355, 5, 117, 0, 0, + 355, 356, 5, 108, 0, 0, 356, 357, 5, 100, 0, 0, 357, 358, 5, 95, 0, 0, + 358, 359, 5, 109, 0, 0, 359, 360, 5, 97, 0, 0, 360, 361, 5, 116, 0, 0, + 361, 362, 5, 99, 0, 0, 362, 384, 5, 104, 0, 0, 363, 364, 5, 77, 0, 0, 364, + 365, 5, 73, 0, 0, 365, 366, 5, 78, 0, 0, 366, 367, 5, 73, 0, 0, 367, 368, + 5, 77, 0, 0, 368, 369, 5, 85, 0, 0, 369, 370, 5, 77, 0, 0, 370, 371, 5, + 95, 0, 0, 371, 372, 5, 83, 0, 0, 372, 373, 5, 72, 0, 0, 373, 374, 5, 79, + 0, 0, 374, 375, 5, 85, 0, 0, 375, 376, 5, 76, 0, 0, 376, 377, 5, 68, 0, + 0, 377, 378, 5, 95, 0, 0, 378, 379, 5, 77, 0, 0, 379, 380, 5, 65, 0, 0, + 380, 381, 5, 84, 0, 0, 381, 382, 5, 67, 0, 0, 382, 384, 5, 72, 0, 0, 383, + 343, 1, 0, 0, 0, 383, 363, 1, 0, 0, 0, 384, 42, 1, 0, 0, 0, 385, 386, 5, + 61, 0, 0, 386, 44, 1, 0, 0, 0, 387, 388, 5, 43, 0, 0, 388, 46, 1, 0, 0, + 0, 389, 390, 5, 45, 0, 0, 390, 48, 1, 0, 0, 0, 391, 392, 5, 42, 0, 0, 392, + 50, 1, 0, 0, 0, 393, 394, 5, 47, 0, 0, 394, 52, 1, 0, 0, 0, 395, 396, 5, + 37, 0, 0, 396, 54, 1, 0, 0, 0, 397, 398, 5, 42, 0, 0, 398, 399, 5, 42, + 0, 0, 399, 56, 1, 0, 0, 0, 400, 401, 5, 60, 0, 0, 401, 402, 5, 60, 0, 0, + 402, 58, 1, 0, 0, 0, 403, 404, 5, 62, 0, 0, 404, 405, 5, 62, 0, 0, 405, + 60, 1, 0, 0, 0, 406, 407, 5, 38, 0, 0, 407, 62, 1, 0, 0, 0, 408, 409, 5, + 124, 0, 0, 409, 64, 1, 0, 0, 0, 410, 411, 5, 94, 0, 0, 411, 66, 1, 0, 0, + 0, 412, 413, 5, 38, 0, 0, 413, 421, 5, 38, 0, 0, 414, 415, 5, 97, 0, 0, + 415, 416, 5, 110, 0, 0, 416, 421, 5, 100, 0, 0, 417, 418, 5, 65, 0, 0, + 418, 419, 5, 78, 0, 0, 419, 421, 5, 68, 0, 0, 420, 412, 1, 0, 0, 0, 420, + 414, 1, 0, 0, 0, 420, 417, 1, 0, 0, 0, 421, 68, 1, 0, 0, 0, 422, 423, 5, + 124, 0, 0, 423, 429, 5, 124, 0, 0, 424, 425, 5, 111, 0, 0, 425, 429, 5, + 114, 0, 0, 426, 427, 5, 79, 0, 0, 427, 429, 5, 82, 0, 0, 428, 422, 1, 0, + 0, 0, 428, 424, 1, 0, 0, 0, 428, 426, 1, 0, 0, 0, 429, 70, 1, 0, 0, 0, + 430, 431, 5, 105, 0, 0, 431, 432, 5, 115, 0, 0, 432, 433, 5, 32, 0, 0, + 433, 434, 5, 110, 0, 0, 434, 435, 5, 117, 0, 0, 435, 436, 5, 108, 0, 0, + 436, 445, 5, 108, 0, 0, 437, 438, 5, 73, 0, 0, 438, 439, 5, 83, 0, 0, 439, + 440, 5, 32, 0, 0, 440, 441, 5, 78, 0, 0, 441, 442, 5, 85, 0, 0, 442, 443, + 5, 76, 0, 0, 443, 445, 5, 76, 0, 0, 444, 430, 1, 0, 0, 0, 444, 437, 1, + 0, 0, 0, 445, 72, 1, 0, 0, 0, 446, 447, 5, 105, 0, 0, 447, 448, 5, 115, + 0, 0, 448, 449, 5, 32, 0, 0, 449, 450, 5, 110, 0, 0, 450, 451, 5, 111, + 0, 0, 451, 452, 5, 116, 0, 0, 452, 453, 5, 32, 0, 0, 453, 454, 5, 110, + 0, 0, 454, 455, 5, 117, 0, 0, 455, 456, 5, 108, 0, 0, 456, 469, 5, 108, + 0, 0, 457, 458, 5, 73, 0, 0, 458, 459, 5, 83, 0, 0, 459, 460, 5, 32, 0, + 0, 460, 461, 5, 78, 0, 0, 461, 462, 5, 79, 0, 0, 462, 463, 5, 84, 0, 0, + 463, 464, 5, 32, 0, 0, 464, 465, 5, 78, 0, 0, 465, 466, 5, 85, 0, 0, 466, + 467, 5, 76, 0, 0, 467, 469, 5, 76, 0, 0, 468, 446, 1, 0, 0, 0, 468, 457, + 1, 0, 0, 0, 469, 74, 1, 0, 0, 0, 470, 471, 5, 126, 0, 0, 471, 76, 1, 0, + 0, 0, 472, 480, 5, 33, 0, 0, 473, 474, 5, 110, 0, 0, 474, 475, 5, 111, + 0, 0, 475, 480, 5, 116, 0, 0, 476, 477, 5, 78, 0, 0, 477, 478, 5, 79, 0, + 0, 478, 480, 5, 84, 0, 0, 479, 472, 1, 0, 0, 0, 479, 473, 1, 0, 0, 0, 479, + 476, 1, 0, 0, 0, 480, 78, 1, 0, 0, 0, 481, 482, 5, 105, 0, 0, 482, 486, + 5, 110, 0, 0, 483, 484, 5, 73, 0, 0, 484, 486, 5, 78, 0, 0, 485, 481, 1, + 0, 0, 0, 485, 483, 1, 0, 0, 0, 486, 80, 1, 0, 0, 0, 487, 492, 5, 91, 0, + 0, 488, 491, 3, 183, 91, 0, 489, 491, 3, 185, 92, 0, 490, 488, 1, 0, 0, + 0, 490, 489, 1, 0, 0, 0, 491, 494, 1, 0, 0, 0, 492, 490, 1, 0, 0, 0, 492, + 493, 1, 0, 0, 0, 493, 495, 1, 0, 0, 0, 494, 492, 1, 0, 0, 0, 495, 496, + 5, 93, 0, 0, 496, 82, 1, 0, 0, 0, 497, 498, 5, 106, 0, 0, 498, 499, 5, + 115, 0, 0, 499, 500, 5, 111, 0, 0, 500, 501, 5, 110, 0, 0, 501, 502, 5, + 95, 0, 0, 502, 503, 5, 99, 0, 0, 503, 504, 5, 111, 0, 0, 504, 505, 5, 110, + 0, 0, 505, 506, 5, 116, 0, 0, 506, 507, 5, 97, 0, 0, 507, 508, 5, 105, + 0, 0, 508, 509, 5, 110, 0, 0, 509, 524, 5, 115, 0, 0, 510, 511, 5, 74, + 0, 0, 511, 512, 5, 83, 0, 0, 512, 513, 5, 79, 0, 0, 513, 514, 5, 78, 0, + 0, 514, 515, 5, 95, 0, 0, 515, 516, 5, 67, 0, 0, 516, 517, 5, 79, 0, 0, + 517, 518, 5, 78, 0, 0, 518, 519, 5, 84, 0, 0, 519, 520, 5, 65, 0, 0, 520, + 521, 5, 73, 0, 0, 521, 522, 5, 78, 0, 0, 522, 524, 5, 83, 0, 0, 523, 497, + 1, 0, 0, 0, 523, 510, 1, 0, 0, 0, 524, 84, 1, 0, 0, 0, 525, 526, 5, 106, + 0, 0, 526, 527, 5, 115, 0, 0, 527, 528, 5, 111, 0, 0, 528, 529, 5, 110, + 0, 0, 529, 530, 5, 95, 0, 0, 530, 531, 5, 99, 0, 0, 531, 532, 5, 111, 0, + 0, 532, 533, 5, 110, 0, 0, 533, 534, 5, 116, 0, 0, 534, 535, 5, 97, 0, + 0, 535, 536, 5, 105, 0, 0, 536, 537, 5, 110, 0, 0, 537, 538, 5, 115, 0, + 0, 538, 539, 5, 95, 0, 0, 539, 540, 5, 97, 0, 0, 540, 541, 5, 108, 0, 0, + 541, 560, 5, 108, 0, 0, 542, 543, 5, 74, 0, 0, 543, 544, 5, 83, 0, 0, 544, + 545, 5, 79, 0, 0, 545, 546, 5, 78, 0, 0, 546, 547, 5, 95, 0, 0, 547, 548, + 5, 67, 0, 0, 548, 549, 5, 79, 0, 0, 549, 550, 5, 78, 0, 0, 550, 551, 5, + 84, 0, 0, 551, 552, 5, 65, 0, 0, 552, 553, 5, 73, 0, 0, 553, 554, 5, 78, + 0, 0, 554, 555, 5, 83, 0, 0, 555, 556, 5, 95, 0, 0, 556, 557, 5, 65, 0, + 0, 557, 558, 5, 76, 0, 0, 558, 560, 5, 76, 0, 0, 559, 525, 1, 0, 0, 0, + 559, 542, 1, 0, 0, 0, 560, 86, 1, 0, 0, 0, 561, 562, 5, 106, 0, 0, 562, + 563, 5, 115, 0, 0, 563, 564, 5, 111, 0, 0, 564, 565, 5, 110, 0, 0, 565, + 566, 5, 95, 0, 0, 566, 567, 5, 99, 0, 0, 567, 568, 5, 111, 0, 0, 568, 569, + 5, 110, 0, 0, 569, 570, 5, 116, 0, 0, 570, 571, 5, 97, 0, 0, 571, 572, + 5, 105, 0, 0, 572, 573, 5, 110, 0, 0, 573, 574, 5, 115, 0, 0, 574, 575, + 5, 95, 0, 0, 575, 576, 5, 97, 0, 0, 576, 577, 5, 110, 0, 0, 577, 596, 5, + 121, 0, 0, 578, 579, 5, 74, 0, 0, 579, 580, 5, 83, 0, 0, 580, 581, 5, 79, + 0, 0, 581, 582, 5, 78, 0, 0, 582, 583, 5, 95, 0, 0, 583, 584, 5, 67, 0, + 0, 584, 585, 5, 79, 0, 0, 585, 586, 5, 78, 0, 0, 586, 587, 5, 84, 0, 0, + 587, 588, 5, 65, 0, 0, 588, 589, 5, 73, 0, 0, 589, 590, 5, 78, 0, 0, 590, + 591, 5, 83, 0, 0, 591, 592, 5, 95, 0, 0, 592, 593, 5, 65, 0, 0, 593, 594, + 5, 78, 0, 0, 594, 596, 5, 89, 0, 0, 595, 561, 1, 0, 0, 0, 595, 578, 1, + 0, 0, 0, 596, 88, 1, 0, 0, 0, 597, 598, 5, 97, 0, 0, 598, 599, 5, 114, + 0, 0, 599, 600, 5, 114, 0, 0, 600, 601, 5, 97, 0, 0, 601, 602, 5, 121, + 0, 0, 602, 603, 5, 95, 0, 0, 603, 604, 5, 99, 0, 0, 604, 605, 5, 111, 0, + 0, 605, 606, 5, 110, 0, 0, 606, 607, 5, 116, 0, 0, 607, 608, 5, 97, 0, + 0, 608, 609, 5, 105, 0, 0, 609, 610, 5, 110, 0, 0, 610, 626, 5, 115, 0, + 0, 611, 612, 5, 65, 0, 0, 612, 613, 5, 82, 0, 0, 613, 614, 5, 82, 0, 0, + 614, 615, 5, 65, 0, 0, 615, 616, 5, 89, 0, 0, 616, 617, 5, 95, 0, 0, 617, + 618, 5, 67, 0, 0, 618, 619, 5, 79, 0, 0, 619, 620, 5, 78, 0, 0, 620, 621, + 5, 84, 0, 0, 621, 622, 5, 65, 0, 0, 622, 623, 5, 73, 0, 0, 623, 624, 5, + 78, 0, 0, 624, 626, 5, 83, 0, 0, 625, 597, 1, 0, 0, 0, 625, 611, 1, 0, + 0, 0, 626, 90, 1, 0, 0, 0, 627, 628, 5, 97, 0, 0, 628, 629, 5, 114, 0, + 0, 629, 630, 5, 114, 0, 0, 630, 631, 5, 97, 0, 0, 631, 632, 5, 121, 0, + 0, 632, 633, 5, 95, 0, 0, 633, 634, 5, 99, 0, 0, 634, 635, 5, 111, 0, 0, + 635, 636, 5, 110, 0, 0, 636, 637, 5, 116, 0, 0, 637, 638, 5, 97, 0, 0, + 638, 639, 5, 105, 0, 0, 639, 640, 5, 110, 0, 0, 640, 641, 5, 115, 0, 0, + 641, 642, 5, 95, 0, 0, 642, 643, 5, 97, 0, 0, 643, 644, 5, 108, 0, 0, 644, + 664, 5, 108, 0, 0, 645, 646, 5, 65, 0, 0, 646, 647, 5, 82, 0, 0, 647, 648, + 5, 82, 0, 0, 648, 649, 5, 65, 0, 0, 649, 650, 5, 89, 0, 0, 650, 651, 5, + 95, 0, 0, 651, 652, 5, 67, 0, 0, 652, 653, 5, 79, 0, 0, 653, 654, 5, 78, + 0, 0, 654, 655, 5, 84, 0, 0, 655, 656, 5, 65, 0, 0, 656, 657, 5, 73, 0, + 0, 657, 658, 5, 78, 0, 0, 658, 659, 5, 83, 0, 0, 659, 660, 5, 95, 0, 0, + 660, 661, 5, 65, 0, 0, 661, 662, 5, 76, 0, 0, 662, 664, 5, 76, 0, 0, 663, + 627, 1, 0, 0, 0, 663, 645, 1, 0, 0, 0, 664, 92, 1, 0, 0, 0, 665, 666, 5, + 97, 0, 0, 666, 667, 5, 114, 0, 0, 667, 668, 5, 114, 0, 0, 668, 669, 5, + 97, 0, 0, 669, 670, 5, 121, 0, 0, 670, 671, 5, 95, 0, 0, 671, 672, 5, 99, + 0, 0, 672, 673, 5, 111, 0, 0, 673, 674, 5, 110, 0, 0, 674, 675, 5, 116, + 0, 0, 675, 676, 5, 97, 0, 0, 676, 677, 5, 105, 0, 0, 677, 678, 5, 110, + 0, 0, 678, 679, 5, 115, 0, 0, 679, 680, 5, 95, 0, 0, 680, 681, 5, 97, 0, + 0, 681, 682, 5, 110, 0, 0, 682, 702, 5, 121, 0, 0, 683, 684, 5, 65, 0, + 0, 684, 685, 5, 82, 0, 0, 685, 686, 5, 82, 0, 0, 686, 687, 5, 65, 0, 0, + 687, 688, 5, 89, 0, 0, 688, 689, 5, 95, 0, 0, 689, 690, 5, 67, 0, 0, 690, + 691, 5, 79, 0, 0, 691, 692, 5, 78, 0, 0, 692, 693, 5, 84, 0, 0, 693, 694, + 5, 65, 0, 0, 694, 695, 5, 73, 0, 0, 695, 696, 5, 78, 0, 0, 696, 697, 5, + 83, 0, 0, 697, 698, 5, 95, 0, 0, 698, 699, 5, 65, 0, 0, 699, 700, 5, 78, + 0, 0, 700, 702, 5, 89, 0, 0, 701, 665, 1, 0, 0, 0, 701, 683, 1, 0, 0, 0, + 702, 94, 1, 0, 0, 0, 703, 704, 5, 97, 0, 0, 704, 705, 5, 114, 0, 0, 705, + 706, 5, 114, 0, 0, 706, 707, 5, 97, 0, 0, 707, 708, 5, 121, 0, 0, 708, + 709, 5, 95, 0, 0, 709, 710, 5, 108, 0, 0, 710, 711, 5, 101, 0, 0, 711, + 712, 5, 110, 0, 0, 712, 713, 5, 103, 0, 0, 713, 714, 5, 116, 0, 0, 714, + 728, 5, 104, 0, 0, 715, 716, 5, 65, 0, 0, 716, 717, 5, 82, 0, 0, 717, 718, + 5, 82, 0, 0, 718, 719, 5, 65, 0, 0, 719, 720, 5, 89, 0, 0, 720, 721, 5, + 95, 0, 0, 721, 722, 5, 76, 0, 0, 722, 723, 5, 69, 0, 0, 723, 724, 5, 78, + 0, 0, 724, 725, 5, 71, 0, 0, 725, 726, 5, 84, 0, 0, 726, 728, 5, 72, 0, + 0, 727, 703, 1, 0, 0, 0, 727, 715, 1, 0, 0, 0, 728, 96, 1, 0, 0, 0, 729, + 730, 5, 101, 0, 0, 730, 731, 5, 108, 0, 0, 731, 732, 5, 101, 0, 0, 732, + 733, 5, 109, 0, 0, 733, 734, 5, 101, 0, 0, 734, 735, 5, 110, 0, 0, 735, + 736, 5, 116, 0, 0, 736, 737, 5, 95, 0, 0, 737, 738, 5, 102, 0, 0, 738, + 739, 5, 105, 0, 0, 739, 740, 5, 108, 0, 0, 740, 741, 5, 116, 0, 0, 741, + 742, 5, 101, 0, 0, 742, 758, 5, 114, 0, 0, 743, 744, 5, 69, 0, 0, 744, + 745, 5, 76, 0, 0, 745, 746, 5, 69, 0, 0, 746, 747, 5, 77, 0, 0, 747, 748, + 5, 69, 0, 0, 748, 749, 5, 78, 0, 0, 749, 750, 5, 84, 0, 0, 750, 751, 5, + 95, 0, 0, 751, 752, 5, 70, 0, 0, 752, 753, 5, 73, 0, 0, 753, 754, 5, 76, + 0, 0, 754, 755, 5, 84, 0, 0, 755, 756, 5, 69, 0, 0, 756, 758, 5, 82, 0, + 0, 757, 729, 1, 0, 0, 0, 757, 743, 1, 0, 0, 0, 758, 98, 1, 0, 0, 0, 759, + 760, 5, 115, 0, 0, 760, 761, 5, 116, 0, 0, 761, 762, 5, 95, 0, 0, 762, + 763, 5, 101, 0, 0, 763, 764, 5, 113, 0, 0, 764, 765, 5, 117, 0, 0, 765, + 766, 5, 97, 0, 0, 766, 767, 5, 108, 0, 0, 767, 778, 5, 115, 0, 0, 768, + 769, 5, 83, 0, 0, 769, 770, 5, 84, 0, 0, 770, 771, 5, 95, 0, 0, 771, 772, + 5, 69, 0, 0, 772, 773, 5, 81, 0, 0, 773, 774, 5, 85, 0, 0, 774, 775, 5, + 65, 0, 0, 775, 776, 5, 76, 0, 0, 776, 778, 5, 83, 0, 0, 777, 759, 1, 0, + 0, 0, 777, 768, 1, 0, 0, 0, 778, 100, 1, 0, 0, 0, 779, 780, 5, 115, 0, + 0, 780, 781, 5, 116, 0, 0, 781, 782, 5, 95, 0, 0, 782, 783, 5, 116, 0, + 0, 783, 784, 5, 111, 0, 0, 784, 785, 5, 117, 0, 0, 785, 786, 5, 99, 0, + 0, 786, 787, 5, 104, 0, 0, 787, 788, 5, 101, 0, 0, 788, 800, 5, 115, 0, + 0, 789, 790, 5, 83, 0, 0, 790, 791, 5, 84, 0, 0, 791, 792, 5, 95, 0, 0, + 792, 793, 5, 84, 0, 0, 793, 794, 5, 79, 0, 0, 794, 795, 5, 85, 0, 0, 795, + 796, 5, 67, 0, 0, 796, 797, 5, 72, 0, 0, 797, 798, 5, 69, 0, 0, 798, 800, + 5, 83, 0, 0, 799, 779, 1, 0, 0, 0, 799, 789, 1, 0, 0, 0, 800, 102, 1, 0, + 0, 0, 801, 802, 5, 115, 0, 0, 802, 803, 5, 116, 0, 0, 803, 804, 5, 95, + 0, 0, 804, 805, 5, 111, 0, 0, 805, 806, 5, 118, 0, 0, 806, 807, 5, 101, + 0, 0, 807, 808, 5, 114, 0, 0, 808, 809, 5, 108, 0, 0, 809, 810, 5, 97, + 0, 0, 810, 811, 5, 112, 0, 0, 811, 824, 5, 115, 0, 0, 812, 813, 5, 83, + 0, 0, 813, 814, 5, 84, 0, 0, 814, 815, 5, 95, 0, 0, 815, 816, 5, 79, 0, + 0, 816, 817, 5, 86, 0, 0, 817, 818, 5, 69, 0, 0, 818, 819, 5, 82, 0, 0, + 819, 820, 5, 76, 0, 0, 820, 821, 5, 65, 0, 0, 821, 822, 5, 80, 0, 0, 822, + 824, 5, 83, 0, 0, 823, 801, 1, 0, 0, 0, 823, 812, 1, 0, 0, 0, 824, 104, + 1, 0, 0, 0, 825, 826, 5, 115, 0, 0, 826, 827, 5, 116, 0, 0, 827, 828, 5, + 95, 0, 0, 828, 829, 5, 99, 0, 0, 829, 830, 5, 114, 0, 0, 830, 831, 5, 111, + 0, 0, 831, 832, 5, 115, 0, 0, 832, 833, 5, 115, 0, 0, 833, 834, 5, 101, + 0, 0, 834, 846, 5, 115, 0, 0, 835, 836, 5, 83, 0, 0, 836, 837, 5, 84, 0, + 0, 837, 838, 5, 95, 0, 0, 838, 839, 5, 67, 0, 0, 839, 840, 5, 82, 0, 0, + 840, 841, 5, 79, 0, 0, 841, 842, 5, 83, 0, 0, 842, 843, 5, 83, 0, 0, 843, + 844, 5, 69, 0, 0, 844, 846, 5, 83, 0, 0, 845, 825, 1, 0, 0, 0, 845, 835, + 1, 0, 0, 0, 846, 106, 1, 0, 0, 0, 847, 848, 5, 115, 0, 0, 848, 849, 5, + 116, 0, 0, 849, 850, 5, 95, 0, 0, 850, 851, 5, 99, 0, 0, 851, 852, 5, 111, + 0, 0, 852, 853, 5, 110, 0, 0, 853, 854, 5, 116, 0, 0, 854, 855, 5, 97, + 0, 0, 855, 856, 5, 105, 0, 0, 856, 857, 5, 110, 0, 0, 857, 870, 5, 115, + 0, 0, 858, 859, 5, 83, 0, 0, 859, 860, 5, 84, 0, 0, 860, 861, 5, 95, 0, + 0, 861, 862, 5, 67, 0, 0, 862, 863, 5, 79, 0, 0, 863, 864, 5, 78, 0, 0, + 864, 865, 5, 84, 0, 0, 865, 866, 5, 65, 0, 0, 866, 867, 5, 73, 0, 0, 867, + 868, 5, 78, 0, 0, 868, 870, 5, 83, 0, 0, 869, 847, 1, 0, 0, 0, 869, 858, + 1, 0, 0, 0, 870, 108, 1, 0, 0, 0, 871, 872, 5, 115, 0, 0, 872, 873, 5, + 116, 0, 0, 873, 874, 5, 95, 0, 0, 874, 875, 5, 105, 0, 0, 875, 876, 5, + 110, 0, 0, 876, 877, 5, 116, 0, 0, 877, 878, 5, 101, 0, 0, 878, 879, 5, + 114, 0, 0, 879, 880, 5, 115, 0, 0, 880, 881, 5, 101, 0, 0, 881, 882, 5, + 99, 0, 0, 882, 883, 5, 116, 0, 0, 883, 898, 5, 115, 0, 0, 884, 885, 5, + 83, 0, 0, 885, 886, 5, 84, 0, 0, 886, 887, 5, 95, 0, 0, 887, 888, 5, 73, + 0, 0, 888, 889, 5, 78, 0, 0, 889, 890, 5, 84, 0, 0, 890, 891, 5, 69, 0, + 0, 891, 892, 5, 82, 0, 0, 892, 893, 5, 83, 0, 0, 893, 894, 5, 69, 0, 0, + 894, 895, 5, 67, 0, 0, 895, 896, 5, 84, 0, 0, 896, 898, 5, 83, 0, 0, 897, + 871, 1, 0, 0, 0, 897, 884, 1, 0, 0, 0, 898, 110, 1, 0, 0, 0, 899, 900, + 5, 115, 0, 0, 900, 901, 5, 116, 0, 0, 901, 902, 5, 95, 0, 0, 902, 903, + 5, 119, 0, 0, 903, 904, 5, 105, 0, 0, 904, 905, 5, 116, 0, 0, 905, 906, + 5, 104, 0, 0, 906, 907, 5, 105, 0, 0, 907, 918, 5, 110, 0, 0, 908, 909, + 5, 83, 0, 0, 909, 910, 5, 84, 0, 0, 910, 911, 5, 95, 0, 0, 911, 912, 5, + 87, 0, 0, 912, 913, 5, 73, 0, 0, 913, 914, 5, 84, 0, 0, 914, 915, 5, 72, + 0, 0, 915, 916, 5, 73, 0, 0, 916, 918, 5, 78, 0, 0, 917, 899, 1, 0, 0, + 0, 917, 908, 1, 0, 0, 0, 918, 112, 1, 0, 0, 0, 919, 920, 5, 115, 0, 0, + 920, 921, 5, 116, 0, 0, 921, 922, 5, 95, 0, 0, 922, 923, 5, 100, 0, 0, + 923, 924, 5, 119, 0, 0, 924, 925, 5, 105, 0, 0, 925, 926, 5, 116, 0, 0, + 926, 927, 5, 104, 0, 0, 927, 928, 5, 105, 0, 0, 928, 940, 5, 110, 0, 0, + 929, 930, 5, 83, 0, 0, 930, 931, 5, 84, 0, 0, 931, 932, 5, 95, 0, 0, 932, + 933, 5, 68, 0, 0, 933, 934, 5, 87, 0, 0, 934, 935, 5, 73, 0, 0, 935, 936, + 5, 84, 0, 0, 936, 937, 5, 72, 0, 0, 937, 938, 5, 73, 0, 0, 938, 940, 5, + 78, 0, 0, 939, 919, 1, 0, 0, 0, 939, 929, 1, 0, 0, 0, 940, 114, 1, 0, 0, + 0, 941, 942, 5, 115, 0, 0, 942, 943, 5, 116, 0, 0, 943, 944, 5, 95, 0, + 0, 944, 945, 5, 105, 0, 0, 945, 946, 5, 115, 0, 0, 946, 947, 5, 118, 0, + 0, 947, 948, 5, 97, 0, 0, 948, 949, 5, 108, 0, 0, 949, 950, 5, 105, 0, + 0, 950, 962, 5, 100, 0, 0, 951, 952, 5, 83, 0, 0, 952, 953, 5, 84, 0, 0, + 953, 954, 5, 95, 0, 0, 954, 955, 5, 73, 0, 0, 955, 956, 5, 83, 0, 0, 956, + 957, 5, 86, 0, 0, 957, 958, 5, 65, 0, 0, 958, 959, 5, 76, 0, 0, 959, 960, + 5, 73, 0, 0, 960, 962, 5, 68, 0, 0, 961, 941, 1, 0, 0, 0, 961, 951, 1, + 0, 0, 0, 962, 116, 1, 0, 0, 0, 963, 964, 5, 116, 0, 0, 964, 965, 5, 114, + 0, 0, 965, 966, 5, 117, 0, 0, 966, 991, 5, 101, 0, 0, 967, 968, 5, 84, + 0, 0, 968, 969, 5, 114, 0, 0, 969, 970, 5, 117, 0, 0, 970, 991, 5, 101, + 0, 0, 971, 972, 5, 84, 0, 0, 972, 973, 5, 82, 0, 0, 973, 974, 5, 85, 0, + 0, 974, 991, 5, 69, 0, 0, 975, 976, 5, 102, 0, 0, 976, 977, 5, 97, 0, 0, + 977, 978, 5, 108, 0, 0, 978, 979, 5, 115, 0, 0, 979, 991, 5, 101, 0, 0, + 980, 981, 5, 70, 0, 0, 981, 982, 5, 97, 0, 0, 982, 983, 5, 108, 0, 0, 983, + 984, 5, 115, 0, 0, 984, 991, 5, 101, 0, 0, 985, 986, 5, 70, 0, 0, 986, + 987, 5, 65, 0, 0, 987, 988, 5, 76, 0, 0, 988, 989, 5, 83, 0, 0, 989, 991, + 5, 69, 0, 0, 990, 963, 1, 0, 0, 0, 990, 967, 1, 0, 0, 0, 990, 971, 1, 0, + 0, 0, 990, 975, 1, 0, 0, 0, 990, 980, 1, 0, 0, 0, 990, 985, 1, 0, 0, 0, + 991, 118, 1, 0, 0, 0, 992, 997, 3, 149, 74, 0, 993, 997, 3, 151, 75, 0, + 994, 997, 3, 153, 76, 0, 995, 997, 3, 147, 73, 0, 996, 992, 1, 0, 0, 0, + 996, 993, 1, 0, 0, 0, 996, 994, 1, 0, 0, 0, 996, 995, 1, 0, 0, 0, 997, + 120, 1, 0, 0, 0, 998, 1001, 3, 165, 82, 0, 999, 1001, 3, 167, 83, 0, 1000, + 998, 1, 0, 0, 0, 1000, 999, 1, 0, 0, 0, 1001, 122, 1, 0, 0, 0, 1002, 1007, + 3, 143, 71, 0, 1003, 1006, 3, 143, 71, 0, 1004, 1006, 3, 145, 72, 0, 1005, + 1003, 1, 0, 0, 0, 1005, 1004, 1, 0, 0, 0, 1006, 1009, 1, 0, 0, 0, 1007, + 1005, 1, 0, 0, 0, 1007, 1008, 1, 0, 0, 0, 1008, 124, 1, 0, 0, 0, 1009, + 1007, 1, 0, 0, 0, 1010, 1011, 5, 36, 0, 0, 1011, 1012, 5, 109, 0, 0, 1012, + 1013, 5, 101, 0, 0, 1013, 1014, 5, 116, 0, 0, 1014, 1015, 5, 97, 0, 0, + 1015, 126, 1, 0, 0, 0, 1016, 1018, 3, 133, 66, 0, 1017, 1016, 1, 0, 0, + 0, 1017, 1018, 1, 0, 0, 0, 1018, 1029, 1, 0, 0, 0, 1019, 1021, 5, 34, 0, + 0, 1020, 1022, 3, 135, 67, 0, 1021, 1020, 1, 0, 0, 0, 1021, 1022, 1, 0, + 0, 0, 1022, 1023, 1, 0, 0, 0, 1023, 1030, 5, 34, 0, 0, 1024, 1026, 5, 39, + 0, 0, 1025, 1027, 3, 137, 68, 0, 1026, 1025, 1, 0, 0, 0, 1026, 1027, 1, + 0, 0, 0, 1027, 1028, 1, 0, 0, 0, 1028, 1030, 5, 39, 0, 0, 1029, 1019, 1, + 0, 0, 0, 1029, 1024, 1, 0, 0, 0, 1030, 128, 1, 0, 0, 0, 1031, 1034, 3, + 123, 61, 0, 1032, 1034, 3, 125, 62, 0, 1033, 1031, 1, 0, 0, 0, 1033, 1032, + 1, 0, 0, 0, 1034, 1042, 1, 0, 0, 0, 1035, 1038, 5, 91, 0, 0, 1036, 1039, + 3, 127, 63, 0, 1037, 1039, 3, 149, 74, 0, 1038, 1036, 1, 0, 0, 0, 1038, + 1037, 1, 0, 0, 0, 1039, 1040, 1, 0, 0, 0, 1040, 1041, 5, 93, 0, 0, 1041, + 1043, 1, 0, 0, 0, 1042, 1035, 1, 0, 0, 0, 1043, 1044, 1, 0, 0, 0, 1044, + 1042, 1, 0, 0, 0, 1044, 1045, 1, 0, 0, 0, 1045, 130, 1, 0, 0, 0, 1046, + 1047, 5, 36, 0, 0, 1047, 1048, 5, 91, 0, 0, 1048, 1049, 1, 0, 0, 0, 1049, + 1050, 3, 123, 61, 0, 1050, 1051, 5, 93, 0, 0, 1051, 132, 1, 0, 0, 0, 1052, + 1053, 5, 117, 0, 0, 1053, 1056, 5, 56, 0, 0, 1054, 1056, 7, 0, 0, 0, 1055, + 1052, 1, 0, 0, 0, 1055, 1054, 1, 0, 0, 0, 1056, 134, 1, 0, 0, 0, 1057, + 1059, 3, 139, 69, 0, 1058, 1057, 1, 0, 0, 0, 1059, 1060, 1, 0, 0, 0, 1060, + 1058, 1, 0, 0, 0, 1060, 1061, 1, 0, 0, 0, 1061, 136, 1, 0, 0, 0, 1062, + 1064, 3, 141, 70, 0, 1063, 1062, 1, 0, 0, 0, 1064, 1065, 1, 0, 0, 0, 1065, + 1063, 1, 0, 0, 0, 1065, 1066, 1, 0, 0, 0, 1066, 138, 1, 0, 0, 0, 1067, + 1075, 8, 1, 0, 0, 1068, 1075, 3, 181, 90, 0, 1069, 1070, 5, 92, 0, 0, 1070, + 1075, 5, 10, 0, 0, 1071, 1072, 5, 92, 0, 0, 1072, 1073, 5, 13, 0, 0, 1073, + 1075, 5, 10, 0, 0, 1074, 1067, 1, 0, 0, 0, 1074, 1068, 1, 0, 0, 0, 1074, + 1069, 1, 0, 0, 0, 1074, 1071, 1, 0, 0, 0, 1075, 140, 1, 0, 0, 0, 1076, + 1084, 8, 2, 0, 0, 1077, 1084, 3, 181, 90, 0, 1078, 1079, 5, 92, 0, 0, 1079, + 1084, 5, 10, 0, 0, 1080, 1081, 5, 92, 0, 0, 1081, 1082, 5, 13, 0, 0, 1082, + 1084, 5, 10, 0, 0, 1083, 1076, 1, 0, 0, 0, 1083, 1077, 1, 0, 0, 0, 1083, + 1078, 1, 0, 0, 0, 1083, 1080, 1, 0, 0, 0, 1084, 142, 1, 0, 0, 0, 1085, + 1086, 7, 3, 0, 0, 1086, 144, 1, 0, 0, 0, 1087, 1088, 7, 4, 0, 0, 1088, + 146, 1, 0, 0, 0, 1089, 1090, 5, 48, 0, 0, 1090, 1092, 7, 5, 0, 0, 1091, + 1093, 7, 6, 0, 0, 1092, 1091, 1, 0, 0, 0, 1093, 1094, 1, 0, 0, 0, 1094, + 1092, 1, 0, 0, 0, 1094, 1095, 1, 0, 0, 0, 1095, 148, 1, 0, 0, 0, 1096, + 1100, 3, 155, 77, 0, 1097, 1099, 3, 145, 72, 0, 1098, 1097, 1, 0, 0, 0, + 1099, 1102, 1, 0, 0, 0, 1100, 1098, 1, 0, 0, 0, 1100, 1101, 1, 0, 0, 0, + 1101, 1105, 1, 0, 0, 0, 1102, 1100, 1, 0, 0, 0, 1103, 1105, 5, 48, 0, 0, + 1104, 1096, 1, 0, 0, 0, 1104, 1103, 1, 0, 0, 0, 1105, 150, 1, 0, 0, 0, + 1106, 1110, 5, 48, 0, 0, 1107, 1109, 3, 157, 78, 0, 1108, 1107, 1, 0, 0, + 0, 1109, 1112, 1, 0, 0, 0, 1110, 1108, 1, 0, 0, 0, 1110, 1111, 1, 0, 0, + 0, 1111, 152, 1, 0, 0, 0, 1112, 1110, 1, 0, 0, 0, 1113, 1114, 5, 48, 0, + 0, 1114, 1115, 7, 7, 0, 0, 1115, 1116, 3, 177, 88, 0, 1116, 154, 1, 0, + 0, 0, 1117, 1118, 7, 8, 0, 0, 1118, 156, 1, 0, 0, 0, 1119, 1120, 7, 9, + 0, 0, 1120, 158, 1, 0, 0, 0, 1121, 1122, 7, 10, 0, 0, 1122, 160, 1, 0, + 0, 0, 1123, 1124, 3, 159, 79, 0, 1124, 1125, 3, 159, 79, 0, 1125, 1126, + 3, 159, 79, 0, 1126, 1127, 3, 159, 79, 0, 1127, 162, 1, 0, 0, 0, 1128, + 1129, 5, 92, 0, 0, 1129, 1130, 5, 117, 0, 0, 1130, 1131, 1, 0, 0, 0, 1131, + 1139, 3, 161, 80, 0, 1132, 1133, 5, 92, 0, 0, 1133, 1134, 5, 85, 0, 0, + 1134, 1135, 1, 0, 0, 0, 1135, 1136, 3, 161, 80, 0, 1136, 1137, 3, 161, + 80, 0, 1137, 1139, 1, 0, 0, 0, 1138, 1128, 1, 0, 0, 0, 1138, 1132, 1, 0, + 0, 0, 1139, 164, 1, 0, 0, 0, 1140, 1142, 3, 169, 84, 0, 1141, 1143, 3, + 171, 85, 0, 1142, 1141, 1, 0, 0, 0, 1142, 1143, 1, 0, 0, 0, 1143, 1148, + 1, 0, 0, 0, 1144, 1145, 3, 173, 86, 0, 1145, 1146, 3, 171, 85, 0, 1146, + 1148, 1, 0, 0, 0, 1147, 1140, 1, 0, 0, 0, 1147, 1144, 1, 0, 0, 0, 1148, + 166, 1, 0, 0, 0, 1149, 1150, 5, 48, 0, 0, 1150, 1153, 7, 7, 0, 0, 1151, + 1154, 3, 175, 87, 0, 1152, 1154, 3, 177, 88, 0, 1153, 1151, 1, 0, 0, 0, + 1153, 1152, 1, 0, 0, 0, 1154, 1155, 1, 0, 0, 0, 1155, 1156, 3, 179, 89, + 0, 1156, 168, 1, 0, 0, 0, 1157, 1159, 3, 173, 86, 0, 1158, 1157, 1, 0, + 0, 0, 1158, 1159, 1, 0, 0, 0, 1159, 1160, 1, 0, 0, 0, 1160, 1161, 5, 46, + 0, 0, 1161, 1166, 3, 173, 86, 0, 1162, 1163, 3, 173, 86, 0, 1163, 1164, + 5, 46, 0, 0, 1164, 1166, 1, 0, 0, 0, 1165, 1158, 1, 0, 0, 0, 1165, 1162, + 1, 0, 0, 0, 1166, 170, 1, 0, 0, 0, 1167, 1169, 7, 11, 0, 0, 1168, 1170, + 7, 12, 0, 0, 1169, 1168, 1, 0, 0, 0, 1169, 1170, 1, 0, 0, 0, 1170, 1171, + 1, 0, 0, 0, 1171, 1172, 3, 173, 86, 0, 1172, 172, 1, 0, 0, 0, 1173, 1175, + 3, 145, 72, 0, 1174, 1173, 1, 0, 0, 0, 1175, 1176, 1, 0, 0, 0, 1176, 1174, + 1, 0, 0, 0, 1176, 1177, 1, 0, 0, 0, 1177, 174, 1, 0, 0, 0, 1178, 1180, + 3, 177, 88, 0, 1179, 1178, 1, 0, 0, 0, 1179, 1180, 1, 0, 0, 0, 1180, 1181, + 1, 0, 0, 0, 1181, 1182, 5, 46, 0, 0, 1182, 1187, 3, 177, 88, 0, 1183, 1184, + 3, 177, 88, 0, 1184, 1185, 5, 46, 0, 0, 1185, 1187, 1, 0, 0, 0, 1186, 1179, + 1, 0, 0, 0, 1186, 1183, 1, 0, 0, 0, 1187, 176, 1, 0, 0, 0, 1188, 1190, + 3, 159, 79, 0, 1189, 1188, 1, 0, 0, 0, 1190, 1191, 1, 0, 0, 0, 1191, 1189, + 1, 0, 0, 0, 1191, 1192, 1, 0, 0, 0, 1192, 178, 1, 0, 0, 0, 1193, 1195, + 7, 13, 0, 0, 1194, 1196, 7, 12, 0, 0, 1195, 1194, 1, 0, 0, 0, 1195, 1196, + 1, 0, 0, 0, 1196, 1197, 1, 0, 0, 0, 1197, 1198, 3, 173, 86, 0, 1198, 180, + 1, 0, 0, 0, 1199, 1200, 5, 92, 0, 0, 1200, 1215, 7, 14, 0, 0, 1201, 1202, + 5, 92, 0, 0, 1202, 1204, 3, 157, 78, 0, 1203, 1205, 3, 157, 78, 0, 1204, + 1203, 1, 0, 0, 0, 1204, 1205, 1, 0, 0, 0, 1205, 1207, 1, 0, 0, 0, 1206, + 1208, 3, 157, 78, 0, 1207, 1206, 1, 0, 0, 0, 1207, 1208, 1, 0, 0, 0, 1208, + 1215, 1, 0, 0, 0, 1209, 1210, 5, 92, 0, 0, 1210, 1211, 5, 120, 0, 0, 1211, + 1212, 1, 0, 0, 0, 1212, 1215, 3, 177, 88, 0, 1213, 1215, 3, 163, 81, 0, + 1214, 1199, 1, 0, 0, 0, 1214, 1201, 1, 0, 0, 0, 1214, 1209, 1, 0, 0, 0, + 1214, 1213, 1, 0, 0, 0, 1215, 182, 1, 0, 0, 0, 1216, 1218, 7, 15, 0, 0, + 1217, 1216, 1, 0, 0, 0, 1218, 1219, 1, 0, 0, 0, 1219, 1217, 1, 0, 0, 0, + 1219, 1220, 1, 0, 0, 0, 1220, 1221, 1, 0, 0, 0, 1221, 1222, 6, 91, 0, 0, + 1222, 184, 1, 0, 0, 0, 1223, 1225, 5, 13, 0, 0, 1224, 1226, 5, 10, 0, 0, + 1225, 1224, 1, 0, 0, 0, 1225, 1226, 1, 0, 0, 0, 1226, 1229, 1, 0, 0, 0, + 1227, 1229, 5, 10, 0, 0, 1228, 1223, 1, 0, 0, 0, 1228, 1227, 1, 0, 0, 0, + 1229, 1230, 1, 0, 0, 0, 1230, 1231, 6, 92, 0, 0, 1231, 186, 1, 0, 0, 0, + 73, 0, 225, 239, 261, 287, 315, 333, 341, 383, 420, 428, 444, 468, 479, + 485, 490, 492, 523, 559, 595, 625, 663, 701, 727, 757, 777, 799, 823, 845, + 869, 897, 917, 939, 961, 990, 996, 1000, 1005, 1007, 1017, 1021, 1026, + 1029, 1033, 1038, 1044, 1055, 1060, 1065, 1074, 1083, 1094, 1100, 1104, + 1110, 1138, 1142, 1147, 1153, 1158, 1165, 1169, 1176, 1179, 1186, 1191, + 1195, 1204, 1207, 1214, 1219, 1225, 1228, 1, 6, 0, 0, } deserializer := antlr.NewATNDeserializer(nil) staticData.atn = deserializer.Deserialize(staticData.serializedATN) @@ -665,70 +683,72 @@ func NewPlanLexer(input antlr.CharStream) *PlanLexer { // PlanLexer tokens. const ( - PlanLexerT__0 = 1 - PlanLexerT__1 = 2 - PlanLexerT__2 = 3 - PlanLexerT__3 = 4 - PlanLexerT__4 = 5 - PlanLexerLBRACE = 6 - PlanLexerRBRACE = 7 - PlanLexerLT = 8 - PlanLexerLE = 9 - PlanLexerGT = 10 - PlanLexerGE = 11 - PlanLexerEQ = 12 - PlanLexerNE = 13 - PlanLexerLIKE = 14 - PlanLexerEXISTS = 15 - PlanLexerTEXTMATCH = 16 - PlanLexerPHRASEMATCH = 17 - PlanLexerRANDOMSAMPLE = 18 - PlanLexerINTERVAL = 19 - PlanLexerISO = 20 - PlanLexerMINIMUM_SHOULD_MATCH = 21 - PlanLexerASSIGN = 22 - PlanLexerADD = 23 - PlanLexerSUB = 24 - PlanLexerMUL = 25 - PlanLexerDIV = 26 - PlanLexerMOD = 27 - PlanLexerPOW = 28 - PlanLexerSHL = 29 - PlanLexerSHR = 30 - PlanLexerBAND = 31 - PlanLexerBOR = 32 - PlanLexerBXOR = 33 - PlanLexerAND = 34 - PlanLexerOR = 35 - PlanLexerISNULL = 36 - PlanLexerISNOTNULL = 37 - PlanLexerBNOT = 38 - PlanLexerNOT = 39 - PlanLexerIN = 40 - PlanLexerEmptyArray = 41 - PlanLexerJSONContains = 42 - PlanLexerJSONContainsAll = 43 - PlanLexerJSONContainsAny = 44 - PlanLexerArrayContains = 45 - PlanLexerArrayContainsAll = 46 - PlanLexerArrayContainsAny = 47 - PlanLexerArrayLength = 48 - PlanLexerSTEuqals = 49 - PlanLexerSTTouches = 50 - PlanLexerSTOverlaps = 51 - PlanLexerSTCrosses = 52 - PlanLexerSTContains = 53 - PlanLexerSTIntersects = 54 - PlanLexerSTWithin = 55 - PlanLexerSTDWithin = 56 - PlanLexerSTIsValid = 57 - PlanLexerBooleanConstant = 58 - PlanLexerIntegerConstant = 59 - PlanLexerFloatingConstant = 60 - PlanLexerIdentifier = 61 - PlanLexerMeta = 62 - PlanLexerStringLiteral = 63 - PlanLexerJSONIdentifier = 64 - PlanLexerWhitespace = 65 - PlanLexerNewline = 66 + PlanLexerT__0 = 1 + PlanLexerT__1 = 2 + PlanLexerT__2 = 3 + PlanLexerT__3 = 4 + PlanLexerT__4 = 5 + PlanLexerLBRACE = 6 + PlanLexerRBRACE = 7 + PlanLexerLT = 8 + PlanLexerLE = 9 + PlanLexerGT = 10 + PlanLexerGE = 11 + PlanLexerEQ = 12 + PlanLexerNE = 13 + PlanLexerLIKE = 14 + PlanLexerEXISTS = 15 + PlanLexerTEXTMATCH = 16 + PlanLexerPHRASEMATCH = 17 + PlanLexerRANDOMSAMPLE = 18 + PlanLexerINTERVAL = 19 + PlanLexerISO = 20 + PlanLexerMINIMUM_SHOULD_MATCH = 21 + PlanLexerASSIGN = 22 + PlanLexerADD = 23 + PlanLexerSUB = 24 + PlanLexerMUL = 25 + PlanLexerDIV = 26 + PlanLexerMOD = 27 + PlanLexerPOW = 28 + PlanLexerSHL = 29 + PlanLexerSHR = 30 + PlanLexerBAND = 31 + PlanLexerBOR = 32 + PlanLexerBXOR = 33 + PlanLexerAND = 34 + PlanLexerOR = 35 + PlanLexerISNULL = 36 + PlanLexerISNOTNULL = 37 + PlanLexerBNOT = 38 + PlanLexerNOT = 39 + PlanLexerIN = 40 + PlanLexerEmptyArray = 41 + PlanLexerJSONContains = 42 + PlanLexerJSONContainsAll = 43 + PlanLexerJSONContainsAny = 44 + PlanLexerArrayContains = 45 + PlanLexerArrayContainsAll = 46 + PlanLexerArrayContainsAny = 47 + PlanLexerArrayLength = 48 + PlanLexerElementFilter = 49 + PlanLexerSTEuqals = 50 + PlanLexerSTTouches = 51 + PlanLexerSTOverlaps = 52 + PlanLexerSTCrosses = 53 + PlanLexerSTContains = 54 + PlanLexerSTIntersects = 55 + PlanLexerSTWithin = 56 + PlanLexerSTDWithin = 57 + PlanLexerSTIsValid = 58 + PlanLexerBooleanConstant = 59 + PlanLexerIntegerConstant = 60 + PlanLexerFloatingConstant = 61 + PlanLexerIdentifier = 62 + PlanLexerMeta = 63 + PlanLexerStringLiteral = 64 + PlanLexerJSONIdentifier = 65 + PlanLexerStructSubFieldIdentifier = 66 + PlanLexerWhitespace = 67 + PlanLexerNewline = 68 ) diff --git a/internal/parser/planparserv2/generated/plan_parser.go b/internal/parser/planparserv2/generated/plan_parser.go index 0199f20236..3490f57b96 100644 --- a/internal/parser/planparserv2/generated/plan_parser.go +++ b/internal/parser/planparserv2/generated/plan_parser.go @@ -36,7 +36,7 @@ func planParserInit() { "'>'", "'>='", "'=='", "'!='", "", "", "", "", "", "", "", "", "'='", "'+'", "'-'", "'*'", "'/'", "'%'", "'**'", "'<<'", "'>>'", "'&'", "'|'", "'^'", "", "", "", "", "'~'", "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", "", "", "", "'$meta'", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "'$meta'", } staticData.SymbolicNames = []string{ "", "", "", "", "", "", "LBRACE", "RBRACE", "LT", "LE", "GT", "GE", @@ -45,24 +45,24 @@ func planParserInit() { "DIV", "MOD", "POW", "SHL", "SHR", "BAND", "BOR", "BXOR", "AND", "OR", "ISNULL", "ISNOTNULL", "BNOT", "NOT", "IN", "EmptyArray", "JSONContains", "JSONContainsAll", "JSONContainsAny", "ArrayContains", "ArrayContainsAll", - "ArrayContainsAny", "ArrayLength", "STEuqals", "STTouches", "STOverlaps", - "STCrosses", "STContains", "STIntersects", "STWithin", "STDWithin", - "STIsValid", "BooleanConstant", "IntegerConstant", "FloatingConstant", - "Identifier", "Meta", "StringLiteral", "JSONIdentifier", "Whitespace", - "Newline", + "ArrayContainsAny", "ArrayLength", "ElementFilter", "STEuqals", "STTouches", + "STOverlaps", "STCrosses", "STContains", "STIntersects", "STWithin", + "STDWithin", "STIsValid", "BooleanConstant", "IntegerConstant", "FloatingConstant", + "Identifier", "Meta", "StringLiteral", "JSONIdentifier", "StructSubFieldIdentifier", + "Whitespace", "Newline", } staticData.RuleNames = []string{ "expr", "textMatchOption", } staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ - 4, 1, 66, 244, 2, 0, 7, 0, 2, 1, 7, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, + 4, 1, 68, 252, 2, 0, 7, 0, 2, 1, 7, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 10, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 22, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 41, 8, 0, 10, 0, 12, - 0, 44, 9, 0, 1, 0, 3, 0, 47, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 61, 8, 0, 1, 0, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 71, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 42, 8, 0, 10, + 0, 12, 0, 45, 9, 0, 1, 0, 3, 0, 48, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 62, 8, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 72, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, @@ -70,107 +70,112 @@ func planParserInit() { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 166, 8, 0, 10, 0, 12, 0, 169, 9, 0, 1, 0, - 3, 0, 172, 8, 0, 3, 0, 174, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 181, - 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 3, 0, 197, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 235, 8, 0, 10, 0, 12, 0, 238, - 9, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 2, 0, 2, 0, 14, 1, 0, 23, - 24, 1, 0, 8, 13, 1, 0, 61, 62, 2, 0, 23, 24, 38, 39, 2, 0, 42, 42, 45, - 45, 2, 0, 43, 43, 46, 46, 2, 0, 44, 44, 47, 47, 2, 0, 61, 61, 64, 64, 1, - 0, 25, 27, 1, 0, 29, 30, 1, 0, 8, 9, 1, 0, 10, 11, 1, 0, 8, 11, 1, 0, 12, - 13, 298, 0, 180, 1, 0, 0, 0, 2, 239, 1, 0, 0, 0, 4, 5, 6, 0, -1, 0, 5, - 9, 5, 61, 0, 0, 6, 7, 7, 0, 0, 0, 7, 8, 5, 19, 0, 0, 8, 10, 5, 63, 0, 0, + 5, 0, 174, 8, 0, 10, 0, 12, 0, 177, 9, 0, 1, 0, 3, 0, 180, 8, 0, 3, 0, + 182, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 189, 8, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, + 0, 205, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 5, 0, 243, 8, 0, 10, 0, 12, 0, 246, 9, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 0, 2, 0, 2, 0, 15, 1, 0, 23, 24, 1, 0, 8, 13, 1, 0, + 62, 63, 2, 0, 23, 24, 38, 39, 2, 0, 42, 42, 45, 45, 2, 0, 43, 43, 46, 46, + 2, 0, 44, 44, 47, 47, 2, 0, 62, 62, 65, 65, 1, 0, 25, 27, 1, 0, 29, 30, + 1, 0, 8, 9, 2, 0, 62, 62, 65, 66, 1, 0, 10, 11, 1, 0, 8, 11, 1, 0, 12, + 13, 308, 0, 188, 1, 0, 0, 0, 2, 247, 1, 0, 0, 0, 4, 5, 6, 0, -1, 0, 5, + 9, 5, 62, 0, 0, 6, 7, 7, 0, 0, 0, 7, 8, 5, 19, 0, 0, 8, 10, 5, 64, 0, 0, 9, 6, 1, 0, 0, 0, 9, 10, 1, 0, 0, 0, 10, 11, 1, 0, 0, 0, 11, 12, 7, 1, - 0, 0, 12, 13, 5, 20, 0, 0, 13, 181, 5, 63, 0, 0, 14, 15, 5, 20, 0, 0, 15, - 16, 5, 63, 0, 0, 16, 17, 7, 1, 0, 0, 17, 21, 5, 61, 0, 0, 18, 19, 7, 0, - 0, 0, 19, 20, 5, 19, 0, 0, 20, 22, 5, 63, 0, 0, 21, 18, 1, 0, 0, 0, 21, - 22, 1, 0, 0, 0, 22, 181, 1, 0, 0, 0, 23, 181, 5, 59, 0, 0, 24, 181, 5, - 60, 0, 0, 25, 181, 5, 58, 0, 0, 26, 181, 5, 63, 0, 0, 27, 181, 7, 2, 0, - 0, 28, 181, 5, 64, 0, 0, 29, 30, 5, 6, 0, 0, 30, 31, 5, 61, 0, 0, 31, 181, - 5, 7, 0, 0, 32, 33, 5, 1, 0, 0, 33, 34, 3, 0, 0, 0, 34, 35, 5, 2, 0, 0, - 35, 181, 1, 0, 0, 0, 36, 37, 5, 3, 0, 0, 37, 42, 3, 0, 0, 0, 38, 39, 5, - 4, 0, 0, 39, 41, 3, 0, 0, 0, 40, 38, 1, 0, 0, 0, 41, 44, 1, 0, 0, 0, 42, - 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 46, 1, 0, 0, 0, 44, 42, 1, 0, 0, - 0, 45, 47, 5, 4, 0, 0, 46, 45, 1, 0, 0, 0, 46, 47, 1, 0, 0, 0, 47, 48, - 1, 0, 0, 0, 48, 49, 5, 5, 0, 0, 49, 181, 1, 0, 0, 0, 50, 181, 5, 41, 0, - 0, 51, 52, 5, 15, 0, 0, 52, 181, 3, 0, 0, 36, 53, 54, 5, 16, 0, 0, 54, - 55, 5, 1, 0, 0, 55, 56, 5, 61, 0, 0, 56, 57, 5, 4, 0, 0, 57, 60, 5, 63, - 0, 0, 58, 59, 5, 4, 0, 0, 59, 61, 3, 2, 1, 0, 60, 58, 1, 0, 0, 0, 60, 61, - 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 181, 5, 2, 0, 0, 63, 64, 5, 17, 0, - 0, 64, 65, 5, 1, 0, 0, 65, 66, 5, 61, 0, 0, 66, 67, 5, 4, 0, 0, 67, 70, - 5, 63, 0, 0, 68, 69, 5, 4, 0, 0, 69, 71, 3, 0, 0, 0, 70, 68, 1, 0, 0, 0, - 70, 71, 1, 0, 0, 0, 71, 72, 1, 0, 0, 0, 72, 181, 5, 2, 0, 0, 73, 74, 5, - 18, 0, 0, 74, 75, 5, 1, 0, 0, 75, 76, 3, 0, 0, 0, 76, 77, 5, 2, 0, 0, 77, - 181, 1, 0, 0, 0, 78, 79, 7, 3, 0, 0, 79, 181, 3, 0, 0, 30, 80, 81, 7, 4, - 0, 0, 81, 82, 5, 1, 0, 0, 82, 83, 3, 0, 0, 0, 83, 84, 5, 4, 0, 0, 84, 85, - 3, 0, 0, 0, 85, 86, 5, 2, 0, 0, 86, 181, 1, 0, 0, 0, 87, 88, 7, 5, 0, 0, - 88, 89, 5, 1, 0, 0, 89, 90, 3, 0, 0, 0, 90, 91, 5, 4, 0, 0, 91, 92, 3, - 0, 0, 0, 92, 93, 5, 2, 0, 0, 93, 181, 1, 0, 0, 0, 94, 95, 7, 6, 0, 0, 95, - 96, 5, 1, 0, 0, 96, 97, 3, 0, 0, 0, 97, 98, 5, 4, 0, 0, 98, 99, 3, 0, 0, - 0, 99, 100, 5, 2, 0, 0, 100, 181, 1, 0, 0, 0, 101, 102, 5, 49, 0, 0, 102, - 103, 5, 1, 0, 0, 103, 104, 5, 61, 0, 0, 104, 105, 5, 4, 0, 0, 105, 106, - 5, 63, 0, 0, 106, 181, 5, 2, 0, 0, 107, 108, 5, 50, 0, 0, 108, 109, 5, - 1, 0, 0, 109, 110, 5, 61, 0, 0, 110, 111, 5, 4, 0, 0, 111, 112, 5, 63, - 0, 0, 112, 181, 5, 2, 0, 0, 113, 114, 5, 51, 0, 0, 114, 115, 5, 1, 0, 0, - 115, 116, 5, 61, 0, 0, 116, 117, 5, 4, 0, 0, 117, 118, 5, 63, 0, 0, 118, - 181, 5, 2, 0, 0, 119, 120, 5, 52, 0, 0, 120, 121, 5, 1, 0, 0, 121, 122, - 5, 61, 0, 0, 122, 123, 5, 4, 0, 0, 123, 124, 5, 63, 0, 0, 124, 181, 5, - 2, 0, 0, 125, 126, 5, 53, 0, 0, 126, 127, 5, 1, 0, 0, 127, 128, 5, 61, - 0, 0, 128, 129, 5, 4, 0, 0, 129, 130, 5, 63, 0, 0, 130, 181, 5, 2, 0, 0, - 131, 132, 5, 54, 0, 0, 132, 133, 5, 1, 0, 0, 133, 134, 5, 61, 0, 0, 134, - 135, 5, 4, 0, 0, 135, 136, 5, 63, 0, 0, 136, 181, 5, 2, 0, 0, 137, 138, - 5, 55, 0, 0, 138, 139, 5, 1, 0, 0, 139, 140, 5, 61, 0, 0, 140, 141, 5, - 4, 0, 0, 141, 142, 5, 63, 0, 0, 142, 181, 5, 2, 0, 0, 143, 144, 5, 56, - 0, 0, 144, 145, 5, 1, 0, 0, 145, 146, 5, 61, 0, 0, 146, 147, 5, 4, 0, 0, - 147, 148, 5, 63, 0, 0, 148, 149, 5, 4, 0, 0, 149, 150, 3, 0, 0, 0, 150, - 151, 5, 2, 0, 0, 151, 181, 1, 0, 0, 0, 152, 153, 5, 57, 0, 0, 153, 154, - 5, 1, 0, 0, 154, 155, 5, 61, 0, 0, 155, 181, 5, 2, 0, 0, 156, 157, 5, 48, - 0, 0, 157, 158, 5, 1, 0, 0, 158, 159, 7, 7, 0, 0, 159, 181, 5, 2, 0, 0, - 160, 161, 5, 61, 0, 0, 161, 173, 5, 1, 0, 0, 162, 167, 3, 0, 0, 0, 163, - 164, 5, 4, 0, 0, 164, 166, 3, 0, 0, 0, 165, 163, 1, 0, 0, 0, 166, 169, - 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 167, 168, 1, 0, 0, 0, 168, 171, 1, 0, - 0, 0, 169, 167, 1, 0, 0, 0, 170, 172, 5, 4, 0, 0, 171, 170, 1, 0, 0, 0, - 171, 172, 1, 0, 0, 0, 172, 174, 1, 0, 0, 0, 173, 162, 1, 0, 0, 0, 173, - 174, 1, 0, 0, 0, 174, 175, 1, 0, 0, 0, 175, 181, 5, 2, 0, 0, 176, 177, - 7, 7, 0, 0, 177, 181, 5, 36, 0, 0, 178, 179, 7, 7, 0, 0, 179, 181, 5, 37, - 0, 0, 180, 4, 1, 0, 0, 0, 180, 14, 1, 0, 0, 0, 180, 23, 1, 0, 0, 0, 180, - 24, 1, 0, 0, 0, 180, 25, 1, 0, 0, 0, 180, 26, 1, 0, 0, 0, 180, 27, 1, 0, - 0, 0, 180, 28, 1, 0, 0, 0, 180, 29, 1, 0, 0, 0, 180, 32, 1, 0, 0, 0, 180, - 36, 1, 0, 0, 0, 180, 50, 1, 0, 0, 0, 180, 51, 1, 0, 0, 0, 180, 53, 1, 0, - 0, 0, 180, 63, 1, 0, 0, 0, 180, 73, 1, 0, 0, 0, 180, 78, 1, 0, 0, 0, 180, - 80, 1, 0, 0, 0, 180, 87, 1, 0, 0, 0, 180, 94, 1, 0, 0, 0, 180, 101, 1, - 0, 0, 0, 180, 107, 1, 0, 0, 0, 180, 113, 1, 0, 0, 0, 180, 119, 1, 0, 0, - 0, 180, 125, 1, 0, 0, 0, 180, 131, 1, 0, 0, 0, 180, 137, 1, 0, 0, 0, 180, - 143, 1, 0, 0, 0, 180, 152, 1, 0, 0, 0, 180, 156, 1, 0, 0, 0, 180, 160, - 1, 0, 0, 0, 180, 176, 1, 0, 0, 0, 180, 178, 1, 0, 0, 0, 181, 236, 1, 0, - 0, 0, 182, 183, 10, 31, 0, 0, 183, 184, 5, 28, 0, 0, 184, 235, 3, 0, 0, - 32, 185, 186, 10, 29, 0, 0, 186, 187, 7, 8, 0, 0, 187, 235, 3, 0, 0, 30, - 188, 189, 10, 28, 0, 0, 189, 190, 7, 0, 0, 0, 190, 235, 3, 0, 0, 29, 191, - 192, 10, 27, 0, 0, 192, 193, 7, 9, 0, 0, 193, 235, 3, 0, 0, 28, 194, 196, - 10, 26, 0, 0, 195, 197, 5, 39, 0, 0, 196, 195, 1, 0, 0, 0, 196, 197, 1, - 0, 0, 0, 197, 198, 1, 0, 0, 0, 198, 199, 5, 40, 0, 0, 199, 235, 3, 0, 0, - 27, 200, 201, 10, 11, 0, 0, 201, 202, 7, 10, 0, 0, 202, 203, 7, 7, 0, 0, - 203, 204, 7, 10, 0, 0, 204, 235, 3, 0, 0, 12, 205, 206, 10, 10, 0, 0, 206, - 207, 7, 11, 0, 0, 207, 208, 7, 7, 0, 0, 208, 209, 7, 11, 0, 0, 209, 235, - 3, 0, 0, 11, 210, 211, 10, 9, 0, 0, 211, 212, 7, 12, 0, 0, 212, 235, 3, - 0, 0, 10, 213, 214, 10, 8, 0, 0, 214, 215, 7, 13, 0, 0, 215, 235, 3, 0, - 0, 9, 216, 217, 10, 7, 0, 0, 217, 218, 5, 31, 0, 0, 218, 235, 3, 0, 0, - 8, 219, 220, 10, 6, 0, 0, 220, 221, 5, 33, 0, 0, 221, 235, 3, 0, 0, 7, - 222, 223, 10, 5, 0, 0, 223, 224, 5, 32, 0, 0, 224, 235, 3, 0, 0, 6, 225, - 226, 10, 4, 0, 0, 226, 227, 5, 34, 0, 0, 227, 235, 3, 0, 0, 5, 228, 229, - 10, 3, 0, 0, 229, 230, 5, 35, 0, 0, 230, 235, 3, 0, 0, 4, 231, 232, 10, - 35, 0, 0, 232, 233, 5, 14, 0, 0, 233, 235, 5, 63, 0, 0, 234, 182, 1, 0, - 0, 0, 234, 185, 1, 0, 0, 0, 234, 188, 1, 0, 0, 0, 234, 191, 1, 0, 0, 0, - 234, 194, 1, 0, 0, 0, 234, 200, 1, 0, 0, 0, 234, 205, 1, 0, 0, 0, 234, - 210, 1, 0, 0, 0, 234, 213, 1, 0, 0, 0, 234, 216, 1, 0, 0, 0, 234, 219, - 1, 0, 0, 0, 234, 222, 1, 0, 0, 0, 234, 225, 1, 0, 0, 0, 234, 228, 1, 0, - 0, 0, 234, 231, 1, 0, 0, 0, 235, 238, 1, 0, 0, 0, 236, 234, 1, 0, 0, 0, - 236, 237, 1, 0, 0, 0, 237, 1, 1, 0, 0, 0, 238, 236, 1, 0, 0, 0, 239, 240, - 5, 21, 0, 0, 240, 241, 5, 22, 0, 0, 241, 242, 5, 59, 0, 0, 242, 3, 1, 0, - 0, 0, 13, 9, 21, 42, 46, 60, 70, 167, 171, 173, 180, 196, 234, 236, + 0, 0, 12, 13, 5, 20, 0, 0, 13, 189, 5, 64, 0, 0, 14, 15, 5, 20, 0, 0, 15, + 16, 5, 64, 0, 0, 16, 17, 7, 1, 0, 0, 17, 21, 5, 62, 0, 0, 18, 19, 7, 0, + 0, 0, 19, 20, 5, 19, 0, 0, 20, 22, 5, 64, 0, 0, 21, 18, 1, 0, 0, 0, 21, + 22, 1, 0, 0, 0, 22, 189, 1, 0, 0, 0, 23, 189, 5, 60, 0, 0, 24, 189, 5, + 61, 0, 0, 25, 189, 5, 59, 0, 0, 26, 189, 5, 64, 0, 0, 27, 189, 7, 2, 0, + 0, 28, 189, 5, 65, 0, 0, 29, 189, 5, 66, 0, 0, 30, 31, 5, 6, 0, 0, 31, + 32, 5, 62, 0, 0, 32, 189, 5, 7, 0, 0, 33, 34, 5, 1, 0, 0, 34, 35, 3, 0, + 0, 0, 35, 36, 5, 2, 0, 0, 36, 189, 1, 0, 0, 0, 37, 38, 5, 3, 0, 0, 38, + 43, 3, 0, 0, 0, 39, 40, 5, 4, 0, 0, 40, 42, 3, 0, 0, 0, 41, 39, 1, 0, 0, + 0, 42, 45, 1, 0, 0, 0, 43, 41, 1, 0, 0, 0, 43, 44, 1, 0, 0, 0, 44, 47, + 1, 0, 0, 0, 45, 43, 1, 0, 0, 0, 46, 48, 5, 4, 0, 0, 47, 46, 1, 0, 0, 0, + 47, 48, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 50, 5, 5, 0, 0, 50, 189, 1, + 0, 0, 0, 51, 189, 5, 41, 0, 0, 52, 53, 5, 15, 0, 0, 53, 189, 3, 0, 0, 37, + 54, 55, 5, 16, 0, 0, 55, 56, 5, 1, 0, 0, 56, 57, 5, 62, 0, 0, 57, 58, 5, + 4, 0, 0, 58, 61, 5, 64, 0, 0, 59, 60, 5, 4, 0, 0, 60, 62, 3, 2, 1, 0, 61, + 59, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 63, 1, 0, 0, 0, 63, 189, 5, 2, + 0, 0, 64, 65, 5, 17, 0, 0, 65, 66, 5, 1, 0, 0, 66, 67, 5, 62, 0, 0, 67, + 68, 5, 4, 0, 0, 68, 71, 5, 64, 0, 0, 69, 70, 5, 4, 0, 0, 70, 72, 3, 0, + 0, 0, 71, 69, 1, 0, 0, 0, 71, 72, 1, 0, 0, 0, 72, 73, 1, 0, 0, 0, 73, 189, + 5, 2, 0, 0, 74, 75, 5, 18, 0, 0, 75, 76, 5, 1, 0, 0, 76, 77, 3, 0, 0, 0, + 77, 78, 5, 2, 0, 0, 78, 189, 1, 0, 0, 0, 79, 80, 5, 49, 0, 0, 80, 81, 5, + 1, 0, 0, 81, 82, 5, 62, 0, 0, 82, 83, 5, 4, 0, 0, 83, 84, 3, 0, 0, 0, 84, + 85, 5, 2, 0, 0, 85, 189, 1, 0, 0, 0, 86, 87, 7, 3, 0, 0, 87, 189, 3, 0, + 0, 30, 88, 89, 7, 4, 0, 0, 89, 90, 5, 1, 0, 0, 90, 91, 3, 0, 0, 0, 91, + 92, 5, 4, 0, 0, 92, 93, 3, 0, 0, 0, 93, 94, 5, 2, 0, 0, 94, 189, 1, 0, + 0, 0, 95, 96, 7, 5, 0, 0, 96, 97, 5, 1, 0, 0, 97, 98, 3, 0, 0, 0, 98, 99, + 5, 4, 0, 0, 99, 100, 3, 0, 0, 0, 100, 101, 5, 2, 0, 0, 101, 189, 1, 0, + 0, 0, 102, 103, 7, 6, 0, 0, 103, 104, 5, 1, 0, 0, 104, 105, 3, 0, 0, 0, + 105, 106, 5, 4, 0, 0, 106, 107, 3, 0, 0, 0, 107, 108, 5, 2, 0, 0, 108, + 189, 1, 0, 0, 0, 109, 110, 5, 50, 0, 0, 110, 111, 5, 1, 0, 0, 111, 112, + 5, 62, 0, 0, 112, 113, 5, 4, 0, 0, 113, 114, 5, 64, 0, 0, 114, 189, 5, + 2, 0, 0, 115, 116, 5, 51, 0, 0, 116, 117, 5, 1, 0, 0, 117, 118, 5, 62, + 0, 0, 118, 119, 5, 4, 0, 0, 119, 120, 5, 64, 0, 0, 120, 189, 5, 2, 0, 0, + 121, 122, 5, 52, 0, 0, 122, 123, 5, 1, 0, 0, 123, 124, 5, 62, 0, 0, 124, + 125, 5, 4, 0, 0, 125, 126, 5, 64, 0, 0, 126, 189, 5, 2, 0, 0, 127, 128, + 5, 53, 0, 0, 128, 129, 5, 1, 0, 0, 129, 130, 5, 62, 0, 0, 130, 131, 5, + 4, 0, 0, 131, 132, 5, 64, 0, 0, 132, 189, 5, 2, 0, 0, 133, 134, 5, 54, + 0, 0, 134, 135, 5, 1, 0, 0, 135, 136, 5, 62, 0, 0, 136, 137, 5, 4, 0, 0, + 137, 138, 5, 64, 0, 0, 138, 189, 5, 2, 0, 0, 139, 140, 5, 55, 0, 0, 140, + 141, 5, 1, 0, 0, 141, 142, 5, 62, 0, 0, 142, 143, 5, 4, 0, 0, 143, 144, + 5, 64, 0, 0, 144, 189, 5, 2, 0, 0, 145, 146, 5, 56, 0, 0, 146, 147, 5, + 1, 0, 0, 147, 148, 5, 62, 0, 0, 148, 149, 5, 4, 0, 0, 149, 150, 5, 64, + 0, 0, 150, 189, 5, 2, 0, 0, 151, 152, 5, 57, 0, 0, 152, 153, 5, 1, 0, 0, + 153, 154, 5, 62, 0, 0, 154, 155, 5, 4, 0, 0, 155, 156, 5, 64, 0, 0, 156, + 157, 5, 4, 0, 0, 157, 158, 3, 0, 0, 0, 158, 159, 5, 2, 0, 0, 159, 189, + 1, 0, 0, 0, 160, 161, 5, 58, 0, 0, 161, 162, 5, 1, 0, 0, 162, 163, 5, 62, + 0, 0, 163, 189, 5, 2, 0, 0, 164, 165, 5, 48, 0, 0, 165, 166, 5, 1, 0, 0, + 166, 167, 7, 7, 0, 0, 167, 189, 5, 2, 0, 0, 168, 169, 5, 62, 0, 0, 169, + 181, 5, 1, 0, 0, 170, 175, 3, 0, 0, 0, 171, 172, 5, 4, 0, 0, 172, 174, + 3, 0, 0, 0, 173, 171, 1, 0, 0, 0, 174, 177, 1, 0, 0, 0, 175, 173, 1, 0, + 0, 0, 175, 176, 1, 0, 0, 0, 176, 179, 1, 0, 0, 0, 177, 175, 1, 0, 0, 0, + 178, 180, 5, 4, 0, 0, 179, 178, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, + 182, 1, 0, 0, 0, 181, 170, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 183, + 1, 0, 0, 0, 183, 189, 5, 2, 0, 0, 184, 185, 7, 7, 0, 0, 185, 189, 5, 36, + 0, 0, 186, 187, 7, 7, 0, 0, 187, 189, 5, 37, 0, 0, 188, 4, 1, 0, 0, 0, + 188, 14, 1, 0, 0, 0, 188, 23, 1, 0, 0, 0, 188, 24, 1, 0, 0, 0, 188, 25, + 1, 0, 0, 0, 188, 26, 1, 0, 0, 0, 188, 27, 1, 0, 0, 0, 188, 28, 1, 0, 0, + 0, 188, 29, 1, 0, 0, 0, 188, 30, 1, 0, 0, 0, 188, 33, 1, 0, 0, 0, 188, + 37, 1, 0, 0, 0, 188, 51, 1, 0, 0, 0, 188, 52, 1, 0, 0, 0, 188, 54, 1, 0, + 0, 0, 188, 64, 1, 0, 0, 0, 188, 74, 1, 0, 0, 0, 188, 79, 1, 0, 0, 0, 188, + 86, 1, 0, 0, 0, 188, 88, 1, 0, 0, 0, 188, 95, 1, 0, 0, 0, 188, 102, 1, + 0, 0, 0, 188, 109, 1, 0, 0, 0, 188, 115, 1, 0, 0, 0, 188, 121, 1, 0, 0, + 0, 188, 127, 1, 0, 0, 0, 188, 133, 1, 0, 0, 0, 188, 139, 1, 0, 0, 0, 188, + 145, 1, 0, 0, 0, 188, 151, 1, 0, 0, 0, 188, 160, 1, 0, 0, 0, 188, 164, + 1, 0, 0, 0, 188, 168, 1, 0, 0, 0, 188, 184, 1, 0, 0, 0, 188, 186, 1, 0, + 0, 0, 189, 244, 1, 0, 0, 0, 190, 191, 10, 31, 0, 0, 191, 192, 5, 28, 0, + 0, 192, 243, 3, 0, 0, 32, 193, 194, 10, 29, 0, 0, 194, 195, 7, 8, 0, 0, + 195, 243, 3, 0, 0, 30, 196, 197, 10, 28, 0, 0, 197, 198, 7, 0, 0, 0, 198, + 243, 3, 0, 0, 29, 199, 200, 10, 27, 0, 0, 200, 201, 7, 9, 0, 0, 201, 243, + 3, 0, 0, 28, 202, 204, 10, 26, 0, 0, 203, 205, 5, 39, 0, 0, 204, 203, 1, + 0, 0, 0, 204, 205, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 207, 5, 40, 0, + 0, 207, 243, 3, 0, 0, 27, 208, 209, 10, 11, 0, 0, 209, 210, 7, 10, 0, 0, + 210, 211, 7, 11, 0, 0, 211, 212, 7, 10, 0, 0, 212, 243, 3, 0, 0, 12, 213, + 214, 10, 10, 0, 0, 214, 215, 7, 12, 0, 0, 215, 216, 7, 11, 0, 0, 216, 217, + 7, 12, 0, 0, 217, 243, 3, 0, 0, 11, 218, 219, 10, 9, 0, 0, 219, 220, 7, + 13, 0, 0, 220, 243, 3, 0, 0, 10, 221, 222, 10, 8, 0, 0, 222, 223, 7, 14, + 0, 0, 223, 243, 3, 0, 0, 9, 224, 225, 10, 7, 0, 0, 225, 226, 5, 31, 0, + 0, 226, 243, 3, 0, 0, 8, 227, 228, 10, 6, 0, 0, 228, 229, 5, 33, 0, 0, + 229, 243, 3, 0, 0, 7, 230, 231, 10, 5, 0, 0, 231, 232, 5, 32, 0, 0, 232, + 243, 3, 0, 0, 6, 233, 234, 10, 4, 0, 0, 234, 235, 5, 34, 0, 0, 235, 243, + 3, 0, 0, 5, 236, 237, 10, 3, 0, 0, 237, 238, 5, 35, 0, 0, 238, 243, 3, + 0, 0, 4, 239, 240, 10, 36, 0, 0, 240, 241, 5, 14, 0, 0, 241, 243, 5, 64, + 0, 0, 242, 190, 1, 0, 0, 0, 242, 193, 1, 0, 0, 0, 242, 196, 1, 0, 0, 0, + 242, 199, 1, 0, 0, 0, 242, 202, 1, 0, 0, 0, 242, 208, 1, 0, 0, 0, 242, + 213, 1, 0, 0, 0, 242, 218, 1, 0, 0, 0, 242, 221, 1, 0, 0, 0, 242, 224, + 1, 0, 0, 0, 242, 227, 1, 0, 0, 0, 242, 230, 1, 0, 0, 0, 242, 233, 1, 0, + 0, 0, 242, 236, 1, 0, 0, 0, 242, 239, 1, 0, 0, 0, 243, 246, 1, 0, 0, 0, + 244, 242, 1, 0, 0, 0, 244, 245, 1, 0, 0, 0, 245, 1, 1, 0, 0, 0, 246, 244, + 1, 0, 0, 0, 247, 248, 5, 21, 0, 0, 248, 249, 5, 22, 0, 0, 249, 250, 5, + 60, 0, 0, 250, 3, 1, 0, 0, 0, 13, 9, 21, 43, 47, 61, 71, 175, 179, 181, + 188, 204, 242, 244, } deserializer := antlr.NewATNDeserializer(nil) staticData.atn = deserializer.Deserialize(staticData.serializedATN) @@ -208,73 +213,75 @@ func NewPlanParser(input antlr.TokenStream) *PlanParser { // PlanParser tokens. const ( - PlanParserEOF = antlr.TokenEOF - PlanParserT__0 = 1 - PlanParserT__1 = 2 - PlanParserT__2 = 3 - PlanParserT__3 = 4 - PlanParserT__4 = 5 - PlanParserLBRACE = 6 - PlanParserRBRACE = 7 - PlanParserLT = 8 - PlanParserLE = 9 - PlanParserGT = 10 - PlanParserGE = 11 - PlanParserEQ = 12 - PlanParserNE = 13 - PlanParserLIKE = 14 - PlanParserEXISTS = 15 - PlanParserTEXTMATCH = 16 - PlanParserPHRASEMATCH = 17 - PlanParserRANDOMSAMPLE = 18 - PlanParserINTERVAL = 19 - PlanParserISO = 20 - PlanParserMINIMUM_SHOULD_MATCH = 21 - PlanParserASSIGN = 22 - PlanParserADD = 23 - PlanParserSUB = 24 - PlanParserMUL = 25 - PlanParserDIV = 26 - PlanParserMOD = 27 - PlanParserPOW = 28 - PlanParserSHL = 29 - PlanParserSHR = 30 - PlanParserBAND = 31 - PlanParserBOR = 32 - PlanParserBXOR = 33 - PlanParserAND = 34 - PlanParserOR = 35 - PlanParserISNULL = 36 - PlanParserISNOTNULL = 37 - PlanParserBNOT = 38 - PlanParserNOT = 39 - PlanParserIN = 40 - PlanParserEmptyArray = 41 - PlanParserJSONContains = 42 - PlanParserJSONContainsAll = 43 - PlanParserJSONContainsAny = 44 - PlanParserArrayContains = 45 - PlanParserArrayContainsAll = 46 - PlanParserArrayContainsAny = 47 - PlanParserArrayLength = 48 - PlanParserSTEuqals = 49 - PlanParserSTTouches = 50 - PlanParserSTOverlaps = 51 - PlanParserSTCrosses = 52 - PlanParserSTContains = 53 - PlanParserSTIntersects = 54 - PlanParserSTWithin = 55 - PlanParserSTDWithin = 56 - PlanParserSTIsValid = 57 - PlanParserBooleanConstant = 58 - PlanParserIntegerConstant = 59 - PlanParserFloatingConstant = 60 - PlanParserIdentifier = 61 - PlanParserMeta = 62 - PlanParserStringLiteral = 63 - PlanParserJSONIdentifier = 64 - PlanParserWhitespace = 65 - PlanParserNewline = 66 + PlanParserEOF = antlr.TokenEOF + PlanParserT__0 = 1 + PlanParserT__1 = 2 + PlanParserT__2 = 3 + PlanParserT__3 = 4 + PlanParserT__4 = 5 + PlanParserLBRACE = 6 + PlanParserRBRACE = 7 + PlanParserLT = 8 + PlanParserLE = 9 + PlanParserGT = 10 + PlanParserGE = 11 + PlanParserEQ = 12 + PlanParserNE = 13 + PlanParserLIKE = 14 + PlanParserEXISTS = 15 + PlanParserTEXTMATCH = 16 + PlanParserPHRASEMATCH = 17 + PlanParserRANDOMSAMPLE = 18 + PlanParserINTERVAL = 19 + PlanParserISO = 20 + PlanParserMINIMUM_SHOULD_MATCH = 21 + PlanParserASSIGN = 22 + PlanParserADD = 23 + PlanParserSUB = 24 + PlanParserMUL = 25 + PlanParserDIV = 26 + PlanParserMOD = 27 + PlanParserPOW = 28 + PlanParserSHL = 29 + PlanParserSHR = 30 + PlanParserBAND = 31 + PlanParserBOR = 32 + PlanParserBXOR = 33 + PlanParserAND = 34 + PlanParserOR = 35 + PlanParserISNULL = 36 + PlanParserISNOTNULL = 37 + PlanParserBNOT = 38 + PlanParserNOT = 39 + PlanParserIN = 40 + PlanParserEmptyArray = 41 + PlanParserJSONContains = 42 + PlanParserJSONContainsAll = 43 + PlanParserJSONContainsAny = 44 + PlanParserArrayContains = 45 + PlanParserArrayContainsAll = 46 + PlanParserArrayContainsAny = 47 + PlanParserArrayLength = 48 + PlanParserElementFilter = 49 + PlanParserSTEuqals = 50 + PlanParserSTTouches = 51 + PlanParserSTOverlaps = 52 + PlanParserSTCrosses = 53 + PlanParserSTContains = 54 + PlanParserSTIntersects = 55 + PlanParserSTWithin = 56 + PlanParserSTDWithin = 57 + PlanParserSTIsValid = 58 + PlanParserBooleanConstant = 59 + PlanParserIntegerConstant = 60 + PlanParserFloatingConstant = 61 + PlanParserIdentifier = 62 + PlanParserMeta = 63 + PlanParserStringLiteral = 64 + PlanParserJSONIdentifier = 65 + PlanParserStructSubFieldIdentifier = 66 + PlanParserWhitespace = 67 + PlanParserNewline = 68 ) // PlanParser rules. @@ -337,130 +344,6 @@ func (s *ExprContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) s return antlr.TreesStringTree(s, ruleNames, recog) } -type JSONIdentifierContext struct { - ExprContext -} - -func NewJSONIdentifierContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *JSONIdentifierContext { - var p = new(JSONIdentifierContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *JSONIdentifierContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *JSONIdentifierContext) JSONIdentifier() antlr.TerminalNode { - return s.GetToken(PlanParserJSONIdentifier, 0) -} - -func (s *JSONIdentifierContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitJSONIdentifier(s) - - default: - return t.VisitChildren(s) - } -} - -type RandomSampleContext struct { - ExprContext -} - -func NewRandomSampleContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *RandomSampleContext { - var p = new(RandomSampleContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *RandomSampleContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *RandomSampleContext) RANDOMSAMPLE() antlr.TerminalNode { - return s.GetToken(PlanParserRANDOMSAMPLE, 0) -} - -func (s *RandomSampleContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *RandomSampleContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitRandomSample(s) - - default: - return t.VisitChildren(s) - } -} - -type ParensContext struct { - ExprContext -} - -func NewParensContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *ParensContext { - var p = new(ParensContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *ParensContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *ParensContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *ParensContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitParens(s) - - default: - return t.VisitChildren(s) - } -} - type StringContext struct { ExprContext } @@ -525,156 +408,6 @@ func (s *FloatingContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } -type JSONContainsAllContext struct { - ExprContext -} - -func NewJSONContainsAllContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *JSONContainsAllContext { - var p = new(JSONContainsAllContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *JSONContainsAllContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *JSONContainsAllContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *JSONContainsAllContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *JSONContainsAllContext) JSONContainsAll() antlr.TerminalNode { - return s.GetToken(PlanParserJSONContainsAll, 0) -} - -func (s *JSONContainsAllContext) ArrayContainsAll() antlr.TerminalNode { - return s.GetToken(PlanParserArrayContainsAll, 0) -} - -func (s *JSONContainsAllContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitJSONContainsAll(s) - - default: - return t.VisitChildren(s) - } -} - -type LogicalOrContext struct { - ExprContext -} - -func NewLogicalOrContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *LogicalOrContext { - var p = new(LogicalOrContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *LogicalOrContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *LogicalOrContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *LogicalOrContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *LogicalOrContext) OR() antlr.TerminalNode { - return s.GetToken(PlanParserOR, 0) -} - -func (s *LogicalOrContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitLogicalOr(s) - - default: - return t.VisitChildren(s) - } -} - type IsNotNullContext struct { ExprContext } @@ -715,92 +448,6 @@ func (s *IsNotNullContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } -type MulDivModContext struct { - ExprContext - op antlr.Token -} - -func NewMulDivModContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *MulDivModContext { - var p = new(MulDivModContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *MulDivModContext) GetOp() antlr.Token { return s.op } - -func (s *MulDivModContext) SetOp(v antlr.Token) { s.op = v } - -func (s *MulDivModContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *MulDivModContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *MulDivModContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *MulDivModContext) MUL() antlr.TerminalNode { - return s.GetToken(PlanParserMUL, 0) -} - -func (s *MulDivModContext) DIV() antlr.TerminalNode { - return s.GetToken(PlanParserDIV, 0) -} - -func (s *MulDivModContext) MOD() antlr.TerminalNode { - return s.GetToken(PlanParserMOD, 0) -} - -func (s *MulDivModContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitMulDivMod(s) - - default: - return t.VisitChildren(s) - } -} - type IdentifierContext struct { ExprContext } @@ -929,119 +576,6 @@ func (s *LikeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } -type LogicalAndContext struct { - ExprContext -} - -func NewLogicalAndContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *LogicalAndContext { - var p = new(LogicalAndContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *LogicalAndContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *LogicalAndContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *LogicalAndContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *LogicalAndContext) AND() antlr.TerminalNode { - return s.GetToken(PlanParserAND, 0) -} - -func (s *LogicalAndContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitLogicalAnd(s) - - default: - return t.VisitChildren(s) - } -} - -type TemplateVariableContext struct { - ExprContext -} - -func NewTemplateVariableContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *TemplateVariableContext { - var p = new(TemplateVariableContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *TemplateVariableContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *TemplateVariableContext) LBRACE() antlr.TerminalNode { - return s.GetToken(PlanParserLBRACE, 0) -} - -func (s *TemplateVariableContext) Identifier() antlr.TerminalNode { - return s.GetToken(PlanParserIdentifier, 0) -} - -func (s *TemplateVariableContext) RBRACE() antlr.TerminalNode { - return s.GetToken(PlanParserRBRACE, 0) -} - -func (s *TemplateVariableContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitTemplateVariable(s) - - default: - return t.VisitChildren(s) - } -} - type EqualityContext struct { ExprContext op antlr.Token @@ -1156,162 +690,6 @@ func (s *BooleanContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } -type TimestamptzCompareReverseContext struct { - ExprContext - compare_string antlr.Token - op2 antlr.Token - op1 antlr.Token - interval_string antlr.Token -} - -func NewTimestamptzCompareReverseContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *TimestamptzCompareReverseContext { - var p = new(TimestamptzCompareReverseContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *TimestamptzCompareReverseContext) GetCompare_string() antlr.Token { return s.compare_string } - -func (s *TimestamptzCompareReverseContext) GetOp2() antlr.Token { return s.op2 } - -func (s *TimestamptzCompareReverseContext) GetOp1() antlr.Token { return s.op1 } - -func (s *TimestamptzCompareReverseContext) GetInterval_string() antlr.Token { return s.interval_string } - -func (s *TimestamptzCompareReverseContext) SetCompare_string(v antlr.Token) { s.compare_string = v } - -func (s *TimestamptzCompareReverseContext) SetOp2(v antlr.Token) { s.op2 = v } - -func (s *TimestamptzCompareReverseContext) SetOp1(v antlr.Token) { s.op1 = v } - -func (s *TimestamptzCompareReverseContext) SetInterval_string(v antlr.Token) { s.interval_string = v } - -func (s *TimestamptzCompareReverseContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *TimestamptzCompareReverseContext) ISO() antlr.TerminalNode { - return s.GetToken(PlanParserISO, 0) -} - -func (s *TimestamptzCompareReverseContext) Identifier() antlr.TerminalNode { - return s.GetToken(PlanParserIdentifier, 0) -} - -func (s *TimestamptzCompareReverseContext) AllStringLiteral() []antlr.TerminalNode { - return s.GetTokens(PlanParserStringLiteral) -} - -func (s *TimestamptzCompareReverseContext) StringLiteral(i int) antlr.TerminalNode { - return s.GetToken(PlanParserStringLiteral, i) -} - -func (s *TimestamptzCompareReverseContext) LT() antlr.TerminalNode { - return s.GetToken(PlanParserLT, 0) -} - -func (s *TimestamptzCompareReverseContext) LE() antlr.TerminalNode { - return s.GetToken(PlanParserLE, 0) -} - -func (s *TimestamptzCompareReverseContext) GT() antlr.TerminalNode { - return s.GetToken(PlanParserGT, 0) -} - -func (s *TimestamptzCompareReverseContext) GE() antlr.TerminalNode { - return s.GetToken(PlanParserGE, 0) -} - -func (s *TimestamptzCompareReverseContext) EQ() antlr.TerminalNode { - return s.GetToken(PlanParserEQ, 0) -} - -func (s *TimestamptzCompareReverseContext) NE() antlr.TerminalNode { - return s.GetToken(PlanParserNE, 0) -} - -func (s *TimestamptzCompareReverseContext) INTERVAL() antlr.TerminalNode { - return s.GetToken(PlanParserINTERVAL, 0) -} - -func (s *TimestamptzCompareReverseContext) ADD() antlr.TerminalNode { - return s.GetToken(PlanParserADD, 0) -} - -func (s *TimestamptzCompareReverseContext) SUB() antlr.TerminalNode { - return s.GetToken(PlanParserSUB, 0) -} - -func (s *TimestamptzCompareReverseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitTimestamptzCompareReverse(s) - - default: - return t.VisitChildren(s) - } -} - -type STDWithinContext struct { - ExprContext -} - -func NewSTDWithinContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STDWithinContext { - var p = new(STDWithinContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *STDWithinContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *STDWithinContext) STDWithin() antlr.TerminalNode { - return s.GetToken(PlanParserSTDWithin, 0) -} - -func (s *STDWithinContext) Identifier() antlr.TerminalNode { - return s.GetToken(PlanParserIdentifier, 0) -} - -func (s *STDWithinContext) StringLiteral() antlr.TerminalNode { - return s.GetToken(PlanParserStringLiteral, 0) -} - -func (s *STDWithinContext) Expr() IExprContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *STDWithinContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitSTDWithin(s) - - default: - return t.VisitChildren(s) - } -} - type ShiftContext struct { ExprContext op antlr.Token @@ -1494,119 +872,6 @@ func (s *TimestamptzCompareForwardContext) Accept(visitor antlr.ParseTreeVisitor } } -type CallContext struct { - ExprContext -} - -func NewCallContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *CallContext { - var p = new(CallContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *CallContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *CallContext) Identifier() antlr.TerminalNode { - return s.GetToken(PlanParserIdentifier, 0) -} - -func (s *CallContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *CallContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *CallContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitCall(s) - - default: - return t.VisitChildren(s) - } -} - -type STCrossesContext struct { - ExprContext -} - -func NewSTCrossesContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STCrossesContext { - var p = new(STCrossesContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *STCrossesContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *STCrossesContext) STCrosses() antlr.TerminalNode { - return s.GetToken(PlanParserSTCrosses, 0) -} - -func (s *STCrossesContext) Identifier() antlr.TerminalNode { - return s.GetToken(PlanParserIdentifier, 0) -} - -func (s *STCrossesContext) StringLiteral() antlr.TerminalNode { - return s.GetToken(PlanParserStringLiteral, 0) -} - -func (s *STCrossesContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitSTCrosses(s) - - default: - return t.VisitChildren(s) - } -} - type ReverseRangeContext struct { ExprContext op1 antlr.Token @@ -1684,6 +949,10 @@ func (s *ReverseRangeContext) JSONIdentifier() antlr.TerminalNode { return s.GetToken(PlanParserJSONIdentifier, 0) } +func (s *ReverseRangeContext) StructSubFieldIdentifier() antlr.TerminalNode { + return s.GetToken(PlanParserStructSubFieldIdentifier, 0) +} + func (s *ReverseRangeContext) AllGT() []antlr.TerminalNode { return s.GetTokens(PlanParserGT) } @@ -1710,79 +979,6 @@ func (s *ReverseRangeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } } -type BitOrContext struct { - ExprContext -} - -func NewBitOrContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *BitOrContext { - var p = new(BitOrContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *BitOrContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *BitOrContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *BitOrContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *BitOrContext) BOR() antlr.TerminalNode { - return s.GetToken(PlanParserBOR, 0) -} - -func (s *BitOrContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitBitOr(s) - - default: - return t.VisitChildren(s) - } -} - type EmptyArrayContext struct { ExprContext } @@ -1815,88 +1011,6 @@ func (s *EmptyArrayContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } -type AddSubContext struct { - ExprContext - op antlr.Token -} - -func NewAddSubContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *AddSubContext { - var p = new(AddSubContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *AddSubContext) GetOp() antlr.Token { return s.op } - -func (s *AddSubContext) SetOp(v antlr.Token) { s.op = v } - -func (s *AddSubContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *AddSubContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *AddSubContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *AddSubContext) ADD() antlr.TerminalNode { - return s.GetToken(PlanParserADD, 0) -} - -func (s *AddSubContext) SUB() antlr.TerminalNode { - return s.GetToken(PlanParserSUB, 0) -} - -func (s *AddSubContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitAddSub(s) - - default: - return t.VisitChildren(s) - } -} - type PhraseMatchContext struct { ExprContext } @@ -1953,96 +1067,6 @@ func (s *PhraseMatchContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } } -type RelationalContext struct { - ExprContext - op antlr.Token -} - -func NewRelationalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *RelationalContext { - var p = new(RelationalContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *RelationalContext) GetOp() antlr.Token { return s.op } - -func (s *RelationalContext) SetOp(v antlr.Token) { s.op = v } - -func (s *RelationalContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *RelationalContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *RelationalContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *RelationalContext) LT() antlr.TerminalNode { - return s.GetToken(PlanParserLT, 0) -} - -func (s *RelationalContext) LE() antlr.TerminalNode { - return s.GetToken(PlanParserLE, 0) -} - -func (s *RelationalContext) GT() antlr.TerminalNode { - return s.GetToken(PlanParserGT, 0) -} - -func (s *RelationalContext) GE() antlr.TerminalNode { - return s.GetToken(PlanParserGE, 0) -} - -func (s *RelationalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitRelational(s) - - default: - return t.VisitChildren(s) - } -} - type ArrayLengthContext struct { ExprContext } @@ -2083,62 +1107,6 @@ func (s *ArrayLengthContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } } -type TextMatchContext struct { - ExprContext -} - -func NewTextMatchContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *TextMatchContext { - var p = new(TextMatchContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *TextMatchContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *TextMatchContext) TEXTMATCH() antlr.TerminalNode { - return s.GetToken(PlanParserTEXTMATCH, 0) -} - -func (s *TextMatchContext) Identifier() antlr.TerminalNode { - return s.GetToken(PlanParserIdentifier, 0) -} - -func (s *TextMatchContext) StringLiteral() antlr.TerminalNode { - return s.GetToken(PlanParserStringLiteral, 0) -} - -func (s *TextMatchContext) TextMatchOption() ITextMatchOptionContext { - var t antlr.RuleContext - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(ITextMatchOptionContext); ok { - t = ctx.(antlr.RuleContext) - break - } - } - - if t == nil { - return nil - } - - return t.(ITextMatchOptionContext) -} - -func (s *TextMatchContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitTextMatch(s) - - default: - return t.VisitChildren(s) - } -} - type STTouchesContext struct { ExprContext } @@ -2179,46 +1147,6 @@ func (s *STTouchesContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } -type STContainsContext struct { - ExprContext -} - -func NewSTContainsContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STContainsContext { - var p = new(STContainsContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *STContainsContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *STContainsContext) STContains() antlr.TerminalNode { - return s.GetToken(PlanParserSTContains, 0) -} - -func (s *STContainsContext) Identifier() antlr.TerminalNode { - return s.GetToken(PlanParserIdentifier, 0) -} - -func (s *STContainsContext) StringLiteral() antlr.TerminalNode { - return s.GetToken(PlanParserStringLiteral, 0) -} - -func (s *STContainsContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitSTContains(s) - - default: - return t.VisitChildren(s) - } -} - type TermContext struct { ExprContext op antlr.Token @@ -2495,6 +1423,10 @@ func (s *RangeContext) JSONIdentifier() antlr.TerminalNode { return s.GetToken(PlanParserJSONIdentifier, 0) } +func (s *RangeContext) StructSubFieldIdentifier() antlr.TerminalNode { + return s.GetToken(PlanParserStructSubFieldIdentifier, 0) +} + func (s *RangeContext) AllLT() []antlr.TerminalNode { return s.GetTokens(PlanParserLT) } @@ -2521,6 +1453,1363 @@ func (s *RangeContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } +type STIsValidContext struct { + ExprContext +} + +func NewSTIsValidContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STIsValidContext { + var p = new(STIsValidContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *STIsValidContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *STIsValidContext) STIsValid() antlr.TerminalNode { + return s.GetToken(PlanParserSTIsValid, 0) +} + +func (s *STIsValidContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *STIsValidContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitSTIsValid(s) + + default: + return t.VisitChildren(s) + } +} + +type BitXorContext struct { + ExprContext +} + +func NewBitXorContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *BitXorContext { + var p = new(BitXorContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *BitXorContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *BitXorContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *BitXorContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *BitXorContext) BXOR() antlr.TerminalNode { + return s.GetToken(PlanParserBXOR, 0) +} + +func (s *BitXorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitBitXor(s) + + default: + return t.VisitChildren(s) + } +} + +type ElementFilterContext struct { + ExprContext +} + +func NewElementFilterContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *ElementFilterContext { + var p = new(ElementFilterContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *ElementFilterContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ElementFilterContext) ElementFilter() antlr.TerminalNode { + return s.GetToken(PlanParserElementFilter, 0) +} + +func (s *ElementFilterContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *ElementFilterContext) Expr() IExprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *ElementFilterContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitElementFilter(s) + + default: + return t.VisitChildren(s) + } +} + +type BitAndContext struct { + ExprContext +} + +func NewBitAndContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *BitAndContext { + var p = new(BitAndContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *BitAndContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *BitAndContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *BitAndContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *BitAndContext) BAND() antlr.TerminalNode { + return s.GetToken(PlanParserBAND, 0) +} + +func (s *BitAndContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitBitAnd(s) + + default: + return t.VisitChildren(s) + } +} + +type STOverlapsContext struct { + ExprContext +} + +func NewSTOverlapsContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STOverlapsContext { + var p = new(STOverlapsContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *STOverlapsContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *STOverlapsContext) STOverlaps() antlr.TerminalNode { + return s.GetToken(PlanParserSTOverlaps, 0) +} + +func (s *STOverlapsContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *STOverlapsContext) StringLiteral() antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, 0) +} + +func (s *STOverlapsContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitSTOverlaps(s) + + default: + return t.VisitChildren(s) + } +} + +type JSONIdentifierContext struct { + ExprContext +} + +func NewJSONIdentifierContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *JSONIdentifierContext { + var p = new(JSONIdentifierContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *JSONIdentifierContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *JSONIdentifierContext) JSONIdentifier() antlr.TerminalNode { + return s.GetToken(PlanParserJSONIdentifier, 0) +} + +func (s *JSONIdentifierContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitJSONIdentifier(s) + + default: + return t.VisitChildren(s) + } +} + +type RandomSampleContext struct { + ExprContext +} + +func NewRandomSampleContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *RandomSampleContext { + var p = new(RandomSampleContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *RandomSampleContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *RandomSampleContext) RANDOMSAMPLE() antlr.TerminalNode { + return s.GetToken(PlanParserRANDOMSAMPLE, 0) +} + +func (s *RandomSampleContext) Expr() IExprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *RandomSampleContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitRandomSample(s) + + default: + return t.VisitChildren(s) + } +} + +type ParensContext struct { + ExprContext +} + +func NewParensContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *ParensContext { + var p = new(ParensContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *ParensContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *ParensContext) Expr() IExprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *ParensContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitParens(s) + + default: + return t.VisitChildren(s) + } +} + +type JSONContainsAllContext struct { + ExprContext +} + +func NewJSONContainsAllContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *JSONContainsAllContext { + var p = new(JSONContainsAllContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *JSONContainsAllContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *JSONContainsAllContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *JSONContainsAllContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *JSONContainsAllContext) JSONContainsAll() antlr.TerminalNode { + return s.GetToken(PlanParserJSONContainsAll, 0) +} + +func (s *JSONContainsAllContext) ArrayContainsAll() antlr.TerminalNode { + return s.GetToken(PlanParserArrayContainsAll, 0) +} + +func (s *JSONContainsAllContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitJSONContainsAll(s) + + default: + return t.VisitChildren(s) + } +} + +type LogicalOrContext struct { + ExprContext +} + +func NewLogicalOrContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *LogicalOrContext { + var p = new(LogicalOrContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *LogicalOrContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *LogicalOrContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *LogicalOrContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *LogicalOrContext) OR() antlr.TerminalNode { + return s.GetToken(PlanParserOR, 0) +} + +func (s *LogicalOrContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitLogicalOr(s) + + default: + return t.VisitChildren(s) + } +} + +type MulDivModContext struct { + ExprContext + op antlr.Token +} + +func NewMulDivModContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *MulDivModContext { + var p = new(MulDivModContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *MulDivModContext) GetOp() antlr.Token { return s.op } + +func (s *MulDivModContext) SetOp(v antlr.Token) { s.op = v } + +func (s *MulDivModContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *MulDivModContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *MulDivModContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *MulDivModContext) MUL() antlr.TerminalNode { + return s.GetToken(PlanParserMUL, 0) +} + +func (s *MulDivModContext) DIV() antlr.TerminalNode { + return s.GetToken(PlanParserDIV, 0) +} + +func (s *MulDivModContext) MOD() antlr.TerminalNode { + return s.GetToken(PlanParserMOD, 0) +} + +func (s *MulDivModContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitMulDivMod(s) + + default: + return t.VisitChildren(s) + } +} + +type LogicalAndContext struct { + ExprContext +} + +func NewLogicalAndContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *LogicalAndContext { + var p = new(LogicalAndContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *LogicalAndContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *LogicalAndContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *LogicalAndContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *LogicalAndContext) AND() antlr.TerminalNode { + return s.GetToken(PlanParserAND, 0) +} + +func (s *LogicalAndContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitLogicalAnd(s) + + default: + return t.VisitChildren(s) + } +} + +type TemplateVariableContext struct { + ExprContext +} + +func NewTemplateVariableContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *TemplateVariableContext { + var p = new(TemplateVariableContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *TemplateVariableContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *TemplateVariableContext) LBRACE() antlr.TerminalNode { + return s.GetToken(PlanParserLBRACE, 0) +} + +func (s *TemplateVariableContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *TemplateVariableContext) RBRACE() antlr.TerminalNode { + return s.GetToken(PlanParserRBRACE, 0) +} + +func (s *TemplateVariableContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitTemplateVariable(s) + + default: + return t.VisitChildren(s) + } +} + +type TimestamptzCompareReverseContext struct { + ExprContext + compare_string antlr.Token + op2 antlr.Token + op1 antlr.Token + interval_string antlr.Token +} + +func NewTimestamptzCompareReverseContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *TimestamptzCompareReverseContext { + var p = new(TimestamptzCompareReverseContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *TimestamptzCompareReverseContext) GetCompare_string() antlr.Token { return s.compare_string } + +func (s *TimestamptzCompareReverseContext) GetOp2() antlr.Token { return s.op2 } + +func (s *TimestamptzCompareReverseContext) GetOp1() antlr.Token { return s.op1 } + +func (s *TimestamptzCompareReverseContext) GetInterval_string() antlr.Token { return s.interval_string } + +func (s *TimestamptzCompareReverseContext) SetCompare_string(v antlr.Token) { s.compare_string = v } + +func (s *TimestamptzCompareReverseContext) SetOp2(v antlr.Token) { s.op2 = v } + +func (s *TimestamptzCompareReverseContext) SetOp1(v antlr.Token) { s.op1 = v } + +func (s *TimestamptzCompareReverseContext) SetInterval_string(v antlr.Token) { s.interval_string = v } + +func (s *TimestamptzCompareReverseContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *TimestamptzCompareReverseContext) ISO() antlr.TerminalNode { + return s.GetToken(PlanParserISO, 0) +} + +func (s *TimestamptzCompareReverseContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *TimestamptzCompareReverseContext) AllStringLiteral() []antlr.TerminalNode { + return s.GetTokens(PlanParserStringLiteral) +} + +func (s *TimestamptzCompareReverseContext) StringLiteral(i int) antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, i) +} + +func (s *TimestamptzCompareReverseContext) LT() antlr.TerminalNode { + return s.GetToken(PlanParserLT, 0) +} + +func (s *TimestamptzCompareReverseContext) LE() antlr.TerminalNode { + return s.GetToken(PlanParserLE, 0) +} + +func (s *TimestamptzCompareReverseContext) GT() antlr.TerminalNode { + return s.GetToken(PlanParserGT, 0) +} + +func (s *TimestamptzCompareReverseContext) GE() antlr.TerminalNode { + return s.GetToken(PlanParserGE, 0) +} + +func (s *TimestamptzCompareReverseContext) EQ() antlr.TerminalNode { + return s.GetToken(PlanParserEQ, 0) +} + +func (s *TimestamptzCompareReverseContext) NE() antlr.TerminalNode { + return s.GetToken(PlanParserNE, 0) +} + +func (s *TimestamptzCompareReverseContext) INTERVAL() antlr.TerminalNode { + return s.GetToken(PlanParserINTERVAL, 0) +} + +func (s *TimestamptzCompareReverseContext) ADD() antlr.TerminalNode { + return s.GetToken(PlanParserADD, 0) +} + +func (s *TimestamptzCompareReverseContext) SUB() antlr.TerminalNode { + return s.GetToken(PlanParserSUB, 0) +} + +func (s *TimestamptzCompareReverseContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitTimestamptzCompareReverse(s) + + default: + return t.VisitChildren(s) + } +} + +type STDWithinContext struct { + ExprContext +} + +func NewSTDWithinContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STDWithinContext { + var p = new(STDWithinContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *STDWithinContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *STDWithinContext) STDWithin() antlr.TerminalNode { + return s.GetToken(PlanParserSTDWithin, 0) +} + +func (s *STDWithinContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *STDWithinContext) StringLiteral() antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, 0) +} + +func (s *STDWithinContext) Expr() IExprContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *STDWithinContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitSTDWithin(s) + + default: + return t.VisitChildren(s) + } +} + +type CallContext struct { + ExprContext +} + +func NewCallContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *CallContext { + var p = new(CallContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *CallContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *CallContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *CallContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *CallContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *CallContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitCall(s) + + default: + return t.VisitChildren(s) + } +} + +type STCrossesContext struct { + ExprContext +} + +func NewSTCrossesContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STCrossesContext { + var p = new(STCrossesContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *STCrossesContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *STCrossesContext) STCrosses() antlr.TerminalNode { + return s.GetToken(PlanParserSTCrosses, 0) +} + +func (s *STCrossesContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *STCrossesContext) StringLiteral() antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, 0) +} + +func (s *STCrossesContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitSTCrosses(s) + + default: + return t.VisitChildren(s) + } +} + +type BitOrContext struct { + ExprContext +} + +func NewBitOrContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *BitOrContext { + var p = new(BitOrContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *BitOrContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *BitOrContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *BitOrContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *BitOrContext) BOR() antlr.TerminalNode { + return s.GetToken(PlanParserBOR, 0) +} + +func (s *BitOrContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitBitOr(s) + + default: + return t.VisitChildren(s) + } +} + +type AddSubContext struct { + ExprContext + op antlr.Token +} + +func NewAddSubContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *AddSubContext { + var p = new(AddSubContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *AddSubContext) GetOp() antlr.Token { return s.op } + +func (s *AddSubContext) SetOp(v antlr.Token) { s.op = v } + +func (s *AddSubContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *AddSubContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *AddSubContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *AddSubContext) ADD() antlr.TerminalNode { + return s.GetToken(PlanParserADD, 0) +} + +func (s *AddSubContext) SUB() antlr.TerminalNode { + return s.GetToken(PlanParserSUB, 0) +} + +func (s *AddSubContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitAddSub(s) + + default: + return t.VisitChildren(s) + } +} + +type RelationalContext struct { + ExprContext + op antlr.Token +} + +func NewRelationalContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *RelationalContext { + var p = new(RelationalContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *RelationalContext) GetOp() antlr.Token { return s.op } + +func (s *RelationalContext) SetOp(v antlr.Token) { s.op = v } + +func (s *RelationalContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *RelationalContext) AllExpr() []IExprContext { + children := s.GetChildren() + len := 0 + for _, ctx := range children { + if _, ok := ctx.(IExprContext); ok { + len++ + } + } + + tst := make([]IExprContext, len) + i := 0 + for _, ctx := range children { + if t, ok := ctx.(IExprContext); ok { + tst[i] = t.(IExprContext) + i++ + } + } + + return tst +} + +func (s *RelationalContext) Expr(i int) IExprContext { + var t antlr.RuleContext + j := 0 + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(IExprContext); ok { + if j == i { + t = ctx.(antlr.RuleContext) + break + } + j++ + } + } + + if t == nil { + return nil + } + + return t.(IExprContext) +} + +func (s *RelationalContext) LT() antlr.TerminalNode { + return s.GetToken(PlanParserLT, 0) +} + +func (s *RelationalContext) LE() antlr.TerminalNode { + return s.GetToken(PlanParserLE, 0) +} + +func (s *RelationalContext) GT() antlr.TerminalNode { + return s.GetToken(PlanParserGT, 0) +} + +func (s *RelationalContext) GE() antlr.TerminalNode { + return s.GetToken(PlanParserGE, 0) +} + +func (s *RelationalContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitRelational(s) + + default: + return t.VisitChildren(s) + } +} + +type TextMatchContext struct { + ExprContext +} + +func NewTextMatchContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *TextMatchContext { + var p = new(TextMatchContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *TextMatchContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *TextMatchContext) TEXTMATCH() antlr.TerminalNode { + return s.GetToken(PlanParserTEXTMATCH, 0) +} + +func (s *TextMatchContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *TextMatchContext) StringLiteral() antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, 0) +} + +func (s *TextMatchContext) TextMatchOption() ITextMatchOptionContext { + var t antlr.RuleContext + for _, ctx := range s.GetChildren() { + if _, ok := ctx.(ITextMatchOptionContext); ok { + t = ctx.(antlr.RuleContext) + break + } + } + + if t == nil { + return nil + } + + return t.(ITextMatchOptionContext) +} + +func (s *TextMatchContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitTextMatch(s) + + default: + return t.VisitChildren(s) + } +} + +type STContainsContext struct { + ExprContext +} + +func NewSTContainsContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STContainsContext { + var p = new(STContainsContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *STContainsContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *STContainsContext) STContains() antlr.TerminalNode { + return s.GetToken(PlanParserSTContains, 0) +} + +func (s *STContainsContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *STContainsContext) StringLiteral() antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, 0) +} + +func (s *STContainsContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitSTContains(s) + + default: + return t.VisitChildren(s) + } +} + type UnaryContext struct { ExprContext op antlr.Token @@ -2764,115 +3053,6 @@ func (s *JSONContainsAnyContext) Accept(visitor antlr.ParseTreeVisitor) interfac } } -type STIsValidContext struct { - ExprContext -} - -func NewSTIsValidContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STIsValidContext { - var p = new(STIsValidContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *STIsValidContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *STIsValidContext) STIsValid() antlr.TerminalNode { - return s.GetToken(PlanParserSTIsValid, 0) -} - -func (s *STIsValidContext) Identifier() antlr.TerminalNode { - return s.GetToken(PlanParserIdentifier, 0) -} - -func (s *STIsValidContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitSTIsValid(s) - - default: - return t.VisitChildren(s) - } -} - -type BitXorContext struct { - ExprContext -} - -func NewBitXorContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *BitXorContext { - var p = new(BitXorContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *BitXorContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *BitXorContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *BitXorContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *BitXorContext) BXOR() antlr.TerminalNode { - return s.GetToken(PlanParserBXOR, 0) -} - -func (s *BitXorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitBitXor(s) - - default: - return t.VisitChildren(s) - } -} - type ExistsContext struct { ExprContext } @@ -2921,79 +3101,6 @@ func (s *ExistsContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } -type BitAndContext struct { - ExprContext -} - -func NewBitAndContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *BitAndContext { - var p = new(BitAndContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *BitAndContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *BitAndContext) AllExpr() []IExprContext { - children := s.GetChildren() - len := 0 - for _, ctx := range children { - if _, ok := ctx.(IExprContext); ok { - len++ - } - } - - tst := make([]IExprContext, len) - i := 0 - for _, ctx := range children { - if t, ok := ctx.(IExprContext); ok { - tst[i] = t.(IExprContext) - i++ - } - } - - return tst -} - -func (s *BitAndContext) Expr(i int) IExprContext { - var t antlr.RuleContext - j := 0 - for _, ctx := range s.GetChildren() { - if _, ok := ctx.(IExprContext); ok { - if j == i { - t = ctx.(antlr.RuleContext) - break - } - j++ - } - } - - if t == nil { - return nil - } - - return t.(IExprContext) -} - -func (s *BitAndContext) BAND() antlr.TerminalNode { - return s.GetToken(PlanParserBAND, 0) -} - -func (s *BitAndContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitBitAnd(s) - - default: - return t.VisitChildren(s) - } -} - type STEuqalsContext struct { ExprContext } @@ -3074,6 +3181,38 @@ func (s *IsNullContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } +type StructSubFieldContext struct { + ExprContext +} + +func NewStructSubFieldContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *StructSubFieldContext { + var p = new(StructSubFieldContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *StructSubFieldContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *StructSubFieldContext) StructSubFieldIdentifier() antlr.TerminalNode { + return s.GetToken(PlanParserStructSubFieldIdentifier, 0) +} + +func (s *StructSubFieldContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitStructSubField(s) + + default: + return t.VisitChildren(s) + } +} + type PowerContext struct { ExprContext } @@ -3147,46 +3286,6 @@ func (s *PowerContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } -type STOverlapsContext struct { - ExprContext -} - -func NewSTOverlapsContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STOverlapsContext { - var p = new(STOverlapsContext) - - InitEmptyExprContext(&p.ExprContext) - p.parser = parser - p.CopyAll(ctx.(*ExprContext)) - - return p -} - -func (s *STOverlapsContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *STOverlapsContext) STOverlaps() antlr.TerminalNode { - return s.GetToken(PlanParserSTOverlaps, 0) -} - -func (s *STOverlapsContext) Identifier() antlr.TerminalNode { - return s.GetToken(PlanParserIdentifier, 0) -} - -func (s *STOverlapsContext) StringLiteral() antlr.TerminalNode { - return s.GetToken(PlanParserStringLiteral, 0) -} - -func (s *STOverlapsContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { - switch t := visitor.(type) { - case PlanVisitor: - return t.VisitSTOverlaps(s) - - default: - return t.VisitChildren(s) - } -} - func (p *PlanParser) Expr() (localctx IExprContext) { return p.expr(0) } @@ -3205,7 +3304,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { var _alt int p.EnterOuterAlt(localctx, 1) - p.SetState(180) + p.SetState(188) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3487,28 +3586,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 9: - localctx = NewTemplateVariableContext(p, localctx) + localctx = NewStructSubFieldContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { p.SetState(29) - p.Match(PlanParserLBRACE) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(30) - p.Match(PlanParserIdentifier) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(31) - p.Match(PlanParserRBRACE) + p.Match(PlanParserStructSubFieldIdentifier) if p.HasError() { // Recognition error - abort rule goto errorExit @@ -3516,24 +3599,28 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 10: - localctx = NewParensContext(p, localctx) + localctx = NewTemplateVariableContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(32) - p.Match(PlanParserT__0) + p.SetState(30) + p.Match(PlanParserLBRACE) if p.HasError() { // Recognition error - abort rule goto errorExit } } { - p.SetState(33) - p.expr(0) + p.SetState(31) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { - p.SetState(34) - p.Match(PlanParserT__1) + p.SetState(32) + p.Match(PlanParserRBRACE) if p.HasError() { // Recognition error - abort rule goto errorExit @@ -3541,11 +3628,36 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 11: + localctx = NewParensContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(33) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(34) + p.expr(0) + } + { + p.SetState(35) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 12: localctx = NewArrayContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(36) + p.SetState(37) p.Match(PlanParserT__2) if p.HasError() { // Recognition error - abort rule @@ -3553,10 +3665,10 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(37) + p.SetState(38) p.expr(0) } - p.SetState(42) + p.SetState(43) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3568,7 +3680,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { { - p.SetState(38) + p.SetState(39) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -3576,12 +3688,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(39) + p.SetState(40) p.expr(0) } } - p.SetState(44) + p.SetState(45) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3591,7 +3703,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { goto errorExit } } - p.SetState(46) + p.SetState(47) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3600,7 +3712,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { if _la == PlanParserT__3 { { - p.SetState(45) + p.SetState(46) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -3610,7 +3722,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { - p.SetState(48) + p.SetState(49) p.Match(PlanParserT__4) if p.HasError() { // Recognition error - abort rule @@ -3618,12 +3730,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 12: + case 13: localctx = NewEmptyArrayContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(50) + p.SetState(51) p.Match(PlanParserEmptyArray) if p.HasError() { // Recognition error - abort rule @@ -3631,12 +3743,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 13: + case 14: localctx = NewExistsContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(51) + p.SetState(52) p.Match(PlanParserEXISTS) if p.HasError() { // Recognition error - abort rule @@ -3644,33 +3756,25 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(52) - p.expr(36) + p.SetState(53) + p.expr(37) } - case 14: + case 15: localctx = NewTextMatchContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(53) + p.SetState(54) p.Match(PlanParserTEXTMATCH) if p.HasError() { // Recognition error - abort rule goto errorExit } } - { - p.SetState(54) - p.Match(PlanParserT__0) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } { p.SetState(55) - p.Match(PlanParserIdentifier) + p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule goto errorExit @@ -3678,73 +3782,6 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { p.SetState(56) - p.Match(PlanParserT__3) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(57) - p.Match(PlanParserStringLiteral) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - p.SetState(60) - p.GetErrorHandler().Sync(p) - if p.HasError() { - goto errorExit - } - _la = p.GetTokenStream().LA(1) - - if _la == PlanParserT__3 { - { - p.SetState(58) - p.Match(PlanParserT__3) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(59) - p.TextMatchOption() - } - - } - { - p.SetState(62) - p.Match(PlanParserT__1) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 15: - localctx = NewPhraseMatchContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(63) - p.Match(PlanParserPHRASEMATCH) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(64) - p.Match(PlanParserT__0) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(65) p.Match(PlanParserIdentifier) if p.HasError() { // Recognition error - abort rule @@ -3752,7 +3789,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(66) + p.SetState(57) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -3760,14 +3797,14 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(67) + p.SetState(58) p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule goto errorExit } } - p.SetState(70) + p.SetState(61) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3776,7 +3813,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { if _la == PlanParserT__3 { { - p.SetState(68) + p.SetState(59) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -3784,13 +3821,13 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(69) - p.expr(0) + p.SetState(60) + p.TextMatchOption() } } { - p.SetState(72) + p.SetState(63) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -3799,19 +3836,19 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 16: - localctx = NewRandomSampleContext(p, localctx) + localctx = NewPhraseMatchContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(73) - p.Match(PlanParserRANDOMSAMPLE) + p.SetState(64) + p.Match(PlanParserPHRASEMATCH) if p.HasError() { // Recognition error - abort rule goto errorExit } } { - p.SetState(74) + p.SetState(65) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule @@ -3819,11 +3856,53 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(75) - p.expr(0) + p.SetState(66) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { - p.SetState(76) + p.SetState(67) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(68) + p.Match(PlanParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(71) + p.GetErrorHandler().Sync(p) + if p.HasError() { + goto errorExit + } + _la = p.GetTokenStream().LA(1) + + if _la == PlanParserT__3 { + { + p.SetState(69) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(70) + p.expr(0) + } + + } + { + p.SetState(73) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -3832,11 +3911,93 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 17: + localctx = NewRandomSampleContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(74) + p.Match(PlanParserRANDOMSAMPLE) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(75) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(76) + p.expr(0) + } + { + p.SetState(77) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 18: + localctx = NewElementFilterContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(79) + p.Match(PlanParserElementFilter) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(80) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(81) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(82) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(83) + p.expr(0) + } + { + p.SetState(84) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 19: localctx = NewUnaryContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(78) + p.SetState(86) var _lt = p.GetTokenStream().LT(1) @@ -3854,16 +4015,16 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(79) + p.SetState(87) p.expr(30) } - case 18: + case 20: localctx = NewJSONContainsContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(80) + p.SetState(88) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserJSONContains || _la == PlanParserArrayContains) { @@ -3874,7 +4035,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(81) + p.SetState(89) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule @@ -3882,11 +4043,11 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(82) + p.SetState(90) p.expr(0) } { - p.SetState(83) + p.SetState(91) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -3894,11 +4055,11 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(84) + p.SetState(92) p.expr(0) } { - p.SetState(85) + p.SetState(93) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -3906,12 +4067,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 19: + case 21: localctx = NewJSONContainsAllContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(87) + p.SetState(95) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserJSONContainsAll || _la == PlanParserArrayContainsAll) { @@ -3922,7 +4083,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(88) + p.SetState(96) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule @@ -3930,11 +4091,11 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(89) + p.SetState(97) p.expr(0) } { - p.SetState(90) + p.SetState(98) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -3942,11 +4103,11 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(91) + p.SetState(99) p.expr(0) } { - p.SetState(92) + p.SetState(100) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -3954,12 +4115,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 20: + case 22: localctx = NewJSONContainsAnyContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(94) + p.SetState(102) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserJSONContainsAny || _la == PlanParserArrayContainsAny) { @@ -3969,62 +4130,9 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { p.Consume() } } - { - p.SetState(95) - p.Match(PlanParserT__0) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(96) - p.expr(0) - } - { - p.SetState(97) - p.Match(PlanParserT__3) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(98) - p.expr(0) - } - { - p.SetState(99) - p.Match(PlanParserT__1) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - - case 21: - localctx = NewSTEuqalsContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx - { - p.SetState(101) - p.Match(PlanParserSTEuqals) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(102) - p.Match(PlanParserT__0) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } { p.SetState(103) - p.Match(PlanParserIdentifier) + p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule goto errorExit @@ -4032,15 +4140,11 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { p.SetState(104) - p.Match(PlanParserT__3) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } + p.expr(0) } { p.SetState(105) - p.Match(PlanParserStringLiteral) + p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule goto errorExit @@ -4048,59 +4152,10 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { p.SetState(106) - p.Match(PlanParserT__1) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } + p.expr(0) } - - case 22: - localctx = NewSTTouchesContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx { p.SetState(107) - p.Match(PlanParserSTTouches) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(108) - p.Match(PlanParserT__0) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(109) - p.Match(PlanParserIdentifier) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(110) - p.Match(PlanParserT__3) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(111) - p.Match(PlanParserStringLiteral) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(112) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -4109,19 +4164,19 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 23: - localctx = NewSTOverlapsContext(p, localctx) + localctx = NewSTEuqalsContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(113) - p.Match(PlanParserSTOverlaps) + p.SetState(109) + p.Match(PlanParserSTEuqals) if p.HasError() { // Recognition error - abort rule goto errorExit } } { - p.SetState(114) + p.SetState(110) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule @@ -4129,7 +4184,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(115) + p.SetState(111) p.Match(PlanParserIdentifier) if p.HasError() { // Recognition error - abort rule @@ -4137,7 +4192,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(116) + p.SetState(112) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -4145,7 +4200,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(117) + p.SetState(113) p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule @@ -4153,7 +4208,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(118) + p.SetState(114) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -4162,19 +4217,19 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 24: - localctx = NewSTCrossesContext(p, localctx) + localctx = NewSTTouchesContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(119) - p.Match(PlanParserSTCrosses) + p.SetState(115) + p.Match(PlanParserSTTouches) if p.HasError() { // Recognition error - abort rule goto errorExit } } { - p.SetState(120) + p.SetState(116) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule @@ -4182,7 +4237,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(121) + p.SetState(117) p.Match(PlanParserIdentifier) if p.HasError() { // Recognition error - abort rule @@ -4190,7 +4245,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(122) + p.SetState(118) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -4198,7 +4253,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(123) + p.SetState(119) p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule @@ -4206,7 +4261,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(124) + p.SetState(120) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -4215,19 +4270,19 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 25: - localctx = NewSTContainsContext(p, localctx) + localctx = NewSTOverlapsContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(125) - p.Match(PlanParserSTContains) + p.SetState(121) + p.Match(PlanParserSTOverlaps) if p.HasError() { // Recognition error - abort rule goto errorExit } } { - p.SetState(126) + p.SetState(122) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule @@ -4235,7 +4290,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(127) + p.SetState(123) p.Match(PlanParserIdentifier) if p.HasError() { // Recognition error - abort rule @@ -4243,7 +4298,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(128) + p.SetState(124) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -4251,7 +4306,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(129) + p.SetState(125) p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule @@ -4259,7 +4314,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(130) + p.SetState(126) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -4268,19 +4323,19 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 26: - localctx = NewSTIntersectsContext(p, localctx) + localctx = NewSTCrossesContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(131) - p.Match(PlanParserSTIntersects) + p.SetState(127) + p.Match(PlanParserSTCrosses) if p.HasError() { // Recognition error - abort rule goto errorExit } } { - p.SetState(132) + p.SetState(128) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule @@ -4288,7 +4343,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(133) + p.SetState(129) p.Match(PlanParserIdentifier) if p.HasError() { // Recognition error - abort rule @@ -4296,7 +4351,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(134) + p.SetState(130) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -4304,7 +4359,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(135) + p.SetState(131) p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule @@ -4312,7 +4367,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(136) + p.SetState(132) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -4321,19 +4376,19 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 27: - localctx = NewSTWithinContext(p, localctx) + localctx = NewSTContainsContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(137) - p.Match(PlanParserSTWithin) + p.SetState(133) + p.Match(PlanParserSTContains) if p.HasError() { // Recognition error - abort rule goto errorExit } } { - p.SetState(138) + p.SetState(134) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule @@ -4341,7 +4396,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(139) + p.SetState(135) p.Match(PlanParserIdentifier) if p.HasError() { // Recognition error - abort rule @@ -4349,7 +4404,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(140) + p.SetState(136) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -4357,7 +4412,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(141) + p.SetState(137) p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule @@ -4365,7 +4420,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(142) + p.SetState(138) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -4374,19 +4429,19 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 28: - localctx = NewSTDWithinContext(p, localctx) + localctx = NewSTIntersectsContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(143) - p.Match(PlanParserSTDWithin) + p.SetState(139) + p.Match(PlanParserSTIntersects) if p.HasError() { // Recognition error - abort rule goto errorExit } } { - p.SetState(144) + p.SetState(140) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule @@ -4394,7 +4449,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(145) + p.SetState(141) p.Match(PlanParserIdentifier) if p.HasError() { // Recognition error - abort rule @@ -4402,7 +4457,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(146) + p.SetState(142) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -4410,13 +4465,50 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(147) + p.SetState(143) p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule goto errorExit } } + { + p.SetState(144) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 29: + localctx = NewSTWithinContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(145) + p.Match(PlanParserSTWithin) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(146) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(147) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } { p.SetState(148) p.Match(PlanParserT__3) @@ -4427,7 +4519,11 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { p.SetState(149) - p.expr(0) + p.Match(PlanParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } } { p.SetState(150) @@ -4438,13 +4534,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 29: - localctx = NewSTIsValidContext(p, localctx) + case 30: + localctx = NewSTDWithinContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx + { + p.SetState(151) + p.Match(PlanParserSTDWithin) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } { p.SetState(152) - p.Match(PlanParserSTIsValid) + p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule goto errorExit @@ -4452,14 +4556,6 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { p.SetState(153) - p.Match(PlanParserT__0) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } - } - { - p.SetState(154) p.Match(PlanParserIdentifier) if p.HasError() { // Recognition error - abort rule @@ -4467,21 +4563,24 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(155) - p.Match(PlanParserT__1) + p.SetState(154) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(155) + p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule goto errorExit } } - - case 30: - localctx = NewArrayLengthContext(p, localctx) - p.SetParserRuleContext(localctx) - _prevctx = localctx { p.SetState(156) - p.Match(PlanParserArrayLength) + p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule goto errorExit @@ -4489,25 +4588,10 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { p.SetState(157) - p.Match(PlanParserT__0) - if p.HasError() { - // Recognition error - abort rule - goto errorExit - } + p.expr(0) } { p.SetState(158) - _la = p.GetTokenStream().LA(1) - - if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { - p.GetErrorHandler().RecoverInline(p) - } else { - p.GetErrorHandler().ReportMatch(p) - p.Consume() - } - } - { - p.SetState(159) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -4516,12 +4600,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 31: - localctx = NewCallContext(p, localctx) + localctx = NewSTIsValidContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { p.SetState(160) - p.Match(PlanParserIdentifier) + p.Match(PlanParserSTIsValid) if p.HasError() { // Recognition error - abort rule goto errorExit @@ -4535,19 +4619,96 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { goto errorExit } } - p.SetState(173) + { + p.SetState(162) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(163) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 32: + localctx = NewArrayLengthContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(164) + p.Match(PlanParserArrayLength) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(165) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(166) + _la = p.GetTokenStream().LA(1) + + if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { + p.GetErrorHandler().RecoverInline(p) + } else { + p.GetErrorHandler().ReportMatch(p) + p.Consume() + } + } + { + p.SetState(167) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 33: + localctx = NewCallContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(168) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(169) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + p.SetState(181) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit } _la = p.GetTokenStream().LA(1) - if (int64((_la-1)) & ^0x3f) == 0 && ((int64(1)<<(_la-1))&-687181414363) != 0 { + if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&-1374362828726) != 0) || ((int64((_la-64)) & ^0x3f) == 0 && ((int64(1)<<(_la-64))&7) != 0) { { - p.SetState(162) + p.SetState(170) p.expr(0) } - p.SetState(167) + p.SetState(175) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -4559,7 +4720,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { { - p.SetState(163) + p.SetState(171) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -4567,12 +4728,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(164) + p.SetState(172) p.expr(0) } } - p.SetState(169) + p.SetState(177) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -4582,7 +4743,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { goto errorExit } } - p.SetState(171) + p.SetState(179) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -4591,7 +4752,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { if _la == PlanParserT__3 { { - p.SetState(170) + p.SetState(178) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -4603,7 +4764,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { - p.SetState(175) + p.SetState(183) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -4611,12 +4772,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 32: + case 34: localctx = NewIsNullContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(176) + p.SetState(184) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { @@ -4627,7 +4788,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(177) + p.SetState(185) p.Match(PlanParserISNULL) if p.HasError() { // Recognition error - abort rule @@ -4635,12 +4796,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 33: + case 35: localctx = NewIsNotNullContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(178) + p.SetState(186) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { @@ -4651,7 +4812,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(179) + p.SetState(187) p.Match(PlanParserISNOTNULL) if p.HasError() { // Recognition error - abort rule @@ -4663,7 +4824,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { goto errorExit } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(236) + p.SetState(244) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -4678,7 +4839,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { p.TriggerExitRuleEvent() } _prevctx = localctx - p.SetState(234) + p.SetState(242) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -4688,14 +4849,14 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { case 1: localctx = NewPowerContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(182) + p.SetState(190) if !(p.Precpred(p.GetParserRuleContext(), 31)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 31)", "")) goto errorExit } { - p.SetState(183) + p.SetState(191) p.Match(PlanParserPOW) if p.HasError() { // Recognition error - abort rule @@ -4703,21 +4864,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(184) + p.SetState(192) p.expr(32) } case 2: localctx = NewMulDivModContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(185) + p.SetState(193) if !(p.Precpred(p.GetParserRuleContext(), 29)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 29)", "")) goto errorExit } { - p.SetState(186) + p.SetState(194) var _lt = p.GetTokenStream().LT(1) @@ -4735,21 +4896,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(187) + p.SetState(195) p.expr(30) } case 3: localctx = NewAddSubContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(188) + p.SetState(196) if !(p.Precpred(p.GetParserRuleContext(), 28)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 28)", "")) goto errorExit } { - p.SetState(189) + p.SetState(197) var _lt = p.GetTokenStream().LT(1) @@ -4767,21 +4928,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(190) + p.SetState(198) p.expr(29) } case 4: localctx = NewShiftContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(191) + p.SetState(199) if !(p.Precpred(p.GetParserRuleContext(), 27)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 27)", "")) goto errorExit } { - p.SetState(192) + p.SetState(200) var _lt = p.GetTokenStream().LT(1) @@ -4799,20 +4960,20 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(193) + p.SetState(201) p.expr(28) } case 5: localctx = NewTermContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(194) + p.SetState(202) if !(p.Precpred(p.GetParserRuleContext(), 26)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 26)", "")) goto errorExit } - p.SetState(196) + p.SetState(204) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -4821,7 +4982,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { if _la == PlanParserNOT { { - p.SetState(195) + p.SetState(203) var _m = p.Match(PlanParserNOT) @@ -4834,7 +4995,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { - p.SetState(198) + p.SetState(206) p.Match(PlanParserIN) if p.HasError() { // Recognition error - abort rule @@ -4842,21 +5003,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(199) + p.SetState(207) p.expr(27) } case 6: localctx = NewRangeContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(200) + p.SetState(208) if !(p.Precpred(p.GetParserRuleContext(), 11)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 11)", "")) goto errorExit } { - p.SetState(201) + p.SetState(209) var _lt = p.GetTokenStream().LT(1) @@ -4874,10 +5035,10 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(202) + p.SetState(210) _la = p.GetTokenStream().LA(1) - if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { + if !((int64((_la-62)) & ^0x3f) == 0 && ((int64(1)<<(_la-62))&25) != 0) { p.GetErrorHandler().RecoverInline(p) } else { p.GetErrorHandler().ReportMatch(p) @@ -4885,7 +5046,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(203) + p.SetState(211) var _lt = p.GetTokenStream().LT(1) @@ -4903,21 +5064,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(204) + p.SetState(212) p.expr(12) } case 7: localctx = NewReverseRangeContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(205) + p.SetState(213) if !(p.Precpred(p.GetParserRuleContext(), 10)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 10)", "")) goto errorExit } { - p.SetState(206) + p.SetState(214) var _lt = p.GetTokenStream().LT(1) @@ -4935,10 +5096,10 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(207) + p.SetState(215) _la = p.GetTokenStream().LA(1) - if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { + if !((int64((_la-62)) & ^0x3f) == 0 && ((int64(1)<<(_la-62))&25) != 0) { p.GetErrorHandler().RecoverInline(p) } else { p.GetErrorHandler().ReportMatch(p) @@ -4946,7 +5107,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(208) + p.SetState(216) var _lt = p.GetTokenStream().LT(1) @@ -4964,21 +5125,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(209) + p.SetState(217) p.expr(11) } case 8: localctx = NewRelationalContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(210) + p.SetState(218) if !(p.Precpred(p.GetParserRuleContext(), 9)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 9)", "")) goto errorExit } { - p.SetState(211) + p.SetState(219) var _lt = p.GetTokenStream().LT(1) @@ -4996,21 +5157,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(212) + p.SetState(220) p.expr(10) } case 9: localctx = NewEqualityContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(213) + p.SetState(221) if !(p.Precpred(p.GetParserRuleContext(), 8)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 8)", "")) goto errorExit } { - p.SetState(214) + p.SetState(222) var _lt = p.GetTokenStream().LT(1) @@ -5028,21 +5189,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(215) + p.SetState(223) p.expr(9) } case 10: localctx = NewBitAndContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(216) + p.SetState(224) if !(p.Precpred(p.GetParserRuleContext(), 7)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 7)", "")) goto errorExit } { - p.SetState(217) + p.SetState(225) p.Match(PlanParserBAND) if p.HasError() { // Recognition error - abort rule @@ -5050,21 +5211,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(218) + p.SetState(226) p.expr(8) } case 11: localctx = NewBitXorContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(219) + p.SetState(227) if !(p.Precpred(p.GetParserRuleContext(), 6)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 6)", "")) goto errorExit } { - p.SetState(220) + p.SetState(228) p.Match(PlanParserBXOR) if p.HasError() { // Recognition error - abort rule @@ -5072,21 +5233,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(221) + p.SetState(229) p.expr(7) } case 12: localctx = NewBitOrContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(222) + p.SetState(230) if !(p.Precpred(p.GetParserRuleContext(), 5)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", "")) goto errorExit } { - p.SetState(223) + p.SetState(231) p.Match(PlanParserBOR) if p.HasError() { // Recognition error - abort rule @@ -5094,21 +5255,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(224) + p.SetState(232) p.expr(6) } case 13: localctx = NewLogicalAndContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(225) + p.SetState(233) if !(p.Precpred(p.GetParserRuleContext(), 4)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) goto errorExit } { - p.SetState(226) + p.SetState(234) p.Match(PlanParserAND) if p.HasError() { // Recognition error - abort rule @@ -5116,21 +5277,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(227) + p.SetState(235) p.expr(5) } case 14: localctx = NewLogicalOrContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(228) + p.SetState(236) if !(p.Precpred(p.GetParserRuleContext(), 3)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) goto errorExit } { - p.SetState(229) + p.SetState(237) p.Match(PlanParserOR) if p.HasError() { // Recognition error - abort rule @@ -5138,21 +5299,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(230) + p.SetState(238) p.expr(4) } case 15: localctx = NewLikeContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(231) + p.SetState(239) - if !(p.Precpred(p.GetParserRuleContext(), 35)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 35)", "")) + if !(p.Precpred(p.GetParserRuleContext(), 36)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 36)", "")) goto errorExit } { - p.SetState(232) + p.SetState(240) p.Match(PlanParserLIKE) if p.HasError() { // Recognition error - abort rule @@ -5160,7 +5321,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(233) + p.SetState(241) p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule @@ -5173,7 +5334,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - p.SetState(238) + p.SetState(246) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -5280,7 +5441,7 @@ func (p *PlanParser) TextMatchOption() (localctx ITextMatchOptionContext) { p.EnterRule(localctx, 2, PlanParserRULE_textMatchOption) p.EnterOuterAlt(localctx, 1) { - p.SetState(239) + p.SetState(247) p.Match(PlanParserMINIMUM_SHOULD_MATCH) if p.HasError() { // Recognition error - abort rule @@ -5288,7 +5449,7 @@ func (p *PlanParser) TextMatchOption() (localctx ITextMatchOptionContext) { } } { - p.SetState(240) + p.SetState(248) p.Match(PlanParserASSIGN) if p.HasError() { // Recognition error - abort rule @@ -5296,7 +5457,7 @@ func (p *PlanParser) TextMatchOption() (localctx ITextMatchOptionContext) { } } { - p.SetState(241) + p.SetState(249) p.Match(PlanParserIntegerConstant) if p.HasError() { // Recognition error - abort rule @@ -5376,7 +5537,7 @@ func (p *PlanParser) Expr_Sempred(localctx antlr.RuleContext, predIndex int) boo return p.Precpred(p.GetParserRuleContext(), 3) case 14: - return p.Precpred(p.GetParserRuleContext(), 35) + return p.Precpred(p.GetParserRuleContext(), 36) default: panic("No predicate with index: " + fmt.Sprint(predIndex)) diff --git a/internal/parser/planparserv2/generated/plan_visitor.go b/internal/parser/planparserv2/generated/plan_visitor.go index b1a42bd903..d841bd99d5 100644 --- a/internal/parser/planparserv2/generated/plan_visitor.go +++ b/internal/parser/planparserv2/generated/plan_visitor.go @@ -7,33 +7,15 @@ import "github.com/antlr4-go/antlr/v4" type PlanVisitor interface { antlr.ParseTreeVisitor - // Visit a parse tree produced by PlanParser#JSONIdentifier. - VisitJSONIdentifier(ctx *JSONIdentifierContext) interface{} - - // Visit a parse tree produced by PlanParser#RandomSample. - VisitRandomSample(ctx *RandomSampleContext) interface{} - - // Visit a parse tree produced by PlanParser#Parens. - VisitParens(ctx *ParensContext) interface{} - // Visit a parse tree produced by PlanParser#String. VisitString(ctx *StringContext) interface{} // Visit a parse tree produced by PlanParser#Floating. VisitFloating(ctx *FloatingContext) interface{} - // Visit a parse tree produced by PlanParser#JSONContainsAll. - VisitJSONContainsAll(ctx *JSONContainsAllContext) interface{} - - // Visit a parse tree produced by PlanParser#LogicalOr. - VisitLogicalOr(ctx *LogicalOrContext) interface{} - // Visit a parse tree produced by PlanParser#IsNotNull. VisitIsNotNull(ctx *IsNotNullContext) interface{} - // Visit a parse tree produced by PlanParser#MulDivMod. - VisitMulDivMod(ctx *MulDivModContext) interface{} - // Visit a parse tree produced by PlanParser#Identifier. VisitIdentifier(ctx *IdentifierContext) interface{} @@ -43,66 +25,33 @@ type PlanVisitor interface { // Visit a parse tree produced by PlanParser#Like. VisitLike(ctx *LikeContext) interface{} - // Visit a parse tree produced by PlanParser#LogicalAnd. - VisitLogicalAnd(ctx *LogicalAndContext) interface{} - - // Visit a parse tree produced by PlanParser#TemplateVariable. - VisitTemplateVariable(ctx *TemplateVariableContext) interface{} - // Visit a parse tree produced by PlanParser#Equality. VisitEquality(ctx *EqualityContext) interface{} // Visit a parse tree produced by PlanParser#Boolean. VisitBoolean(ctx *BooleanContext) interface{} - // Visit a parse tree produced by PlanParser#TimestamptzCompareReverse. - VisitTimestamptzCompareReverse(ctx *TimestamptzCompareReverseContext) interface{} - - // Visit a parse tree produced by PlanParser#STDWithin. - VisitSTDWithin(ctx *STDWithinContext) interface{} - // Visit a parse tree produced by PlanParser#Shift. VisitShift(ctx *ShiftContext) interface{} // Visit a parse tree produced by PlanParser#TimestamptzCompareForward. VisitTimestamptzCompareForward(ctx *TimestamptzCompareForwardContext) interface{} - // Visit a parse tree produced by PlanParser#Call. - VisitCall(ctx *CallContext) interface{} - - // Visit a parse tree produced by PlanParser#STCrosses. - VisitSTCrosses(ctx *STCrossesContext) interface{} - // Visit a parse tree produced by PlanParser#ReverseRange. VisitReverseRange(ctx *ReverseRangeContext) interface{} - // Visit a parse tree produced by PlanParser#BitOr. - VisitBitOr(ctx *BitOrContext) interface{} - // Visit a parse tree produced by PlanParser#EmptyArray. VisitEmptyArray(ctx *EmptyArrayContext) interface{} - // Visit a parse tree produced by PlanParser#AddSub. - VisitAddSub(ctx *AddSubContext) interface{} - // Visit a parse tree produced by PlanParser#PhraseMatch. VisitPhraseMatch(ctx *PhraseMatchContext) interface{} - // Visit a parse tree produced by PlanParser#Relational. - VisitRelational(ctx *RelationalContext) interface{} - // Visit a parse tree produced by PlanParser#ArrayLength. VisitArrayLength(ctx *ArrayLengthContext) interface{} - // Visit a parse tree produced by PlanParser#TextMatch. - VisitTextMatch(ctx *TextMatchContext) interface{} - // Visit a parse tree produced by PlanParser#STTouches. VisitSTTouches(ctx *STTouchesContext) interface{} - // Visit a parse tree produced by PlanParser#STContains. - VisitSTContains(ctx *STContainsContext) interface{} - // Visit a parse tree produced by PlanParser#Term. VisitTerm(ctx *TermContext) interface{} @@ -115,6 +64,72 @@ type PlanVisitor interface { // Visit a parse tree produced by PlanParser#Range. VisitRange(ctx *RangeContext) interface{} + // Visit a parse tree produced by PlanParser#STIsValid. + VisitSTIsValid(ctx *STIsValidContext) interface{} + + // Visit a parse tree produced by PlanParser#BitXor. + VisitBitXor(ctx *BitXorContext) interface{} + + // Visit a parse tree produced by PlanParser#ElementFilter. + VisitElementFilter(ctx *ElementFilterContext) interface{} + + // Visit a parse tree produced by PlanParser#BitAnd. + VisitBitAnd(ctx *BitAndContext) interface{} + + // Visit a parse tree produced by PlanParser#STOverlaps. + VisitSTOverlaps(ctx *STOverlapsContext) interface{} + + // Visit a parse tree produced by PlanParser#JSONIdentifier. + VisitJSONIdentifier(ctx *JSONIdentifierContext) interface{} + + // Visit a parse tree produced by PlanParser#RandomSample. + VisitRandomSample(ctx *RandomSampleContext) interface{} + + // Visit a parse tree produced by PlanParser#Parens. + VisitParens(ctx *ParensContext) interface{} + + // Visit a parse tree produced by PlanParser#JSONContainsAll. + VisitJSONContainsAll(ctx *JSONContainsAllContext) interface{} + + // Visit a parse tree produced by PlanParser#LogicalOr. + VisitLogicalOr(ctx *LogicalOrContext) interface{} + + // Visit a parse tree produced by PlanParser#MulDivMod. + VisitMulDivMod(ctx *MulDivModContext) interface{} + + // Visit a parse tree produced by PlanParser#LogicalAnd. + VisitLogicalAnd(ctx *LogicalAndContext) interface{} + + // Visit a parse tree produced by PlanParser#TemplateVariable. + VisitTemplateVariable(ctx *TemplateVariableContext) interface{} + + // Visit a parse tree produced by PlanParser#TimestamptzCompareReverse. + VisitTimestamptzCompareReverse(ctx *TimestamptzCompareReverseContext) interface{} + + // Visit a parse tree produced by PlanParser#STDWithin. + VisitSTDWithin(ctx *STDWithinContext) interface{} + + // Visit a parse tree produced by PlanParser#Call. + VisitCall(ctx *CallContext) interface{} + + // Visit a parse tree produced by PlanParser#STCrosses. + VisitSTCrosses(ctx *STCrossesContext) interface{} + + // Visit a parse tree produced by PlanParser#BitOr. + VisitBitOr(ctx *BitOrContext) interface{} + + // Visit a parse tree produced by PlanParser#AddSub. + VisitAddSub(ctx *AddSubContext) interface{} + + // Visit a parse tree produced by PlanParser#Relational. + VisitRelational(ctx *RelationalContext) interface{} + + // Visit a parse tree produced by PlanParser#TextMatch. + VisitTextMatch(ctx *TextMatchContext) interface{} + + // Visit a parse tree produced by PlanParser#STContains. + VisitSTContains(ctx *STContainsContext) interface{} + // Visit a parse tree produced by PlanParser#Unary. VisitUnary(ctx *UnaryContext) interface{} @@ -127,30 +142,21 @@ type PlanVisitor interface { // Visit a parse tree produced by PlanParser#JSONContainsAny. VisitJSONContainsAny(ctx *JSONContainsAnyContext) interface{} - // Visit a parse tree produced by PlanParser#STIsValid. - VisitSTIsValid(ctx *STIsValidContext) interface{} - - // Visit a parse tree produced by PlanParser#BitXor. - VisitBitXor(ctx *BitXorContext) interface{} - // Visit a parse tree produced by PlanParser#Exists. VisitExists(ctx *ExistsContext) interface{} - // Visit a parse tree produced by PlanParser#BitAnd. - VisitBitAnd(ctx *BitAndContext) interface{} - // Visit a parse tree produced by PlanParser#STEuqals. VisitSTEuqals(ctx *STEuqalsContext) interface{} // Visit a parse tree produced by PlanParser#IsNull. VisitIsNull(ctx *IsNullContext) interface{} + // Visit a parse tree produced by PlanParser#StructSubField. + VisitStructSubField(ctx *StructSubFieldContext) interface{} + // Visit a parse tree produced by PlanParser#Power. VisitPower(ctx *PowerContext) interface{} - // Visit a parse tree produced by PlanParser#STOverlaps. - VisitSTOverlaps(ctx *STOverlapsContext) interface{} - // Visit a parse tree produced by PlanParser#textMatchOption. VisitTextMatchOption(ctx *TextMatchOptionContext) interface{} } diff --git a/internal/parser/planparserv2/parser_visitor.go b/internal/parser/planparserv2/parser_visitor.go index 6265fb6f19..ac93953263 100644 --- a/internal/parser/planparserv2/parser_visitor.go +++ b/internal/parser/planparserv2/parser_visitor.go @@ -42,6 +42,8 @@ type ParserVisitor struct { parser.BasePlanVisitor schema *typeutil.SchemaHelper args *ParserVisitorArgs + // currentStructArrayField stores the struct array field name when processing ElementFilter + currentStructArrayField string } func NewParserVisitor(schema *typeutil.SchemaHelper, args *ParserVisitorArgs) *ParserVisitor { @@ -658,6 +660,10 @@ func isRandomSampleExpr(expr *ExprWithType) bool { return expr.expr.GetRandomSampleExpr() != nil } +func isElementFilterExpr(expr *ExprWithType) bool { + return expr.expr.GetElementFilterExpr() != nil +} + const EPSILON = 1e-10 func (v *ParserVisitor) VisitRandomSample(ctx *parser.RandomSampleContext) interface{} { @@ -773,7 +779,47 @@ func (v *ParserVisitor) VisitTerm(ctx *parser.TermContext) interface{} { } } -func (v *ParserVisitor) getChildColumnInfo(identifier, child antlr.TerminalNode) (*planpb.ColumnInfo, error) { +func isValidStructSubField(tokenText string) bool { + return len(tokenText) >= 4 && tokenText[:2] == "$[" && tokenText[len(tokenText)-1] == ']' +} + +func (v *ParserVisitor) getColumnInfoFromStructSubField(tokenText string) (*planpb.ColumnInfo, error) { + if !isValidStructSubField(tokenText) { + return nil, fmt.Errorf("invalid struct sub-field syntax: %s", tokenText) + } + // Remove "$[" prefix and "]" suffix + fieldName := tokenText[2 : len(tokenText)-1] + + // Check if we're inside an ElementFilter context + if v.currentStructArrayField == "" { + return nil, fmt.Errorf("$[%s] syntax can only be used inside ElementFilter", fieldName) + } + + // Construct full field name for struct array field + fullFieldName := v.currentStructArrayField + "[" + fieldName + "]" + // Get the struct array field info + field, err := v.schema.GetFieldFromName(fullFieldName) + if err != nil { + return nil, fmt.Errorf("array field not found: %s, error: %s", fullFieldName, err) + } + + // In element-level context, data_type should be the element type + elementType := field.GetElementType() + + return &planpb.ColumnInfo{ + FieldId: field.FieldID, + DataType: elementType, // Use element type, not storage type + IsPrimaryKey: field.IsPrimaryKey, + IsAutoID: field.AutoID, + IsPartitionKey: field.IsPartitionKey, + IsClusteringKey: field.IsClusteringKey, + ElementType: elementType, + Nullable: field.GetNullable(), + IsElementLevel: true, // Mark as element-level access + }, nil +} + +func (v *ParserVisitor) getChildColumnInfo(identifier, child, structSubField antlr.TerminalNode) (*planpb.ColumnInfo, error) { if identifier != nil { childExpr, err := v.translateIdentifier(identifier.GetText()) if err != nil { @@ -782,6 +828,10 @@ func (v *ParserVisitor) getChildColumnInfo(identifier, child antlr.TerminalNode) return toColumnInfo(childExpr), nil } + if structSubField != nil { + return v.getColumnInfoFromStructSubField(structSubField.GetText()) + } + return v.getColumnInfoFromJSONIdentifier(child.GetText()) } @@ -812,7 +862,7 @@ func (v *ParserVisitor) VisitCall(ctx *parser.CallContext) interface{} { // VisitRange translates expr to range plan. func (v *ParserVisitor) VisitRange(ctx *parser.RangeContext) interface{} { - columnInfo, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier()) + columnInfo, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier(), ctx.StructSubFieldIdentifier()) if err != nil { return err } @@ -893,7 +943,7 @@ func (v *ParserVisitor) VisitRange(ctx *parser.RangeContext) interface{} { // VisitReverseRange parses the expression like "1 > a > 0". func (v *ParserVisitor) VisitReverseRange(ctx *parser.ReverseRangeContext) interface{} { - columnInfo, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier()) + columnInfo, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier(), ctx.StructSubFieldIdentifier()) if err != nil { return err } @@ -1081,6 +1131,10 @@ func (v *ParserVisitor) VisitLogicalOr(ctx *parser.LogicalOrContext) interface{} return errors.New("random sample expression cannot be used in logical and expression") } + if isElementFilterExpr(leftExpr) { + return errors.New("element filter expression can only be the last expression in the logical or expression") + } + if !canBeExecuted(leftExpr) || !canBeExecuted(rightExpr) { return errors.New("'or' can only be used between boolean expressions") } @@ -1133,6 +1187,10 @@ func (v *ParserVisitor) VisitLogicalAnd(ctx *parser.LogicalAndContext) interface return errors.New("random sample expression can only be the last expression in the logical and expression") } + if isElementFilterExpr(leftExpr) { + return errors.New("element filter expression can only be the last expression in the logical and expression") + } + if !canBeExecuted(leftExpr) || !canBeExecuted(rightExpr) { return errors.New("'and' can only be used between boolean expressions") } @@ -1146,6 +1204,15 @@ func (v *ParserVisitor) VisitLogicalAnd(ctx *parser.LogicalAndContext) interface RandomSampleExpr: randomSampleExpr, }, } + } else if isElementFilterExpr(rightExpr) { + // Similar to RandomSampleExpr, extract doc-level predicate + elementFilterExpr := rightExpr.expr.GetElementFilterExpr() + elementFilterExpr.Predicate = leftExpr.expr + expr = &planpb.Expr{ + Expr: &planpb.Expr_ElementFilterExpr{ + ElementFilterExpr: elementFilterExpr, + }, + } } else { expr = &planpb.Expr{ Expr: &planpb.Expr_BinaryExpr{ @@ -1410,7 +1477,7 @@ func (v *ParserVisitor) VisitEmptyArray(ctx *parser.EmptyArrayContext) interface } func (v *ParserVisitor) VisitIsNotNull(ctx *parser.IsNotNullContext) interface{} { - column, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier()) + column, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier(), nil) if err != nil { return err } @@ -1450,7 +1517,7 @@ func (v *ParserVisitor) VisitIsNotNull(ctx *parser.IsNotNullContext) interface{} } func (v *ParserVisitor) VisitIsNull(ctx *parser.IsNullContext) interface{} { - column, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier()) + column, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier(), nil) if err != nil { return err } @@ -1653,7 +1720,7 @@ func (v *ParserVisitor) VisitJSONContainsAny(ctx *parser.JSONContainsAnyContext) } func (v *ParserVisitor) VisitArrayLength(ctx *parser.ArrayLengthContext) interface{} { - columnInfo, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier()) + columnInfo, err := v.getChildColumnInfo(ctx.Identifier(), ctx.JSONIdentifier(), nil) if err != nil { return err } @@ -2182,3 +2249,90 @@ func validateAndExtractMinShouldMatch(minShouldMatchExpr interface{}) ([]*planpb } return nil, nil } + +// VisitElementFilter handles ElementFilter(structArrayField, elementExpr) syntax. +func (v *ParserVisitor) VisitElementFilter(ctx *parser.ElementFilterContext) interface{} { + // Check for nested ElementFilter - not allowed + if v.currentStructArrayField != "" { + return fmt.Errorf("nested ElementFilter is not supported, already inside ElementFilter for field: %s", v.currentStructArrayField) + } + + // Get struct array field name (first parameter) + arrayFieldName := ctx.Identifier().GetText() + + // Set current context for element expression parsing + v.currentStructArrayField = arrayFieldName + defer func() { v.currentStructArrayField = "" }() + + elementExpr := ctx.Expr().Accept(v) + if err := getError(elementExpr); err != nil { + return fmt.Errorf("cannot parse element expression: %s, error: %s", ctx.Expr().GetText(), err) + } + + exprWithType := getExpr(elementExpr) + if exprWithType == nil { + return fmt.Errorf("invalid element expression: %s", ctx.Expr().GetText()) + } + + // Build ElementFilterExpr proto + return &ExprWithType{ + expr: &planpb.Expr{ + Expr: &planpb.Expr_ElementFilterExpr{ + ElementFilterExpr: &planpb.ElementFilterExpr{ + ElementExpr: exprWithType.expr, + StructName: arrayFieldName, + }, + }, + }, + dataType: schemapb.DataType_Bool, + } +} + +// VisitStructSubField handles $[fieldName] syntax within ElementFilter. +func (v *ParserVisitor) VisitStructSubField(ctx *parser.StructSubFieldContext) interface{} { + // Extract the field name from $[fieldName] + tokenText := ctx.StructSubFieldIdentifier().GetText() + if !isValidStructSubField(tokenText) { + return fmt.Errorf("invalid struct sub-field syntax: %s", tokenText) + } + // Remove "$[" prefix and "]" suffix + fieldName := tokenText[2 : len(tokenText)-1] + + // Check if we're inside an ElementFilter context + if v.currentStructArrayField == "" { + return fmt.Errorf("$[%s] syntax can only be used inside ElementFilter", fieldName) + } + + // Construct full field name for struct array field + fullFieldName := v.currentStructArrayField + "[" + fieldName + "]" + // Get the struct array field info + field, err := v.schema.GetFieldFromName(fullFieldName) + if err != nil { + return fmt.Errorf("array field not found: %s, error: %s", fullFieldName, err) + } + + // In element-level context, data_type should be the element type + elementType := field.GetElementType() + + return &ExprWithType{ + expr: &planpb.Expr{ + Expr: &planpb.Expr_ColumnExpr{ + ColumnExpr: &planpb.ColumnExpr{ + Info: &planpb.ColumnInfo{ + FieldId: field.FieldID, + DataType: elementType, // Use element type, not storage type + IsPrimaryKey: field.IsPrimaryKey, + IsAutoID: field.AutoID, + IsPartitionKey: field.IsPartitionKey, + IsClusteringKey: field.IsClusteringKey, + ElementType: elementType, + Nullable: field.GetNullable(), + IsElementLevel: true, // Mark as element-level access + }, + }, + }, + }, + dataType: elementType, // Expression evaluates to element type + nodeDependent: true, + } +} diff --git a/internal/parser/planparserv2/plan_parser_v2_test.go b/internal/parser/planparserv2/plan_parser_v2_test.go index 490f59565c..0166b01073 100644 --- a/internal/parser/planparserv2/plan_parser_v2_test.go +++ b/internal/parser/planparserv2/plan_parser_v2_test.go @@ -48,11 +48,27 @@ func newTestSchema(EnableDynamicField bool) *schemapb.CollectionSchema { ElementType: schemapb.DataType_VarChar, }) + structArrayField := &schemapb.StructArrayFieldSchema{ + FieldID: 132, Name: "struct_array", Fields: []*schemapb.FieldSchema{ + { + FieldID: 133, Name: "struct_array[sub_str]", IsPrimaryKey: false, Description: "sub struct array field for string", + DataType: schemapb.DataType_Array, + ElementType: schemapb.DataType_VarChar, + }, + { + FieldID: 134, Name: "struct_array[sub_int]", IsPrimaryKey: false, Description: "sub struct array field for int", + DataType: schemapb.DataType_Array, + ElementType: schemapb.DataType_Int32, + }, + }, + } + return &schemapb.CollectionSchema{ Name: "test", Description: "schema for test used", AutoID: true, Fields: fields, + StructArrayFields: []*schemapb.StructArrayFieldSchema{structArrayField}, EnableDynamicField: EnableDynamicField, } } @@ -2487,3 +2503,57 @@ func TestExpr_GISFunctionsInvalidParameterTypes(t *testing.T) { assertInvalidExpr(t, schema, expr) } } + +func TestExpr_ElementFilter(t *testing.T) { + schema := newTestSchema(true) + helper, err := typeutil.CreateSchemaHelper(schema) + assert.NoError(t, err) + + // Valid expressions + validExprs := []string{ + `element_filter(struct_array, 2 > $[sub_int] > 1)`, + `element_filter(struct_array, $[sub_int] > 1)`, + `element_filter(struct_array, $[sub_int] == 100)`, + `element_filter(struct_array, $[sub_int] >= 0)`, + `element_filter(struct_array, $[sub_int] <= 1000)`, + `element_filter(struct_array, $[sub_int] != 0)`, + + `element_filter(struct_array, $[sub_str] == "1")`, + `element_filter(struct_array, $[sub_str] != "")`, + + `element_filter(struct_array, $[sub_str] == "1" || $[sub_int] > 1)`, + `element_filter(struct_array, $[sub_str] == "1" && $[sub_int] > 1)`, + `element_filter(struct_array, $[sub_int] > 0 && $[sub_int] < 100)`, + + `element_filter(struct_array, ($[sub_int] > 0 && $[sub_int] < 100) || $[sub_str] == "default")`, + `element_filter(struct_array, !($[sub_int] < 0))`, + + `Int64Field > 0 && element_filter(struct_array, $[sub_int] > 1)`, + } + + for _, expr := range validExprs { + assertValidExpr(t, helper, expr) + } + + // Invalid expressions + invalidExprs := []string{ + `element_filter(struct_array, element_filter(struct_array, $[sub_int] > 1))`, + `element_filter(struct_array, $[sub_int] > 1 && element_filter(struct_array, $[sub_str] == "1"))`, + + `$[sub_int] > 1`, + `Int64Field > 0 && $[sub_int] > 1`, + + `element_filter(struct_array, $[non_existent_field] > 1)`, + `element_filter(non_existent_array, $[sub_int] > 1)`, + + `element_filter(struct_array)`, // missing element expression + `element_filter()`, // missing all parameters + + `element_filter(struct_array, $[sub_int] > 1) || element_filter(struct_array, $[sub_str] == "test")`, + `element_filter(struct_array, $[sub_int] > 1) && Int64Field > 0`, + } + + for _, expr := range invalidExprs { + assertInvalidExpr(t, helper, expr) + } +} diff --git a/internal/proxy/search_reduce_util.go b/internal/proxy/search_reduce_util.go index beeabb8ccd..5517e61a1c 100644 --- a/internal/proxy/search_reduce_util.go +++ b/internal/proxy/search_reduce_util.go @@ -150,6 +150,18 @@ func reduceAdvanceGroupBy(ctx context.Context, subSearchResultData []*schemapb.S gpFieldBuilder.Add(groupByVal) typeutil.AppendPKs(ret.Results.Ids, pk) ret.Results.Scores = append(ret.Results.Scores, score) + + // Handle ElementIndices if present + if subData.ElementIndices != nil { + if ret.Results.ElementIndices == nil { + ret.Results.ElementIndices = &schemapb.LongArray{ + Data: make([]int64, 0, limit), + } + } + elemIdx := subData.ElementIndices.GetData()[innerIdx] + ret.Results.ElementIndices.Data = append(ret.Results.ElementIndices.Data, elemIdx) + } + dataCount += 1 } } @@ -308,6 +320,18 @@ func reduceSearchResultDataWithGroupBy(ctx context.Context, subSearchResultData } typeutil.AppendPKs(ret.Results.Ids, groupEntity.id) ret.Results.Scores = append(ret.Results.Scores, groupEntity.score) + + // Handle ElementIndices if present + if subResData.ElementIndices != nil { + if ret.Results.ElementIndices == nil { + ret.Results.ElementIndices = &schemapb.LongArray{ + Data: make([]int64, 0, limit), + } + } + elemIdx := subResData.ElementIndices.GetData()[groupEntity.resultIdx] + ret.Results.ElementIndices.Data = append(ret.Results.ElementIndices.Data, elemIdx) + } + gpFieldBuilder.Add(groupVal) } } @@ -436,6 +460,18 @@ func reduceSearchResultDataNoGroupBy(ctx context.Context, subSearchResultData [] } typeutil.CopyPk(ret.Results.Ids, subSearchResultData[subSearchIdx].GetIds(), int(resultDataIdx)) ret.Results.Scores = append(ret.Results.Scores, score) + + // Handle ElementIndices if present + if subSearchResultData[subSearchIdx].ElementIndices != nil { + if ret.Results.ElementIndices == nil { + ret.Results.ElementIndices = &schemapb.LongArray{ + Data: make([]int64, 0, limit), + } + } + elemIdx := subSearchResultData[subSearchIdx].ElementIndices.GetData()[resultDataIdx] + ret.Results.ElementIndices.Data = append(ret.Results.ElementIndices.Data, elemIdx) + } + cursors[subSearchIdx]++ } if realTopK != -1 && realTopK != j { diff --git a/internal/proxy/task_index.go b/internal/proxy/task_index.go index ee29011793..b9c36fca89 100644 --- a/internal/proxy/task_index.go +++ b/internal/proxy/task_index.go @@ -421,10 +421,22 @@ func (cit *createIndexTask) parseIndexParams(ctx context.Context) error { return merr.WrapErrParameterInvalid("valid index params", "invalid index params", "int vector index does not support metric type: "+metricType) } } else if typeutil.IsArrayOfVectorType(cit.fieldSchema.DataType) { - // TODO(SpadeA): adjust it when more metric types are supported. Especially, when different metric types - // are supported for different element types. if !funcutil.SliceContain(indexparamcheck.EmbListMetrics, metricType) { - return merr.WrapErrParameterInvalid("valid index params", "invalid index params", "array of vector index does not support metric type: "+metricType) + if typeutil.IsDenseFloatVectorType(cit.fieldSchema.ElementType) { + if !funcutil.SliceContain(indexparamcheck.FloatVectorMetrics, metricType) { + return merr.WrapErrParameterInvalid("valid index params", "invalid index params", "array of vector with float element type does not support metric type: "+metricType) + } + } else if typeutil.IsBinaryVectorType(cit.fieldSchema.ElementType) { + if !funcutil.SliceContain(indexparamcheck.BinaryVectorMetrics, metricType) { + return merr.WrapErrParameterInvalid("valid index params", "invalid index params", "array of vector with binary element type does not support metric type: "+metricType) + } + } else if typeutil.IsIntVectorType(cit.fieldSchema.ElementType) { + if !funcutil.SliceContain(indexparamcheck.IntVectorMetrics, metricType) { + return merr.WrapErrParameterInvalid("valid index params", "invalid index params", "array of vector with int element type does not support metric type: "+metricType) + } + } else { + return merr.WrapErrParameterInvalid("valid index params", "invalid index params", "array of vector index does not support metric type: "+metricType) + } } } } diff --git a/internal/proxy/task_index_test.go b/internal/proxy/task_index_test.go index d03c262487..a59d65941a 100644 --- a/internal/proxy/task_index_test.go +++ b/internal/proxy/task_index_test.go @@ -1229,37 +1229,6 @@ func Test_checkEmbeddingListIndex(t *testing.T) { assert.NoError(t, err) }) - t.Run("metrics wrong for embedding list index", func(t *testing.T) { - cit := &createIndexTask{ - Condition: nil, - req: &milvuspb.CreateIndexRequest{ - ExtraParams: []*commonpb.KeyValuePair{ - { - Key: common.IndexTypeKey, - Value: "HNSW", - }, - { - Key: common.MetricTypeKey, - Value: metric.L2, - }, - }, - IndexName: "", - }, - fieldSchema: &schemapb.FieldSchema{ - FieldID: 101, - Name: "EmbListFloat", - IsPrimaryKey: false, - DataType: schemapb.DataType_ArrayOfVector, - ElementType: schemapb.DataType_FloatVector, - TypeParams: []*commonpb.KeyValuePair{ - {Key: common.DimKey, Value: "128"}, - }, - }, - } - err := cit.parseIndexParams(context.TODO()) - assert.True(t, strings.Contains(err.Error(), "array of vector index does not support metric type: L2")) - }) - t.Run("metric type wrong", func(t *testing.T) { cit := &createIndexTask{ Condition: nil, diff --git a/internal/querynodev2/segments/search_reduce.go b/internal/querynodev2/segments/search_reduce.go index 38a2b89fc9..430c6c3ff6 100644 --- a/internal/querynodev2/segments/search_reduce.go +++ b/internal/querynodev2/segments/search_reduce.go @@ -45,6 +45,20 @@ func (scr *SearchCommonReduce) ReduceSearchResultData(ctx context.Context, searc Topks: make([]int64, 0), } + // Check element-level consistency: all results must have ElementIndices or none + hasElementIndices := searchResultData[0].ElementIndices != nil + for i, data := range searchResultData { + if (data.ElementIndices != nil) != hasElementIndices { + return nil, fmt.Errorf("inconsistent element-level flag in search results: result[0] has ElementIndices=%v, but result[%d] has ElementIndices=%v", + hasElementIndices, i, data.ElementIndices != nil) + } + } + if hasElementIndices { + ret.ElementIndices = &schemapb.LongArray{ + Data: make([]int64, 0), + } + } + resultOffsets := make([][]int64, len(searchResultData)) for i := 0; i < len(searchResultData); i++ { resultOffsets[i] = make([]int64, len(searchResultData[i].Topks)) @@ -76,6 +90,9 @@ func (scr *SearchCommonReduce) ReduceSearchResultData(ctx context.Context, searc retSize += typeutil.AppendFieldData(ret.FieldsData, searchResultData[sel].FieldsData, idx) typeutil.AppendPKs(ret.Ids, id) ret.Scores = append(ret.Scores, score) + if searchResultData[sel].ElementIndices != nil && ret.ElementIndices != nil { + ret.ElementIndices.Data = append(ret.ElementIndices.Data, searchResultData[sel].ElementIndices.Data[idx]) + } idSet[id] = struct{}{} j++ } else { @@ -127,6 +144,20 @@ func (sbr *SearchGroupByReduce) ReduceSearchResultData(ctx context.Context, sear Topks: make([]int64, 0), } + // Check element-level consistency: all results must have ElementIndices or none + hasElementIndices := searchResultData[0].ElementIndices != nil + for i, data := range searchResultData { + if (data.ElementIndices != nil) != hasElementIndices { + return nil, fmt.Errorf("inconsistent element-level flag in search results: result[0] has ElementIndices=%v, but result[%d] has ElementIndices=%v", + hasElementIndices, i, data.ElementIndices != nil) + } + } + if hasElementIndices { + ret.ElementIndices = &schemapb.LongArray{ + Data: make([]int64, 0), + } + } + resultOffsets := make([][]int64, len(searchResultData)) groupByValIterator := make([]func(int) any, len(searchResultData)) for i := range searchResultData { @@ -180,6 +211,9 @@ func (sbr *SearchGroupByReduce) ReduceSearchResultData(ctx context.Context, sear retSize += typeutil.AppendFieldData(ret.FieldsData, searchResultData[sel].FieldsData, idx) typeutil.AppendPKs(ret.Ids, id) ret.Scores = append(ret.Scores, score) + if searchResultData[sel].ElementIndices != nil && ret.ElementIndices != nil { + ret.ElementIndices.Data = append(ret.ElementIndices.Data, searchResultData[sel].ElementIndices.Data[idx]) + } gpFieldBuilder.Add(groupByVal) groupByValueMap[groupByVal] += 1 idSet[id] = struct{}{} diff --git a/internal/querynodev2/segments/segment_loader.go b/internal/querynodev2/segments/segment_loader.go index 487f01c7aa..007c5002a7 100644 --- a/internal/querynodev2/segments/segment_loader.go +++ b/internal/querynodev2/segments/segment_loader.go @@ -2120,8 +2120,18 @@ func estimateLoadingResourceUsageOfSegment(schema *schemapb.CollectionSchema, lo } } + // per struct memory size, used to keep mapping between row id and element id + var structArrayOffsetsSize uint64 + // PART 6: calculate size of struct array offsets + // The memory size is 4 * row_count + 4 * total_element_count + // We cannot easily get the element count, so we estimate it by the row count * 10 + rowCount := uint64(loadInfo.GetNumOfRows()) + for range len(schema.GetStructArrayFields()) { + structArrayOffsetsSize += 4*rowCount + 4*rowCount*10 + } + return &ResourceUsage{ - MemorySize: segMemoryLoadingSize + indexMemorySize, + MemorySize: segMemoryLoadingSize + indexMemorySize + structArrayOffsetsSize, DiskSize: segDiskLoadingSize, MmapFieldCount: mmapFieldCount, FieldGpuMemorySize: fieldGpuMemorySize, diff --git a/internal/util/indexparamcheck/vector_index_checker.go b/internal/util/indexparamcheck/vector_index_checker.go index 1568c9cb5c..af50963478 100644 --- a/internal/util/indexparamcheck/vector_index_checker.go +++ b/internal/util/indexparamcheck/vector_index_checker.go @@ -59,7 +59,21 @@ func (c vecIndexChecker) StaticCheck(dataType schemapb.DataType, elementType sch } } else if typeutil.IsArrayOfVectorType(dataType) { if !CheckStrByValues(params, Metric, EmbListMetrics) { - return fmt.Errorf("metric type %s not found or not supported, supported: %v", params[Metric], EmbListMetrics) + if typeutil.IsDenseFloatVectorType(elementType) { + if !CheckStrByValues(params, Metric, FloatVectorMetrics) { + return fmt.Errorf("metric type %s not found or not supported for array of vector with float element type, supported: %v", params[Metric], FloatVectorMetrics) + } + } else if typeutil.IsBinaryVectorType(elementType) { + if !CheckStrByValues(params, Metric, BinaryVectorMetrics) { + return fmt.Errorf("metric type %s not found or not supported for array of vector with binary element type, supported: %v", params[Metric], BinaryVectorMetrics) + } + } else if typeutil.IsIntVectorType(elementType) { + if !CheckStrByValues(params, Metric, IntVectorMetrics) { + return fmt.Errorf("metric type %s not found or not supported for array of vector with int element type, supported: %v", params[Metric], IntVectorMetrics) + } + } else { + return fmt.Errorf("metric type %s not found or not supported for array of vector, supported: %v", params[Metric], EmbListMetrics) + } } } diff --git a/pkg/proto/plan.proto b/pkg/proto/plan.proto index 35df351a39..149f1cfe3e 100644 --- a/pkg/proto/plan.proto +++ b/pkg/proto/plan.proto @@ -98,6 +98,7 @@ message ColumnInfo { schema.DataType element_type = 7; bool is_clustering_key = 8; bool nullable = 9; + bool is_element_level = 10; } message ColumnExpr { @@ -245,6 +246,12 @@ message RandomSampleExpr { Expr predicate = 2; } +message ElementFilterExpr { + Expr element_expr = 1; + string struct_name = 2; + Expr predicate = 3; +} + message AlwaysTrueExpr {} message Interval { @@ -285,6 +292,7 @@ message Expr { RandomSampleExpr random_sample_expr = 16; GISFunctionFilterExpr gisfunction_filter_expr = 17; TimestamptzArithCompareExpr timestamptz_arith_compare_expr = 18; + ElementFilterExpr element_filter_expr = 19; }; bool is_template = 20; } diff --git a/pkg/proto/planpb/plan.pb.go b/pkg/proto/planpb/plan.pb.go index 030b380768..7a0bd16e7e 100644 --- a/pkg/proto/planpb/plan.pb.go +++ b/pkg/proto/planpb/plan.pb.go @@ -1080,6 +1080,7 @@ type ColumnInfo struct { ElementType schemapb.DataType `protobuf:"varint,7,opt,name=element_type,json=elementType,proto3,enum=milvus.proto.schema.DataType" json:"element_type,omitempty"` IsClusteringKey bool `protobuf:"varint,8,opt,name=is_clustering_key,json=isClusteringKey,proto3" json:"is_clustering_key,omitempty"` Nullable bool `protobuf:"varint,9,opt,name=nullable,proto3" json:"nullable,omitempty"` + IsElementLevel bool `protobuf:"varint,10,opt,name=is_element_level,json=isElementLevel,proto3" json:"is_element_level,omitempty"` } func (x *ColumnInfo) Reset() { @@ -1177,6 +1178,13 @@ func (x *ColumnInfo) GetNullable() bool { return false } +func (x *ColumnInfo) GetIsElementLevel() bool { + if x != nil { + return x.IsElementLevel + } + return false +} + type ColumnExpr struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2288,6 +2296,69 @@ func (x *RandomSampleExpr) GetPredicate() *Expr { return nil } +type ElementFilterExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ElementExpr *Expr `protobuf:"bytes,1,opt,name=element_expr,json=elementExpr,proto3" json:"element_expr,omitempty"` + StructName string `protobuf:"bytes,2,opt,name=struct_name,json=structName,proto3" json:"struct_name,omitempty"` + Predicate *Expr `protobuf:"bytes,3,opt,name=predicate,proto3" json:"predicate,omitempty"` +} + +func (x *ElementFilterExpr) Reset() { + *x = ElementFilterExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_plan_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ElementFilterExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ElementFilterExpr) ProtoMessage() {} + +func (x *ElementFilterExpr) ProtoReflect() protoreflect.Message { + mi := &file_plan_proto_msgTypes[22] + 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 ElementFilterExpr.ProtoReflect.Descriptor instead. +func (*ElementFilterExpr) Descriptor() ([]byte, []int) { + return file_plan_proto_rawDescGZIP(), []int{22} +} + +func (x *ElementFilterExpr) GetElementExpr() *Expr { + if x != nil { + return x.ElementExpr + } + return nil +} + +func (x *ElementFilterExpr) GetStructName() string { + if x != nil { + return x.StructName + } + return "" +} + +func (x *ElementFilterExpr) GetPredicate() *Expr { + if x != nil { + return x.Predicate + } + return nil +} + type AlwaysTrueExpr struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2297,7 +2368,7 @@ type AlwaysTrueExpr struct { func (x *AlwaysTrueExpr) Reset() { *x = AlwaysTrueExpr{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[22] + mi := &file_plan_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2310,7 +2381,7 @@ func (x *AlwaysTrueExpr) String() string { func (*AlwaysTrueExpr) ProtoMessage() {} func (x *AlwaysTrueExpr) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[22] + mi := &file_plan_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2323,7 +2394,7 @@ func (x *AlwaysTrueExpr) ProtoReflect() protoreflect.Message { // Deprecated: Use AlwaysTrueExpr.ProtoReflect.Descriptor instead. func (*AlwaysTrueExpr) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{22} + return file_plan_proto_rawDescGZIP(), []int{23} } type Interval struct { @@ -2342,7 +2413,7 @@ type Interval struct { func (x *Interval) Reset() { *x = Interval{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[23] + mi := &file_plan_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2355,7 +2426,7 @@ func (x *Interval) String() string { func (*Interval) ProtoMessage() {} func (x *Interval) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[23] + mi := &file_plan_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2368,7 +2439,7 @@ func (x *Interval) ProtoReflect() protoreflect.Message { // Deprecated: Use Interval.ProtoReflect.Descriptor instead. func (*Interval) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{23} + return file_plan_proto_rawDescGZIP(), []int{24} } func (x *Interval) GetYears() int64 { @@ -2429,7 +2500,7 @@ type TimestamptzArithCompareExpr struct { func (x *TimestamptzArithCompareExpr) Reset() { *x = TimestamptzArithCompareExpr{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[24] + mi := &file_plan_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2442,7 +2513,7 @@ func (x *TimestamptzArithCompareExpr) String() string { func (*TimestamptzArithCompareExpr) ProtoMessage() {} func (x *TimestamptzArithCompareExpr) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[24] + mi := &file_plan_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2455,7 +2526,7 @@ func (x *TimestamptzArithCompareExpr) ProtoReflect() protoreflect.Message { // Deprecated: Use TimestamptzArithCompareExpr.ProtoReflect.Descriptor instead. func (*TimestamptzArithCompareExpr) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{24} + return file_plan_proto_rawDescGZIP(), []int{25} } func (x *TimestamptzArithCompareExpr) GetTimestamptzColumn() *ColumnInfo { @@ -2518,6 +2589,7 @@ type Expr struct { // *Expr_RandomSampleExpr // *Expr_GisfunctionFilterExpr // *Expr_TimestamptzArithCompareExpr + // *Expr_ElementFilterExpr Expr isExpr_Expr `protobuf_oneof:"expr"` IsTemplate bool `protobuf:"varint,20,opt,name=is_template,json=isTemplate,proto3" json:"is_template,omitempty"` } @@ -2525,7 +2597,7 @@ type Expr struct { func (x *Expr) Reset() { *x = Expr{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[25] + mi := &file_plan_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2538,7 +2610,7 @@ func (x *Expr) String() string { func (*Expr) ProtoMessage() {} func (x *Expr) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[25] + mi := &file_plan_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2551,7 +2623,7 @@ func (x *Expr) ProtoReflect() protoreflect.Message { // Deprecated: Use Expr.ProtoReflect.Descriptor instead. func (*Expr) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{25} + return file_plan_proto_rawDescGZIP(), []int{26} } func (m *Expr) GetExpr() isExpr_Expr { @@ -2687,6 +2759,13 @@ func (x *Expr) GetTimestamptzArithCompareExpr() *TimestamptzArithCompareExpr { return nil } +func (x *Expr) GetElementFilterExpr() *ElementFilterExpr { + if x, ok := x.GetExpr().(*Expr_ElementFilterExpr); ok { + return x.ElementFilterExpr + } + return nil +} + func (x *Expr) GetIsTemplate() bool { if x != nil { return x.IsTemplate @@ -2770,6 +2849,10 @@ type Expr_TimestamptzArithCompareExpr struct { TimestamptzArithCompareExpr *TimestamptzArithCompareExpr `protobuf:"bytes,18,opt,name=timestamptz_arith_compare_expr,json=timestamptzArithCompareExpr,proto3,oneof"` } +type Expr_ElementFilterExpr struct { + ElementFilterExpr *ElementFilterExpr `protobuf:"bytes,19,opt,name=element_filter_expr,json=elementFilterExpr,proto3,oneof"` +} + func (*Expr_TermExpr) isExpr_Expr() {} func (*Expr_UnaryExpr) isExpr_Expr() {} @@ -2806,6 +2889,8 @@ func (*Expr_GisfunctionFilterExpr) isExpr_Expr() {} func (*Expr_TimestamptzArithCompareExpr) isExpr_Expr() {} +func (*Expr_ElementFilterExpr) isExpr_Expr() {} + type VectorANNS struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2821,7 +2906,7 @@ type VectorANNS struct { func (x *VectorANNS) Reset() { *x = VectorANNS{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[26] + mi := &file_plan_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2834,7 +2919,7 @@ func (x *VectorANNS) String() string { func (*VectorANNS) ProtoMessage() {} func (x *VectorANNS) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[26] + mi := &file_plan_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2847,7 +2932,7 @@ func (x *VectorANNS) ProtoReflect() protoreflect.Message { // Deprecated: Use VectorANNS.ProtoReflect.Descriptor instead. func (*VectorANNS) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{26} + return file_plan_proto_rawDescGZIP(), []int{27} } func (x *VectorANNS) GetVectorType() VectorType { @@ -2898,7 +2983,7 @@ type QueryPlanNode struct { func (x *QueryPlanNode) Reset() { *x = QueryPlanNode{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[27] + mi := &file_plan_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2911,7 +2996,7 @@ func (x *QueryPlanNode) String() string { func (*QueryPlanNode) ProtoMessage() {} func (x *QueryPlanNode) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[27] + mi := &file_plan_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2924,7 +3009,7 @@ func (x *QueryPlanNode) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryPlanNode.ProtoReflect.Descriptor instead. func (*QueryPlanNode) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{27} + return file_plan_proto_rawDescGZIP(), []int{28} } func (x *QueryPlanNode) GetPredicates() *Expr { @@ -2962,7 +3047,7 @@ type ScoreFunction struct { func (x *ScoreFunction) Reset() { *x = ScoreFunction{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[28] + mi := &file_plan_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2975,7 +3060,7 @@ func (x *ScoreFunction) String() string { func (*ScoreFunction) ProtoMessage() {} func (x *ScoreFunction) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[28] + mi := &file_plan_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2988,7 +3073,7 @@ func (x *ScoreFunction) ProtoReflect() protoreflect.Message { // Deprecated: Use ScoreFunction.ProtoReflect.Descriptor instead. func (*ScoreFunction) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{28} + return file_plan_proto_rawDescGZIP(), []int{29} } func (x *ScoreFunction) GetFilter() *Expr { @@ -3031,7 +3116,7 @@ type ScoreOption struct { func (x *ScoreOption) Reset() { *x = ScoreOption{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[29] + mi := &file_plan_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3044,7 +3129,7 @@ func (x *ScoreOption) String() string { func (*ScoreOption) ProtoMessage() {} func (x *ScoreOption) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[29] + mi := &file_plan_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3057,7 +3142,7 @@ func (x *ScoreOption) ProtoReflect() protoreflect.Message { // Deprecated: Use ScoreOption.ProtoReflect.Descriptor instead. func (*ScoreOption) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{29} + return file_plan_proto_rawDescGZIP(), []int{30} } func (x *ScoreOption) GetBoostMode() BoostMode { @@ -3085,7 +3170,7 @@ type PlanOption struct { func (x *PlanOption) Reset() { *x = PlanOption{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[30] + mi := &file_plan_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3098,7 +3183,7 @@ func (x *PlanOption) String() string { func (*PlanOption) ProtoMessage() {} func (x *PlanOption) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[30] + mi := &file_plan_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3111,7 +3196,7 @@ func (x *PlanOption) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanOption.ProtoReflect.Descriptor instead. func (*PlanOption) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{30} + return file_plan_proto_rawDescGZIP(), []int{31} } func (x *PlanOption) GetExprUseJsonStats() bool { @@ -3143,7 +3228,7 @@ type PlanNode struct { func (x *PlanNode) Reset() { *x = PlanNode{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[31] + mi := &file_plan_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3156,7 +3241,7 @@ func (x *PlanNode) String() string { func (*PlanNode) ProtoMessage() {} func (x *PlanNode) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[31] + mi := &file_plan_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3169,7 +3254,7 @@ func (x *PlanNode) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanNode.ProtoReflect.Descriptor instead. func (*PlanNode) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{31} + return file_plan_proto_rawDescGZIP(), []int{32} } func (m *PlanNode) GetNode() isPlanNode_Node { @@ -3343,7 +3428,7 @@ var file_plan_proto_rawDesc = []byte{ 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x43, 0x61, 0x73, 0x74, 0x42, 0x1a, 0x0a, 0x18, 0x5f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x32, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x22, - 0xfb, 0x02, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, + 0xa5, 0x03, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x3a, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x6d, @@ -3366,500 +3451,518 @@ var file_plan_proto_rawDesc = []byte{ 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x3f, 0x0a, - 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x12, 0x31, 0x0a, 0x04, 0x69, - 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, - 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x3f, - 0x0a, 0x0a, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x45, 0x78, 0x70, 0x72, 0x12, 0x31, 0x0a, 0x04, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x28, 0x0a, + 0x10, 0x69, 0x73, 0x5f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x65, 0x76, 0x65, + 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x73, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x3f, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x45, 0x78, 0x70, 0x72, 0x12, 0x31, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x3f, 0x0a, 0x0a, 0x45, 0x78, 0x69, 0x73, + 0x74, 0x73, 0x45, 0x78, 0x70, 0x72, 0x12, 0x31, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x78, 0x0a, 0x09, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, + 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, + 0x16, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0xac, 0x02, 0x0a, 0x0e, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, + 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, + 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, + 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x29, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x02, 0x6f, + 0x70, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x42, + 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x65, 0x78, 0x74, 0x72, 0x61, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x22, 0xa9, 0x03, 0x0a, 0x0f, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, + 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, + 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, + 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x27, 0x0a, 0x0f, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x5f, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0e, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x12, + 0x27, 0x0a, 0x0f, 0x75, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, + 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x75, 0x70, 0x70, 0x65, 0x72, 0x49, + 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x6c, 0x6f, 0x77, 0x65, + 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, + 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, + 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, + 0x70, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, + 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0a, 0x75, 0x70, 0x70, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x1c, + 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x19, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, + 0x1c, 0x75, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x19, 0x75, 0x70, 0x70, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x79, + 0x0a, 0x08, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x48, 0x0a, 0x13, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 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, 0x12, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x0b, 0x43, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x47, 0x0a, 0x10, 0x6c, 0x65, 0x66, + 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x0e, 0x6c, 0x65, 0x66, 0x74, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x49, 0x0a, 0x11, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x75, + 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x29, 0x0a, + 0x02, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x69, 0x6c, 0x76, + 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4f, 0x70, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x02, 0x6f, 0x70, 0x22, 0xd9, 0x01, 0x0a, 0x08, 0x54, 0x65, 0x72, + 0x6d, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, - 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, - 0x78, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x35, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, - 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, - 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, - 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xac, 0x02, 0x0a, 0x0e, 0x55, 0x6e, - 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, - 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x29, 0x0a, 0x02, - 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4f, 0x70, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, - 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x37, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, + 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1e, + 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x49, 0x6e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, - 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, - 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x65, 0x78, 0x74, - 0x72, 0x61, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xa9, 0x03, 0x0a, 0x0f, 0x42, 0x69, 0x6e, - 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, - 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xf6, 0x02, 0x0a, 0x10, 0x4a, 0x53, 0x4f, 0x4e, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3b, 0x0a, 0x08, 0x65, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, + 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x73, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x4f, 0x70, 0x52, 0x02, + 0x6f, 0x70, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x73, + 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x61, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x06, 0x4a, 0x53, 0x4f, 0x4e, 0x4f, 0x70, + 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, + 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x41, 0x6c, 0x6c, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x41, 0x6e, 0x79, 0x10, 0x03, 0x22, 0xb0, 0x01, + 0x0a, 0x08, 0x4e, 0x75, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, + 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, + 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x02, 0x6f, 0x70, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x45, + 0x78, 0x70, 0x72, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, 0x22, 0x30, + 0x0a, 0x06, 0x4e, 0x75, 0x6c, 0x6c, 0x4f, 0x70, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x10, + 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x73, 0x4e, 0x6f, 0x74, 0x4e, 0x75, 0x6c, 0x6c, 0x10, 0x02, + 0x22, 0xe3, 0x02, 0x0a, 0x15, 0x47, 0x49, 0x53, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, + 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, + 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x77, 0x6b, + 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x77, 0x6b, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x3e, 0x0a, 0x02, 0x6f, 0x70, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x49, 0x53, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x78, 0x70, 0x72, 0x2e, + 0x47, 0x49, 0x53, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x64, 0x69, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x8e, 0x01, 0x0a, 0x05, 0x47, 0x49, 0x53, 0x4f, 0x70, 0x12, + 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, + 0x45, 0x71, 0x75, 0x61, 0x6c, 0x73, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x6f, 0x75, 0x63, + 0x68, 0x65, 0x73, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x70, + 0x73, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x10, 0x04, + 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x10, 0x05, 0x12, 0x0e, + 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x73, 0x10, 0x06, 0x12, 0x0a, + 0x0a, 0x06, 0x57, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x10, 0x07, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x57, + 0x69, 0x74, 0x68, 0x69, 0x6e, 0x10, 0x08, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x54, 0x49, 0x73, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x10, 0x09, 0x22, 0x91, 0x01, 0x0a, 0x09, 0x55, 0x6e, 0x61, 0x72, 0x79, + 0x45, 0x78, 0x70, 0x72, 0x12, 0x34, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x24, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x55, + 0x6e, 0x61, 0x72, 0x79, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x2d, 0x0a, 0x05, 0x63, 0x68, + 0x69, 0x6c, 0x64, 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, 0x52, 0x05, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x1f, 0x0a, 0x07, 0x55, 0x6e, 0x61, + 0x72, 0x79, 0x4f, 0x70, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, + 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x6f, 0x74, 0x10, 0x01, 0x22, 0xd8, 0x01, 0x0a, 0x0a, 0x42, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x12, 0x36, 0x0a, 0x02, 0x6f, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x45, 0x78, 0x70, 0x72, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x4f, 0x70, 0x52, 0x02, 0x6f, + 0x70, 0x12, 0x2b, 0x0a, 0x04, 0x6c, 0x65, 0x66, 0x74, 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, 0x52, 0x04, 0x6c, 0x65, 0x66, 0x74, 0x12, 0x2d, + 0x0a, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 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, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x36, 0x0a, + 0x08, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x4f, 0x70, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, + 0x6c, 0x41, 0x6e, 0x64, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, + 0x6c, 0x4f, 0x72, 0x10, 0x02, 0x22, 0xd0, 0x01, 0x0a, 0x0d, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, 0x08, 0x61, 0x72, 0x69, 0x74, 0x68, + 0x5f, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, + 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x72, + 0x69, 0x74, 0x68, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x61, 0x72, 0x69, 0x74, 0x68, + 0x4f, 0x70, 0x12, 0x44, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, + 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x22, 0x9d, 0x01, 0x0a, 0x0f, 0x42, 0x69, 0x6e, + 0x61, 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x45, 0x78, 0x70, 0x72, 0x12, 0x2b, 0x0a, 0x04, + 0x6c, 0x65, 0x66, 0x74, 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, 0x04, 0x6c, 0x65, 0x66, 0x74, 0x12, 0x2d, 0x0a, 0x05, 0x72, 0x69, 0x67, + 0x68, 0x74, 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, 0x52, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2e, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x02, 0x6f, 0x70, 0x22, 0xc5, 0x03, 0x0a, 0x1a, 0x42, 0x69, 0x6e, + 0x61, 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x45, 0x76, 0x61, 0x6c, 0x52, 0x61, + 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, 0x08, 0x61, 0x72, 0x69, 0x74, 0x68, + 0x5f, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, + 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x72, + 0x69, 0x74, 0x68, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x61, 0x72, 0x69, 0x74, 0x68, + 0x4f, 0x70, 0x12, 0x44, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, + 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x12, 0x29, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x02, 0x6f, 0x70, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a, 0x1e, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x1b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x3f, 0x0a, 0x1c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x22, 0x6e, 0x0a, 0x10, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x45, 0x78, 0x70, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x66, + 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0c, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x35, 0x0a, 0x09, 0x70, 0x72, 0x65, + 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 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, 0x52, 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x22, 0xa7, 0x01, 0x0a, 0x11, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3a, 0x0a, 0x0c, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x65, 0x78, 0x70, 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, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x45, 0x78, + 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x18, 0x03, 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, + 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x41, 0x6c, + 0x77, 0x61, 0x79, 0x73, 0x54, 0x72, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x22, 0x96, 0x01, 0x0a, + 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x79, 0x65, 0x61, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x79, 0x65, 0x61, 0x72, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x06, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x64, 0x61, 0x79, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x68, + 0x6f, 0x75, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x68, 0x6f, 0x75, 0x72, + 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xdf, 0x02, 0x0a, 0x1b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x74, 0x7a, 0x41, 0x72, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, + 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x4c, 0x0a, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x74, 0x7a, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x27, 0x0a, 0x0f, - 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x63, 0x6c, - 0x75, 0x73, 0x69, 0x76, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x75, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x69, - 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, - 0x75, 0x70, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x12, 0x40, - 0x0a, 0x0b, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, - 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x75, 0x70, 0x70, 0x65, 0x72, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x1c, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6d, 0x70, - 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x54, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x1c, 0x75, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x75, 0x70, 0x70, 0x65, 0x72, - 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x79, 0x0a, 0x08, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, - 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x48, 0x0a, 0x13, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, - 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, 0x12, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, - 0xcc, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, - 0x47, 0x0a, 0x10, 0x6c, 0x65, 0x66, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, - 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x6c, 0x65, 0x66, 0x74, 0x43, 0x6f, - 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x49, 0x0a, 0x11, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x0f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x29, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x19, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, - 0x6c, 0x61, 0x6e, 0x2e, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x02, 0x6f, 0x70, 0x22, 0xd9, - 0x01, 0x0a, 0x08, 0x54, 0x65, 0x72, 0x6d, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x63, - 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x37, 0x0a, 0x06, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, + 0x52, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x74, 0x7a, 0x43, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x12, 0x39, 0x0a, 0x08, 0x61, 0x72, 0x69, 0x74, 0x68, 0x5f, 0x6f, 0x70, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, + 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x61, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x12, 0x37, + 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x08, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x72, 0x65, 0x5f, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x49, 0x6e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, - 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, - 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xf6, 0x02, 0x0a, 0x10, 0x4a, - 0x53, 0x4f, 0x4e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x78, 0x70, 0x72, 0x12, - 0x3e, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x3b, 0x0a, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x02, - 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4a, 0x53, 0x4f, - 0x4e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x4a, 0x53, - 0x4f, 0x4e, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x61, - 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, - 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x06, - 0x4a, 0x53, 0x4f, 0x4e, 0x4f, 0x70, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x10, - 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x41, 0x6c, 0x6c, - 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x41, 0x6e, - 0x79, 0x10, 0x03, 0x22, 0xb0, 0x01, 0x0a, 0x08, 0x4e, 0x75, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, - 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x32, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x6d, - 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, - 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x4f, 0x70, - 0x52, 0x02, 0x6f, 0x70, 0x22, 0x30, 0x0a, 0x06, 0x4e, 0x75, 0x6c, 0x6c, 0x4f, 0x70, 0x12, 0x0b, - 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x49, - 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x73, 0x4e, 0x6f, 0x74, - 0x4e, 0x75, 0x6c, 0x6c, 0x10, 0x02, 0x22, 0xe3, 0x02, 0x0a, 0x15, 0x47, 0x49, 0x53, 0x46, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x78, 0x70, 0x72, - 0x12, 0x3e, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x1d, 0x0a, 0x0a, 0x77, 0x6b, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x77, 0x6b, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, - 0x3e, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x6d, 0x69, - 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, - 0x47, 0x49, 0x53, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x47, 0x49, 0x53, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, 0x12, - 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x01, 0x52, 0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x8e, 0x01, 0x0a, 0x05, - 0x47, 0x49, 0x53, 0x4f, 0x70, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x73, 0x10, 0x01, 0x12, 0x0b, - 0x0a, 0x07, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x4f, - 0x76, 0x65, 0x72, 0x6c, 0x61, 0x70, 0x73, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x72, 0x6f, - 0x73, 0x73, 0x65, 0x73, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x73, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, - 0x74, 0x73, 0x10, 0x06, 0x12, 0x0a, 0x0a, 0x06, 0x57, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x10, 0x07, - 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x57, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x10, 0x08, 0x12, 0x0d, 0x0a, - 0x09, 0x53, 0x54, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x09, 0x22, 0x91, 0x01, 0x0a, - 0x09, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x12, 0x34, 0x0a, 0x02, 0x6f, 0x70, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x79, - 0x45, 0x78, 0x70, 0x72, 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, - 0x12, 0x2d, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x6c, 0x64, 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, 0x52, 0x05, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, - 0x1f, 0x0a, 0x07, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x4f, 0x70, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x6e, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x6f, 0x74, 0x10, 0x01, - 0x22, 0xd8, 0x01, 0x0a, 0x0a, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x12, - 0x36, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x6d, 0x69, - 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, - 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x2b, 0x0a, 0x04, 0x6c, 0x65, 0x66, 0x74, 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, 0x52, 0x04, - 0x6c, 0x65, 0x66, 0x74, 0x12, 0x2d, 0x0a, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 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, 0x05, 0x72, 0x69, - 0x67, 0x68, 0x74, 0x22, 0x36, 0x0a, 0x08, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x4f, 0x70, 0x12, - 0x0b, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, - 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x41, 0x6e, 0x64, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, - 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x4f, 0x72, 0x10, 0x02, 0x22, 0xd0, 0x01, 0x0a, 0x0d, - 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x12, 0x3e, 0x0a, - 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, - 0x08, 0x61, 0x72, 0x69, 0x74, 0x68, 0x5f, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, - 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x07, 0x61, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x12, 0x44, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, - 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x0c, 0x72, 0x69, 0x67, 0x68, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x22, 0x9d, - 0x01, 0x0a, 0x0f, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x45, 0x78, - 0x70, 0x72, 0x12, 0x2b, 0x0a, 0x04, 0x6c, 0x65, 0x66, 0x74, 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, 0x04, 0x6c, 0x65, 0x66, 0x74, 0x12, - 0x2d, 0x0a, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 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, 0x52, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2e, - 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, - 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, - 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x02, 0x6f, 0x70, 0x22, 0xc5, - 0x03, 0x0a, 0x1a, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, - 0x45, 0x76, 0x61, 0x6c, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, - 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, - 0x08, 0x61, 0x72, 0x69, 0x74, 0x68, 0x5f, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, - 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x07, 0x61, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x12, 0x44, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, - 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x0c, 0x72, 0x69, 0x67, 0x68, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x12, 0x29, - 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x69, 0x6c, - 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4f, - 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x4f, + 0x70, 0x12, 0x44, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x43, 0x0a, 0x1e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, - 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, - 0x64, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x1c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x74, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6e, 0x0a, 0x10, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, - 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x02, 0x52, 0x0c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, - 0x35, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 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, 0x52, 0x09, 0x70, 0x72, 0x65, - 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, - 0x54, 0x72, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x22, 0x96, 0x01, 0x0a, 0x08, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x79, 0x65, 0x61, 0x72, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x79, 0x65, 0x61, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, - 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x6f, 0x6e, - 0x74, 0x68, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x04, 0x64, 0x61, 0x79, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x68, 0x6f, 0x75, 0x72, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, - 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, - 0x73, 0x22, 0xdf, 0x02, 0x0a, 0x1b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x74, - 0x7a, 0x41, 0x72, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x45, 0x78, 0x70, - 0x72, 0x12, 0x4c, 0x0a, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x74, 0x7a, - 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x74, 0x7a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, - 0x39, 0x0a, 0x08, 0x61, 0x72, 0x69, 0x74, 0x68, 0x5f, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x07, 0x61, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x12, 0x37, 0x0a, 0x08, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, - 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x6f, - 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4f, 0x70, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x4f, 0x70, 0x12, 0x44, 0x0a, - 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0xa9, 0x0b, 0x0a, 0x04, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3a, 0x0a, 0x09, - 0x74, 0x65, 0x72, 0x6d, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, - 0x6c, 0x61, 0x6e, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x08, - 0x74, 0x65, 0x72, 0x6d, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3d, 0x0a, 0x0a, 0x75, 0x6e, 0x61, 0x72, - 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, - 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, - 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x09, 0x75, 0x6e, - 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x62, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x03, 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, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x62, - 0x69, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x12, 0x43, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, - 0x70, 0x61, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x04, 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, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, - 0x00, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x4d, - 0x0a, 0x10, 0x75, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x65, 0x78, - 0x70, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x55, 0x6e, 0x61, - 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0e, 0x75, - 0x6e, 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x50, 0x0a, - 0x11, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x65, 0x78, - 0x70, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x69, 0x6e, - 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0f, - 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, - 0x74, 0x0a, 0x1f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x5f, - 0x6f, 0x70, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x65, 0x78, - 0x70, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x69, 0x6e, - 0x61, 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x45, 0x76, 0x61, 0x6c, 0x52, 0x61, - 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x1a, 0x62, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x45, 0x76, 0x61, 0x6c, 0x52, 0x61, 0x6e, 0x67, - 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x50, 0x0a, 0x11, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, - 0x61, 0x72, 0x69, 0x74, 0x68, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, - 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x41, 0x72, - 0x69, 0x74, 0x68, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3d, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x69, - 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x09, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x0a, 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, - 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6f, - 0x6c, 0x75, 0x6d, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x65, 0x78, 0x69, 0x73, - 0x74, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x0b, 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, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0a, - 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x45, 0x78, 0x70, 0x72, 0x12, 0x4d, 0x0a, 0x10, 0x61, 0x6c, - 0x77, 0x61, 0x79, 0x73, 0x5f, 0x74, 0x72, 0x75, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x54, - 0x72, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0e, 0x61, 0x6c, 0x77, 0x61, 0x79, - 0x73, 0x54, 0x72, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x53, 0x0a, 0x12, 0x6a, 0x73, 0x6f, - 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x10, 0x6a, 0x73, - 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3a, - 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, - 0x52, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3a, 0x0a, 0x09, 0x6e, 0x75, - 0x6c, 0x6c, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, - 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, - 0x6e, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x08, 0x6e, 0x75, - 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x12, 0x53, 0x0a, 0x12, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, - 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x10, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x53, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x10, 0x72, 0x61, 0x6e, 0x64, 0x6f, - 0x6d, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x62, 0x0a, 0x17, 0x67, - 0x69, 0x73, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6d, - 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, - 0x2e, 0x47, 0x49, 0x53, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x15, 0x67, 0x69, 0x73, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x78, 0x70, 0x72, 0x12, - 0x75, 0x0a, 0x1e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x74, 0x7a, 0x5f, 0x61, - 0x72, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x70, - 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x74, 0x7a, 0x41, 0x72, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6d, 0x70, - 0x61, 0x72, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x1b, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x74, 0x7a, 0x41, 0x72, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6d, 0x70, 0x61, - 0x72, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x74, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x54, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x22, - 0x86, 0x02, 0x0a, 0x0a, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x4e, 0x4e, 0x53, 0x12, 0x3e, - 0x0a, 0x0b, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 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, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0a, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, - 0x0a, 0x08, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x70, 0x72, 0x65, - 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x03, 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, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 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, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x27, 0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x74, - 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, - 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x54, 0x61, 0x67, 0x22, 0x79, 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, 0x70, 0x72, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, - 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 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, + 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x72, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x81, 0x0c, 0x0a, 0x04, 0x45, 0x78, 0x70, 0x72, + 0x12, 0x3a, 0x0a, 0x09, 0x74, 0x65, 0x72, 0x6d, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x45, 0x78, 0x70, 0x72, + 0x48, 0x00, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3d, 0x0a, 0x0a, + 0x75, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, + 0x52, 0x09, 0x75, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x62, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x03, 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, + 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x48, + 0x00, 0x52, 0x0a, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x12, 0x43, 0x0a, + 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x04, 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, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x45, + 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x45, 0x78, + 0x70, 0x72, 0x12, 0x4d, 0x0a, 0x10, 0x75, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, + 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, + 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, + 0x00, 0x52, 0x0e, 0x75, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, + 0x72, 0x12, 0x50, 0x0a, 0x11, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, + 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, + 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, + 0x48, 0x00, 0x52, 0x0f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, + 0x78, 0x70, 0x72, 0x12, 0x74, 0x0a, 0x1f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x72, + 0x69, 0x74, 0x68, 0x5f, 0x6f, 0x70, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6d, + 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, + 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x45, 0x76, + 0x61, 0x6c, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x1a, 0x62, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x45, 0x76, 0x61, 0x6c, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x50, 0x0a, 0x11, 0x62, 0x69, 0x6e, + 0x61, 0x72, 0x79, 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x41, + 0x72, 0x69, 0x74, 0x68, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x62, 0x69, 0x6e, 0x61, + 0x72, 0x79, 0x41, 0x72, 0x69, 0x74, 0x68, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3d, 0x0a, 0x0a, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, + 0x6c, 0x61, 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, + 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x63, 0x6f, + 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x0a, 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, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, + 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x12, 0x40, 0x0a, 0x0b, + 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x0b, 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, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x45, 0x78, 0x70, 0x72, + 0x48, 0x00, 0x52, 0x0a, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x45, 0x78, 0x70, 0x72, 0x12, 0x4d, + 0x0a, 0x10, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x5f, 0x74, 0x72, 0x75, 0x65, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x77, + 0x61, 0x79, 0x73, 0x54, 0x72, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x0e, 0x61, + 0x6c, 0x77, 0x61, 0x79, 0x73, 0x54, 0x72, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x53, 0x0a, + 0x12, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x5f, 0x65, + 0x78, 0x70, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x69, 0x6c, 0x76, + 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4a, 0x53, + 0x4f, 0x4e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, + 0x52, 0x10, 0x6a, 0x73, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x78, + 0x70, 0x72, 0x12, 0x3a, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, + 0x70, 0x72, 0x48, 0x00, 0x52, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3a, + 0x0a, 0x09, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, + 0x52, 0x08, 0x6e, 0x75, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x12, 0x53, 0x0a, 0x12, 0x72, 0x61, + 0x6e, 0x64, 0x6f, 0x6d, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, + 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x52, 0x61, 0x6e, 0x64, 0x6f, + 0x6d, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x10, 0x72, + 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, + 0x62, 0x0a, 0x17, 0x67, 0x69, 0x73, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x28, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x47, 0x49, 0x53, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x15, 0x67, 0x69, + 0x73, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, + 0x78, 0x70, 0x72, 0x12, 0x75, 0x0a, 0x1e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x74, 0x7a, 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, + 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6d, 0x69, + 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x74, 0x7a, 0x41, 0x72, 0x69, 0x74, 0x68, + 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x1b, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x74, 0x7a, 0x41, 0x72, 0x69, 0x74, 0x68, 0x43, + 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x56, 0x0a, 0x13, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x65, 0x78, 0x70, + 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x45, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, + 0x11, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x78, + 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x22, 0x86, 0x02, 0x0a, 0x0a, + 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x4e, 0x4e, 0x53, 0x12, 0x3e, 0x0a, 0x0b, 0x76, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 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, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, + 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x73, 0x18, 0x03, 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, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x3b, + 0x0a, 0x0a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 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, 0x6e, 0x66, 0x6f, + 0x52, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x27, 0x0a, 0x0f, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, + 0x72, 0x54, 0x61, 0x67, 0x22, 0x79, 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, + 0x70, 0x72, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x19, + 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 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, 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, 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, + 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, 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 ( @@ -3875,7 +3978,7 @@ func file_plan_proto_rawDescGZIP() []byte { } var file_plan_proto_enumTypes = make([]protoimpl.EnumInfo, 11) -var file_plan_proto_msgTypes = make([]protoimpl.MessageInfo, 32) +var file_plan_proto_msgTypes = make([]protoimpl.MessageInfo, 33) var file_plan_proto_goTypes = []interface{}{ (OpType)(0), // 0: milvus.proto.plan.OpType (ArithOpType)(0), // 1: milvus.proto.plan.ArithOpType @@ -3910,27 +4013,28 @@ var file_plan_proto_goTypes = []interface{}{ (*BinaryArithExpr)(nil), // 30: milvus.proto.plan.BinaryArithExpr (*BinaryArithOpEvalRangeExpr)(nil), // 31: milvus.proto.plan.BinaryArithOpEvalRangeExpr (*RandomSampleExpr)(nil), // 32: milvus.proto.plan.RandomSampleExpr - (*AlwaysTrueExpr)(nil), // 33: milvus.proto.plan.AlwaysTrueExpr - (*Interval)(nil), // 34: milvus.proto.plan.Interval - (*TimestamptzArithCompareExpr)(nil), // 35: milvus.proto.plan.TimestamptzArithCompareExpr - (*Expr)(nil), // 36: milvus.proto.plan.Expr - (*VectorANNS)(nil), // 37: milvus.proto.plan.VectorANNS - (*QueryPlanNode)(nil), // 38: milvus.proto.plan.QueryPlanNode - (*ScoreFunction)(nil), // 39: milvus.proto.plan.ScoreFunction - (*ScoreOption)(nil), // 40: milvus.proto.plan.ScoreOption - (*PlanOption)(nil), // 41: milvus.proto.plan.PlanOption - (*PlanNode)(nil), // 42: milvus.proto.plan.PlanNode - (schemapb.DataType)(0), // 43: milvus.proto.schema.DataType - (*commonpb.KeyValuePair)(nil), // 44: milvus.proto.common.KeyValuePair + (*ElementFilterExpr)(nil), // 33: milvus.proto.plan.ElementFilterExpr + (*AlwaysTrueExpr)(nil), // 34: milvus.proto.plan.AlwaysTrueExpr + (*Interval)(nil), // 35: milvus.proto.plan.Interval + (*TimestamptzArithCompareExpr)(nil), // 36: milvus.proto.plan.TimestamptzArithCompareExpr + (*Expr)(nil), // 37: milvus.proto.plan.Expr + (*VectorANNS)(nil), // 38: milvus.proto.plan.VectorANNS + (*QueryPlanNode)(nil), // 39: milvus.proto.plan.QueryPlanNode + (*ScoreFunction)(nil), // 40: milvus.proto.plan.ScoreFunction + (*ScoreOption)(nil), // 41: milvus.proto.plan.ScoreOption + (*PlanOption)(nil), // 42: milvus.proto.plan.PlanOption + (*PlanNode)(nil), // 43: milvus.proto.plan.PlanNode + (schemapb.DataType)(0), // 44: milvus.proto.schema.DataType + (*commonpb.KeyValuePair)(nil), // 45: milvus.proto.common.KeyValuePair } var file_plan_proto_depIdxs = []int32{ 12, // 0: milvus.proto.plan.GenericValue.array_val:type_name -> milvus.proto.plan.Array 11, // 1: milvus.proto.plan.Array.array:type_name -> milvus.proto.plan.GenericValue - 43, // 2: milvus.proto.plan.Array.element_type:type_name -> milvus.proto.schema.DataType + 44, // 2: milvus.proto.plan.Array.element_type:type_name -> milvus.proto.schema.DataType 13, // 3: milvus.proto.plan.QueryInfo.search_iterator_v2_info:type_name -> milvus.proto.plan.SearchIteratorV2Info - 43, // 4: milvus.proto.plan.QueryInfo.json_type:type_name -> milvus.proto.schema.DataType - 43, // 5: milvus.proto.plan.ColumnInfo.data_type:type_name -> milvus.proto.schema.DataType - 43, // 6: milvus.proto.plan.ColumnInfo.element_type:type_name -> milvus.proto.schema.DataType + 44, // 4: milvus.proto.plan.QueryInfo.json_type:type_name -> milvus.proto.schema.DataType + 44, // 5: milvus.proto.plan.ColumnInfo.data_type:type_name -> milvus.proto.schema.DataType + 44, // 6: milvus.proto.plan.ColumnInfo.element_type:type_name -> milvus.proto.schema.DataType 15, // 7: milvus.proto.plan.ColumnExpr.info:type_name -> milvus.proto.plan.ColumnInfo 15, // 8: milvus.proto.plan.ExistsExpr.info:type_name -> milvus.proto.plan.ColumnInfo 11, // 9: milvus.proto.plan.ValueExpr.value:type_name -> milvus.proto.plan.GenericValue @@ -3941,7 +4045,7 @@ var file_plan_proto_depIdxs = []int32{ 15, // 14: milvus.proto.plan.BinaryRangeExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo 11, // 15: milvus.proto.plan.BinaryRangeExpr.lower_value:type_name -> milvus.proto.plan.GenericValue 11, // 16: milvus.proto.plan.BinaryRangeExpr.upper_value:type_name -> milvus.proto.plan.GenericValue - 36, // 17: milvus.proto.plan.CallExpr.function_parameters:type_name -> milvus.proto.plan.Expr + 37, // 17: milvus.proto.plan.CallExpr.function_parameters:type_name -> milvus.proto.plan.Expr 15, // 18: milvus.proto.plan.CompareExpr.left_column_info:type_name -> milvus.proto.plan.ColumnInfo 15, // 19: milvus.proto.plan.CompareExpr.right_column_info:type_name -> milvus.proto.plan.ColumnInfo 0, // 20: milvus.proto.plan.CompareExpr.op:type_name -> milvus.proto.plan.OpType @@ -3955,65 +4059,68 @@ var file_plan_proto_depIdxs = []int32{ 15, // 28: milvus.proto.plan.GISFunctionFilterExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo 8, // 29: milvus.proto.plan.GISFunctionFilterExpr.op:type_name -> milvus.proto.plan.GISFunctionFilterExpr.GISOp 9, // 30: milvus.proto.plan.UnaryExpr.op:type_name -> milvus.proto.plan.UnaryExpr.UnaryOp - 36, // 31: milvus.proto.plan.UnaryExpr.child:type_name -> milvus.proto.plan.Expr + 37, // 31: milvus.proto.plan.UnaryExpr.child:type_name -> milvus.proto.plan.Expr 10, // 32: milvus.proto.plan.BinaryExpr.op:type_name -> milvus.proto.plan.BinaryExpr.BinaryOp - 36, // 33: milvus.proto.plan.BinaryExpr.left:type_name -> milvus.proto.plan.Expr - 36, // 34: milvus.proto.plan.BinaryExpr.right:type_name -> milvus.proto.plan.Expr + 37, // 33: milvus.proto.plan.BinaryExpr.left:type_name -> milvus.proto.plan.Expr + 37, // 34: milvus.proto.plan.BinaryExpr.right:type_name -> milvus.proto.plan.Expr 15, // 35: milvus.proto.plan.BinaryArithOp.column_info:type_name -> milvus.proto.plan.ColumnInfo 1, // 36: milvus.proto.plan.BinaryArithOp.arith_op:type_name -> milvus.proto.plan.ArithOpType 11, // 37: milvus.proto.plan.BinaryArithOp.right_operand:type_name -> milvus.proto.plan.GenericValue - 36, // 38: milvus.proto.plan.BinaryArithExpr.left:type_name -> milvus.proto.plan.Expr - 36, // 39: milvus.proto.plan.BinaryArithExpr.right:type_name -> milvus.proto.plan.Expr + 37, // 38: milvus.proto.plan.BinaryArithExpr.left:type_name -> milvus.proto.plan.Expr + 37, // 39: milvus.proto.plan.BinaryArithExpr.right:type_name -> milvus.proto.plan.Expr 1, // 40: milvus.proto.plan.BinaryArithExpr.op:type_name -> milvus.proto.plan.ArithOpType 15, // 41: milvus.proto.plan.BinaryArithOpEvalRangeExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo 1, // 42: milvus.proto.plan.BinaryArithOpEvalRangeExpr.arith_op:type_name -> milvus.proto.plan.ArithOpType 11, // 43: milvus.proto.plan.BinaryArithOpEvalRangeExpr.right_operand:type_name -> milvus.proto.plan.GenericValue 0, // 44: milvus.proto.plan.BinaryArithOpEvalRangeExpr.op:type_name -> milvus.proto.plan.OpType 11, // 45: milvus.proto.plan.BinaryArithOpEvalRangeExpr.value:type_name -> milvus.proto.plan.GenericValue - 36, // 46: milvus.proto.plan.RandomSampleExpr.predicate:type_name -> milvus.proto.plan.Expr - 15, // 47: milvus.proto.plan.TimestamptzArithCompareExpr.timestamptz_column:type_name -> milvus.proto.plan.ColumnInfo - 1, // 48: milvus.proto.plan.TimestamptzArithCompareExpr.arith_op:type_name -> milvus.proto.plan.ArithOpType - 34, // 49: milvus.proto.plan.TimestamptzArithCompareExpr.interval:type_name -> milvus.proto.plan.Interval - 0, // 50: milvus.proto.plan.TimestamptzArithCompareExpr.compare_op:type_name -> milvus.proto.plan.OpType - 11, // 51: milvus.proto.plan.TimestamptzArithCompareExpr.compare_value:type_name -> milvus.proto.plan.GenericValue - 23, // 52: milvus.proto.plan.Expr.term_expr:type_name -> milvus.proto.plan.TermExpr - 27, // 53: milvus.proto.plan.Expr.unary_expr:type_name -> milvus.proto.plan.UnaryExpr - 28, // 54: milvus.proto.plan.Expr.binary_expr:type_name -> milvus.proto.plan.BinaryExpr - 22, // 55: milvus.proto.plan.Expr.compare_expr:type_name -> milvus.proto.plan.CompareExpr - 19, // 56: milvus.proto.plan.Expr.unary_range_expr:type_name -> milvus.proto.plan.UnaryRangeExpr - 20, // 57: milvus.proto.plan.Expr.binary_range_expr:type_name -> milvus.proto.plan.BinaryRangeExpr - 31, // 58: milvus.proto.plan.Expr.binary_arith_op_eval_range_expr:type_name -> milvus.proto.plan.BinaryArithOpEvalRangeExpr - 30, // 59: milvus.proto.plan.Expr.binary_arith_expr:type_name -> milvus.proto.plan.BinaryArithExpr - 18, // 60: milvus.proto.plan.Expr.value_expr:type_name -> milvus.proto.plan.ValueExpr - 16, // 61: milvus.proto.plan.Expr.column_expr:type_name -> milvus.proto.plan.ColumnExpr - 17, // 62: milvus.proto.plan.Expr.exists_expr:type_name -> milvus.proto.plan.ExistsExpr - 33, // 63: milvus.proto.plan.Expr.always_true_expr:type_name -> milvus.proto.plan.AlwaysTrueExpr - 24, // 64: milvus.proto.plan.Expr.json_contains_expr:type_name -> milvus.proto.plan.JSONContainsExpr - 21, // 65: milvus.proto.plan.Expr.call_expr:type_name -> milvus.proto.plan.CallExpr - 25, // 66: milvus.proto.plan.Expr.null_expr:type_name -> milvus.proto.plan.NullExpr - 32, // 67: milvus.proto.plan.Expr.random_sample_expr:type_name -> milvus.proto.plan.RandomSampleExpr - 26, // 68: milvus.proto.plan.Expr.gisfunction_filter_expr:type_name -> milvus.proto.plan.GISFunctionFilterExpr - 35, // 69: milvus.proto.plan.Expr.timestamptz_arith_compare_expr:type_name -> milvus.proto.plan.TimestamptzArithCompareExpr - 2, // 70: milvus.proto.plan.VectorANNS.vector_type:type_name -> milvus.proto.plan.VectorType - 36, // 71: milvus.proto.plan.VectorANNS.predicates:type_name -> milvus.proto.plan.Expr - 14, // 72: milvus.proto.plan.VectorANNS.query_info:type_name -> milvus.proto.plan.QueryInfo - 36, // 73: milvus.proto.plan.QueryPlanNode.predicates:type_name -> milvus.proto.plan.Expr - 36, // 74: milvus.proto.plan.ScoreFunction.filter:type_name -> milvus.proto.plan.Expr - 3, // 75: milvus.proto.plan.ScoreFunction.type:type_name -> milvus.proto.plan.FunctionType - 44, // 76: milvus.proto.plan.ScoreFunction.params:type_name -> milvus.proto.common.KeyValuePair - 5, // 77: milvus.proto.plan.ScoreOption.boost_mode:type_name -> milvus.proto.plan.BoostMode - 4, // 78: milvus.proto.plan.ScoreOption.function_mode:type_name -> milvus.proto.plan.FunctionMode - 37, // 79: milvus.proto.plan.PlanNode.vector_anns:type_name -> milvus.proto.plan.VectorANNS - 36, // 80: milvus.proto.plan.PlanNode.predicates:type_name -> milvus.proto.plan.Expr - 38, // 81: milvus.proto.plan.PlanNode.query:type_name -> milvus.proto.plan.QueryPlanNode - 39, // 82: milvus.proto.plan.PlanNode.scorers:type_name -> milvus.proto.plan.ScoreFunction - 41, // 83: milvus.proto.plan.PlanNode.plan_options:type_name -> milvus.proto.plan.PlanOption - 40, // 84: milvus.proto.plan.PlanNode.score_option:type_name -> milvus.proto.plan.ScoreOption - 85, // [85:85] is the sub-list for method output_type - 85, // [85:85] is the sub-list for method input_type - 85, // [85:85] is the sub-list for extension type_name - 85, // [85:85] is the sub-list for extension extendee - 0, // [0:85] is the sub-list for field type_name + 37, // 46: milvus.proto.plan.RandomSampleExpr.predicate:type_name -> milvus.proto.plan.Expr + 37, // 47: milvus.proto.plan.ElementFilterExpr.element_expr:type_name -> milvus.proto.plan.Expr + 37, // 48: milvus.proto.plan.ElementFilterExpr.predicate:type_name -> milvus.proto.plan.Expr + 15, // 49: milvus.proto.plan.TimestamptzArithCompareExpr.timestamptz_column:type_name -> milvus.proto.plan.ColumnInfo + 1, // 50: milvus.proto.plan.TimestamptzArithCompareExpr.arith_op:type_name -> milvus.proto.plan.ArithOpType + 35, // 51: milvus.proto.plan.TimestamptzArithCompareExpr.interval:type_name -> milvus.proto.plan.Interval + 0, // 52: milvus.proto.plan.TimestamptzArithCompareExpr.compare_op:type_name -> milvus.proto.plan.OpType + 11, // 53: milvus.proto.plan.TimestamptzArithCompareExpr.compare_value:type_name -> milvus.proto.plan.GenericValue + 23, // 54: milvus.proto.plan.Expr.term_expr:type_name -> milvus.proto.plan.TermExpr + 27, // 55: milvus.proto.plan.Expr.unary_expr:type_name -> milvus.proto.plan.UnaryExpr + 28, // 56: milvus.proto.plan.Expr.binary_expr:type_name -> milvus.proto.plan.BinaryExpr + 22, // 57: milvus.proto.plan.Expr.compare_expr:type_name -> milvus.proto.plan.CompareExpr + 19, // 58: milvus.proto.plan.Expr.unary_range_expr:type_name -> milvus.proto.plan.UnaryRangeExpr + 20, // 59: milvus.proto.plan.Expr.binary_range_expr:type_name -> milvus.proto.plan.BinaryRangeExpr + 31, // 60: milvus.proto.plan.Expr.binary_arith_op_eval_range_expr:type_name -> milvus.proto.plan.BinaryArithOpEvalRangeExpr + 30, // 61: milvus.proto.plan.Expr.binary_arith_expr:type_name -> milvus.proto.plan.BinaryArithExpr + 18, // 62: milvus.proto.plan.Expr.value_expr:type_name -> milvus.proto.plan.ValueExpr + 16, // 63: milvus.proto.plan.Expr.column_expr:type_name -> milvus.proto.plan.ColumnExpr + 17, // 64: milvus.proto.plan.Expr.exists_expr:type_name -> milvus.proto.plan.ExistsExpr + 34, // 65: milvus.proto.plan.Expr.always_true_expr:type_name -> milvus.proto.plan.AlwaysTrueExpr + 24, // 66: milvus.proto.plan.Expr.json_contains_expr:type_name -> milvus.proto.plan.JSONContainsExpr + 21, // 67: milvus.proto.plan.Expr.call_expr:type_name -> milvus.proto.plan.CallExpr + 25, // 68: milvus.proto.plan.Expr.null_expr:type_name -> milvus.proto.plan.NullExpr + 32, // 69: milvus.proto.plan.Expr.random_sample_expr:type_name -> milvus.proto.plan.RandomSampleExpr + 26, // 70: milvus.proto.plan.Expr.gisfunction_filter_expr:type_name -> milvus.proto.plan.GISFunctionFilterExpr + 36, // 71: milvus.proto.plan.Expr.timestamptz_arith_compare_expr:type_name -> milvus.proto.plan.TimestamptzArithCompareExpr + 33, // 72: milvus.proto.plan.Expr.element_filter_expr:type_name -> milvus.proto.plan.ElementFilterExpr + 2, // 73: milvus.proto.plan.VectorANNS.vector_type:type_name -> milvus.proto.plan.VectorType + 37, // 74: milvus.proto.plan.VectorANNS.predicates:type_name -> milvus.proto.plan.Expr + 14, // 75: milvus.proto.plan.VectorANNS.query_info:type_name -> milvus.proto.plan.QueryInfo + 37, // 76: milvus.proto.plan.QueryPlanNode.predicates:type_name -> milvus.proto.plan.Expr + 37, // 77: milvus.proto.plan.ScoreFunction.filter:type_name -> milvus.proto.plan.Expr + 3, // 78: milvus.proto.plan.ScoreFunction.type:type_name -> milvus.proto.plan.FunctionType + 45, // 79: milvus.proto.plan.ScoreFunction.params:type_name -> milvus.proto.common.KeyValuePair + 5, // 80: milvus.proto.plan.ScoreOption.boost_mode:type_name -> milvus.proto.plan.BoostMode + 4, // 81: milvus.proto.plan.ScoreOption.function_mode:type_name -> milvus.proto.plan.FunctionMode + 38, // 82: milvus.proto.plan.PlanNode.vector_anns:type_name -> milvus.proto.plan.VectorANNS + 37, // 83: milvus.proto.plan.PlanNode.predicates:type_name -> milvus.proto.plan.Expr + 39, // 84: milvus.proto.plan.PlanNode.query:type_name -> milvus.proto.plan.QueryPlanNode + 40, // 85: milvus.proto.plan.PlanNode.scorers:type_name -> milvus.proto.plan.ScoreFunction + 42, // 86: milvus.proto.plan.PlanNode.plan_options:type_name -> milvus.proto.plan.PlanOption + 41, // 87: milvus.proto.plan.PlanNode.score_option:type_name -> milvus.proto.plan.ScoreOption + 88, // [88:88] is the sub-list for method output_type + 88, // [88:88] is the sub-list for method input_type + 88, // [88:88] is the sub-list for extension type_name + 88, // [88:88] is the sub-list for extension extendee + 0, // [0:88] is the sub-list for field type_name } func init() { file_plan_proto_init() } @@ -4287,7 +4394,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AlwaysTrueExpr); i { + switch v := v.(*ElementFilterExpr); i { case 0: return &v.state case 1: @@ -4299,7 +4406,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interval); i { + switch v := v.(*AlwaysTrueExpr); i { case 0: return &v.state case 1: @@ -4311,7 +4418,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TimestamptzArithCompareExpr); i { + switch v := v.(*Interval); i { case 0: return &v.state case 1: @@ -4323,7 +4430,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr); i { + switch v := v.(*TimestamptzArithCompareExpr); i { case 0: return &v.state case 1: @@ -4335,7 +4442,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VectorANNS); i { + switch v := v.(*Expr); i { case 0: return &v.state case 1: @@ -4347,7 +4454,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryPlanNode); i { + switch v := v.(*VectorANNS); i { case 0: return &v.state case 1: @@ -4359,7 +4466,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ScoreFunction); i { + switch v := v.(*QueryPlanNode); i { case 0: return &v.state case 1: @@ -4371,7 +4478,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ScoreOption); i { + switch v := v.(*ScoreFunction); i { case 0: return &v.state case 1: @@ -4383,7 +4490,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlanOption); i { + switch v := v.(*ScoreOption); i { case 0: return &v.state case 1: @@ -4395,6 +4502,18 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[31].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[32].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanNode); i { case 0: return &v.state @@ -4416,7 +4535,7 @@ func file_plan_proto_init() { } file_plan_proto_msgTypes[2].OneofWrappers = []interface{}{} file_plan_proto_msgTypes[3].OneofWrappers = []interface{}{} - file_plan_proto_msgTypes[25].OneofWrappers = []interface{}{ + file_plan_proto_msgTypes[26].OneofWrappers = []interface{}{ (*Expr_TermExpr)(nil), (*Expr_UnaryExpr)(nil), (*Expr_BinaryExpr)(nil), @@ -4435,8 +4554,9 @@ func file_plan_proto_init() { (*Expr_RandomSampleExpr)(nil), (*Expr_GisfunctionFilterExpr)(nil), (*Expr_TimestamptzArithCompareExpr)(nil), + (*Expr_ElementFilterExpr)(nil), } - file_plan_proto_msgTypes[31].OneofWrappers = []interface{}{ + file_plan_proto_msgTypes[32].OneofWrappers = []interface{}{ (*PlanNode_VectorAnns)(nil), (*PlanNode_Predicates)(nil), (*PlanNode_Query)(nil), @@ -4447,7 +4567,7 @@ func file_plan_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_plan_proto_rawDesc, NumEnums: 11, - NumMessages: 32, + NumMessages: 33, NumExtensions: 0, NumServices: 0, },