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, },