From cd931a0388e57f0b474f4d272ebd6294048f6869 Mon Sep 17 00:00:00 2001 From: ZhuXi <150327960+Yinwei-Yu@users.noreply.github.com> Date: Tue, 26 Aug 2025 19:11:55 +0800 Subject: [PATCH] feat:Geospatial Data Type and GIS Function support for milvus (#43661) issue: #43427 pr: #37417 This pr's main goal is merge #37417 to milvus 2.5 without conflicts. # Main Goals 1. Create and describe collections with geospatial type 2. Insert geospatial data into the insert binlog 3. Load segments containing geospatial data into memory 4. Enable query and search can display geospatial data 5. Support using GIS funtions like ST_EQUALS in query # Solution 1. **Add Type**: Modify the Milvus core by adding a Geospatial type in both the C++ and Go code layers, defining the Geospatial data structure and the corresponding interfaces. 2. **Dependency Libraries**: Introduce necessary geospatial data processing libraries. In the C++ source code, use Conan package management to include the GDAL library. In the Go source code, add the go-geom library to the go.mod file. 3. **Protocol Interface**: Revise the Milvus protocol to provide mechanisms for Geospatial message serialization and deserialization. 4. **Data Pipeline**: Facilitate interaction between the client and proxy using the WKT format for geospatial data. The proxy will convert all data into WKB format for downstream processing, providing column data interfaces, segment encapsulation, segment loading, payload writing, and cache block management. 5. **Query Operators**: Implement simple display and support for filter queries. Initially, focus on filtering based on spatial relationships for a single column of geospatial literal values, providing parsing and execution for query expressions.Now only support brutal search 6. **Client Modification**: Enable the client to handle user input for geospatial data and facilitate end-to-end testing.Check the modification in pymilvus. --------- Signed-off-by: Yinwei Li Signed-off-by: Cai Zhang Co-authored-by: cai.zhang --- client/column/geometry.go | 117 ++ client/column/geometry_test.go | 82 ++ client/entity/field.go | 8 + client/go.mod | 2 +- client/go.sum | 4 +- client/milvusclient/client_suite_test.go | 16 + go.mod | 38 +- go.sum | 81 +- internal/core/conanfile.py | 15 +- internal/core/src/common/Array.h | 24 +- internal/core/src/common/Chunk.h | 2 + internal/core/src/common/ChunkWriter.cpp | 65 + internal/core/src/common/ChunkWriter.h | 11 + internal/core/src/common/FieldData.cpp | 17 + internal/core/src/common/FieldData.h | 11 + internal/core/src/common/FieldDataInterface.h | 69 ++ internal/core/src/common/Geometry.h | 142 +++ internal/core/src/common/Types.h | 30 +- internal/core/src/common/VectorTrait.h | 8 +- internal/core/src/exec/expression/Expr.cpp | 13 +- .../exec/expression/GISFunctionFilterExpr.cpp | 152 +++ .../exec/expression/GISFunctionFilterExpr.h | 61 + internal/core/src/expr/ITypeExpr.h | 24 + internal/core/src/mmap/Utils.h | 22 + internal/core/src/query/PlanProto.cpp | 23 + internal/core/src/query/PlanProto.h | 4 + .../src/segcore/ChunkedSegmentSealedImpl.cpp | 33 + .../core/src/segcore/ConcurrentVector.cpp | 12 + internal/core/src/segcore/InsertRecord.h | 5 + .../core/src/segcore/SegmentGrowingImpl.cpp | 9 + .../core/src/segcore/SegmentSealedImpl.cpp | 35 + internal/core/src/segcore/Utils.cpp | 33 + internal/core/src/storage/Event.cpp | 12 + internal/core/src/storage/Util.cpp | 9 +- .../unittest/test_cached_search_iterator.cpp | 3 +- internal/core/unittest/test_chunk.cpp | 210 +++- internal/core/unittest/test_chunk_vector.cpp | 5 + .../core/unittest/test_chunked_segment.cpp | 10 +- internal/core/unittest/test_data_codec.cpp | 105 ++ internal/core/unittest/test_expr.cpp | 405 +++++++ internal/core/unittest/test_group_by.cpp | 5 +- internal/core/unittest/test_growing.cpp | 5 + internal/core/unittest/test_sealed.cpp | 61 + internal/core/unittest/test_utils/DataGen.h | 137 +++ .../distributed/proxy/httpserver/utils.go | 44 + .../proxy/httpserver/utils_test.go | 40 +- internal/parser/planparserv2/Plan.g4 | 15 + .../parser/planparserv2/generated/Plan.interp | 16 +- .../parser/planparserv2/generated/Plan.tokens | 27 +- .../planparserv2/generated/PlanLexer.interp | 23 +- .../planparserv2/generated/PlanLexer.tokens | 27 +- .../generated/plan_base_visitor.go | 28 + .../planparserv2/generated/plan_lexer.go | 874 +++++++------- .../planparserv2/generated/plan_parser.go | 1044 ++++++++++++++--- .../planparserv2/generated/plan_visitor.go | 21 + .../parser/planparserv2/parser_visitor.go | 215 ++++ internal/parser/planparserv2/utils.go | 5 + internal/proxy/task_insert_test.go | 3 + internal/proxy/task_query.go | 4 + internal/proxy/task_search.go | 4 + internal/proxy/task_test.go | 15 + internal/proxy/validate_util.go | 110 +- internal/storage/data_codec.go | 21 + internal/storage/data_sorter.go | 3 + internal/storage/insert_data.go | 88 ++ internal/storage/payload.go | 2 + internal/storage/payload_reader.go | 22 + internal/storage/payload_writer.go | 44 + internal/storage/print_binlog.go | 20 + internal/storage/print_binlog_test.go | 21 + internal/storage/serde.go | 1 + internal/storage/utils.go | 22 + internal/storage/utils_test.go | 25 +- .../util/importutilv2/parquet/field_reader.go | 42 + .../util/importutilv2/parquet/reader_test.go | 2 + internal/util/importutilv2/parquet/util.go | 2 + .../indexparamcheck/inverted_checker_test.go | 1 + internal/util/testutil/test_util.go | 11 + internal/util/typeutil/schema.go | 5 + internal/util/typeutil/storage.go | 2 + pkg/go.mod | 28 +- pkg/go.sum | 77 +- pkg/proto/plan.proto | 17 + pkg/proto/planpb/plan.pb.go | 908 ++++++++------ pkg/util/funcutil/func.go | 4 + pkg/util/testutils/gen_data.go | 105 ++ pkg/util/typeutil/gen_empty_field_data.go | 16 + pkg/util/typeutil/schema.go | 50 +- pkg/util/typeutil/schema_test.go | 78 +- tests/go_client/common/consts.go | 2 +- tests/go_client/common/response_checker.go | 14 + tests/go_client/go.mod | 20 +- tests/go_client/go.sum | 47 +- .../go_client/testcases/helper/data_helper.go | 22 + .../testcases/helper/field_helper.go | 2 + tests/go_client/testcases/helper/helper.go | 3 + .../testcases/helper/index_helper.go | 2 +- tests/go_client/testcases/index_test.go | 4 +- .../compaction/mix_compaction_test.go | 2 + tests/integration/import/import_test.go | 27 +- tests/integration/util_insert.go | 5 + tests/integration/util_schema.go | 57 +- .../geometry_comprehensive_test.py | 327 ++++++ 103 files changed, 5658 insertions(+), 1143 deletions(-) create mode 100644 client/column/geometry.go create mode 100644 client/column/geometry_test.go create mode 100644 internal/core/src/common/Geometry.h create mode 100644 internal/core/src/exec/expression/GISFunctionFilterExpr.cpp create mode 100644 internal/core/src/exec/expression/GISFunctionFilterExpr.h create mode 100644 tests/python_client/geometry_comprehensive_test.py diff --git a/client/column/geometry.go b/client/column/geometry.go new file mode 100644 index 0000000000..066498a4d0 --- /dev/null +++ b/client/column/geometry.go @@ -0,0 +1,117 @@ +package column + +import ( + "fmt" + + "github.com/cockroachdb/errors" + + "github.com/milvus-io/milvus-proto/go-api/v2/schemapb" + "github.com/milvus-io/milvus/client/v2/entity" +) + +type ColumnGeometryBytes struct { + *genericColumnBase[[]byte] +} + +// Name returns column name. +func (c *ColumnGeometryBytes) Name() string { + return c.name +} + +// Type returns column entity.FieldType. +func (c *ColumnGeometryBytes) Type() entity.FieldType { + return entity.FieldTypeGeometry +} + +// Len returns column values length. +func (c *ColumnGeometryBytes) Len() int { + return len(c.values) +} + +func (c *ColumnGeometryBytes) Slice(start, end int) Column { + l := c.Len() + if start > l { + start = l + } + if end == -1 || end > l { + end = l + } + return &ColumnGeometryBytes{ + genericColumnBase: c.genericColumnBase.slice(start, end), + } +} + +// Get returns value at index as interface{}. +func (c *ColumnGeometryBytes) Get(idx int) (interface{}, error) { + if idx < 0 || idx >= c.Len() { + return nil, errors.New("index out of range") + } + return c.values[idx], nil +} + +func (c *ColumnGeometryBytes) GetAsString(idx int) (string, error) { + bs, err := c.ValueByIdx(idx) + if err != nil { + return "", err + } + return string(bs), nil +} + +// FieldData return column data mapped to schemapb.FieldData. +func (c *ColumnGeometryBytes) FieldData() *schemapb.FieldData { + fd := &schemapb.FieldData{ + Type: schemapb.DataType_Geometry, + FieldName: c.name, + } + + fd.Field = &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: c.values, + }, + }, + }, + } + + return fd +} + +// ValueByIdx returns value of the provided index. +func (c *ColumnGeometryBytes) ValueByIdx(idx int) ([]byte, error) { + if idx < 0 || idx >= c.Len() { + return nil, errors.New("index out of range") + } + return c.values[idx], nil +} + +// AppendValue append value into column. +func (c *ColumnGeometryBytes) AppendValue(i interface{}) error { + var v []byte + switch raw := i.(type) { + case []byte: + v = raw + case string: + v = []byte(raw) + default: + return fmt.Errorf("expect geometry compatible type([]byte, struct, map), got %T", i) + } + c.values = append(c.values, v) + + return nil +} + +// Data returns column data. +func (c *ColumnGeometryBytes) Data() [][]byte { + return c.values +} + +func NewColumnGeometryBytes(name string, values [][]byte) *ColumnGeometryBytes { + return &ColumnGeometryBytes{ + genericColumnBase: &genericColumnBase[[]byte]{ + name: name, + fieldType: entity.FieldTypeGeometry, + values: values, + }, + } +} diff --git a/client/column/geometry_test.go b/client/column/geometry_test.go new file mode 100644 index 0000000000..cea570338e --- /dev/null +++ b/client/column/geometry_test.go @@ -0,0 +1,82 @@ +package column + +import ( + "fmt" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/suite" + + "github.com/milvus-io/milvus/client/v2/entity" +) + +type ColumnGeometryBytesSuite struct { + suite.Suite +} + +func (s *ColumnGeometryBytesSuite) SetupSuite() { + rand.Seed(time.Now().UnixNano()) +} + +func (s *ColumnGeometryBytesSuite) TestAttrMethods() { + columnName := fmt.Sprintf("column_Geometrybs_%d", rand.Int()) + columnLen := 8 + rand.Intn(10) + + v := make([][]byte, columnLen) + column := NewColumnGeometryBytes(columnName, v) + + s.Run("test_meta", func() { + ft := entity.FieldTypeGeometry + s.Equal("Geometry", ft.Name()) + s.Equal("Geometry", ft.String()) + pbName, pbType := ft.PbFieldType() + s.Equal("Geometry", pbName) + s.Equal("Geometry", pbType) + }) + + s.Run("test_column_attribute", func() { + s.Equal(columnName, column.Name()) + s.Equal(entity.FieldTypeGeometry, column.Type()) + s.Equal(columnLen, column.Len()) + s.EqualValues(v, column.Data()) + }) + + s.Run("test_column_field_data", func() { + fd := column.FieldData() + s.NotNil(fd) + s.Equal(fd.GetFieldName(), columnName) + }) + + s.Run("test_column_valuer_by_idx", func() { + _, err := column.ValueByIdx(-1) + s.Error(err) + _, err = column.ValueByIdx(columnLen) + s.Error(err) + for i := 0; i < columnLen; i++ { + v, err := column.ValueByIdx(i) + s.NoError(err) + s.Equal(column.values[i], v) + } + }) + + s.Run("test_append_value", func() { + item := make([]byte, 10) + err := column.AppendValue(item) + s.NoError(err) + s.Equal(columnLen+1, column.Len()) + val, err := column.ValueByIdx(columnLen) + s.NoError(err) + s.Equal(item, val) + + err = column.AppendValue("POINT (30.123 -10.456)") + s.NoError(err) + + err = column.AppendValue(1) + s.Error(err) + }) +} + +func TestColumnGeometryBytes(t *testing.T) { + suite.Run(t, new(ColumnGeometryBytesSuite)) +} diff --git a/client/entity/field.go b/client/entity/field.go index d16ca05814..82f62400e1 100644 --- a/client/entity/field.go +++ b/client/entity/field.go @@ -54,6 +54,8 @@ func (t FieldType) Name() string { return "Array" case FieldTypeJSON: return "JSON" + case FieldTypeGeometry: + return "Geometry" case FieldTypeBinaryVector: return "BinaryVector" case FieldTypeFloatVector: @@ -92,6 +94,8 @@ func (t FieldType) String() string { return "Array" case FieldTypeJSON: return "JSON" + case FieldTypeGeometry: + return "Geometry" case FieldTypeBinaryVector: return "[]byte" case FieldTypeFloatVector: @@ -128,6 +132,8 @@ func (t FieldType) PbFieldType() (string, string) { return "VarChar", "string" case FieldTypeJSON: return "JSON", "JSON" + case FieldTypeGeometry: + return "Geometry", "Geometry" case FieldTypeBinaryVector: return "[]byte", "" case FieldTypeFloatVector: @@ -167,6 +173,8 @@ const ( FieldTypeArray FieldType = 22 // FieldTypeJSON field type JSON FieldTypeJSON FieldType = 23 + // FieldTypeGeometry field type Geometry + FieldTypeGeometry FieldType = 24 // FieldTypeBinaryVector field type binary vector FieldTypeBinaryVector FieldType = 100 // FieldTypeFloatVector field type float vector diff --git a/client/go.mod b/client/go.mod index 5103e5c38d..b434f4acaf 100644 --- a/client/go.mod +++ b/client/go.mod @@ -6,7 +6,7 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/cockroachdb/errors v1.9.1 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 - github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17 + github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786 github.com/milvus-io/milvus/pkg/v2 v2.5.7 github.com/quasilyte/go-ruleguard/dsl v0.3.22 github.com/samber/lo v1.27.0 diff --git a/client/go.sum b/client/go.sum index 794b019d1b..c7e0f537a6 100644 --- a/client/go.sum +++ b/client/go.sum @@ -318,8 +318,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17 h1:LDOodBVtc2AYxcgc51vDwe+gJp96s6yhJLfdGbLrK+0= -github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= +github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786 h1:GspXs2i+sm2GE4n46VRWBjSCQjqtJDIwwcye+gFyxZA= +github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= github.com/milvus-io/milvus/pkg/v2 v2.5.7 h1:b45jq1s1v03AekFucs2/dkkXohB57gEx7gspJuAkfbY= github.com/milvus-io/milvus/pkg/v2 v2.5.7/go.mod h1:pImw1IGNS7k/5yvlZV2tZi5vZu1VQRlQij+r39d+XnI= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= diff --git a/client/milvusclient/client_suite_test.go b/client/milvusclient/client_suite_test.go index 6c452575f8..92a01b276c 100644 --- a/client/milvusclient/client_suite_test.go +++ b/client/milvusclient/client_suite_test.go @@ -212,6 +212,22 @@ func (s *MockSuiteBase) getJSONBytesFieldData(name string, data [][]byte, isDyna } } +func (s *MockSuiteBase) getGeometryBytesFieldData(name string, data [][]byte) *schemapb.FieldData { + return &schemapb.FieldData{ + Type: schemapb.DataType_Geometry, + FieldName: name, + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: data, + }, + }, + }, + }, + } +} + func (s *MockSuiteBase) getFloatVectorFieldData(name string, dim int64, data []float32) *schemapb.FieldData { return &schemapb.FieldData{ Type: schemapb.DataType_FloatVector, diff --git a/go.mod b/go.mod index 9af2cdcf68..4ade37d262 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,11 @@ go 1.24.4 require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0 github.com/aliyun/credentials-go v1.2.7 github.com/apache/arrow/go/v12 v12.0.1 + github.com/apache/pulsar-client-go v0.6.1-0.20210728062540-29414db801a7 // indirect github.com/bits-and-blooms/bloom/v3 v3.3.1 github.com/blang/semver/v4 v4.0.0 github.com/casbin/casbin/v2 v2.44.2 @@ -21,7 +22,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/klauspost/compress v1.18.0 github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d - github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17 + github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786 github.com/minio/minio-go/v7 v7.0.73 github.com/panjf2000/ants/v2 v2.11.3 // indirect github.com/pingcap/log v1.1.1-0.20221015072633-39906604fb81 @@ -35,6 +36,7 @@ require ( github.com/spf13/cast v1.3.1 github.com/spf13/viper v1.8.1 github.com/stretchr/testify v1.10.0 + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.865 github.com/tikv/client-go/v2 v2.0.4 go.etcd.io/etcd/api/v3 v3.5.5 @@ -61,7 +63,7 @@ require ( github.com/bits-and-blooms/bitset v1.10.0 github.com/bytedance/mockey v1.2.14 github.com/bytedance/sonic v1.13.2 - github.com/cenkalti/backoff/v4 v4.2.1 + github.com/cenkalti/backoff/v4 v4.3.0 github.com/cockroachdb/redact v1.1.3 github.com/goccy/go-json v0.10.3 github.com/google/uuid v1.6.0 @@ -73,6 +75,7 @@ require ( github.com/remeh/sizedwaitgroup v1.0.0 github.com/shirou/gopsutil/v4 v4.24.10 github.com/tidwall/gjson v1.17.1 + github.com/twpayne/go-geom v1.5.7 github.com/valyala/fastjson v1.6.4 github.com/zeebo/xxh3 v1.0.2 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 @@ -98,7 +101,6 @@ require ( github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect github.com/alibabacloud-go/tea v1.1.8 // indirect github.com/andybalholm/brotli v1.0.4 // indirect - github.com/apache/pulsar-client-go v0.6.1-0.20210728062540-29414db801a7 // indirect github.com/apache/thrift v0.18.1 // indirect github.com/ardielle/ardielle-go v1.5.2 // indirect github.com/benesch/cgosymbolizer v0.0.0-20190515212042-bec6fe6e597b // indirect @@ -117,7 +119,7 @@ require ( github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect - github.com/docker/go-units v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/ebitengine/purego v0.8.1 // indirect @@ -131,7 +133,7 @@ require ( github.com/go-ini/ini v1.67.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect @@ -151,7 +153,7 @@ require ( github.com/gorilla/websocket v1.4.2 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -167,8 +169,8 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/linkedin/goavro/v2 v2.11.1 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect - github.com/magiconair/properties v1.8.5 // indirect + github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.11 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect @@ -197,12 +199,13 @@ require ( github.com/pingcap/kvproto v0.0.0-20221129023506-621ec37aac7a // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/xid v1.5.0 // indirect - github.com/shirou/gopsutil/v3 v3.22.9 // indirect + github.com/shirou/gopsutil/v3 v3.24.2 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartystreets/assertions v1.2.0 // indirect github.com/smartystreets/goconvey v1.7.2 // indirect @@ -214,13 +217,12 @@ require ( github.com/streamnative/pulsarctl v0.5.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.2.0 // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 // indirect - github.com/tklauser/go-sysconf v0.3.12 // indirect - github.com/tklauser/numcpus v0.6.1 // indirect + github.com/tklauser/go-sysconf v0.3.13 // indirect + github.com/tklauser/numcpus v0.7.0 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twmb/murmur3 v1.1.6 // indirect @@ -237,13 +239,13 @@ require ( go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.13.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.20.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/automaxprocs v1.6.0 // indirect golang.org/x/arch v0.11.0 // indirect golang.org/x/mod v0.17.0 // indirect @@ -254,7 +256,7 @@ require ( golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index dc50bf90d3..be32808960 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/AthenZ/athenz v1.10.39 h1:mtwHTF/v62ewY2Z5KWhuZgVXftBej1/Tn80zx4DcawY github.com/AthenZ/athenz v1.10.39/go.mod h1:3Tg8HLsiQZp81BJY58JBeU2BR6B/H4/0MQGfCwhHNEA= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 h1:jBQA3cKT4L2rWMpgE7Yt3Hwh2aUj8KXjIGLxjHeYNNo= github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0 h1:Ma67P/GGprNwsslzEH6+Kb8nybI8jpDTm4Wmzu2ReK8= @@ -77,6 +77,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= @@ -93,6 +95,10 @@ github.com/actgardner/gogen-avro/v10 v10.2.1/go.mod h1:QUhjeHPchheYmMDni/Nx7VB0R github.com/actgardner/gogen-avro/v9 v9.1.0/go.mod h1:nyTj6wPqDJoxM3qdnjcLv+EnMDSDFqE0qDpva2QRmKc= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= +github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -155,8 +161,8 @@ github.com/casbin/casbin/v2 v2.44.2/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRt github.com/casbin/json-adapter/v2 v2.0.0 h1:nOCN3TK1CJKSNQQ/MnakbU9/cUcNR3N0AxBDnEBLSDI= github.com/casbin/json-adapter/v2 v2.0.0/go.mod h1:LvsfPXXr8CD0ZFucAxawcY9Xb0FtLk3mozJ1qcSTUD4= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= @@ -227,8 +233,8 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA= github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= @@ -314,8 +320,9 @@ github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -354,8 +361,6 @@ github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeD github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -473,8 +478,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hamba/avro v1.5.6/go.mod h1:3vNT0RLXXpFm2Tb/5KC71ZRJlOroggq1Rcitb6k4Fr8= @@ -506,6 +511,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/heetch/avro v0.3.1/go.mod h1:4xn38Oz/+hiEUTpbVfGVLfvOg0yKLlRP7Q9+gJJILgA= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= @@ -601,12 +608,14 @@ github.com/linkedin/goavro/v2 v2.10.0/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF github.com/linkedin/goavro/v2 v2.10.1/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= github.com/linkedin/goavro/v2 v2.11.1 h1:4cuAtbDfqkKnBXp9E+tRkIJGa6W6iAjwonwt8O1f4U0= github.com/linkedin/goavro/v2 v2.11.1/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI= +github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -639,8 +648,8 @@ github.com/milvus-io/cgosymbolizer v0.0.0-20240722103217-b7dee0e50119 h1:9VXijWu github.com/milvus-io/cgosymbolizer v0.0.0-20240722103217-b7dee0e50119/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg= github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b h1:TfeY0NxYxZzUfIfYe5qYDBzt4ZYRqzUjTR6CvUzjat8= github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b/go.mod h1:iwW+9cWfIzzDseEBCCeDSN5SD16Tidvy8cwQ7ZY8Qj4= -github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17 h1:LDOodBVtc2AYxcgc51vDwe+gJp96s6yhJLfdGbLrK+0= -github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= +github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786 h1:GspXs2i+sm2GE4n46VRWBjSCQjqtJDIwwcye+gFyxZA= +github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= github.com/milvus-io/pulsar-client-go v0.12.1 h1:O2JZp1tsYiO7C0MQ4hrUY/aJXnn2Gry6hpm7UodghmE= github.com/milvus-io/pulsar-client-go v0.12.1/go.mod h1:dkutuH4oS2pXiGm+Ti7fQZ4MRjrMPZ8IJeEGAWMeckk= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= @@ -747,8 +756,9 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -813,10 +823,14 @@ github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtm github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA= -github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= +github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y= +github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk= github.com/shirou/gopsutil/v4 v4.24.10 h1:7VOzPtfw/5YDU+jLEoBwXwxJbQetULywoSV4RYY7HkM= github.com/shirou/gopsutil/v4 v4.24.10/go.mod h1:s4D/wg+ag4rG0WO7AiTj2BeYCRhym0vM7DHbZRxnIT8= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/httpfs v0.0.0-20181222201310-74dc9339e414/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -883,6 +897,7 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= @@ -903,12 +918,12 @@ github.com/tikv/client-go/v2 v2.0.4 h1:cPtMXTExqjzk8L40qhrgB/mXiBXKP5LRU0vwjtI2X github.com/tikv/client-go/v2 v2.0.4/go.mod h1:v52O5zDtv2BBus4lm5yrSQhxGW4Z4RaXWfg0U1Kuyqo= github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 h1:ckPpxKcl75mO2N6a4cJXiZH43hvcHPpqc9dh1TmH1nc= github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07/go.mod h1:CipBxPfxPUME+BImx9MUYXCnAVLS3VJUr3mnSJwh40A= -github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= -github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= -github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= +github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= +github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -916,6 +931,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= +github.com/twpayne/go-geom v1.5.7 h1:7fdceDUr03/MP7rAKOaTV6x9njMiQdxB/D0PDzMTCDc= +github.com/twpayne/go-geom v1.5.7/go.mod h1:y4fTAQtLedXW8eG2Yo4tYrIGN1yIwwKkmA+K3iSHKBA= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -951,7 +968,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= @@ -998,11 +1014,11 @@ go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIj go.opentelemetry.io/otel/exporters/jaeger v1.13.0 h1:VAMoGujbVV8Q0JNM/cEbhzUIWWBxnEqH45HP9iBKN04= go.opentelemetry.io/otel/exporters/jaeger v1.13.0/go.mod h1:fHwbmle6mBFJA1p2ZIhilvffCdq/dM5UTIiCOmEjS+w= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.20.0 h1:CsBiKCiQPdSjS+MlRiqeTI9JDDpSuk0Hb6QTRfwer8k= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.20.0/go.mod h1:CMJYNAfooOwSZSAmAeMUV1M+TXld3BiK++z9fqIm2xk= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0 h1:4s9HxB4azeeQkhY0GE5wZlMj4/pz8tE5gx2OQpGUw58= @@ -1017,8 +1033,8 @@ go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+ go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -1257,15 +1273,14 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= @@ -1451,8 +1466,8 @@ google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+n google.golang.org/genproto v0.0.0-20220503193339-ba3ae3f07e29/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d h1:PksQg4dV6Sem3/HkBX+Ltq8T0ke0PKIRBNBatoDTVls= google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:s7iA721uChleev562UJO2OYB0PPT9CMFjV+Ce7VJH5M= -google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc= -google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= diff --git a/internal/core/conanfile.py b/internal/core/conanfile.py index c9b7224669..5cb7b9d1b7 100644 --- a/internal/core/conanfile.py +++ b/internal/core/conanfile.py @@ -8,8 +8,8 @@ class MilvusConan(ConanFile): "rocksdb/6.29.5@milvus/dev#b1842a53ddff60240c5282a3da498ba1", "boost/1.82.0#744a17160ebb5838e9115eab4d6d0c06", "onetbb/2021.9.0#4a223ff1b4025d02f31b65aedf5e7f4a", - "nlohmann_json/3.11.2#ffb9e9236619f1c883e36662f944345d", - "zstd/1.5.4#308b8b048f9a3823ce248f9c150cc889", + "nlohmann_json/3.11.3#ffb9e9236619f1c883e36662f944345d", + "zstd/1.5.5#34e9debe03bf0964834a09dfbc31a5dd", "lz4/1.9.4#c5afb86edd69ac0df30e3a9e192e43db", "snappy/1.1.9#0519333fef284acd04806243de7d3070", "lzo/2.10#9517fc1bcc4d4cc229a79806003a1baa", @@ -47,7 +47,14 @@ class MilvusConan(ConanFile): "rapidjson/cci.20230929#624c0094d741e6a3749d2e44d834b96c", "simde/0.8.2#5e1edfd5cba92f25d79bf6ef4616b972", "unordered_dense/4.4.0#6a855c992618cc4c63019109a2e47298", - "xxhash/0.8.3#199e63ab9800302c232d030b27accec0" + "xxhash/0.8.3#199e63ab9800302c232d030b27accec0", + "json-c/0.17#aaea4a8164c63860731ea7ce4fa206f2", + "sqlite3/3.44.2#497f5b5414e48e35a717dd3035947819", + "proj/9.3.1#38e8bacd0f98467d38e20f46a085b4b3", + "libtiff/4.6.0#32ca1d04c9f024637d49c0c2882cfdbe", + "libgeotiff/1.7.1#0375633ef1116fc067b3773be7fd902f", + "geos/3.12.0#b76c27884c1fa4ee8c9e486337b7dc4e", + "gdal/3.5.3#61a42c933d3440a449cac89fd0866621" ) generators = ("cmake", "cmake_find_package") default_options = { @@ -81,6 +88,8 @@ class MilvusConan(ConanFile): "fmt:header_only": True, "onetbb:tbbmalloc": False, "onetbb:tbbproxy": False, + "gdal:shared": True, + "gdal:fPIC": True, } def configure(self): diff --git a/internal/core/src/common/Array.h b/internal/core/src/common/Array.h index 199f5218bf..5dab13f552 100644 --- a/internal/core/src/common/Array.h +++ b/internal/core/src/common/Array.h @@ -231,7 +231,9 @@ class Array { return true; } case DataType::STRING: - case DataType::VARCHAR: { + case DataType::VARCHAR: + //treat Geometry as wkb string + case DataType::GEOMETRY: { for (int i = 0; i < length_; ++i) { if (get_data(i) != arr.get_data(i)) { @@ -340,6 +342,13 @@ class Array { } break; } + case DataType::GEOMETRY: { + for (int j = 0; j < length_; ++j) { + auto element = get_data(j); + data_array.mutable_geometry_data()->add_data(element); + } + break; + } default: { // empty array } @@ -427,7 +436,8 @@ class Array { return true; } case DataType::VARCHAR: - case DataType::STRING: { + case DataType::STRING: + case DataType::GEOMETRY: { for (int i = 0; i < length_; i++) { auto val = get_data(i); if (val != arr2.array(i).string_val()) { @@ -577,6 +587,13 @@ class ArrayView { } break; } + case DataType::GEOMETRY: { + for (int j = 0; j < length_; ++j) { + auto element = get_data(j); + data_array.mutable_geometry_data()->add_data(element); + } + break; + } default: { // empty array } @@ -661,7 +678,8 @@ class ArrayView { return true; } case DataType::VARCHAR: - case DataType::STRING: { + case DataType::STRING: + case DataType::GEOMETRY: { for (int i = 0; i < length_; i++) { auto val = get_data(i); if (val != arr2.array(i).string_val()) { diff --git a/internal/core/src/common/Chunk.h b/internal/core/src/common/Chunk.h index ebf5b7eeb3..41f4b405f0 100644 --- a/internal/core/src/common/Chunk.h +++ b/internal/core/src/common/Chunk.h @@ -33,6 +33,7 @@ namespace milvus { constexpr uint64_t MMAP_STRING_PADDING = 1; +constexpr uint64_t MMAP_GEOMETRY_PADDING = 1; constexpr uint64_t MMAP_ARRAY_PADDING = 1; class Chunk { public: @@ -211,6 +212,7 @@ class StringChunk : public Chunk { }; using JSONChunk = StringChunk; +using GeometryChunk = StringChunk; class ArrayChunk : public Chunk { public: diff --git a/internal/core/src/common/ChunkWriter.cpp b/internal/core/src/common/ChunkWriter.cpp index f0b594642d..afc83e0ab8 100644 --- a/internal/core/src/common/ChunkWriter.cpp +++ b/internal/core/src/common/ChunkWriter.cpp @@ -20,6 +20,7 @@ #include "common/Chunk.h" #include "common/EasyAssert.h" #include "common/FieldDataInterface.h" +#include "common/Geometry.h" #include "common/Types.h" #include "common/VectorTrait.h" #include "simdjson/common_defs.h" @@ -157,6 +158,66 @@ JSONChunkWriter::finish() { row_nums_, data, size, nullable_, std::move(mmap_file_raii)); } +void +GeometryChunkWriter::write(std::shared_ptr data) { + auto size = 0; + std::vector wkb_strs; + std::vector> null_bitmaps; + for (auto batch : *data) { + auto data = batch.ValueOrDie()->column(0); + auto array = std::dynamic_pointer_cast(data); + for (int i = 0; i < array->length(); i++) { + auto str = array->GetView(i); + wkb_strs.emplace_back(str); + size += str.size(); + } + if (nullable_) { + auto null_bitmap_n = (data->length() + 7) / 8; + null_bitmaps.emplace_back(data->null_bitmap_data(), null_bitmap_n); + size += null_bitmap_n; + } + row_nums_ += array->length(); + } + // use 32-bit offsets to align with StringChunk layout + size += sizeof(uint32_t) * (row_nums_ + 1) + MMAP_GEOMETRY_PADDING; + if (!file_path_.empty()) { + target_ = std::make_shared(file_path_); + } else { + target_ = std::make_shared(size); + } + + // chunk layout: null bitmap, offset1, offset2, ..., offsetn, wkb1, wkb2, ..., wkbn, padding + // write null bitmaps + write_null_bit_maps(null_bitmaps); + + int offset_num = row_nums_ + 1; + uint32_t offset_start_pos = + static_cast(target_->tell() + sizeof(uint32_t) * offset_num); + std::vector offsets; + + for (auto str : wkb_strs) { + offsets.push_back(offset_start_pos); + offset_start_pos += str.size(); + } + offsets.push_back(offset_start_pos); + + target_->write(offsets.data(), offsets.size() * sizeof(uint32_t)); + + for (auto str : wkb_strs) { + target_->write(str.data(), str.size()); + } +} + +std::shared_ptr +GeometryChunkWriter::finish() { + // write padding, maybe not needed anymore + // FIXME + char padding[MMAP_GEOMETRY_PADDING]; + target_->write(padding, MMAP_GEOMETRY_PADDING); + auto [data, size] = target_->get(); + return std::make_shared(row_nums_, data, size, nullable_); +} + void ArrayChunkWriter::write(std::shared_ptr data) { auto size = 0; @@ -368,6 +429,10 @@ create_chunk_writer(const FieldMeta& field_meta, Args&&... args) { case milvus::DataType::JSON: return std::make_shared( std::forward(args)..., nullable); + case milvus::DataType::GEOMETRY: { + return std::make_shared( + std::forward(args)..., nullable); + } case milvus::DataType::ARRAY: return std::make_shared( field_meta.get_element_type(), diff --git a/internal/core/src/common/ChunkWriter.h b/internal/core/src/common/ChunkWriter.h index c349918d9a..23af0e108e 100644 --- a/internal/core/src/common/ChunkWriter.h +++ b/internal/core/src/common/ChunkWriter.h @@ -25,6 +25,7 @@ #include "storage/FileWriter.h" +#include "common/Geometry.h" namespace milvus { class ChunkWriterBase { @@ -207,6 +208,16 @@ class JSONChunkWriter : public ChunkWriterBase { finish() override; }; +class GeometryChunkWriter : public ChunkWriterBase { + public: + using ChunkWriterBase::ChunkWriterBase; + void + write(std::shared_ptr data) override; + + std::shared_ptr + finish() override; +}; + class ArrayChunkWriter : public ChunkWriterBase { public: ArrayChunkWriter(const milvus::DataType element_type, bool nullable) diff --git a/internal/core/src/common/FieldData.cpp b/internal/core/src/common/FieldData.cpp index 18113d884d..c849eb5078 100644 --- a/internal/core/src/common/FieldData.cpp +++ b/internal/core/src/common/FieldData.cpp @@ -213,6 +213,19 @@ FieldDataImpl::FillFieldData( } return FillFieldData(values.data(), element_count); } + case DataType::GEOMETRY: { + auto geometry_array = + std::dynamic_pointer_cast(array); + std::vector values(element_count); + for (size_t index = 0; index < element_count; ++index) { + values[index] = *geometry_array->GetValue(index, 0); + } + if (nullable_) { + return FillFieldData( + values.data(), array->null_bitmap_data(), element_count); + } + return FillFieldData(values.data(), element_count); + } case DataType::ARRAY: { auto array_array = std::dynamic_pointer_cast(array); @@ -278,6 +291,7 @@ template class FieldDataImpl; template class FieldDataImpl; template class FieldDataImpl; template class FieldDataImpl; +template class FieldDataImpl; template class FieldDataImpl; // vector data @@ -315,6 +329,9 @@ InitScalarFieldData(const DataType& type, bool nullable, int64_t cap_rows) { type, nullable, cap_rows); case DataType::JSON: return std::make_shared>(type, nullable, cap_rows); + case DataType::GEOMETRY: + return std::make_shared>( + type, nullable, cap_rows); default: PanicInfo(DataTypeInvalid, "InitScalarFieldData not support data type " + diff --git a/internal/core/src/common/FieldData.h b/internal/core/src/common/FieldData.h index cdd2b73546..df522410df 100644 --- a/internal/core/src/common/FieldData.h +++ b/internal/core/src/common/FieldData.h @@ -69,6 +69,17 @@ class FieldData : public FieldDataJsonImpl { } }; +template <> +class FieldData : public FieldDataGeometryImpl { + public: + static_assert(IsScalar); + explicit FieldData(DataType data_type, + bool nullable, + int64_t buffered_num_rows = 0) + : FieldDataGeometryImpl(data_type, nullable, buffered_num_rows) { + } +}; + template <> class FieldData : public FieldDataArrayImpl { public: diff --git a/internal/core/src/common/FieldDataInterface.h b/internal/core/src/common/FieldDataInterface.h index 4f61e435cd..21d4808c2c 100644 --- a/internal/core/src/common/FieldDataInterface.h +++ b/internal/core/src/common/FieldDataInterface.h @@ -572,6 +572,75 @@ class FieldDataStringImpl : public FieldDataImpl { } }; +class FieldDataGeometryImpl : public FieldDataImpl { + public: + explicit FieldDataGeometryImpl(DataType data_type, + bool nullable, + int64_t total_num_rows = 0) + : FieldDataImpl( + 1, data_type, nullable, total_num_rows) { + } + + int64_t + DataSize() const override { + int64_t data_size = 0; + for (size_t offset = 0; offset < length(); ++offset) { + data_size += data_[offset].size(); + } + + return data_size; + } + + int64_t + DataSize(ssize_t offset) const override { + AssertInfo(offset < get_num_rows(), + "field data subscript out of range"); + AssertInfo(offset < length(), + "subscript position don't has valid value"); + return data_[offset].size(); + } + void + FillFieldData(const std::shared_ptr array) override { + AssertInfo(array->type()->id() == arrow::Type::type::BINARY, + "inconsistent data type, expected: {}, got: {}", + "BINARY", + array->type()->ToString()); + auto geometry_array = + std::dynamic_pointer_cast(array); + FillFieldData(geometry_array); + } + void + FillFieldData(const std::shared_ptr& array) override { + auto n = array->length(); + if (n == 0) { + return; + } + null_count_ = array->null_count(); + + std::lock_guard lck(tell_mutex_); + if (length_ + n > get_num_rows()) { + resize_field_data(length_ + n); + } + auto i = 0; + for (const auto& geometry : *array) { + if (!geometry.has_value()) { + i++; + continue; + } + data_[length_ + i] = geometry.value(); + i++; + } + if (IsNullable()) { + auto valid_data = array->null_bitmap_data(); + if (valid_data != nullptr) { + bitset::detail::ElementWiseBitsetPolicy::op_copy( + valid_data, 0, valid_data_.data(), length_, n); + } + } + length_ += n; + } +}; + class FieldDataJsonImpl : public FieldDataImpl { public: explicit FieldDataJsonImpl(DataType data_type, diff --git a/internal/core/src/common/Geometry.h b/internal/core/src/common/Geometry.h new file mode 100644 index 0000000000..4e38c85bb3 --- /dev/null +++ b/internal/core/src/common/Geometry.h @@ -0,0 +1,142 @@ +// 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 +#pragma once + +#include "ogr_geometry.h" +#include +#include "common/EasyAssert.h" + +namespace milvus { + +struct OGRGeometryDeleter { + void + operator()(OGRGeometry* ptr) const noexcept { + if (ptr) { + OGRGeometryFactory::destroyGeometry(ptr); + } + } +}; + +class Geometry { + public: + Geometry() = default; + + // all ctr assume that wkb data is valid + explicit Geometry(const void* wkb, size_t size) { + OGRGeometry* geometry = nullptr; + OGRGeometryFactory::createFromWkb(wkb, nullptr, &geometry, size); + + AssertInfo(geometry != nullptr, + "failed to construct geometry from wkb data"); + geometry_.reset(geometry); + } + + explicit Geometry(const char* wkt) { + OGRGeometry* geometry = nullptr; + OGRGeometryFactory::createFromWkt(wkt, nullptr, &geometry); + AssertInfo(geometry != nullptr, + "failed to construct geometry from wkt data"); + geometry_.reset(geometry); + } + + Geometry(const Geometry& other) { + if (other.IsValid()) { + this->geometry_.reset(other.geometry_->clone()); + } + } + + Geometry(Geometry&& other) noexcept + : geometry_(std::move(other.geometry_)) { + } + + Geometry& + operator=(const Geometry& other) { + if (this != &other && other.IsValid()) { + this->geometry_.reset(other.geometry_->clone()); + } + return *this; + } + + Geometry& + operator=(Geometry&& other) noexcept { + if (this != &other) { + geometry_ = std::move(other.geometry_); + } + return *this; + } + + ~Geometry() = default; + + bool + IsValid() const { + return geometry_ != nullptr; + } + + OGRGeometry* + GetGeometry() const { + return geometry_.get(); + } + + //spatial relation + bool + equals(const Geometry& other) const { + return geometry_->Equals(other.geometry_.get()); + } + + bool + touches(const Geometry& other) const { + return geometry_->Touches(other.geometry_.get()); + } + + bool + overlaps(const Geometry& other) const { + return geometry_->Overlaps(other.geometry_.get()); + } + + bool + crosses(const Geometry& other) const { + return geometry_->Crosses(other.geometry_.get()); + } + + bool + contains(const Geometry& other) const { + return geometry_->Contains(other.geometry_.get()); + } + + bool + intersects(const Geometry& other) const { + return geometry_->Intersects(other.geometry_.get()); + } + + bool + within(const Geometry& other) const { + return geometry_->Within(other.geometry_.get()); + } + + std::string + to_wkt_string() const { + return geometry_->exportToWkt(); + } + + // used for test + std::string + to_wkb_string() const { + std::unique_ptr wkb(new unsigned char[geometry_->WkbSize()]); + geometry_->exportToWkb(wkbNDR, wkb.get()); + return std::string(reinterpret_cast(wkb.get()), + geometry_->WkbSize()); + } + + private: + std::unique_ptr geometry_; +}; + +} // namespace milvus \ No newline at end of file diff --git a/internal/core/src/common/Types.h b/internal/core/src/common/Types.h index 864f64468e..ef60003468 100644 --- a/internal/core/src/common/Types.h +++ b/internal/core/src/common/Types.h @@ -45,6 +45,7 @@ #include "pb/schema.pb.h" #include "pb/segcore.pb.h" #include "Json.h" +#include "Geometry.h" #include "CustomBitset.h" @@ -75,6 +76,7 @@ enum class DataType { VARCHAR = 21, ARRAY = 22, JSON = 23, + GEOMETRY = 24, // Some special Data type, start from after 50 // just for internal use now, may sync proto in future @@ -180,6 +182,8 @@ GetDataTypeName(DataType data_type) { return "array"; case DataType::JSON: return "json"; + case DataType::GEOMETRY: + return "geometry"; case DataType::VECTOR_FLOAT: return "vector_float"; case DataType::VECTOR_BINARY: @@ -216,6 +220,7 @@ using GroupByValueType = std::variant; using ContainsType = proto::plan::JSONContainsExpr_JSONOp; using NullExprType = proto::plan::NullExpr_NullOp; +using GISFunctionType = proto::plan::GISFunctionFilterExpr_GISOp; inline bool IsPrimaryKeyDataType(DataType data_type) { @@ -268,6 +273,11 @@ IsJsonDataType(DataType data_type) { return data_type == DataType::JSON; } +inline bool +IsGeometryDataType(DataType data_type) { + return data_type == DataType::GEOMETRY; +} + inline bool IsArrayDataType(DataType data_type) { return data_type == DataType::ARRAY; @@ -275,7 +285,8 @@ IsArrayDataType(DataType data_type) { inline bool IsBinaryDataType(DataType data_type) { - return IsJsonDataType(data_type) || IsArrayDataType(data_type); + return IsJsonDataType(data_type) || IsArrayDataType(data_type) || + IsGeometryDataType(data_type); } inline bool @@ -301,6 +312,11 @@ IsJsonType(proto::schema::DataType type) { return type == proto::schema::DataType::JSON; } +inline bool +IsGeometryType(proto::schema::DataType type) { + return type == proto::schema::DataType::Geometry; +} + inline bool IsArrayType(proto::schema::DataType type) { return type == proto::schema::DataType::Array; @@ -543,6 +559,15 @@ struct TypeTraits { static constexpr const char* Name = "JSON"; }; +template <> +struct TypeTraits { + using NativeType = void; + static constexpr DataType TypeKind = DataType::GEOMETRY; + static constexpr bool IsPrimitiveType = false; + static constexpr bool IsFixedWidth = false; + static constexpr const char* Name = "GEOMETRY"; +}; + template <> struct TypeTraits { using NativeType = void; @@ -630,6 +655,9 @@ struct fmt::formatter : formatter { case milvus::DataType::JSON: name = "JSON"; break; + case milvus::DataType::GEOMETRY: + name = "GEOMETRY"; + break; case milvus::DataType::ROW: name = "ROW"; break; diff --git a/internal/core/src/common/VectorTrait.h b/internal/core/src/common/VectorTrait.h index e021558bbd..a58ad0e5c6 100644 --- a/internal/core/src/common/VectorTrait.h +++ b/internal/core/src/common/VectorTrait.h @@ -60,9 +60,9 @@ constexpr bool IsVector = std::is_base_of_v; template constexpr bool IsScalar = std::is_fundamental_v || std::is_same_v || - std::is_same_v || std::is_same_v || - std::is_same_v || std::is_same_v || - std::is_same_v; + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v; template constexpr bool IsSparse = std::is_same_v || @@ -73,7 +73,7 @@ constexpr bool IsVariableType = std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || - IsSparse; + std::is_same_v || IsSparse; template constexpr bool IsVariableTypeSupportInChunk = diff --git a/internal/core/src/exec/expression/Expr.cpp b/internal/core/src/exec/expression/Expr.cpp index 99a9062e05..111770b185 100644 --- a/internal/core/src/exec/expression/Expr.cpp +++ b/internal/core/src/exec/expression/Expr.cpp @@ -25,12 +25,14 @@ #include "exec/expression/CompareExpr.h" #include "exec/expression/ConjunctExpr.h" #include "exec/expression/ExistsExpr.h" +#include "exec/expression/GISFunctionFilterExpr.h" #include "exec/expression/JsonContainsExpr.h" #include "exec/expression/LogicalBinaryExpr.h" #include "exec/expression/LogicalUnaryExpr.h" #include "exec/expression/NullExpr.h" #include "exec/expression/TermExpr.h" #include "exec/expression/UnaryExpr.h" +#include "expr/ITypeExpr.h" #include "exec/expression/ValueExpr.h" #include "expr/ITypeExpr.h" @@ -46,7 +48,6 @@ ExprSet::Eval(int32_t begin, EvalCtx& context, std::vector& results) { results.resize(exprs_.size()); - for (size_t i = begin; i < end; ++i) { exprs_[i]->Eval(context, results[i]); } @@ -305,6 +306,16 @@ CompileExpression(const expr::TypedExprPtr& expr, context->get_active_count(), context->query_config()->get_expr_batch_size(), context->get_consistency_level()); + } else if (auto casted_expr = std::dynamic_pointer_cast< + const milvus::expr::GISFunctionFilterExpr>(expr)) { + result = std::make_shared( + compiled_inputs, + casted_expr, + "PhyGISFunctionFilterExpr", + context->get_segment(), + context->get_active_count(), + context->query_config()->get_expr_batch_size(), + context->get_consistency_level()); } else { PanicInfo(ExprInvalid, "unsupport expr: ", expr->ToString()); } diff --git a/internal/core/src/exec/expression/GISFunctionFilterExpr.cpp b/internal/core/src/exec/expression/GISFunctionFilterExpr.cpp new file mode 100644 index 0000000000..6010cf3b04 --- /dev/null +++ b/internal/core/src/exec/expression/GISFunctionFilterExpr.cpp @@ -0,0 +1,152 @@ +// 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 "GISFunctionFilterExpr.h" +#include "common/EasyAssert.h" +#include "common/Geometry.h" +#include "common/Types.h" +#include "pb/plan.pb.h" +namespace milvus { +namespace exec { + +#define GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(_DataType, method) \ + auto execute_sub_batch = [](const _DataType* data, \ + const bool* valid_data, \ + const int32_t* offsets, \ + const int size, \ + TargetBitmapView res, \ + TargetBitmapView valid_res, \ + const Geometry& right_source) { \ + for (int i = 0; i < size; ++i) { \ + if (valid_data != nullptr && !valid_data[i]) { \ + res[i] = valid_res[i] = false; \ + continue; \ + } \ + res[i] = \ + Geometry(data[i].data(), data[i].size()).method(right_source); \ + } \ + }; \ + int64_t processed_size = ProcessDataChunks<_DataType>( \ + execute_sub_batch, std::nullptr_t{}, res, valid_res, right_source); \ + AssertInfo(processed_size == real_batch_size, \ + "internal error: expr processed rows {} not equal " \ + "expect batch size {}", \ + processed_size, \ + real_batch_size); \ + return res_vec; + +void +PhyGISFunctionFilterExpr::Eval(EvalCtx& context, VectorPtr& result) { + AssertInfo(expr_->column_.data_type_ == DataType::GEOMETRY, + "unsupported data type: {}", + expr_->column_.data_type_); + if (is_index_mode_) { + // result = EvalForIndexSegment(); + PanicInfo(NotImplemented, "index for geos not implement"); + } else { + result = EvalForDataSegment(); + } +} + +VectorPtr +PhyGISFunctionFilterExpr::EvalForDataSegment() { + auto real_batch_size = GetNextBatchSize(); + if (real_batch_size == 0) { + return nullptr; + } + auto res_vec = std::make_shared( + TargetBitmap(real_batch_size), TargetBitmap(real_batch_size)); + TargetBitmapView res(res_vec->GetRawData(), real_batch_size); + TargetBitmapView valid_res(res_vec->GetValidRawData(), real_batch_size); + valid_res.set(); + + auto& right_source = expr_->geometry_; + + // Choose underlying data type according to segment type to avoid element + // size mismatch: Sealed segment variable column stores std::string_view; + // Growing segment stores std::string. + using SealedType = std::string_view; + using GrowingType = std::string; + + switch (expr_->op_) { + case proto::plan::GISFunctionFilterExpr_GISOp_Equals: { + if (segment_->type() == SegmentType::Sealed) { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(SealedType, equals); + } else { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(GrowingType, equals); + } + } + case proto::plan::GISFunctionFilterExpr_GISOp_Touches: { + if (segment_->type() == SegmentType::Sealed) { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(SealedType, touches); + } else { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(GrowingType, + touches); + } + } + case proto::plan::GISFunctionFilterExpr_GISOp_Overlaps: { + if (segment_->type() == SegmentType::Sealed) { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(SealedType, + overlaps); + } else { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(GrowingType, + overlaps); + } + } + case proto::plan::GISFunctionFilterExpr_GISOp_Crosses: { + if (segment_->type() == SegmentType::Sealed) { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(SealedType, crosses); + } else { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(GrowingType, + crosses); + } + } + case proto::plan::GISFunctionFilterExpr_GISOp_Contains: { + if (segment_->type() == SegmentType::Sealed) { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(SealedType, + contains); + } else { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(GrowingType, + contains); + } + } + case proto::plan::GISFunctionFilterExpr_GISOp_Intersects: { + if (segment_->type() == SegmentType::Sealed) { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(SealedType, + intersects); + } else { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(GrowingType, + intersects); + } + } + case proto::plan::GISFunctionFilterExpr_GISOp_Within: { + if (segment_->type() == SegmentType::Sealed) { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(SealedType, within); + } else { + GEOMETRY_EXECUTE_SUB_BATCH_WITH_COMPARISON(GrowingType, within); + } + } + default: { + PanicInfo(NotImplemented, + "internal error: unknown GIS op : {}", + expr_->op_); + } + } + return res_vec; +} + +// VectorPtr +// PhyGISFunctionFilterExpr::EvalForIndexSegment() { +// // TODO +// } + +} //namespace exec +} // namespace milvus \ No newline at end of file diff --git a/internal/core/src/exec/expression/GISFunctionFilterExpr.h b/internal/core/src/exec/expression/GISFunctionFilterExpr.h new file mode 100644 index 0000000000..28d5687b06 --- /dev/null +++ b/internal/core/src/exec/expression/GISFunctionFilterExpr.h @@ -0,0 +1,61 @@ +// 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 + +#pragma once + +#include + +#include "common/FieldDataInterface.h" +#include "common/Vector.h" +#include "exec/expression/Expr.h" +#include "expr/ITypeExpr.h" +#include "segcore/SegmentInterface.h" + +namespace milvus { +namespace exec { + +class PhyGISFunctionFilterExpr : public SegmentExpr { + public: + PhyGISFunctionFilterExpr( + const std::vector>& input, + const std::shared_ptr& expr, + const std::string& name, + const segcore::SegmentInternalInterface* segment, + int64_t active_count, + int64_t batch_size, + int32_t consistency_level) + : SegmentExpr(std::move(input), + name, + segment, + expr->column_.field_id_, + expr->column_.nested_path_, + DataType::GEOMETRY, + active_count, + batch_size, + consistency_level), + expr_(expr) { + } + + void + Eval(EvalCtx& context, VectorPtr& result) override; + + private: + // VectorPtr + // EvalForIndexSegment(); + + VectorPtr + EvalForDataSegment(); + + private: + std::shared_ptr expr_; +}; +} //namespace exec +} // namespace milvus diff --git a/internal/core/src/expr/ITypeExpr.h b/internal/core/src/expr/ITypeExpr.h index 3c78fe4be7..2931ffa3f2 100644 --- a/internal/core/src/expr/ITypeExpr.h +++ b/internal/core/src/expr/ITypeExpr.h @@ -21,11 +21,13 @@ #include #include +#include "common/Geometry.h" #include "exec/expression/function/FunctionFactory.h" #include "common/Exception.h" #include "common/Schema.h" #include "common/Types.h" #include "common/Utils.h" +#include "ogr_geometry.h" #include "pb/plan.pb.h" namespace milvus { @@ -757,6 +759,28 @@ class CompareExpr : public ITypeFilterExpr { const proto::plan::OpType op_type_; }; +class GISFunctionFilterExpr : public ITypeFilterExpr { + public: + GISFunctionFilterExpr(ColumnInfo cloumn, + GISFunctionType op, + const Geometry& geometry) + : column_(cloumn), op_(op), geometry_(geometry){}; + std::string + ToString() const override { + return fmt::format( + "GISFunctionFilterExpr:[Column: {}, Operator: {} " + "WktValue: {}]", + column_.ToString(), + GISFunctionFilterExpr_GISOp_Name(op_), + geometry_.to_wkt_string()); + } + + public: + const ColumnInfo column_; + const GISFunctionType op_; + const Geometry geometry_; +}; + class JsonContainsExpr : public ITypeFilterExpr { public: JsonContainsExpr(ColumnInfo column, diff --git a/internal/core/src/mmap/Utils.h b/internal/core/src/mmap/Utils.h index 3dbd88e198..5d04cc815b 100644 --- a/internal/core/src/mmap/Utils.h +++ b/internal/core/src/mmap/Utils.h @@ -26,6 +26,7 @@ #include #include "common/FieldMeta.h" +#include "common/Geometry.h" #include "common/Types.h" #include "mmap/Types.h" #include "storage/Util.h" @@ -136,6 +137,27 @@ WriteFieldData(File& file, } break; } + case DataType::GEOMETRY: { + // write as: |size|data|size|data...... + for (ssize_t i = 0; i < data->get_num_rows(); ++i) { + indices.push_back(total_written); + auto geo_ptr = + static_cast(data->RawValue(i)); + ssize_t written_data_size = + file.WriteInt(geo_ptr->size()); + if (written_data_size != sizeof(uint32_t)) { + THROW_FILE_WRITE_ERROR + } + total_written += written_data_size; + ssize_t written_data = + file.Write(geo_ptr->data(), geo_ptr->size()); + if (written_data < geo_ptr->size()) { + THROW_FILE_WRITE_ERROR + } + total_written += written_data; + } + break; + } case DataType::ARRAY: { // write as: |data|data|data|data|data...... for (size_t i = 0; i < data->get_num_rows(); ++i) { diff --git a/internal/core/src/query/PlanProto.cpp b/internal/core/src/query/PlanProto.cpp index 0790a841b2..e2f5aa58f1 100644 --- a/internal/core/src/query/PlanProto.cpp +++ b/internal/core/src/query/PlanProto.cpp @@ -14,12 +14,17 @@ #include #include +#include #include #include +#include "common/Geometry.h" #include "common/VectorTrait.h" #include "common/EasyAssert.h" #include "exec/expression/function/FunctionFactory.h" +#include "log/Log.h" +#include "ogr_core.h" +#include "ogr_geometry.h" #include "pb/plan.pb.h" #include "query/Utils.h" #include "knowhere/comp/materialized_view.h" @@ -475,6 +480,19 @@ ProtoParser::ParseValueExprs(const proto::plan::ValueExpr& expr_pb) { return std::make_shared(expr_pb.value()); } +expr::TypedExprPtr +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[field_id].get_data_type(); + Assert(data_type == (DataType)columnInfo.data_type()); + const std::string& str = expr_pb.wkt_string(); + Geometry geometry(str.data()); + return std::make_shared( + columnInfo, expr_pb.op(), geometry); +} + expr::TypedExprPtr ProtoParser::CreateAlwaysTrueExprs() { return std::make_shared(); @@ -544,6 +562,11 @@ ProtoParser::ParseExprs(const proto::plan::Expr& expr_pb, result = ParseNullExprs(expr_pb.null_expr()); break; } + case ppe::kGisfunctionFilterExpr: { + result = + ParseGISFunctionFilterExprs(expr_pb.gisfunction_filter_expr()); + break; + } 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 5aa5063d0a..f7c37d628f 100644 --- a/internal/core/src/query/PlanProto.h +++ b/internal/core/src/query/PlanProto.h @@ -86,6 +86,10 @@ class ProtoParser { expr::TypedExprPtr ParseJsonContainsExprs(const proto::plan::JSONContainsExpr& expr_pb); + expr::TypedExprPtr + ParseGISFunctionFilterExprs( + const proto::plan::GISFunctionFilterExpr& expr_pb); + expr::TypedExprPtr ParseTermExprs(const proto::plan::TermExpr& expr_pb); diff --git a/internal/core/src/segcore/ChunkedSegmentSealedImpl.cpp b/internal/core/src/segcore/ChunkedSegmentSealedImpl.cpp index 4fd22c2895..f8873c54ea 100644 --- a/internal/core/src/segcore/ChunkedSegmentSealedImpl.cpp +++ b/internal/core/src/segcore/ChunkedSegmentSealedImpl.cpp @@ -33,6 +33,7 @@ #include "common/Consts.h" #include "common/EasyAssert.h" #include "common/FieldData.h" +#include "common/FieldDataInterface.h" #include "common/FieldMeta.h" #include "common/File.h" #include "common/Json.h" @@ -369,6 +370,21 @@ ChunkedSegmentSealedImpl::LoadFieldData(FieldId field_id, FieldDataInfo& data) { column = std::move(var_column); break; } + case milvus::DataType::GEOMETRY: { + auto var_column = + std::make_shared>( + field_meta); + std::shared_ptr r; + while (data.arrow_reader_channel->pop(r)) { + auto chunk = create_chunk(field_meta, r->reader); + var_column->AddChunk(chunk); + } + // var_column->Seal(); + stats_.mem_size += var_column->DataByteSize(); + field_data_size = var_column->DataByteSize(); + column = std::move(var_column); + break; + } case milvus::DataType::ARRAY: { auto var_column = std::make_shared(field_meta); @@ -531,6 +547,14 @@ ChunkedSegmentSealedImpl::MapFieldData(const FieldId field_id, column = std::move(var_column); break; } + case milvus::DataType::GEOMETRY: { + auto var_column = + std::make_shared>( + field_meta, chunks); + // var_column->Seal(std::move(indices)); + column = std::move(var_column); + break; + } case milvus::DataType::ARRAY: { auto arr_column = std::make_shared(field_meta, chunks); @@ -1576,6 +1600,15 @@ ChunkedSegmentSealedImpl::get_raw_data(FieldId field_id, break; } + case DataType::GEOMETRY: { + bulk_subscript_ptr_impl(column.get(), + seg_offsets, + count, + ret->mutable_scalars() + ->mutable_geometry_data() + ->mutable_data()); + break; + } case DataType::ARRAY: { bulk_subscript_array_impl( column.get(), diff --git a/internal/core/src/segcore/ConcurrentVector.cpp b/internal/core/src/segcore/ConcurrentVector.cpp index 0fc665d303..5af29a5f8a 100644 --- a/internal/core/src/segcore/ConcurrentVector.cpp +++ b/internal/core/src/segcore/ConcurrentVector.cpp @@ -98,6 +98,18 @@ VectorBase::set_data_raw(ssize_t element_offset, return set_data_raw(element_offset, data_raw.data(), element_count); } + case DataType::GEOMETRY: { + // get the geometry array of a column from proto message + auto& geometry_data = FIELD_DATA(data, geometry); + std::vector data_raw{}; + data_raw.reserve(geometry_data.size()); + for (auto& geometry_bytes : geometry_data) { + //this geometry_bytes consider as wkt strings from milvus-proto + data_raw.emplace_back( + std::string(geometry_bytes.data(), geometry_bytes.size())); + } + return set_data_raw(element_offset, data_raw.data(), element_count); + } case DataType::ARRAY: { auto& array_data = FIELD_DATA(data, array); std::vector data_raw{}; diff --git a/internal/core/src/segcore/InsertRecord.h b/internal/core/src/segcore/InsertRecord.h index 602e7f3680..52ee13d937 100644 --- a/internal/core/src/segcore/InsertRecord.h +++ b/internal/core/src/segcore/InsertRecord.h @@ -437,6 +437,11 @@ struct InsertRecord { field_id, size_per_chunk, scalar_mmap_descriptor); break; } + case DataType::GEOMETRY: { + this->append_data( + field_id, size_per_chunk, scalar_mmap_descriptor); + break; + } case DataType::ARRAY: { this->append_data( field_id, size_per_chunk, scalar_mmap_descriptor); diff --git a/internal/core/src/segcore/SegmentGrowingImpl.cpp b/internal/core/src/segcore/SegmentGrowingImpl.cpp index 07bb648c8a..1cb6d151f8 100644 --- a/internal/core/src/segcore/SegmentGrowingImpl.cpp +++ b/internal/core/src/segcore/SegmentGrowingImpl.cpp @@ -647,6 +647,15 @@ SegmentGrowingImpl::bulk_subscript(FieldId field_id, result->mutable_scalars()->mutable_json_data()->mutable_data()); break; } + case DataType::GEOMETRY: { + bulk_subscript_ptr_impl(vec_ptr, + seg_offsets, + count, + result->mutable_scalars() + ->mutable_geometry_data() + ->mutable_data()); + break; + } case DataType::ARRAY: { // element bulk_subscript_array_impl(*vec_ptr, diff --git a/internal/core/src/segcore/SegmentSealedImpl.cpp b/internal/core/src/segcore/SegmentSealedImpl.cpp index 480504e7ad..cbefb72f67 100644 --- a/internal/core/src/segcore/SegmentSealedImpl.cpp +++ b/internal/core/src/segcore/SegmentSealedImpl.cpp @@ -35,6 +35,7 @@ #include "common/FieldMeta.h" #include "common/File.h" #include "common/Json.h" +#include "common/Geometry.h" #include "common/LoadInfo.h" #include "common/Tracer.h" #include "common/Types.h" @@ -432,6 +433,20 @@ SegmentSealedImpl::LoadFieldData(FieldId field_id, FieldDataInfo& data) { column = std::move(var_column); break; } + case milvus::DataType::GEOMETRY: { + auto var_column = std::make_shared< + SingleChunkVariableColumn>( + num_rows, field_meta, get_block_size()); + FieldDataPtr field_data; + while (data.channel->pop(field_data)) { + var_column->Append(std::move(field_data)); + } + var_column->Seal(); + stats_.mem_size += var_column->MemoryUsageBytes(); + field_data_size = var_column->DataByteSize(); + column = std::move(var_column); + break; + } case milvus::DataType::ARRAY: { auto var_column = std::make_shared( num_rows, field_meta); @@ -593,6 +608,17 @@ SegmentSealedImpl::MapFieldData(const FieldId field_id, FieldDataInfo& data) { column = std::move(var_column); break; } + case milvus::DataType::GEOMETRY: { + auto var_column = + std::make_shared>( + file, + total_written, + field_meta, + DEFAULT_MMAP_VRCOL_BLOCK_SIZE); + var_column->Seal(std::move(indices)); + column = std::move(var_column); + break; + } case milvus::DataType::ARRAY: { auto arr_column = std::make_shared( file, total_written, field_meta); @@ -1444,6 +1470,15 @@ SegmentSealedImpl::get_raw_data(FieldId field_id, break; } + case DataType::GEOMETRY: { + bulk_subscript_ptr_impl(column.get(), + seg_offsets, + count, + ret->mutable_scalars() + ->mutable_geometry_data() + ->mutable_data()); + break; + } case DataType::ARRAY: { bulk_subscript_array_impl( column.get(), diff --git a/internal/core/src/segcore/Utils.cpp b/internal/core/src/segcore/Utils.cpp index 46e9b1b3ac..c470203d46 100644 --- a/internal/core/src/segcore/Utils.cpp +++ b/internal/core/src/segcore/Utils.cpp @@ -19,7 +19,9 @@ #include "common/Common.h" #include "common/FieldData.h" +#include "common/FieldDataInterface.h" #include "common/Types.h" +#include "common/Utils.h" #include "index/ScalarIndex.h" #include "log/Log.h" #include "storage/DataCodec.h" @@ -145,6 +147,13 @@ GetRawDataSizeOfDataArray(const DataArray* data, } break; } + case DataType::GEOMETRY: { + auto& geometry_data = FIELD_DATA(data, geometry); + for (auto& geometry_bytes : geometry_data) { + result += geometry_bytes.size(); + } + break; + } case DataType::ARRAY: { auto& array_data = FIELD_DATA(data, array); switch (field_meta.get_element_type()) { @@ -291,6 +300,14 @@ CreateScalarDataArray(int64_t count, const FieldMeta& field_meta) { } break; } + case DataType::GEOMETRY: { + auto obj = scalar_array->mutable_geometry_data(); + obj->mutable_data()->Reserve(count); + for (int i = 0; i < count; i++) { + *(obj->mutable_data()->Add()) = std::string(); + } + break; + } case DataType::ARRAY: { auto obj = scalar_array->mutable_array_data(); obj->mutable_data()->Reserve(count); @@ -439,6 +456,15 @@ CreateScalarDataArrayFrom(const void* data_raw, } break; } + case DataType::GEOMETRY: { + auto data = reinterpret_cast(data_raw); + auto obj = scalar_array->mutable_geometry_data(); + for (auto i = 0; i < count; i++) { + *(obj->mutable_data()->Add()) = + std::string(data[i].data(), data[i].size()); + } + break; + } case DataType::ARRAY: { auto data = reinterpret_cast(data_raw); auto obj = scalar_array->mutable_array_data(); @@ -654,6 +680,13 @@ MergeDataArray(std::vector& merge_bases, *(obj->mutable_data()->Add()) = data[src_offset]; break; } + case DataType::GEOMETRY: { + auto& data = FIELD_DATA(src_field_data, geometry); + auto obj = scalar_array->mutable_geometry_data(); + *(obj->mutable_data()->Add()) = std::string( + data[src_offset].data(), data[src_offset].size()); + break; + } case DataType::ARRAY: { auto& data = FIELD_DATA(src_field_data, array); auto obj = scalar_array->mutable_array_data(); diff --git a/internal/core/src/storage/Event.cpp b/internal/core/src/storage/Event.cpp index 866d68fb2e..ba6d2de34a 100644 --- a/internal/core/src/storage/Event.cpp +++ b/internal/core/src/storage/Event.cpp @@ -21,6 +21,7 @@ #include "common/Consts.h" #include "common/EasyAssert.h" #include "common/FieldMeta.h" +#include "common/Geometry.h" #include "common/Json.h" #include "fmt/format.h" #include "nlohmann/json.hpp" @@ -297,6 +298,17 @@ BaseEventData::Serialize() { } break; } + case DataType::GEOMETRY: { + for (size_t offset = 0; offset < field_data->get_num_rows(); + ++offset) { + auto geo_ptr = static_cast( + field_data->RawValue(offset)); + payload_writer->add_one_binary_payload( + reinterpret_cast(geo_ptr->data()), + geo_ptr->size()); + } + break; + } case DataType::VECTOR_SPARSE_FLOAT: { for (size_t offset = 0; offset < field_data->get_num_rows(); ++offset) { diff --git a/internal/core/src/storage/Util.cpp b/internal/core/src/storage/Util.cpp index e1bb95579a..9eef525d59 100644 --- a/internal/core/src/storage/Util.cpp +++ b/internal/core/src/storage/Util.cpp @@ -275,7 +275,8 @@ CreateArrowBuilder(DataType data_type) { return std::make_shared(); } case DataType::ARRAY: - case DataType::JSON: { + case DataType::JSON: + case DataType::GEOMETRY: { return std::make_shared(); } // sparse float vector doesn't require a dim @@ -356,7 +357,8 @@ CreateArrowSchema(DataType data_type, bool nullable) { {arrow::field("val", arrow::utf8(), nullable)}); } case DataType::ARRAY: - case DataType::JSON: { + case DataType::JSON: + case DataType::GEOMETRY: { return arrow::schema( {arrow::field("val", arrow::binary(), nullable)}); } @@ -849,6 +851,9 @@ CreateFieldData(const DataType& type, case DataType::JSON: return std::make_shared>( type, nullable, total_num_rows); + case DataType::GEOMETRY: + return std::make_shared>( + type, nullable, total_num_rows); case DataType::ARRAY: return std::make_shared>( type, nullable, total_num_rows); diff --git a/internal/core/unittest/test_cached_search_iterator.cpp b/internal/core/unittest/test_cached_search_iterator.cpp index e6154eae05..d8287b6bc7 100644 --- a/internal/core/unittest/test_cached_search_iterator.cpp +++ b/internal/core/unittest/test_cached_search_iterator.cpp @@ -251,7 +251,8 @@ class CachedSearchIteratorTest size_t offset = 0; for (size_t i = 0; i < num_chunks_; ++i) { - const size_t rows = std::min(nb_ - offset, kSizePerChunk); + const size_t rows = + std::min(static_cast(nb_ - offset), kSizePerChunk); const size_t chunk_bitset_size = (rows + 7) / 8; const size_t buf_size = chunk_bitset_size + rows * dim_ * sizeof(float); diff --git a/internal/core/unittest/test_chunk.cpp b/internal/core/unittest/test_chunk.cpp index b4b31b4907..bd701a85f1 100644 --- a/internal/core/unittest/test_chunk.cpp +++ b/internal/core/unittest/test_chunk.cpp @@ -26,6 +26,7 @@ #include "common/FieldDataInterface.h" #include "common/FieldMeta.h" #include "common/File.h" +#include "common/Geometry.h" #include "common/Types.h" #include "storage/Event.h" #include "storage/Util.h" @@ -126,7 +127,8 @@ TEST(chunk, test_json_field) { auto ser_data = event_data.Serialize(); auto get_record_batch_reader = - [&]() -> std::shared_ptr<::arrow::RecordBatchReader> { + [&]() -> std::pair, + std::unique_ptr> { auto buffer = std::make_shared( ser_data.data() + 2 * sizeof(milvus::Timestamp), ser_data.size() - 2 * sizeof(milvus::Timestamp)); @@ -141,11 +143,11 @@ TEST(chunk, test_json_field) { std::shared_ptr<::arrow::RecordBatchReader> rb_reader; s = arrow_reader->GetRecordBatchReader(&rb_reader); EXPECT_TRUE(s.ok()); - return rb_reader; + return {rb_reader, std::move(arrow_reader)}; }; { - auto rb_reader = get_record_batch_reader(); + auto [rb_reader, arrow_reader] = get_record_batch_reader(); // nullable=false FieldMeta field_meta( FieldName("a"), milvus::FieldId(1), DataType::JSON, false); @@ -173,7 +175,7 @@ TEST(chunk, test_json_field) { } } { - auto rb_reader = get_record_batch_reader(); + auto [rb_reader, arrow_reader] = get_record_batch_reader(); // nullable=true FieldMeta field_meta( FieldName("a"), milvus::FieldId(1), DataType::JSON, true); @@ -456,4 +458,204 @@ TEST(chunk, test_sparse_float) { EXPECT_EQ(v1[j].val, v2[j].val); } } +} + +class TempDir { + public: + TempDir() { + auto path = boost::filesystem::unique_path("%%%%_%%%%"); + auto abs_path = boost::filesystem::temp_directory_path() / path; + boost::filesystem::create_directory(abs_path); + dir_ = abs_path; + } + + ~TempDir() { + boost::filesystem::remove_all(dir_); + } + + std::string + dir() { + return dir_.string(); + } + + private: + boost::filesystem::path dir_; +}; + +TEST(chunk, test_geometry_field) { + // Create simple geometry data - just a few points + FixedVector data; + data.reserve(3); + + // Create simple point geometries using WKT format + std::string point1_wkt = "POINT(0 0)"; + std::string point2_wkt = "POINT(1 1)"; + std::string point3_wkt = "POINT(2 2)"; + + // Convert WKT to WKB format + data.push_back(Geometry(point1_wkt.data()).to_wkb_string()); + data.push_back(Geometry(point2_wkt.data()).to_wkb_string()); + data.push_back(Geometry(point3_wkt.data()).to_wkb_string()); + + auto field_data = + milvus::storage::CreateFieldData(storage::DataType::GEOMETRY); + field_data->FillFieldData(data.data(), data.size()); + + storage::InsertEventData event_data; + auto payload_reader = + std::make_shared(field_data); + event_data.payload_reader = payload_reader; + auto ser_data = event_data.Serialize(); + auto buffer = std::make_shared( + ser_data.data() + 2 * sizeof(milvus::Timestamp), + ser_data.size() - 2 * sizeof(milvus::Timestamp)); + + parquet::arrow::FileReaderBuilder reader_builder; + auto s = reader_builder.Open(buffer); + EXPECT_TRUE(s.ok()); + std::unique_ptr arrow_reader; + s = reader_builder.Build(&arrow_reader); + EXPECT_TRUE(s.ok()); + + std::shared_ptr<::arrow::RecordBatchReader> rb_reader; + s = arrow_reader->GetRecordBatchReader(&rb_reader); + EXPECT_TRUE(s.ok()); + + FieldMeta field_meta( + FieldName("a"), milvus::FieldId(1), DataType::GEOMETRY, false); + auto chunk = create_chunk(field_meta, rb_reader); + + // Since GeometryChunk is an alias for StringChunk, we can use StringViews + auto views = std::dynamic_pointer_cast(chunk)->StringViews( + std::nullopt); + EXPECT_EQ(views.first.size(), data.size()); + for (size_t i = 0; i < data.size(); ++i) { + EXPECT_EQ(views.first[i], data[i]); + } +} + +TEST(chunk, test_geometry_field_nullable_all_valid) { + // Prepare geometry data (WKB strings) – all rows valid but nullable flag enabled + FixedVector data; + data.reserve(3); + data.push_back(Geometry("POINT(0 0)").to_wkb_string()); + data.push_back(Geometry("POINT(1 1)").to_wkb_string()); + data.push_back(Geometry("POINT(2 2)").to_wkb_string()); + + auto field_data = + milvus::storage::CreateFieldData(storage::DataType::GEOMETRY, true); + // All rows are valid – need explicit valid bitmap when nullable=true + uint8_t* valid_bitmap_all = + new uint8_t[1]{0x07}; // 0b00000111 (3 rows valid) + field_data->FillFieldData(data.data(), valid_bitmap_all, data.size()); + + storage::InsertEventData event_data; + event_data.payload_reader = + std::make_shared(field_data); + auto ser_data = event_data.Serialize(); + auto buffer = std::make_shared( + ser_data.data() + 2 * sizeof(milvus::Timestamp), + ser_data.size() - 2 * sizeof(milvus::Timestamp)); + + parquet::arrow::FileReaderBuilder reader_builder; + ASSERT_TRUE(reader_builder.Open(buffer).ok()); + std::unique_ptr arrow_reader; + ASSERT_TRUE(reader_builder.Build(&arrow_reader).ok()); + std::shared_ptr<::arrow::RecordBatchReader> rb_reader; + ASSERT_TRUE(arrow_reader->GetRecordBatchReader(&rb_reader).ok()); + + FieldMeta field_meta( + FieldName("geo"), milvus::FieldId(1), DataType::GEOMETRY, true); + auto chunk = create_chunk(field_meta, rb_reader); + + auto [views, valid] = + std::dynamic_pointer_cast(chunk)->StringViews( + std::nullopt); + ASSERT_EQ(views.size(), data.size()); + for (size_t i = 0; i < data.size(); ++i) { + EXPECT_EQ(views[i], data[i]); + EXPECT_TRUE(valid[i]); + } + + delete[] valid_bitmap_all; +} + +TEST(chunk, test_geometry_field_mmap_with_nulls) { + // Prepare geometry data with one NULL row (middle) + FixedVector data; + data.reserve(3); + data.push_back(Geometry("POINT(0 0)").to_wkb_string()); + data.push_back( + Geometry("POINT(1 1)").to_wkb_string()); // will be marked NULL + data.push_back(Geometry("POINT(2 2)").to_wkb_string()); + + // Validity bitmap: 0b00000101 -> rows 0 and 2 valid, row 1 invalid + uint8_t* valid_bitmap = new uint8_t[1]{0x05}; + + auto field_data = + milvus::storage::CreateFieldData(storage::DataType::GEOMETRY, true); + field_data->FillFieldData(data.data(), valid_bitmap, data.size()); + + storage::InsertEventData event_data; + event_data.payload_reader = + std::make_shared(field_data); + auto ser_data = event_data.Serialize(); + auto buffer = std::make_shared( + ser_data.data() + 2 * sizeof(milvus::Timestamp), + ser_data.size() - 2 * sizeof(milvus::Timestamp)); + + parquet::arrow::FileReaderBuilder reader_builder; + ASSERT_TRUE(reader_builder.Open(buffer).ok()); + std::unique_ptr arrow_reader; + ASSERT_TRUE(reader_builder.Build(&arrow_reader).ok()); + std::shared_ptr<::arrow::RecordBatchReader> rb_reader; + ASSERT_TRUE(arrow_reader->GetRecordBatchReader(&rb_reader).ok()); + + // Prepare mmap file + TempDir temp; + std::string temp_dir = temp.dir(); + auto file = File::Open(temp_dir + "/geo_mmap", O_CREAT | O_RDWR); + int file_offset = 0; + + FieldMeta field_meta( + FieldName("geo"), milvus::FieldId(1), DataType::GEOMETRY, true); + auto chunk = create_chunk(field_meta, rb_reader); + + auto [views, valid] = + std::dynamic_pointer_cast(chunk)->StringViews( + std::nullopt); + ASSERT_EQ(views.size(), data.size()); + for (size_t i = 0; i < data.size(); ++i) { + if (valid[i]) { + EXPECT_EQ(views[i], data[i]); + } else { + EXPECT_FALSE(valid[i]); + } + } + file.Close(); + delete[] valid_bitmap; +} + +TEST(array, test_geometry_array_output_data) { + // Prepare two simple geometries (WKB strings) + std::string wkb1 = Geometry("POINT(10 10)").to_wkb_string(); + std::string wkb2 = Geometry("POINT(20 20)").to_wkb_string(); + + // Build raw buffer and offsets for two variable-length geometry elements + // Need to support kGeometry in construct Array(const ScalarArray& field_data) + uint32_t offsets_raw[2] = {0, static_cast(wkb1.size())}; + size_t total_size = wkb1.size() + wkb2.size(); + std::vector buf(total_size); + std::copy(wkb1.begin(), wkb1.end(), buf.begin()); + std::copy(wkb2.begin(), wkb2.end(), buf.begin() + wkb1.size()); + + // Construct Array with element_type = GEOMETRY + Array geo_array( + buf.data(), /*len=*/2, total_size, DataType::GEOMETRY, offsets_raw); + + auto serialized = geo_array.output_data(); + + ASSERT_EQ(serialized.geometry_data().data_size(), 2); + EXPECT_EQ(serialized.geometry_data().data(0), wkb1); + EXPECT_EQ(serialized.geometry_data().data(1), wkb2); } \ No newline at end of file diff --git a/internal/core/unittest/test_chunk_vector.cpp b/internal/core/unittest/test_chunk_vector.cpp index 66867bbbd0..2220ee486a 100644 --- a/internal/core/unittest/test_chunk_vector.cpp +++ b/internal/core/unittest/test_chunk_vector.cpp @@ -51,6 +51,7 @@ TEST_F(ChunkVectorTest, FillDataWithMmap) { auto double_field = schema->AddDebugField("double", DataType::DOUBLE); auto varchar_field = schema->AddDebugField("varchar", DataType::VARCHAR); auto json_field = schema->AddDebugField("json", DataType::JSON); + auto geometry_field = schema->AddDebugField("geometry", DataType::GEOMETRY); auto int_array_field = schema->AddDebugField("int_array", DataType::ARRAY, DataType::INT8); auto long_array_field = @@ -116,6 +117,8 @@ TEST_F(ChunkVectorTest, FillDataWithMmap) { varchar_field, ids_ds->GetIds(), num_inserted); auto json_result = segment->bulk_subscript(json_field, ids_ds->GetIds(), num_inserted); + auto geometry_result = segment->bulk_subscript( + geometry_field, ids_ds->GetIds(), num_inserted); auto int_array_result = segment->bulk_subscript( int_array_field, ids_ds->GetIds(), num_inserted); auto long_array_result = segment->bulk_subscript( @@ -150,6 +153,8 @@ TEST_F(ChunkVectorTest, FillDataWithMmap) { EXPECT_EQ(varchar_result->scalars().string_data().data_size(), num_inserted); EXPECT_EQ(json_result->scalars().json_data().data_size(), num_inserted); + EXPECT_EQ(geometry_result->scalars().geometry_data().data_size(), + num_inserted); EXPECT_EQ(fp32_vec_result->vectors().float_vector().data_size(), num_inserted * dim); EXPECT_EQ(fp16_vec_result->vectors().float16_vector().size(), diff --git a/internal/core/unittest/test_chunked_segment.cpp b/internal/core/unittest/test_chunked_segment.cpp index b8f2af3f8f..8c95d37a3d 100644 --- a/internal/core/unittest/test_chunked_segment.cpp +++ b/internal/core/unittest/test_chunked_segment.cpp @@ -41,6 +41,7 @@ #include #include #include +#include struct DeferRelease { using functype = std::function; @@ -79,8 +80,13 @@ TEST(test_chunk_segment, TestSearchOnSealed) { auto data = dataset.get_col(fakevec_id); auto buf_size = chunk_bitset_size + 4 * data.size(); - char* buf = new char[buf_size]; - defer.AddDefer([buf]() { delete[] buf; }); + char* buf = reinterpret_cast(mmap(nullptr, + buf_size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, + -1, + 0)); + ASSERT_NE(buf, MAP_FAILED); memcpy(buf + chunk_bitset_size, data.data(), 4 * data.size()); auto chunk = std::make_shared( diff --git a/internal/core/unittest/test_data_codec.cpp b/internal/core/unittest/test_data_codec.cpp index e031b9b636..63dbedc5c5 100644 --- a/internal/core/unittest/test_data_codec.cpp +++ b/internal/core/unittest/test_data_codec.cpp @@ -17,6 +17,9 @@ #include #include +#include "common/Geometry.h" +#include "ogr_core.h" +#include "ogr_geometry.h" #include "storage/DataCodec.h" #include "storage/InsertData.h" #include "storage/IndexData.h" @@ -351,7 +354,109 @@ TEST(storage, InsertDataInt64Nullable) { ASSERT_EQ(*new_payload->ValidData(), *valid_data); delete[] valid_data; } +TEST(storage, InsertDataGeometry) { + OGRPoint point1(10.25, 0.55), point2(9.75, -0.23), point3(-8.50, 1.44); + OGRLineString linstring; + linstring.addPoint(&point1); + linstring.addPoint(&point2); + linstring.addPoint(&point3); + OGRPolygon polygon; + OGRLinearRing ring; + ring.addPoint(&point1); + ring.addPoint(&point2); + ring.addPoint(&point3); + ring.closeRings(); + polygon.addRing(&ring); + std::string str1, str2, str3; + str1 = Geometry(point1.exportToWkt().data()).to_wkb_string(); + str2 = Geometry(linstring.exportToWkt().data()).to_wkb_string(); + str3 = Geometry(polygon.exportToWkt().data()).to_wkb_string(); + FixedVector data = {str1, str2, str3}; + auto field_data = + milvus::storage::CreateFieldData(storage::DataType::GEOMETRY, false); + field_data->FillFieldData(data.data(), data.size()); + auto payload_reader = + std::make_shared(field_data); + storage::InsertData insert_data(payload_reader); + storage::FieldDataMeta field_data_meta{100, 101, 102, 103}; + insert_data.SetFieldDataMeta(field_data_meta); + insert_data.SetTimestamps(0, 100); + auto serialized_bytes = insert_data.Serialize(storage::StorageType::Remote); + std::shared_ptr serialized_data_ptr(serialized_bytes.data(), + [&](uint8_t*) {}); + auto new_insert_data = storage::DeserializeFileData( + serialized_data_ptr, serialized_bytes.size()); + ASSERT_EQ(new_insert_data->GetCodecType(), storage::InsertDataType); + ASSERT_EQ(new_insert_data->GetTimeRage(), + std::make_pair(Timestamp(0), Timestamp(100))); + auto new_payload = new_insert_data->GetFieldData(); + ASSERT_EQ(new_payload->get_data_type(), storage::DataType::GEOMETRY); + ASSERT_EQ(new_payload->get_num_rows(), data.size()); + FixedVector new_data(data.size()); + ASSERT_EQ(new_payload->get_null_count(), 0); + for (int i = 0; i < data.size(); ++i) { + new_data[i] = + *static_cast(new_payload->RawValue(i)); + ASSERT_EQ(new_payload->DataSize(i), data[i].size()); + } + ASSERT_EQ(data, new_data); +} + +TEST(storage, InsertDataGeometryNullable) { + // Prepare five simple point geometries in WKB format + OGRPoint p1(0.0, 0.0), p2(1.0, 1.0), p3(2.0, 2.0), p4(3.0, 3.0), + p5(4.0, 4.0); + std::string str1 = Geometry(p1.exportToWkt().data()).to_wkb_string(); + std::string str2 = Geometry(p2.exportToWkt().data()).to_wkb_string(); + std::string str3 = Geometry(p3.exportToWkt().data()).to_wkb_string(); + std::string str4 = Geometry(p4.exportToWkt().data()).to_wkb_string(); + std::string str5 = Geometry(p5.exportToWkt().data()).to_wkb_string(); + + FixedVector data = {str1, str2, str3, str4, str5}; + + // Create nullable geometry FieldData + auto field_data = + milvus::storage::CreateFieldData(storage::DataType::GEOMETRY, true); + // valid_data bitmap: 0xF3 (11110011 b) – rows 0,1,4 valid; rows 2,3 null + uint8_t* valid_data = new uint8_t[1]{0xF3}; + field_data->FillFieldData(data.data(), valid_data, data.size()); + + // Round-trip the payload through InsertData serialization pipeline + auto payload_reader = + std::make_shared(field_data); + storage::InsertData insert_data(payload_reader); + storage::FieldDataMeta field_data_meta{100, 101, 102, 103}; + insert_data.SetFieldDataMeta(field_data_meta); + insert_data.SetTimestamps(0, 100); + + auto serialized_bytes = insert_data.Serialize(storage::StorageType::Remote); + std::shared_ptr serialized_data_ptr(serialized_bytes.data(), + [&](uint8_t*) {}); + auto new_insert_data = storage::DeserializeFileData( + serialized_data_ptr, serialized_bytes.size()); + + ASSERT_EQ(new_insert_data->GetCodecType(), storage::InsertDataType); + ASSERT_EQ(new_insert_data->GetTimeRage(), + std::make_pair(Timestamp(0), Timestamp(100))); + + auto new_payload = new_insert_data->GetFieldData(); + ASSERT_EQ(new_payload->get_data_type(), storage::DataType::GEOMETRY); + ASSERT_EQ(new_payload->get_num_rows(), data.size()); + // Note: current geometry serialization path writes empty string for null + // rows and loses Arrow null-bitmap, so null_count()==0 after round-trip. + + // Expected data: original rows preserved (bitmap ignored by codec) + FixedVector new_data(data.size()); + for (int i = 0; i < data.size(); ++i) { + new_data[i] = + *static_cast(new_payload->RawValue(i)); + ASSERT_EQ(new_payload->DataSize(i), data[i].size()); + } + ASSERT_EQ(data, new_data); + + delete[] valid_data; +} TEST(storage, InsertDataString) { FixedVector data = { "test1", "test2", "test3", "test4", "test5"}; diff --git a/internal/core/unittest/test_expr.cpp b/internal/core/unittest/test_expr.cpp index 37936f8a1b..a0d06771a2 100644 --- a/internal/core/unittest/test_expr.cpp +++ b/internal/core/unittest/test_expr.cpp @@ -27,6 +27,7 @@ #include #include "common/FieldDataInterface.h" +#include "common/Geometry.h" #include "common/Json.h" #include "common/JsonCastType.h" #include "common/LoadInfo.h" @@ -17081,3 +17082,407 @@ TEST_P(JsonIndexBinaryExprTest, TestBinaryRangeExpr) { EXPECT_TRUE(res == expect_result); } } + +TEST_P(ExprTest, TestGISFunction) { + using namespace milvus; + using namespace milvus::query; + using namespace milvus::segcore; + + // Create schema with geometry field + auto schema = std::make_shared(); + auto int_fid = schema->AddDebugField("int", DataType::INT64); + auto vec_fid = schema->AddDebugField( + "fakevec", DataType::VECTOR_FLOAT, 16, knowhere::metric::L2); + auto geom_fid = schema->AddDebugField("geometry", DataType::GEOMETRY); + schema->set_primary_field_id(int_fid); + + auto seg = CreateGrowingSegment(schema, empty_index_meta); + int N = 1000; + int num_iters = 1; + + // Generate test data + for (int iter = 0; iter < num_iters; ++iter) { + auto raw_data = DataGen(schema, N, iter); + seg->PreInsert(N); + seg->Insert(iter * N, + N, + raw_data.row_ids_.data(), + raw_data.timestamps_.data(), + raw_data.raw_); + } + + auto seg_promote = dynamic_cast(seg.get()); + + // Define GIS test cases using struct like JSON tests + struct GISTestcase { + std::string wkt_string; + proto::plan::GISFunctionFilterExpr_GISOp op; + }; + + std::vector testcases = { + {"POINT(0 0)", proto::plan::GISFunctionFilterExpr_GISOp_Intersects}, + {"POLYGON((-1 -1, 1 -1, 1 1, -1 1, -1 -1))", + proto::plan::GISFunctionFilterExpr_GISOp_Contains}, + {"LINESTRING(-2 0, 2 0)", + proto::plan::GISFunctionFilterExpr_GISOp_Crosses}, + {"POINT(10 10)", proto::plan::GISFunctionFilterExpr_GISOp_Equals}, + {"POLYGON((5 5, 15 5, 15 15, 5 15, 5 5))", + proto::plan::GISFunctionFilterExpr_GISOp_Touches}, + {"POLYGON((0.5 0.5, 1.5 0.5, 1.5 1.5, 0.5 1.5, 0.5 0.5))", + proto::plan::GISFunctionFilterExpr_GISOp_Overlaps}, + {"POLYGON((-10 -10, 10 -10, 10 10, -10 10, -10 -10))", + proto::plan::GISFunctionFilterExpr_GISOp_Within}}; + + // Execute tests + for (const auto& testcase : testcases) { + // Create Geometry object from WKT string + milvus::Geometry geometry(testcase.wkt_string.c_str()); + + // Create GIS expression + auto gis_expr = std::make_shared( + milvus::expr::ColumnInfo(geom_fid, DataType::GEOMETRY), + testcase.op, + geometry); + + auto plan = std::make_shared(DEFAULT_PLANNODE_ID, + gis_expr); + + // Verify query execution doesn't throw exceptions + ASSERT_NO_THROW({ + BitsetType final = ExecuteQueryExpr( + plan, seg_promote, N * num_iters, MAX_TIMESTAMP); + + EXPECT_EQ(final.size(), N * num_iters); + + // Verify result is not empty (at least some geometry data satisfies conditions) + bool has_true_result = false; + for (int i = 0; i < final.size(); ++i) { + if (final[i]) { + has_true_result = true; + break; + } + } + // Note: Since we use random data, all results might be false, which is normal + // We mainly verify the function execution doesn't crash + }); + } +} + +TEST(ExprTest, SealedSegmentAllOperators) { + // 1. Build schema with geometry field and primary key + auto schema = std::make_shared(); + auto pk_fid = schema->AddDebugField("pk", DataType::INT64); + auto geo_fid = schema->AddDebugField("geo", DataType::GEOMETRY); + schema->set_primary_field_id(pk_fid); + + // 2. Generate random data and load into a sealed segment + const int64_t N = 1000; + auto dataset = DataGen(schema, N); + auto seg = CreateSealedSegment(schema); + SealedLoadFieldData(dataset, *seg); + + // 3. Prepare (op, wkt) pairs to hit every GIS operator + std::vector< + std::pair> + test_cases = { + {proto::plan::GISFunctionFilterExpr_GISOp_Equals, "POINT(0 0)"}, + {proto::plan::GISFunctionFilterExpr_GISOp_Touches, + "POLYGON((-1 -1, -1 1, 1 1, 1 -1, -1 -1))"}, + {proto::plan::GISFunctionFilterExpr_GISOp_Overlaps, + "POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))"}, + {proto::plan::GISFunctionFilterExpr_GISOp_Crosses, + "LINESTRING(-1 0, 1 0)"}, + {proto::plan::GISFunctionFilterExpr_GISOp_Contains, + "POLYGON((-2 -2, 2 -2, 2 2, -2 2, -2 -2))"}, + {proto::plan::GISFunctionFilterExpr_GISOp_Intersects, "POINT(1 1)"}, + {proto::plan::GISFunctionFilterExpr_GISOp_Within, + "POLYGON((-5 -5, 5 -5, 5 5, -5 5, -5 -5))"}, + }; + + for (const auto& [op, wkt] : test_cases) { + // Build constant geometry used on right side of comparison + milvus::Geometry right_source(wkt.c_str()); + + // Create expression & plan node + auto gis_expr = std::make_shared( + expr::ColumnInfo(geo_fid, DataType::GEOMETRY), op, right_source); + auto plan_node = std::make_shared( + DEFAULT_PLANNODE_ID, gis_expr); + + // Execute expression over the sealed segment + BitsetType result = + ExecuteQueryExpr(plan_node, seg.get(), N, MAX_TIMESTAMP); + + // Validate basic expectations: bitset size should equal N + ASSERT_EQ(result.size(), N); + } +} + +TEST_P(ExprTest, TestGISFunctionWithControlledData) { + using namespace milvus; + using namespace milvus::query; + using namespace milvus::segcore; + + // Create schema with geometry field + auto schema = std::make_shared(); + auto int_fid = schema->AddDebugField("int", DataType::INT64); + auto vec_fid = schema->AddDebugField( + "fakevec", DataType::VECTOR_FLOAT, 16, knowhere::metric::L2); + auto geom_fid = schema->AddDebugField("geometry", DataType::GEOMETRY); + schema->set_primary_field_id(int_fid); + + auto seg = CreateGrowingSegment(schema, empty_index_meta); + int N = 100; + int num_iters = 1; + + // Generate controlled test data + for (int iter = 0; iter < num_iters; ++iter) { + auto raw_data = DataGen(schema, N, iter); + + // Replace geometry data with controlled test data + milvus::proto::schema::FieldData* geometry_field_data = nullptr; + for (auto& fd : *raw_data.raw_->mutable_fields_data()) { + if (fd.field_id() == geom_fid.get()) { + geometry_field_data = &fd; + break; + } + } + assert(geometry_field_data != nullptr); + geometry_field_data->mutable_scalars() + ->mutable_geometry_data() + ->clear_data(); + + // Create some controlled geometry data for testing + for (int i = 0; i < N; ++i) { + OGRGeometry* geometry = nullptr; + + if (i % 4 == 0) { + // Create point (0, 0) + OGRPoint point(0.0, 0.0); + geometry = point.clone(); + } else if (i % 4 == 1) { + // Create polygon containing (0, 0) + OGRPolygon polygon; + OGRLinearRing ring; + ring.addPoint(-1.0, -1.0); + ring.addPoint(1.0, -1.0); + ring.addPoint(1.0, 1.0); + ring.addPoint(-1.0, 1.0); + ring.addPoint(-1.0, -1.0); + polygon.addRing(&ring); + geometry = polygon.clone(); + } else if (i % 4 == 2) { + // Create polygon not containing (0, 0) + OGRPolygon polygon; + OGRLinearRing ring; + ring.addPoint(10.0, 10.0); + ring.addPoint(20.0, 10.0); + ring.addPoint(20.0, 20.0); + ring.addPoint(10.0, 20.0); + ring.addPoint(10.0, 10.0); + polygon.addRing(&ring); + geometry = polygon.clone(); + } else { + // Create line passing through (0, 0) + OGRLineString lineString; + lineString.addPoint(-1.0, 0.0); + lineString.addPoint(1.0, 0.0); + geometry = lineString.clone(); + } + + // Convert to WKB format + size_t size = geometry->WkbSize(); + std::vector wkb(size); + geometry->exportToWkb(wkbNDR, wkb.data()); + + geometry_field_data->mutable_scalars() + ->mutable_geometry_data() + ->add_data( + std::string(reinterpret_cast(wkb.data()), size)); + + OGRGeometryFactory::destroyGeometry(geometry); + } + + seg->PreInsert(N); + seg->Insert(iter * N, + N, + raw_data.row_ids_.data(), + raw_data.timestamps_.data(), + raw_data.raw_); + } + + auto seg_promote = dynamic_cast(seg.get()); + + // Test specific GIS operations + auto test_gis_operation = [&](const std::string& wkt, + proto::plan::GISFunctionFilterExpr_GISOp op, + std::function expected_func) { + // Create Geometry object from WKT string + milvus::Geometry geometry(wkt.c_str()); + + // Create GIS expression directly + auto gis_expr = std::make_shared( + milvus::expr::ColumnInfo(geom_fid, DataType::GEOMETRY), + op, + geometry); + + auto plan = std::make_shared(DEFAULT_PLANNODE_ID, + gis_expr); + + BitsetType final = + ExecuteQueryExpr(plan, seg_promote, N * num_iters, MAX_TIMESTAMP); + + EXPECT_EQ(final.size(), N * num_iters); + + // Verify results + for (int i = 0; i < N * num_iters; ++i) { + auto ans = final[i]; + auto expected = expected_func(i); + ASSERT_EQ(ans, expected) << "GIS operation failed at index " << i; + } + }; + + // Test contains operation + test_gis_operation("POLYGON((-2 -2, 2 -2, 2 2, -2 2, -2 -2))", + proto::plan::GISFunctionFilterExpr_GISOp_Within, + [](int i) -> bool { + // Only geometry at index 0,1 (polygon containing (0,0)) + return (i % 4 == 0) || (i % 4 == 1) || (i % 4 == 3); + }); + + // Test intersects operation + test_gis_operation("POINT(0 0)", + proto::plan::GISFunctionFilterExpr_GISOp_Intersects, + [](int i) -> bool { + // Point at index 0 (0,0), polygon at index 1, line at index 3 should all intersect with point (0,0) + return (i % 4 == 0) || (i % 4 == 1) || (i % 4 == 3); + }); + + // Test equals operation + test_gis_operation("POINT(0 0)", + proto::plan::GISFunctionFilterExpr_GISOp_Equals, + [](int i) -> bool { + // Only point at index 0 (0,0) should be equal + return (i % 4 == 0); + }); +} + +TEST_P(ExprTest, ParseGISFunctionFilterExprs) { + // Build Schema + auto schema = std::make_shared(); + auto dim = 16; + auto vec_id = schema->AddDebugField( + "vec", DataType::VECTOR_FLOAT, dim, knowhere::metric::L2); + auto geo_id = schema->AddDebugField("geo", DataType::GEOMETRY); + auto pk_id = schema->AddDebugField("pk", DataType::INT64); + schema->set_primary_field_id(pk_id); + + // Generate data and load + int64_t N = 1000; + auto dataset = DataGen(schema, N); + auto seg = CreateSealedSegment(schema); + SealedLoadFieldData(dataset, *seg); + + // Test plan with gisfunction_filter_expr + std::string raw_plan = R"PLAN(vector_anns: < + field_id: 100 + predicates: < + gisfunction_filter_expr: < + column_info: < + field_id: 101 + data_type: Geometry + > + op: Within + wkt_string: "POLYGON((0 0,1 0,1 1,0 1,0 0))" + > + > + query_info: < + topk: 5 + metric_type: "L2" + round_decimal: 3 + search_params: "{\"nprobe\":10}" + > + placeholder_tag: "$0" + >)PLAN"; + + // Convert and parse + auto bin_plan = translate_text_plan_with_metric_type(raw_plan); + auto plan = + CreateSearchPlanByExpr(*schema, bin_plan.data(), bin_plan.size()); + + // If parsing fails, test will fail with exception + // If parsing succeeds, ParseGISFunctionFilterExprs is covered + + // Execute search to verify execution logic + + auto ph_raw = CreatePlaceholderGroup(5, dim, 123); + auto ph_grp = ParsePlaceholderGroup(plan.get(), ph_raw.SerializeAsString()); + auto sr = seg->Search(plan.get(), ph_grp.get(), MAX_TIMESTAMP); +} + +TEST(ExprTest, ParseGISFunctionFilterExprsMultipleOps) { + // Build Schema + auto schema = std::make_shared(); + auto dim = 16; + auto vec_id = schema->AddDebugField( + "vec", DataType::VECTOR_FLOAT, dim, knowhere::metric::L2); + auto geo_id = schema->AddDebugField("geo", DataType::GEOMETRY); + auto pk_id = schema->AddDebugField("pk", DataType::INT64); + schema->set_primary_field_id(pk_id); + + // Generate data and load + int64_t N = 1000; + auto dataset = DataGen(schema, N); + auto seg = CreateSealedSegment(schema); + SealedLoadFieldData(dataset, *seg); + + // Test different GIS operations + std::vector> test_cases = { + {"Within", "POLYGON((0 0,1 0,1 1,0 1,0 0))"}, + {"Contains", "POINT(0.5 0.5)"}, + {"Intersects", "LINESTRING(0 0,1 1)"}, + {"Equals", "POINT(0 0)"}, + {"Touches", "POLYGON((10 10,11 10,11 11,10 11,10 10))"}}; + + for (const auto& test_case : test_cases) { + const auto& op = test_case.first; + const auto& wkt = test_case.second; + + std::string raw_plan = R"( + vector_anns: < + field_id: 100 + predicates: < + gisfunction_filter_expr: < + column_info: < + field_id: 101 + data_type: Geometry + > + op: )" + + op + R"( + wkt_string: ")" + + wkt + R"(" + > + > + query_info: < + topk: 5 + metric_type: "L2" + round_decimal: 3 + search_params: "{\"nprobe\":10}" + > + placeholder_tag: "$0" + > + )"; + + // Convert and parse + auto bin_plan = translate_text_plan_to_binary_plan(raw_plan.c_str()); + auto plan = + CreateSearchPlanByExpr(*schema, bin_plan.data(), bin_plan.size()); + + // Execute search to verify execution logic + auto ph_raw = CreatePlaceholderGroup(5, dim, 123); + auto ph_grp = + ParsePlaceholderGroup(plan.get(), ph_raw.SerializeAsString()); + auto sr = seg->Search(plan.get(), ph_grp.get(), MAX_TIMESTAMP); + EXPECT_EQ(sr->total_nq_, 5) << "Failed for operation: " << op; + } +} \ No newline at end of file diff --git a/internal/core/unittest/test_group_by.cpp b/internal/core/unittest/test_group_by.cpp index f9f86687b5..6c4d4381cf 100644 --- a/internal/core/unittest/test_group_by.cpp +++ b/internal/core/unittest/test_group_by.cpp @@ -10,6 +10,7 @@ // or implied. See the License for the specific language governing permissions and limitations under the License #include +#include #include "common/Schema.h" #include "query/Plan.h" #include "segcore/SegmentSealedImpl.h" @@ -543,9 +544,9 @@ TEST(GroupBY, Reduce) { int repeat_count_1 = 2; int repeat_count_2 = 5; auto raw_data1 = - DataGen(schema, N, seed, ts_offset, repeat_count_1, false, false); + DataGen(schema, N, seed, ts_offset, repeat_count_1, 10, false, false); auto raw_data2 = - DataGen(schema, N, seed, ts_offset, repeat_count_2, false, false); + DataGen(schema, N, seed, ts_offset, repeat_count_2, 10, false, false); auto fields = schema->get_fields(); //load segment1 raw data diff --git a/internal/core/unittest/test_growing.cpp b/internal/core/unittest/test_growing.cpp index 898dad93f0..8e63d466a3 100644 --- a/internal/core/unittest/test_growing.cpp +++ b/internal/core/unittest/test_growing.cpp @@ -150,6 +150,7 @@ TEST_P(GrowingTest, FillData) { auto double_field = schema->AddDebugField("double", DataType::DOUBLE); auto varchar_field = schema->AddDebugField("varchar", DataType::VARCHAR); auto json_field = schema->AddDebugField("json", DataType::JSON); + auto geometry_field = schema->AddDebugField("geometry", DataType::GEOMETRY); auto int_array_field = schema->AddDebugField("int_array", DataType::ARRAY, DataType::INT8); auto long_array_field = @@ -213,6 +214,8 @@ TEST_P(GrowingTest, FillData) { varchar_field, ids_ds->GetIds(), num_inserted); auto json_result = segment->bulk_subscript(json_field, ids_ds->GetIds(), num_inserted); + auto geometry_result = segment->bulk_subscript( + geometry_field, ids_ds->GetIds(), num_inserted); auto int_array_result = segment->bulk_subscript( int_array_field, ids_ds->GetIds(), num_inserted); auto long_array_result = segment->bulk_subscript( @@ -241,6 +244,8 @@ TEST_P(GrowingTest, FillData) { EXPECT_EQ(varchar_result->scalars().string_data().data_size(), num_inserted); EXPECT_EQ(json_result->scalars().json_data().data_size(), num_inserted); + EXPECT_EQ(geometry_result->scalars().geometry_data().data_size(), + num_inserted); if (data_type == DataType::VECTOR_FLOAT) { EXPECT_EQ(vec_result->vectors().float_vector().data_size(), num_inserted * dim); diff --git a/internal/core/unittest/test_sealed.cpp b/internal/core/unittest/test_sealed.cpp index e1bf41a9c0..5b4a1c4634 100644 --- a/internal/core/unittest/test_sealed.cpp +++ b/internal/core/unittest/test_sealed.cpp @@ -491,6 +491,7 @@ TEST(Sealed, LoadFieldData) { schema->AddDebugField("int16", DataType::INT16); schema->AddDebugField("float", DataType::FLOAT); schema->AddDebugField("json", DataType::JSON); + schema->AddDebugField("geometry", DataType::GEOMETRY); schema->AddDebugField("array", DataType::ARRAY, DataType::INT64); schema->set_primary_field_id(counter_id); auto int8_nullable_id = @@ -668,6 +669,7 @@ TEST(Sealed, ClearData) { schema->AddDebugField("int16", DataType::INT16); schema->AddDebugField("float", DataType::FLOAT); schema->AddDebugField("json", DataType::JSON); + schema->AddDebugField("geometry", DataType::GEOMETRY); schema->AddDebugField("array", DataType::ARRAY, DataType::INT64); schema->set_primary_field_id(counter_id); @@ -799,6 +801,7 @@ TEST(Sealed, LoadFieldDataMmap) { schema->AddDebugField("int16", DataType::INT16); schema->AddDebugField("float", DataType::FLOAT); schema->AddDebugField("json", DataType::JSON); + schema->AddDebugField("geometry", DataType::GEOMETRY); schema->AddDebugField("array", DataType::ARRAY, DataType::INT64); schema->set_primary_field_id(counter_id); @@ -2263,6 +2266,7 @@ TEST(Sealed, QueryAllFields) { auto double_field = schema->AddDebugField("double", DataType::DOUBLE); auto varchar_field = schema->AddDebugField("varchar", DataType::VARCHAR); auto json_field = schema->AddDebugField("json", DataType::JSON); + auto geometry_field = schema->AddDebugField("geometry", DataType::GEOMETRY); auto int_array_field = schema->AddDebugField("int_array", DataType::ARRAY, DataType::INT8); auto long_array_field = @@ -2310,6 +2314,7 @@ TEST(Sealed, QueryAllFields) { auto double_values = dataset.get_col(double_field); auto varchar_values = dataset.get_col(varchar_field); auto json_values = dataset.get_col(json_field); + auto geometry_values = dataset.get_col(geometry_field); auto int_array_values = dataset.get_col(int_array_field); auto long_array_values = dataset.get_col(long_array_field); auto bool_array_values = dataset.get_col(bool_array_field); @@ -2339,6 +2344,8 @@ TEST(Sealed, QueryAllFields) { segment->bulk_subscript(varchar_field, ids_ds->GetIds(), dataset_size); auto json_result = segment->bulk_subscript(json_field, ids_ds->GetIds(), dataset_size); + auto geometry_result = + segment->bulk_subscript(geometry_field, ids_ds->GetIds(), dataset_size); auto int_array_result = segment->bulk_subscript( int_array_field, ids_ds->GetIds(), dataset_size); auto long_array_result = segment->bulk_subscript( @@ -2368,6 +2375,8 @@ TEST(Sealed, QueryAllFields) { EXPECT_EQ(varchar_result->scalars().string_data().data_size(), dataset_size); EXPECT_EQ(json_result->scalars().json_data().data_size(), dataset_size); + EXPECT_EQ(geometry_result->scalars().geometry_data().data_size(), + dataset_size); EXPECT_EQ(vec_result->vectors().float_vector().data_size(), dataset_size * dim); EXPECT_EQ(float16_vec_result->vectors().float16_vector().size(), @@ -2417,6 +2426,8 @@ TEST(Sealed, QueryAllNullableFields) { auto varchar_field = schema->AddDebugField("varchar", DataType::VARCHAR, true); auto json_field = schema->AddDebugField("json", DataType::JSON, true); + auto geometry_field = + schema->AddDebugField("geometry", DataType::GEOMETRY, true); auto int_array_field = schema->AddDebugField( "int_array", DataType::ARRAY, DataType::INT8, true); auto long_array_field = schema->AddDebugField( @@ -2460,6 +2471,7 @@ TEST(Sealed, QueryAllNullableFields) { auto double_values = dataset.get_col(double_field); auto varchar_values = dataset.get_col(varchar_field); auto json_values = dataset.get_col(json_field); + auto geometry_values = dataset.get_col(geometry_field); auto int_array_values = dataset.get_col(int_array_field); auto long_array_values = dataset.get_col(long_array_field); auto bool_array_values = dataset.get_col(bool_array_field); @@ -2476,6 +2488,7 @@ TEST(Sealed, QueryAllNullableFields) { auto double_valid_values = dataset.get_col_valid(double_field); auto varchar_valid_values = dataset.get_col_valid(varchar_field); auto json_valid_values = dataset.get_col_valid(json_field); + auto geometry_valid_values = dataset.get_col_valid(geometry_field); auto int_array_valid_values = dataset.get_col_valid(int_array_field); auto long_array_valid_values = dataset.get_col_valid(long_array_field); auto bool_array_valid_values = dataset.get_col_valid(bool_array_field); @@ -2502,6 +2515,8 @@ TEST(Sealed, QueryAllNullableFields) { segment->bulk_subscript(varchar_field, ids_ds->GetIds(), dataset_size); auto json_result = segment->bulk_subscript(json_field, ids_ds->GetIds(), dataset_size); + auto geometry_result = + segment->bulk_subscript(geometry_field, ids_ds->GetIds(), dataset_size); auto int_array_result = segment->bulk_subscript( int_array_field, ids_ds->GetIds(), dataset_size); auto long_array_result = segment->bulk_subscript( @@ -2527,6 +2542,8 @@ TEST(Sealed, QueryAllNullableFields) { EXPECT_EQ(varchar_result->scalars().string_data().data_size(), dataset_size); EXPECT_EQ(json_result->scalars().json_data().data_size(), dataset_size); + EXPECT_EQ(geometry_result->scalars().geometry_data().data_size(), + dataset_size); EXPECT_EQ(vec_result->vectors().float_vector().data_size(), dataset_size * dim); EXPECT_EQ(int_array_result->scalars().array_data().data_size(), @@ -2550,6 +2567,7 @@ TEST(Sealed, QueryAllNullableFields) { EXPECT_EQ(double_result->valid_data_size(), dataset_size); EXPECT_EQ(varchar_result->valid_data_size(), dataset_size); EXPECT_EQ(json_result->valid_data_size(), dataset_size); + EXPECT_EQ(geometry_result->valid_data_size(), dataset_size); EXPECT_EQ(int_array_result->valid_data_size(), dataset_size); EXPECT_EQ(long_array_result->valid_data_size(), dataset_size); EXPECT_EQ(bool_array_result->valid_data_size(), dataset_size); @@ -2579,3 +2597,46 @@ TEST(Sealed, SearchSortedPk) { EXPECT_EQ(5, offsets2.size()); EXPECT_EQ(100, offsets2[0].get()); } + +TEST(Sealed, QueryAllFieldsWithGeo) { + auto schema = std::make_shared(); + auto metric_type = knowhere::metric::L2; + auto int64_field = schema->AddDebugField("int64", DataType::INT64); + auto geometry_field = schema->AddDebugField("geometry", DataType::GEOMETRY); + auto vec = schema->AddDebugField( + "embeddings", DataType::VECTOR_FLOAT, 128, metric_type); + schema->set_primary_field_id(int64_field); + + std::map index_params = { + {"index_type", "IVF_FLAT"}, + {"metric_type", metric_type}, + {"nlist", "128"}}; + std::map type_params = {{"dim", "128"}}; + FieldIndexMeta fieldIndexMeta( + vec, std::move(index_params), std::move(type_params)); + std::map filedMap = {{vec, fieldIndexMeta}}; + IndexMetaPtr metaPtr = + std::make_shared(100000, std::move(filedMap)); + auto segment_sealed = CreateSealedSegment(schema, metaPtr); + auto segment = dynamic_cast(segment_sealed.get()); + + int64_t dataset_size = 1000; + auto dataset = DataGen(schema, dataset_size); + SealedLoadFieldData(dataset, *segment); + + auto geometry_values = dataset.get_col(geometry_field); + + auto ids_ds = GenRandomIds(dataset_size); + auto geometry_result = + segment->bulk_subscript(geometry_field, ids_ds->GetIds(), dataset_size); + + EXPECT_EQ(geometry_result->scalars().geometry_data().data_size(), + dataset_size); + + for (size_t i = 0; i < dataset_size; ++i) { + auto id = ids_ds->GetIds()[i]; + // verify + ASSERT_EQ(geometry_values[id], + geometry_result->scalars().geometry_data().data(i)); + } +} diff --git a/internal/core/unittest/test_utils/DataGen.h b/internal/core/unittest/test_utils/DataGen.h index e6eaedb2d8..e6722ea091 100644 --- a/internal/core/unittest/test_utils/DataGen.h +++ b/internal/core/unittest/test_utils/DataGen.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "Constants.h" @@ -207,6 +208,14 @@ struct GeneratedData { std::copy(src_data.begin(), src_data.end(), ret_data); break; } + case DataType::GEOMETRY: { + auto ret_data = + reinterpret_cast(ret.data()); + auto src_data = + target_field_data.scalars().geometry_data().data(); + std::copy(src_data.begin(), src_data.end(), ret_data); + break; + } default: { PanicInfo(Unsupported, "unsupported"); } @@ -335,6 +344,109 @@ GenerateRandomSparseFloatVector(size_t rows, return tensor; } +inline OGRGeometry* makeGeometryValid(OGRGeometry* geometry) { + if (!geometry || geometry->IsValid()) + return geometry; + + OGRGeometry* fixed = geometry->MakeValid(); + if (fixed) { + OGRGeometryFactory::destroyGeometry(geometry); + geometry = fixed; + } + return geometry; +} + +inline void +generateRandomPoint(OGRPoint& point) { + point.setX(static_cast(rand()) / RAND_MAX * 360.0 - 180.0); + point.setY(static_cast(rand()) / RAND_MAX * 180.0 - 90.0); +} + +inline void +generateRandomValidLineString(OGRLineString& lineString, int numPoints) { + // Generate a simple line string that doesn't self-intersect + double startX = static_cast(rand()) / RAND_MAX * 300.0 - 150.0; + double startY = static_cast(rand()) / RAND_MAX * 160.0 - 80.0; + + OGRPoint point; + point.setX(startX); + point.setY(startY); + lineString.addPoint(&point); + + for (int i = 1; i < numPoints; ++i) { + // Generate next point with some distance from previous point + double deltaX = (static_cast(rand()) / RAND_MAX - 0.5) * 20.0; + double deltaY = (static_cast(rand()) / RAND_MAX - 0.5) * 20.0; + + point.setX(startX + deltaX); + point.setY(startY + deltaY); + lineString.addPoint(&point); + + startX = point.getX(); + startY = point.getY(); + } +} + +inline void +generateRandomValidPolygon(OGRPolygon& polygon, int numPoints) { + // Generate a simple convex polygon to avoid self-intersection + if (numPoints < 3) + numPoints = 3; + + OGRLinearRing ring; + + // Generate center point + double centerX = static_cast(rand()) / RAND_MAX * 300.0 - 150.0; + double centerY = static_cast(rand()) / RAND_MAX * 160.0 - 80.0; + + // Generate radius + double radius = 5.0 + static_cast(rand()) / RAND_MAX * 15.0; + + // Generate points in a circle to form a convex polygon + for (int i = 0; i < numPoints; ++i) { + double angle = 2.0 * M_PI * i / numPoints; + double x = centerX + radius * cos(angle); + double y = centerY + radius * sin(angle); + + OGRPoint point; + point.setX(x); + point.setY(y); + ring.addPoint(&point); + } + + // Close the ring + ring.closeRings(); + polygon.addRing(&ring); +} + +inline OGRGeometry* +GenRandomGeometry() { + OGRGeometry* geometry = nullptr; + int geomType = rand() % 3; // Randomly select a geometry type (0 to 2) + switch (geomType) { + case 0: { + OGRPoint point; + generateRandomPoint(point); + geometry = point.clone(); + break; + } + case 1: { + OGRLineString lineString; + generateRandomValidLineString(lineString, 5); + geometry = lineString.clone(); + break; + } + case 2: { + OGRPolygon polygon; + generateRandomValidPolygon(polygon, 5); + geometry = polygon.clone(); + break; + } + } + geometry = makeGeometryValid(geometry); + return geometry; +} + inline GeneratedData DataGen(SchemaPtr schema, int64_t N, @@ -545,6 +657,21 @@ DataGen(SchemaPtr schema, insert_cols(data, N, field_meta, random_valid); break; } + case DataType::GEOMETRY: { + vector data(N); + for (int i = 0; i < N / repeat_count; i++) { + OGRGeometry* geo = GenRandomGeometry(); + size_t size = geo->WkbSize(); + auto wkb_data = new unsigned char[size]; + geo->exportToWkb(wkbNDR, wkb_data); + data[i] = std::string( + reinterpret_cast(wkb_data), size); + OGRGeometryFactory::destroyGeometry(geo); + delete[] wkb_data; + } + insert_cols(data, N, field_meta, random_valid); + break; + } case DataType::ARRAY: { vector data(N); switch (field_meta.get_element_type()) { @@ -1186,6 +1313,16 @@ CreateFieldDataFromDataArray(ssize_t raw_count, } break; } + case DataType::GEOMETRY: { + auto src_data = data->scalars().geometry_data().data(); + std::vector data_raw(src_data.size()); + for (int i = 0; i < src_data.size(); i++) { + auto str = src_data.Get(i); + data_raw[i] = std::move(std::string(str)); + } + createFieldData(data_raw.data(), DataType::GEOMETRY, dim); + break; + } case DataType::ARRAY: { auto src_data = data->scalars().array_data().data(); std::vector data_raw(src_data.size()); diff --git a/internal/distributed/proxy/httpserver/utils.go b/internal/distributed/proxy/httpserver/utils.go index b05693122d..8d951301be 100644 --- a/internal/distributed/proxy/httpserver/utils.go +++ b/internal/distributed/proxy/httpserver/utils.go @@ -19,6 +19,7 @@ package httpserver import ( "bytes" "context" + "encoding/base64" "fmt" "math" "reflect" @@ -30,6 +31,8 @@ import ( "github.com/gin-gonic/gin" "github.com/spf13/cast" "github.com/tidwall/gjson" + "github.com/twpayne/go-geom/encoding/wkb" + "github.com/twpayne/go-geom/encoding/wkt" "go.uber.org/zap" "google.golang.org/protobuf/proto" @@ -545,6 +548,25 @@ func checkAndSetData(body []byte, collSchema *schemapb.CollectionSchema) (error, } case schemapb.DataType_JSON: reallyData[fieldName] = []byte(dataString) + case schemapb.DataType_Geometry: + // treat as string(wkt) data,the string data must be valid + WktString, err := base64.StdEncoding.DecodeString(dataString) + if err != nil { + log.Warn("proxy can not decode datastring with base64", zap.String("WktString:", dataString)) + return merr.WrapErrParameterInvalid(schemapb.DataType_name[int32(fieldType)], dataString, err.Error()), reallyDataArray, validDataMap + } + geomT, err := wkt.Unmarshal(string(WktString)) + if err != nil { + log.Warn("proxy change wkt to geomtyr failed!!", zap.String("WktString:", dataString)) + return merr.WrapErrParameterInvalid(schemapb.DataType_name[int32(fieldType)], dataString, err.Error()), reallyDataArray, validDataMap + } + // translate the wkt bytes to wkb bytes ,store the bytes in LittleEndian which cpp core used as well + dataWkbBytes, err := wkb.Marshal(geomT, wkb.NDR) + if err != nil { + log.Warn("proxy change geomtry to wkb failed!!", zap.String("WktString:", dataString)) + return merr.WrapErrParameterInvalid(schemapb.DataType_name[int32(fieldType)], dataString, err.Error()), reallyDataArray, validDataMap + } + reallyData[fieldName] = dataWkbBytes case schemapb.DataType_Float: result, err := cast.ToFloat32E(dataString) if err != nil { @@ -752,6 +774,8 @@ func anyToColumns(rows []map[string]interface{}, validDataMap map[string][]bool, data = make([]*schemapb.ScalarField, 0, rowsLen) case schemapb.DataType_JSON: data = make([][]byte, 0, rowsLen) + case schemapb.DataType_Geometry: + data = make([][]byte, 0, rowsLen) case schemapb.DataType_FloatVector: data = make([][]float32, 0, rowsLen) dim, _ := getDim(field) @@ -841,6 +865,8 @@ func anyToColumns(rows []map[string]interface{}, validDataMap map[string][]bool, nameColumns[field.Name] = append(nameColumns[field.Name].([]*schemapb.ScalarField), candi.v.Interface().(*schemapb.ScalarField)) case schemapb.DataType_JSON: nameColumns[field.Name] = append(nameColumns[field.Name].([][]byte), candi.v.Interface().([]byte)) + case schemapb.DataType_Geometry: + nameColumns[field.Name] = append(nameColumns[field.Name].([][]byte), candi.v.Interface().([]byte)) case schemapb.DataType_FloatVector: nameColumns[field.Name] = append(nameColumns[field.Name].([][]float32), candi.v.Interface().([]float32)) case schemapb.DataType_BinaryVector: @@ -1005,6 +1031,16 @@ func anyToColumns(rows []map[string]interface{}, validDataMap map[string][]bool, }, }, } + case schemapb.DataType_Geometry: + colData.Field = &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: column.([][]byte), + }, + }, + }, + } case schemapb.DataType_FloatVector: dim := nameDims[name] arr, err := convertFloatVectorToArray(column.([][]float32), dim) @@ -1273,6 +1309,8 @@ func buildQueryResp(rowsNum int64, needFields []string, fieldDataList []*schemap rowsNum = int64(len(fieldDataList[0].GetScalars().GetArrayData().Data)) case schemapb.DataType_JSON: rowsNum = int64(len(fieldDataList[0].GetScalars().GetJsonData().Data)) + case schemapb.DataType_Geometry: + rowsNum = int64(len(fieldDataList[0].GetScalars().GetGeometryData().Data)) case schemapb.DataType_BinaryVector: rowsNum = int64(len(fieldDataList[0].GetVectors().GetBinaryVector())*8) / fieldDataList[0].GetVectors().GetDim() case schemapb.DataType_FloatVector: @@ -1423,6 +1461,12 @@ func buildQueryResp(rowsNum int64, needFields []string, fieldDataList []*schemap } } } + case schemapb.DataType_Geometry: + if len(fieldDataList[j].ValidData) != 0 && !fieldDataList[j].ValidData[i] { + row[fieldDataList[j].FieldName] = nil + continue + } + row[fieldDataList[j].FieldName] = fieldDataList[j].GetScalars().GetGeometryData().Data[i] default: row[fieldDataList[j].FieldName] = "" } diff --git a/internal/distributed/proxy/httpserver/utils_test.go b/internal/distributed/proxy/httpserver/utils_test.go index a8d2f0f79a..7216099e77 100644 --- a/internal/distributed/proxy/httpserver/utils_test.go +++ b/internal/distributed/proxy/httpserver/utils_test.go @@ -1229,6 +1229,12 @@ func compareRow(m1 map[string]interface{}, m2 map[string]interface{}) bool { if arr1 != string(arr2) { return false } + } else if key == "field-geometry" { + arr1 := value.([]uint8) + arr2 := string(m2[key].([]byte)) + if arr2 != (string)(arr1) { + return false + } } else if strings.HasPrefix(key, "array-") { continue } else if value != m2[key] { @@ -1237,7 +1243,7 @@ func compareRow(m1 map[string]interface{}, m2 map[string]interface{}) bool { } for key, value := range m2 { - if (key == FieldBookIntro) || (key == "field-json") || (key == "field-array") { + if (key == FieldBookIntro) || (key == "field-json") || (key == "field-geometry") || (key == "field-array") { continue } else if strings.HasPrefix(key, "array-") { continue @@ -1337,6 +1343,12 @@ func newCollectionSchema(coll *schemapb.CollectionSchema) *schemapb.CollectionSc } coll.Fields = append(coll.Fields, &fieldSchema10) + fieldSchema11 := schemapb.FieldSchema{ + Name: "field-geometry", + DataType: schemapb.DataType_Geometry, + IsDynamic: false, + } + coll.Fields = append(coll.Fields, &fieldSchema11) return coll } @@ -1583,6 +1595,28 @@ func newFieldData(fieldDatas []*schemapb.FieldData, firstFieldType schemapb.Data } fieldDatas = append(fieldDatas, &fieldData11) + fieldData12 := schemapb.FieldData{ + Type: schemapb.DataType_Geometry, + FieldName: "field-geometry", + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + // WKT: POINT (30.123 -10.456) + Data: [][]byte{ + []byte(`POINT (30.123 -10.456)`), + []byte(`POINT (30.123 -10.456)`), + []byte(`POINT (30.123 -10.456)`), + // wkb:{0x01, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x4}, + }, + }, + }, + }, + }, + IsDynamic: false, + } + fieldDatas = append(fieldDatas, &fieldData12) + switch firstFieldType { case schemapb.DataType_None: return fieldDatas @@ -1618,6 +1652,8 @@ func newFieldData(fieldDatas []*schemapb.FieldData, firstFieldType schemapb.Data return []*schemapb.FieldData{&fieldData10} case schemapb.DataType_JSON: return []*schemapb.FieldData{&fieldData9} + case schemapb.DataType_Geometry: + return []*schemapb.FieldData{&fieldData12} case schemapb.DataType_SparseFloatVector: vectorField := generateVectorFieldData(firstFieldType) return []*schemapb.FieldData{&vectorField} @@ -1883,6 +1919,7 @@ func newSearchResult(results []map[string]interface{}) []map[string]interface{} result["field-varchar"] = strconv.Itoa(i) result["field-string"] = strconv.Itoa(i) result["field-json"] = []byte(`{"XXX": 0}`) + result["field-geometry"] = []byte(`POINT (30.123 -10.456)`) result["field-array"] = []bool{true} result["array-bool"] = []bool{true} result["array-int8"] = []int32{0} @@ -2175,6 +2212,7 @@ func TestBuildQueryResps(t *testing.T) { schemapb.DataType_Float, schemapb.DataType_Double, schemapb.DataType_String, schemapb.DataType_VarChar, schemapb.DataType_JSON, schemapb.DataType_Array, + schemapb.DataType_Geometry, } for _, dateType := range dataTypes { _, err := buildQueryResp(int64(0), outputFields, newFieldData([]*schemapb.FieldData{}, dateType), generateIDs(schemapb.DataType_Int64, 3), DefaultScores, true, nil) diff --git a/internal/parser/planparserv2/Plan.g4 b/internal/parser/planparserv2/Plan.g4 index fe40748642..f969e9893d 100644 --- a/internal/parser/planparserv2/Plan.g4 +++ b/internal/parser/planparserv2/Plan.g4 @@ -25,6 +25,13 @@ expr: | (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 | ArrayLength'('(Identifier | JSONIdentifier)')' # ArrayLength | Identifier '(' ( expr (',' expr )* ','? )? ')' # Call | expr op1 = (LT | LE) (Identifier | JSONIdentifier) op2 = (LT | LE) expr # Range @@ -96,6 +103,14 @@ ArrayContainsAll: 'array_contains_all' | 'ARRAY_CONTAINS_ALL'; ArrayContainsAny: 'array_contains_any' | 'ARRAY_CONTAINS_ANY'; ArrayLength: 'array_length' | 'ARRAY_LENGTH'; +STEuqals:'st_equals' | 'ST_EQUALS'; +STTouches:'st_touches' | 'ST_TOUCHES'; +STOverlaps: 'st_overlaps' | 'ST_OVERLAPS'; +STCrosses: 'st_crosses' | 'ST_CROSSES'; +STContains: 'st_contains' | 'ST_CONTAINS'; +STIntersects : 'st_intersects' | 'ST_INTERSECTS'; +STWithin :'st_within' | 'ST_WITHIN'; + BooleanConstant: 'true' | 'True' | 'TRUE' | 'false' | 'False' | 'FALSE'; IntegerConstant: diff --git a/internal/parser/planparserv2/generated/Plan.interp b/internal/parser/planparserv2/generated/Plan.interp index 71914be6c8..3458c103cd 100644 --- a/internal/parser/planparserv2/generated/Plan.interp +++ b/internal/parser/planparserv2/generated/Plan.interp @@ -47,6 +47,13 @@ null null null null +null +null +null +null +null +null +null '$meta' null null @@ -98,6 +105,13 @@ ArrayContains ArrayContainsAll ArrayContainsAny ArrayLength +STEuqals +STTouches +STOverlaps +STCrosses +STContains +STIntersects +STWithin BooleanConstant IntegerConstant FloatingConstant @@ -113,4 +127,4 @@ expr atn: -[4, 1, 52, 156, 2, 0, 7, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 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, 21, 8, 0, 10, 0, 12, 0, 24, 9, 0, 1, 0, 3, 0, 27, 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, 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, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 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, 82, 8, 0, 10, 0, 12, 0, 85, 9, 0, 1, 0, 3, 0, 88, 8, 0, 3, 0, 90, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 97, 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, 113, 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, 151, 8, 0, 10, 0, 12, 0, 154, 9, 0, 1, 0, 0, 1, 0, 1, 0, 0, 13, 1, 0, 47, 48, 2, 0, 18, 19, 33, 34, 2, 0, 37, 37, 40, 40, 2, 0, 38, 38, 41, 41, 2, 0, 39, 39, 42, 42, 2, 0, 47, 47, 50, 50, 1, 0, 20, 22, 1, 0, 18, 19, 1, 0, 24, 25, 1, 0, 8, 9, 1, 0, 10, 11, 1, 0, 8, 11, 1, 0, 12, 13, 196, 0, 96, 1, 0, 0, 0, 2, 3, 6, 0, -1, 0, 3, 97, 5, 45, 0, 0, 4, 97, 5, 46, 0, 0, 5, 97, 5, 44, 0, 0, 6, 97, 5, 49, 0, 0, 7, 97, 7, 0, 0, 0, 8, 97, 5, 50, 0, 0, 9, 10, 5, 6, 0, 0, 10, 11, 5, 47, 0, 0, 11, 97, 5, 7, 0, 0, 12, 13, 5, 1, 0, 0, 13, 14, 3, 0, 0, 0, 14, 15, 5, 2, 0, 0, 15, 97, 1, 0, 0, 0, 16, 17, 5, 3, 0, 0, 17, 22, 3, 0, 0, 0, 18, 19, 5, 4, 0, 0, 19, 21, 3, 0, 0, 0, 20, 18, 1, 0, 0, 0, 21, 24, 1, 0, 0, 0, 22, 20, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 26, 1, 0, 0, 0, 24, 22, 1, 0, 0, 0, 25, 27, 5, 4, 0, 0, 26, 25, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 29, 5, 5, 0, 0, 29, 97, 1, 0, 0, 0, 30, 97, 5, 36, 0, 0, 31, 32, 5, 15, 0, 0, 32, 97, 3, 0, 0, 26, 33, 34, 5, 16, 0, 0, 34, 35, 5, 1, 0, 0, 35, 36, 5, 47, 0, 0, 36, 37, 5, 4, 0, 0, 37, 38, 5, 49, 0, 0, 38, 97, 5, 2, 0, 0, 39, 40, 5, 17, 0, 0, 40, 41, 5, 1, 0, 0, 41, 42, 5, 47, 0, 0, 42, 43, 5, 4, 0, 0, 43, 46, 5, 49, 0, 0, 44, 45, 5, 4, 0, 0, 45, 47, 3, 0, 0, 0, 46, 44, 1, 0, 0, 0, 46, 47, 1, 0, 0, 0, 47, 48, 1, 0, 0, 0, 48, 97, 5, 2, 0, 0, 49, 50, 7, 1, 0, 0, 50, 97, 3, 0, 0, 21, 51, 52, 7, 2, 0, 0, 52, 53, 5, 1, 0, 0, 53, 54, 3, 0, 0, 0, 54, 55, 5, 4, 0, 0, 55, 56, 3, 0, 0, 0, 56, 57, 5, 2, 0, 0, 57, 97, 1, 0, 0, 0, 58, 59, 7, 3, 0, 0, 59, 60, 5, 1, 0, 0, 60, 61, 3, 0, 0, 0, 61, 62, 5, 4, 0, 0, 62, 63, 3, 0, 0, 0, 63, 64, 5, 2, 0, 0, 64, 97, 1, 0, 0, 0, 65, 66, 7, 4, 0, 0, 66, 67, 5, 1, 0, 0, 67, 68, 3, 0, 0, 0, 68, 69, 5, 4, 0, 0, 69, 70, 3, 0, 0, 0, 70, 71, 5, 2, 0, 0, 71, 97, 1, 0, 0, 0, 72, 73, 5, 43, 0, 0, 73, 74, 5, 1, 0, 0, 74, 75, 7, 5, 0, 0, 75, 97, 5, 2, 0, 0, 76, 77, 5, 47, 0, 0, 77, 89, 5, 1, 0, 0, 78, 83, 3, 0, 0, 0, 79, 80, 5, 4, 0, 0, 80, 82, 3, 0, 0, 0, 81, 79, 1, 0, 0, 0, 82, 85, 1, 0, 0, 0, 83, 81, 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 87, 1, 0, 0, 0, 85, 83, 1, 0, 0, 0, 86, 88, 5, 4, 0, 0, 87, 86, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 90, 1, 0, 0, 0, 89, 78, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 91, 1, 0, 0, 0, 91, 97, 5, 2, 0, 0, 92, 93, 7, 5, 0, 0, 93, 97, 5, 31, 0, 0, 94, 95, 7, 5, 0, 0, 95, 97, 5, 32, 0, 0, 96, 2, 1, 0, 0, 0, 96, 4, 1, 0, 0, 0, 96, 5, 1, 0, 0, 0, 96, 6, 1, 0, 0, 0, 96, 7, 1, 0, 0, 0, 96, 8, 1, 0, 0, 0, 96, 9, 1, 0, 0, 0, 96, 12, 1, 0, 0, 0, 96, 16, 1, 0, 0, 0, 96, 30, 1, 0, 0, 0, 96, 31, 1, 0, 0, 0, 96, 33, 1, 0, 0, 0, 96, 39, 1, 0, 0, 0, 96, 49, 1, 0, 0, 0, 96, 51, 1, 0, 0, 0, 96, 58, 1, 0, 0, 0, 96, 65, 1, 0, 0, 0, 96, 72, 1, 0, 0, 0, 96, 76, 1, 0, 0, 0, 96, 92, 1, 0, 0, 0, 96, 94, 1, 0, 0, 0, 97, 152, 1, 0, 0, 0, 98, 99, 10, 22, 0, 0, 99, 100, 5, 23, 0, 0, 100, 151, 3, 0, 0, 23, 101, 102, 10, 20, 0, 0, 102, 103, 7, 6, 0, 0, 103, 151, 3, 0, 0, 21, 104, 105, 10, 19, 0, 0, 105, 106, 7, 7, 0, 0, 106, 151, 3, 0, 0, 20, 107, 108, 10, 18, 0, 0, 108, 109, 7, 8, 0, 0, 109, 151, 3, 0, 0, 19, 110, 112, 10, 17, 0, 0, 111, 113, 5, 34, 0, 0, 112, 111, 1, 0, 0, 0, 112, 113, 1, 0, 0, 0, 113, 114, 1, 0, 0, 0, 114, 115, 5, 35, 0, 0, 115, 151, 3, 0, 0, 18, 116, 117, 10, 11, 0, 0, 117, 118, 7, 9, 0, 0, 118, 119, 7, 5, 0, 0, 119, 120, 7, 9, 0, 0, 120, 151, 3, 0, 0, 12, 121, 122, 10, 10, 0, 0, 122, 123, 7, 10, 0, 0, 123, 124, 7, 5, 0, 0, 124, 125, 7, 10, 0, 0, 125, 151, 3, 0, 0, 11, 126, 127, 10, 9, 0, 0, 127, 128, 7, 11, 0, 0, 128, 151, 3, 0, 0, 10, 129, 130, 10, 8, 0, 0, 130, 131, 7, 12, 0, 0, 131, 151, 3, 0, 0, 9, 132, 133, 10, 7, 0, 0, 133, 134, 5, 26, 0, 0, 134, 151, 3, 0, 0, 8, 135, 136, 10, 6, 0, 0, 136, 137, 5, 28, 0, 0, 137, 151, 3, 0, 0, 7, 138, 139, 10, 5, 0, 0, 139, 140, 5, 27, 0, 0, 140, 151, 3, 0, 0, 6, 141, 142, 10, 4, 0, 0, 142, 143, 5, 29, 0, 0, 143, 151, 3, 0, 0, 5, 144, 145, 10, 3, 0, 0, 145, 146, 5, 30, 0, 0, 146, 151, 3, 0, 0, 4, 147, 148, 10, 25, 0, 0, 148, 149, 5, 14, 0, 0, 149, 151, 5, 49, 0, 0, 150, 98, 1, 0, 0, 0, 150, 101, 1, 0, 0, 0, 150, 104, 1, 0, 0, 0, 150, 107, 1, 0, 0, 0, 150, 110, 1, 0, 0, 0, 150, 116, 1, 0, 0, 0, 150, 121, 1, 0, 0, 0, 150, 126, 1, 0, 0, 0, 150, 129, 1, 0, 0, 0, 150, 132, 1, 0, 0, 0, 150, 135, 1, 0, 0, 0, 150, 138, 1, 0, 0, 0, 150, 141, 1, 0, 0, 0, 150, 144, 1, 0, 0, 0, 150, 147, 1, 0, 0, 0, 151, 154, 1, 0, 0, 0, 152, 150, 1, 0, 0, 0, 152, 153, 1, 0, 0, 0, 153, 1, 1, 0, 0, 0, 154, 152, 1, 0, 0, 0, 10, 22, 26, 46, 83, 87, 89, 96, 112, 150, 152] \ No newline at end of file +[4, 1, 59, 198, 2, 0, 7, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 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, 21, 8, 0, 10, 0, 12, 0, 24, 9, 0, 1, 0, 3, 0, 27, 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, 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, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 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, 124, 8, 0, 10, 0, 12, 0, 127, 9, 0, 1, 0, 3, 0, 130, 8, 0, 3, 0, 132, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 139, 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, 155, 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, 193, 8, 0, 10, 0, 12, 0, 196, 9, 0, 1, 0, 0, 1, 0, 1, 0, 0, 13, 1, 0, 54, 55, 2, 0, 18, 19, 33, 34, 2, 0, 37, 37, 40, 40, 2, 0, 38, 38, 41, 41, 2, 0, 39, 39, 42, 42, 2, 0, 54, 54, 57, 57, 1, 0, 20, 22, 1, 0, 18, 19, 1, 0, 24, 25, 1, 0, 8, 9, 1, 0, 10, 11, 1, 0, 8, 11, 1, 0, 12, 13, 245, 0, 138, 1, 0, 0, 0, 2, 3, 6, 0, -1, 0, 3, 139, 5, 52, 0, 0, 4, 139, 5, 53, 0, 0, 5, 139, 5, 51, 0, 0, 6, 139, 5, 56, 0, 0, 7, 139, 7, 0, 0, 0, 8, 139, 5, 57, 0, 0, 9, 10, 5, 6, 0, 0, 10, 11, 5, 54, 0, 0, 11, 139, 5, 7, 0, 0, 12, 13, 5, 1, 0, 0, 13, 14, 3, 0, 0, 0, 14, 15, 5, 2, 0, 0, 15, 139, 1, 0, 0, 0, 16, 17, 5, 3, 0, 0, 17, 22, 3, 0, 0, 0, 18, 19, 5, 4, 0, 0, 19, 21, 3, 0, 0, 0, 20, 18, 1, 0, 0, 0, 21, 24, 1, 0, 0, 0, 22, 20, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 26, 1, 0, 0, 0, 24, 22, 1, 0, 0, 0, 25, 27, 5, 4, 0, 0, 26, 25, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 29, 5, 5, 0, 0, 29, 139, 1, 0, 0, 0, 30, 139, 5, 36, 0, 0, 31, 32, 5, 15, 0, 0, 32, 139, 3, 0, 0, 33, 33, 34, 5, 16, 0, 0, 34, 35, 5, 1, 0, 0, 35, 36, 5, 54, 0, 0, 36, 37, 5, 4, 0, 0, 37, 38, 5, 56, 0, 0, 38, 139, 5, 2, 0, 0, 39, 40, 5, 17, 0, 0, 40, 41, 5, 1, 0, 0, 41, 42, 5, 54, 0, 0, 42, 43, 5, 4, 0, 0, 43, 46, 5, 56, 0, 0, 44, 45, 5, 4, 0, 0, 45, 47, 3, 0, 0, 0, 46, 44, 1, 0, 0, 0, 46, 47, 1, 0, 0, 0, 47, 48, 1, 0, 0, 0, 48, 139, 5, 2, 0, 0, 49, 50, 7, 1, 0, 0, 50, 139, 3, 0, 0, 28, 51, 52, 7, 2, 0, 0, 52, 53, 5, 1, 0, 0, 53, 54, 3, 0, 0, 0, 54, 55, 5, 4, 0, 0, 55, 56, 3, 0, 0, 0, 56, 57, 5, 2, 0, 0, 57, 139, 1, 0, 0, 0, 58, 59, 7, 3, 0, 0, 59, 60, 5, 1, 0, 0, 60, 61, 3, 0, 0, 0, 61, 62, 5, 4, 0, 0, 62, 63, 3, 0, 0, 0, 63, 64, 5, 2, 0, 0, 64, 139, 1, 0, 0, 0, 65, 66, 7, 4, 0, 0, 66, 67, 5, 1, 0, 0, 67, 68, 3, 0, 0, 0, 68, 69, 5, 4, 0, 0, 69, 70, 3, 0, 0, 0, 70, 71, 5, 2, 0, 0, 71, 139, 1, 0, 0, 0, 72, 73, 5, 44, 0, 0, 73, 74, 5, 1, 0, 0, 74, 75, 5, 54, 0, 0, 75, 76, 5, 4, 0, 0, 76, 77, 5, 56, 0, 0, 77, 139, 5, 2, 0, 0, 78, 79, 5, 45, 0, 0, 79, 80, 5, 1, 0, 0, 80, 81, 5, 54, 0, 0, 81, 82, 5, 4, 0, 0, 82, 83, 5, 56, 0, 0, 83, 139, 5, 2, 0, 0, 84, 85, 5, 46, 0, 0, 85, 86, 5, 1, 0, 0, 86, 87, 5, 54, 0, 0, 87, 88, 5, 4, 0, 0, 88, 89, 5, 56, 0, 0, 89, 139, 5, 2, 0, 0, 90, 91, 5, 47, 0, 0, 91, 92, 5, 1, 0, 0, 92, 93, 5, 54, 0, 0, 93, 94, 5, 4, 0, 0, 94, 95, 5, 56, 0, 0, 95, 139, 5, 2, 0, 0, 96, 97, 5, 48, 0, 0, 97, 98, 5, 1, 0, 0, 98, 99, 5, 54, 0, 0, 99, 100, 5, 4, 0, 0, 100, 101, 5, 56, 0, 0, 101, 139, 5, 2, 0, 0, 102, 103, 5, 49, 0, 0, 103, 104, 5, 1, 0, 0, 104, 105, 5, 54, 0, 0, 105, 106, 5, 4, 0, 0, 106, 107, 5, 56, 0, 0, 107, 139, 5, 2, 0, 0, 108, 109, 5, 50, 0, 0, 109, 110, 5, 1, 0, 0, 110, 111, 5, 54, 0, 0, 111, 112, 5, 4, 0, 0, 112, 113, 5, 56, 0, 0, 113, 139, 5, 2, 0, 0, 114, 115, 5, 43, 0, 0, 115, 116, 5, 1, 0, 0, 116, 117, 7, 5, 0, 0, 117, 139, 5, 2, 0, 0, 118, 119, 5, 54, 0, 0, 119, 131, 5, 1, 0, 0, 120, 125, 3, 0, 0, 0, 121, 122, 5, 4, 0, 0, 122, 124, 3, 0, 0, 0, 123, 121, 1, 0, 0, 0, 124, 127, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 125, 126, 1, 0, 0, 0, 126, 129, 1, 0, 0, 0, 127, 125, 1, 0, 0, 0, 128, 130, 5, 4, 0, 0, 129, 128, 1, 0, 0, 0, 129, 130, 1, 0, 0, 0, 130, 132, 1, 0, 0, 0, 131, 120, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 139, 5, 2, 0, 0, 134, 135, 7, 5, 0, 0, 135, 139, 5, 31, 0, 0, 136, 137, 7, 5, 0, 0, 137, 139, 5, 32, 0, 0, 138, 2, 1, 0, 0, 0, 138, 4, 1, 0, 0, 0, 138, 5, 1, 0, 0, 0, 138, 6, 1, 0, 0, 0, 138, 7, 1, 0, 0, 0, 138, 8, 1, 0, 0, 0, 138, 9, 1, 0, 0, 0, 138, 12, 1, 0, 0, 0, 138, 16, 1, 0, 0, 0, 138, 30, 1, 0, 0, 0, 138, 31, 1, 0, 0, 0, 138, 33, 1, 0, 0, 0, 138, 39, 1, 0, 0, 0, 138, 49, 1, 0, 0, 0, 138, 51, 1, 0, 0, 0, 138, 58, 1, 0, 0, 0, 138, 65, 1, 0, 0, 0, 138, 72, 1, 0, 0, 0, 138, 78, 1, 0, 0, 0, 138, 84, 1, 0, 0, 0, 138, 90, 1, 0, 0, 0, 138, 96, 1, 0, 0, 0, 138, 102, 1, 0, 0, 0, 138, 108, 1, 0, 0, 0, 138, 114, 1, 0, 0, 0, 138, 118, 1, 0, 0, 0, 138, 134, 1, 0, 0, 0, 138, 136, 1, 0, 0, 0, 139, 194, 1, 0, 0, 0, 140, 141, 10, 29, 0, 0, 141, 142, 5, 23, 0, 0, 142, 193, 3, 0, 0, 30, 143, 144, 10, 27, 0, 0, 144, 145, 7, 6, 0, 0, 145, 193, 3, 0, 0, 28, 146, 147, 10, 26, 0, 0, 147, 148, 7, 7, 0, 0, 148, 193, 3, 0, 0, 27, 149, 150, 10, 25, 0, 0, 150, 151, 7, 8, 0, 0, 151, 193, 3, 0, 0, 26, 152, 154, 10, 24, 0, 0, 153, 155, 5, 34, 0, 0, 154, 153, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, 155, 156, 1, 0, 0, 0, 156, 157, 5, 35, 0, 0, 157, 193, 3, 0, 0, 25, 158, 159, 10, 11, 0, 0, 159, 160, 7, 9, 0, 0, 160, 161, 7, 5, 0, 0, 161, 162, 7, 9, 0, 0, 162, 193, 3, 0, 0, 12, 163, 164, 10, 10, 0, 0, 164, 165, 7, 10, 0, 0, 165, 166, 7, 5, 0, 0, 166, 167, 7, 10, 0, 0, 167, 193, 3, 0, 0, 11, 168, 169, 10, 9, 0, 0, 169, 170, 7, 11, 0, 0, 170, 193, 3, 0, 0, 10, 171, 172, 10, 8, 0, 0, 172, 173, 7, 12, 0, 0, 173, 193, 3, 0, 0, 9, 174, 175, 10, 7, 0, 0, 175, 176, 5, 26, 0, 0, 176, 193, 3, 0, 0, 8, 177, 178, 10, 6, 0, 0, 178, 179, 5, 28, 0, 0, 179, 193, 3, 0, 0, 7, 180, 181, 10, 5, 0, 0, 181, 182, 5, 27, 0, 0, 182, 193, 3, 0, 0, 6, 183, 184, 10, 4, 0, 0, 184, 185, 5, 29, 0, 0, 185, 193, 3, 0, 0, 5, 186, 187, 10, 3, 0, 0, 187, 188, 5, 30, 0, 0, 188, 193, 3, 0, 0, 4, 189, 190, 10, 32, 0, 0, 190, 191, 5, 14, 0, 0, 191, 193, 5, 56, 0, 0, 192, 140, 1, 0, 0, 0, 192, 143, 1, 0, 0, 0, 192, 146, 1, 0, 0, 0, 192, 149, 1, 0, 0, 0, 192, 152, 1, 0, 0, 0, 192, 158, 1, 0, 0, 0, 192, 163, 1, 0, 0, 0, 192, 168, 1, 0, 0, 0, 192, 171, 1, 0, 0, 0, 192, 174, 1, 0, 0, 0, 192, 177, 1, 0, 0, 0, 192, 180, 1, 0, 0, 0, 192, 183, 1, 0, 0, 0, 192, 186, 1, 0, 0, 0, 192, 189, 1, 0, 0, 0, 193, 196, 1, 0, 0, 0, 194, 192, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 1, 1, 0, 0, 0, 196, 194, 1, 0, 0, 0, 10, 22, 26, 46, 125, 129, 131, 138, 154, 192, 194] \ No newline at end of file diff --git a/internal/parser/planparserv2/generated/Plan.tokens b/internal/parser/planparserv2/generated/Plan.tokens index 820be82be1..fbefcddabe 100644 --- a/internal/parser/planparserv2/generated/Plan.tokens +++ b/internal/parser/planparserv2/generated/Plan.tokens @@ -41,15 +41,22 @@ ArrayContains=40 ArrayContainsAll=41 ArrayContainsAny=42 ArrayLength=43 -BooleanConstant=44 -IntegerConstant=45 -FloatingConstant=46 -Identifier=47 -Meta=48 -StringLiteral=49 -JSONIdentifier=50 -Whitespace=51 -Newline=52 +STEuqals=44 +STTouches=45 +STOverlaps=46 +STCrosses=47 +STContains=48 +STIntersects=49 +STWithin=50 +BooleanConstant=51 +IntegerConstant=52 +FloatingConstant=53 +Identifier=54 +Meta=55 +StringLiteral=56 +JSONIdentifier=57 +Whitespace=58 +Newline=59 '('=1 ')'=2 '['=3 @@ -75,4 +82,4 @@ Newline=52 '|'=27 '^'=28 '~'=33 -'$meta'=48 +'$meta'=55 diff --git a/internal/parser/planparserv2/generated/PlanLexer.interp b/internal/parser/planparserv2/generated/PlanLexer.interp index e8b2eff451..d07432aeb1 100644 --- a/internal/parser/planparserv2/generated/PlanLexer.interp +++ b/internal/parser/planparserv2/generated/PlanLexer.interp @@ -47,6 +47,13 @@ null null null null +null +null +null +null +null +null +null '$meta' null null @@ -98,6 +105,13 @@ ArrayContains ArrayContainsAll ArrayContainsAny ArrayLength +STEuqals +STTouches +STOverlaps +STCrosses +STContains +STIntersects +STWithin BooleanConstant IntegerConstant FloatingConstant @@ -152,6 +166,13 @@ ArrayContains ArrayContainsAll ArrayContainsAny ArrayLength +STEuqals +STTouches +STOverlaps +STCrosses +STContains +STIntersects +STWithin BooleanConstant IntegerConstant FloatingConstant @@ -195,4 +216,4 @@ mode names: DEFAULT_MODE atn: -[4, 0, 52, 862, 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, 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, 194, 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, 208, 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, 230, 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, 256, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 3, 28, 291, 8, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 299, 8, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 3, 30, 315, 8, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 339, 8, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 350, 8, 33, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 356, 8, 34, 1, 35, 1, 35, 1, 35, 5, 35, 361, 8, 35, 10, 35, 12, 35, 364, 9, 35, 1, 35, 1, 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, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 394, 8, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 3, 37, 430, 8, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 466, 8, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 496, 8, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 3, 40, 534, 8, 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, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 572, 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, 3, 42, 598, 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, 3, 43, 627, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 633, 8, 44, 1, 45, 1, 45, 3, 45, 637, 8, 45, 1, 46, 1, 46, 1, 46, 5, 46, 642, 8, 46, 10, 46, 12, 46, 645, 9, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 3, 48, 654, 8, 48, 1, 48, 1, 48, 3, 48, 658, 8, 48, 1, 48, 1, 48, 1, 48, 3, 48, 663, 8, 48, 1, 48, 3, 48, 666, 8, 48, 1, 49, 1, 49, 3, 49, 670, 8, 49, 1, 49, 1, 49, 1, 49, 3, 49, 675, 8, 49, 1, 49, 1, 49, 4, 49, 679, 8, 49, 11, 49, 12, 49, 680, 1, 50, 1, 50, 1, 50, 3, 50, 686, 8, 50, 1, 51, 4, 51, 689, 8, 51, 11, 51, 12, 51, 690, 1, 52, 4, 52, 694, 8, 52, 11, 52, 12, 52, 695, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 705, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 714, 8, 54, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 4, 57, 723, 8, 57, 11, 57, 12, 57, 724, 1, 58, 1, 58, 5, 58, 729, 8, 58, 10, 58, 12, 58, 732, 9, 58, 1, 58, 3, 58, 735, 8, 58, 1, 59, 1, 59, 5, 59, 739, 8, 59, 10, 59, 12, 59, 742, 9, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 769, 8, 65, 1, 66, 1, 66, 3, 66, 773, 8, 66, 1, 66, 1, 66, 1, 66, 3, 66, 778, 8, 66, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 784, 8, 67, 1, 67, 1, 67, 1, 68, 3, 68, 789, 8, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 796, 8, 68, 1, 69, 1, 69, 3, 69, 800, 8, 69, 1, 69, 1, 69, 1, 70, 4, 70, 805, 8, 70, 11, 70, 12, 70, 806, 1, 71, 3, 71, 810, 8, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 3, 71, 817, 8, 71, 1, 72, 4, 72, 820, 8, 72, 11, 72, 12, 72, 821, 1, 73, 1, 73, 3, 73, 826, 8, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 3, 74, 835, 8, 74, 1, 74, 3, 74, 838, 8, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 3, 74, 845, 8, 74, 1, 75, 4, 75, 848, 8, 75, 11, 75, 12, 75, 849, 1, 75, 1, 75, 1, 76, 1, 76, 3, 76, 856, 8, 76, 1, 76, 3, 76, 859, 8, 76, 1, 76, 1, 76, 0, 0, 77, 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, 0, 103, 0, 105, 0, 107, 0, 109, 0, 111, 0, 113, 0, 115, 0, 117, 0, 119, 0, 121, 0, 123, 0, 125, 0, 127, 0, 129, 0, 131, 0, 133, 0, 135, 0, 137, 0, 139, 0, 141, 0, 143, 0, 145, 0, 147, 0, 149, 0, 151, 51, 153, 52, 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, 909, 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, 151, 1, 0, 0, 0, 0, 153, 1, 0, 0, 0, 1, 155, 1, 0, 0, 0, 3, 157, 1, 0, 0, 0, 5, 159, 1, 0, 0, 0, 7, 161, 1, 0, 0, 0, 9, 163, 1, 0, 0, 0, 11, 165, 1, 0, 0, 0, 13, 167, 1, 0, 0, 0, 15, 169, 1, 0, 0, 0, 17, 171, 1, 0, 0, 0, 19, 174, 1, 0, 0, 0, 21, 176, 1, 0, 0, 0, 23, 179, 1, 0, 0, 0, 25, 182, 1, 0, 0, 0, 27, 193, 1, 0, 0, 0, 29, 207, 1, 0, 0, 0, 31, 229, 1, 0, 0, 0, 33, 255, 1, 0, 0, 0, 35, 257, 1, 0, 0, 0, 37, 259, 1, 0, 0, 0, 39, 261, 1, 0, 0, 0, 41, 263, 1, 0, 0, 0, 43, 265, 1, 0, 0, 0, 45, 267, 1, 0, 0, 0, 47, 270, 1, 0, 0, 0, 49, 273, 1, 0, 0, 0, 51, 276, 1, 0, 0, 0, 53, 278, 1, 0, 0, 0, 55, 280, 1, 0, 0, 0, 57, 290, 1, 0, 0, 0, 59, 298, 1, 0, 0, 0, 61, 314, 1, 0, 0, 0, 63, 338, 1, 0, 0, 0, 65, 340, 1, 0, 0, 0, 67, 349, 1, 0, 0, 0, 69, 355, 1, 0, 0, 0, 71, 357, 1, 0, 0, 0, 73, 393, 1, 0, 0, 0, 75, 429, 1, 0, 0, 0, 77, 465, 1, 0, 0, 0, 79, 495, 1, 0, 0, 0, 81, 533, 1, 0, 0, 0, 83, 571, 1, 0, 0, 0, 85, 597, 1, 0, 0, 0, 87, 626, 1, 0, 0, 0, 89, 632, 1, 0, 0, 0, 91, 636, 1, 0, 0, 0, 93, 638, 1, 0, 0, 0, 95, 646, 1, 0, 0, 0, 97, 653, 1, 0, 0, 0, 99, 669, 1, 0, 0, 0, 101, 685, 1, 0, 0, 0, 103, 688, 1, 0, 0, 0, 105, 693, 1, 0, 0, 0, 107, 704, 1, 0, 0, 0, 109, 713, 1, 0, 0, 0, 111, 715, 1, 0, 0, 0, 113, 717, 1, 0, 0, 0, 115, 719, 1, 0, 0, 0, 117, 734, 1, 0, 0, 0, 119, 736, 1, 0, 0, 0, 121, 743, 1, 0, 0, 0, 123, 747, 1, 0, 0, 0, 125, 749, 1, 0, 0, 0, 127, 751, 1, 0, 0, 0, 129, 753, 1, 0, 0, 0, 131, 768, 1, 0, 0, 0, 133, 777, 1, 0, 0, 0, 135, 779, 1, 0, 0, 0, 137, 795, 1, 0, 0, 0, 139, 797, 1, 0, 0, 0, 141, 804, 1, 0, 0, 0, 143, 816, 1, 0, 0, 0, 145, 819, 1, 0, 0, 0, 147, 823, 1, 0, 0, 0, 149, 844, 1, 0, 0, 0, 151, 847, 1, 0, 0, 0, 153, 858, 1, 0, 0, 0, 155, 156, 5, 40, 0, 0, 156, 2, 1, 0, 0, 0, 157, 158, 5, 41, 0, 0, 158, 4, 1, 0, 0, 0, 159, 160, 5, 91, 0, 0, 160, 6, 1, 0, 0, 0, 161, 162, 5, 44, 0, 0, 162, 8, 1, 0, 0, 0, 163, 164, 5, 93, 0, 0, 164, 10, 1, 0, 0, 0, 165, 166, 5, 123, 0, 0, 166, 12, 1, 0, 0, 0, 167, 168, 5, 125, 0, 0, 168, 14, 1, 0, 0, 0, 169, 170, 5, 60, 0, 0, 170, 16, 1, 0, 0, 0, 171, 172, 5, 60, 0, 0, 172, 173, 5, 61, 0, 0, 173, 18, 1, 0, 0, 0, 174, 175, 5, 62, 0, 0, 175, 20, 1, 0, 0, 0, 176, 177, 5, 62, 0, 0, 177, 178, 5, 61, 0, 0, 178, 22, 1, 0, 0, 0, 179, 180, 5, 61, 0, 0, 180, 181, 5, 61, 0, 0, 181, 24, 1, 0, 0, 0, 182, 183, 5, 33, 0, 0, 183, 184, 5, 61, 0, 0, 184, 26, 1, 0, 0, 0, 185, 186, 5, 108, 0, 0, 186, 187, 5, 105, 0, 0, 187, 188, 5, 107, 0, 0, 188, 194, 5, 101, 0, 0, 189, 190, 5, 76, 0, 0, 190, 191, 5, 73, 0, 0, 191, 192, 5, 75, 0, 0, 192, 194, 5, 69, 0, 0, 193, 185, 1, 0, 0, 0, 193, 189, 1, 0, 0, 0, 194, 28, 1, 0, 0, 0, 195, 196, 5, 101, 0, 0, 196, 197, 5, 120, 0, 0, 197, 198, 5, 105, 0, 0, 198, 199, 5, 115, 0, 0, 199, 200, 5, 116, 0, 0, 200, 208, 5, 115, 0, 0, 201, 202, 5, 69, 0, 0, 202, 203, 5, 88, 0, 0, 203, 204, 5, 73, 0, 0, 204, 205, 5, 83, 0, 0, 205, 206, 5, 84, 0, 0, 206, 208, 5, 83, 0, 0, 207, 195, 1, 0, 0, 0, 207, 201, 1, 0, 0, 0, 208, 30, 1, 0, 0, 0, 209, 210, 5, 116, 0, 0, 210, 211, 5, 101, 0, 0, 211, 212, 5, 120, 0, 0, 212, 213, 5, 116, 0, 0, 213, 214, 5, 95, 0, 0, 214, 215, 5, 109, 0, 0, 215, 216, 5, 97, 0, 0, 216, 217, 5, 116, 0, 0, 217, 218, 5, 99, 0, 0, 218, 230, 5, 104, 0, 0, 219, 220, 5, 84, 0, 0, 220, 221, 5, 69, 0, 0, 221, 222, 5, 88, 0, 0, 222, 223, 5, 84, 0, 0, 223, 224, 5, 95, 0, 0, 224, 225, 5, 77, 0, 0, 225, 226, 5, 65, 0, 0, 226, 227, 5, 84, 0, 0, 227, 228, 5, 67, 0, 0, 228, 230, 5, 72, 0, 0, 229, 209, 1, 0, 0, 0, 229, 219, 1, 0, 0, 0, 230, 32, 1, 0, 0, 0, 231, 232, 5, 112, 0, 0, 232, 233, 5, 104, 0, 0, 233, 234, 5, 114, 0, 0, 234, 235, 5, 97, 0, 0, 235, 236, 5, 115, 0, 0, 236, 237, 5, 101, 0, 0, 237, 238, 5, 95, 0, 0, 238, 239, 5, 109, 0, 0, 239, 240, 5, 97, 0, 0, 240, 241, 5, 116, 0, 0, 241, 242, 5, 99, 0, 0, 242, 256, 5, 104, 0, 0, 243, 244, 5, 80, 0, 0, 244, 245, 5, 72, 0, 0, 245, 246, 5, 82, 0, 0, 246, 247, 5, 65, 0, 0, 247, 248, 5, 83, 0, 0, 248, 249, 5, 69, 0, 0, 249, 250, 5, 95, 0, 0, 250, 251, 5, 77, 0, 0, 251, 252, 5, 65, 0, 0, 252, 253, 5, 84, 0, 0, 253, 254, 5, 67, 0, 0, 254, 256, 5, 72, 0, 0, 255, 231, 1, 0, 0, 0, 255, 243, 1, 0, 0, 0, 256, 34, 1, 0, 0, 0, 257, 258, 5, 43, 0, 0, 258, 36, 1, 0, 0, 0, 259, 260, 5, 45, 0, 0, 260, 38, 1, 0, 0, 0, 261, 262, 5, 42, 0, 0, 262, 40, 1, 0, 0, 0, 263, 264, 5, 47, 0, 0, 264, 42, 1, 0, 0, 0, 265, 266, 5, 37, 0, 0, 266, 44, 1, 0, 0, 0, 267, 268, 5, 42, 0, 0, 268, 269, 5, 42, 0, 0, 269, 46, 1, 0, 0, 0, 270, 271, 5, 60, 0, 0, 271, 272, 5, 60, 0, 0, 272, 48, 1, 0, 0, 0, 273, 274, 5, 62, 0, 0, 274, 275, 5, 62, 0, 0, 275, 50, 1, 0, 0, 0, 276, 277, 5, 38, 0, 0, 277, 52, 1, 0, 0, 0, 278, 279, 5, 124, 0, 0, 279, 54, 1, 0, 0, 0, 280, 281, 5, 94, 0, 0, 281, 56, 1, 0, 0, 0, 282, 283, 5, 38, 0, 0, 283, 291, 5, 38, 0, 0, 284, 285, 5, 97, 0, 0, 285, 286, 5, 110, 0, 0, 286, 291, 5, 100, 0, 0, 287, 288, 5, 65, 0, 0, 288, 289, 5, 78, 0, 0, 289, 291, 5, 68, 0, 0, 290, 282, 1, 0, 0, 0, 290, 284, 1, 0, 0, 0, 290, 287, 1, 0, 0, 0, 291, 58, 1, 0, 0, 0, 292, 293, 5, 124, 0, 0, 293, 299, 5, 124, 0, 0, 294, 295, 5, 111, 0, 0, 295, 299, 5, 114, 0, 0, 296, 297, 5, 79, 0, 0, 297, 299, 5, 82, 0, 0, 298, 292, 1, 0, 0, 0, 298, 294, 1, 0, 0, 0, 298, 296, 1, 0, 0, 0, 299, 60, 1, 0, 0, 0, 300, 301, 5, 105, 0, 0, 301, 302, 5, 115, 0, 0, 302, 303, 5, 32, 0, 0, 303, 304, 5, 110, 0, 0, 304, 305, 5, 117, 0, 0, 305, 306, 5, 108, 0, 0, 306, 315, 5, 108, 0, 0, 307, 308, 5, 73, 0, 0, 308, 309, 5, 83, 0, 0, 309, 310, 5, 32, 0, 0, 310, 311, 5, 78, 0, 0, 311, 312, 5, 85, 0, 0, 312, 313, 5, 76, 0, 0, 313, 315, 5, 76, 0, 0, 314, 300, 1, 0, 0, 0, 314, 307, 1, 0, 0, 0, 315, 62, 1, 0, 0, 0, 316, 317, 5, 105, 0, 0, 317, 318, 5, 115, 0, 0, 318, 319, 5, 32, 0, 0, 319, 320, 5, 110, 0, 0, 320, 321, 5, 111, 0, 0, 321, 322, 5, 116, 0, 0, 322, 323, 5, 32, 0, 0, 323, 324, 5, 110, 0, 0, 324, 325, 5, 117, 0, 0, 325, 326, 5, 108, 0, 0, 326, 339, 5, 108, 0, 0, 327, 328, 5, 73, 0, 0, 328, 329, 5, 83, 0, 0, 329, 330, 5, 32, 0, 0, 330, 331, 5, 78, 0, 0, 331, 332, 5, 79, 0, 0, 332, 333, 5, 84, 0, 0, 333, 334, 5, 32, 0, 0, 334, 335, 5, 78, 0, 0, 335, 336, 5, 85, 0, 0, 336, 337, 5, 76, 0, 0, 337, 339, 5, 76, 0, 0, 338, 316, 1, 0, 0, 0, 338, 327, 1, 0, 0, 0, 339, 64, 1, 0, 0, 0, 340, 341, 5, 126, 0, 0, 341, 66, 1, 0, 0, 0, 342, 350, 5, 33, 0, 0, 343, 344, 5, 110, 0, 0, 344, 345, 5, 111, 0, 0, 345, 350, 5, 116, 0, 0, 346, 347, 5, 78, 0, 0, 347, 348, 5, 79, 0, 0, 348, 350, 5, 84, 0, 0, 349, 342, 1, 0, 0, 0, 349, 343, 1, 0, 0, 0, 349, 346, 1, 0, 0, 0, 350, 68, 1, 0, 0, 0, 351, 352, 5, 105, 0, 0, 352, 356, 5, 110, 0, 0, 353, 354, 5, 73, 0, 0, 354, 356, 5, 78, 0, 0, 355, 351, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 356, 70, 1, 0, 0, 0, 357, 362, 5, 91, 0, 0, 358, 361, 3, 151, 75, 0, 359, 361, 3, 153, 76, 0, 360, 358, 1, 0, 0, 0, 360, 359, 1, 0, 0, 0, 361, 364, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, 365, 1, 0, 0, 0, 364, 362, 1, 0, 0, 0, 365, 366, 5, 93, 0, 0, 366, 72, 1, 0, 0, 0, 367, 368, 5, 106, 0, 0, 368, 369, 5, 115, 0, 0, 369, 370, 5, 111, 0, 0, 370, 371, 5, 110, 0, 0, 371, 372, 5, 95, 0, 0, 372, 373, 5, 99, 0, 0, 373, 374, 5, 111, 0, 0, 374, 375, 5, 110, 0, 0, 375, 376, 5, 116, 0, 0, 376, 377, 5, 97, 0, 0, 377, 378, 5, 105, 0, 0, 378, 379, 5, 110, 0, 0, 379, 394, 5, 115, 0, 0, 380, 381, 5, 74, 0, 0, 381, 382, 5, 83, 0, 0, 382, 383, 5, 79, 0, 0, 383, 384, 5, 78, 0, 0, 384, 385, 5, 95, 0, 0, 385, 386, 5, 67, 0, 0, 386, 387, 5, 79, 0, 0, 387, 388, 5, 78, 0, 0, 388, 389, 5, 84, 0, 0, 389, 390, 5, 65, 0, 0, 390, 391, 5, 73, 0, 0, 391, 392, 5, 78, 0, 0, 392, 394, 5, 83, 0, 0, 393, 367, 1, 0, 0, 0, 393, 380, 1, 0, 0, 0, 394, 74, 1, 0, 0, 0, 395, 396, 5, 106, 0, 0, 396, 397, 5, 115, 0, 0, 397, 398, 5, 111, 0, 0, 398, 399, 5, 110, 0, 0, 399, 400, 5, 95, 0, 0, 400, 401, 5, 99, 0, 0, 401, 402, 5, 111, 0, 0, 402, 403, 5, 110, 0, 0, 403, 404, 5, 116, 0, 0, 404, 405, 5, 97, 0, 0, 405, 406, 5, 105, 0, 0, 406, 407, 5, 110, 0, 0, 407, 408, 5, 115, 0, 0, 408, 409, 5, 95, 0, 0, 409, 410, 5, 97, 0, 0, 410, 411, 5, 108, 0, 0, 411, 430, 5, 108, 0, 0, 412, 413, 5, 74, 0, 0, 413, 414, 5, 83, 0, 0, 414, 415, 5, 79, 0, 0, 415, 416, 5, 78, 0, 0, 416, 417, 5, 95, 0, 0, 417, 418, 5, 67, 0, 0, 418, 419, 5, 79, 0, 0, 419, 420, 5, 78, 0, 0, 420, 421, 5, 84, 0, 0, 421, 422, 5, 65, 0, 0, 422, 423, 5, 73, 0, 0, 423, 424, 5, 78, 0, 0, 424, 425, 5, 83, 0, 0, 425, 426, 5, 95, 0, 0, 426, 427, 5, 65, 0, 0, 427, 428, 5, 76, 0, 0, 428, 430, 5, 76, 0, 0, 429, 395, 1, 0, 0, 0, 429, 412, 1, 0, 0, 0, 430, 76, 1, 0, 0, 0, 431, 432, 5, 106, 0, 0, 432, 433, 5, 115, 0, 0, 433, 434, 5, 111, 0, 0, 434, 435, 5, 110, 0, 0, 435, 436, 5, 95, 0, 0, 436, 437, 5, 99, 0, 0, 437, 438, 5, 111, 0, 0, 438, 439, 5, 110, 0, 0, 439, 440, 5, 116, 0, 0, 440, 441, 5, 97, 0, 0, 441, 442, 5, 105, 0, 0, 442, 443, 5, 110, 0, 0, 443, 444, 5, 115, 0, 0, 444, 445, 5, 95, 0, 0, 445, 446, 5, 97, 0, 0, 446, 447, 5, 110, 0, 0, 447, 466, 5, 121, 0, 0, 448, 449, 5, 74, 0, 0, 449, 450, 5, 83, 0, 0, 450, 451, 5, 79, 0, 0, 451, 452, 5, 78, 0, 0, 452, 453, 5, 95, 0, 0, 453, 454, 5, 67, 0, 0, 454, 455, 5, 79, 0, 0, 455, 456, 5, 78, 0, 0, 456, 457, 5, 84, 0, 0, 457, 458, 5, 65, 0, 0, 458, 459, 5, 73, 0, 0, 459, 460, 5, 78, 0, 0, 460, 461, 5, 83, 0, 0, 461, 462, 5, 95, 0, 0, 462, 463, 5, 65, 0, 0, 463, 464, 5, 78, 0, 0, 464, 466, 5, 89, 0, 0, 465, 431, 1, 0, 0, 0, 465, 448, 1, 0, 0, 0, 466, 78, 1, 0, 0, 0, 467, 468, 5, 97, 0, 0, 468, 469, 5, 114, 0, 0, 469, 470, 5, 114, 0, 0, 470, 471, 5, 97, 0, 0, 471, 472, 5, 121, 0, 0, 472, 473, 5, 95, 0, 0, 473, 474, 5, 99, 0, 0, 474, 475, 5, 111, 0, 0, 475, 476, 5, 110, 0, 0, 476, 477, 5, 116, 0, 0, 477, 478, 5, 97, 0, 0, 478, 479, 5, 105, 0, 0, 479, 480, 5, 110, 0, 0, 480, 496, 5, 115, 0, 0, 481, 482, 5, 65, 0, 0, 482, 483, 5, 82, 0, 0, 483, 484, 5, 82, 0, 0, 484, 485, 5, 65, 0, 0, 485, 486, 5, 89, 0, 0, 486, 487, 5, 95, 0, 0, 487, 488, 5, 67, 0, 0, 488, 489, 5, 79, 0, 0, 489, 490, 5, 78, 0, 0, 490, 491, 5, 84, 0, 0, 491, 492, 5, 65, 0, 0, 492, 493, 5, 73, 0, 0, 493, 494, 5, 78, 0, 0, 494, 496, 5, 83, 0, 0, 495, 467, 1, 0, 0, 0, 495, 481, 1, 0, 0, 0, 496, 80, 1, 0, 0, 0, 497, 498, 5, 97, 0, 0, 498, 499, 5, 114, 0, 0, 499, 500, 5, 114, 0, 0, 500, 501, 5, 97, 0, 0, 501, 502, 5, 121, 0, 0, 502, 503, 5, 95, 0, 0, 503, 504, 5, 99, 0, 0, 504, 505, 5, 111, 0, 0, 505, 506, 5, 110, 0, 0, 506, 507, 5, 116, 0, 0, 507, 508, 5, 97, 0, 0, 508, 509, 5, 105, 0, 0, 509, 510, 5, 110, 0, 0, 510, 511, 5, 115, 0, 0, 511, 512, 5, 95, 0, 0, 512, 513, 5, 97, 0, 0, 513, 514, 5, 108, 0, 0, 514, 534, 5, 108, 0, 0, 515, 516, 5, 65, 0, 0, 516, 517, 5, 82, 0, 0, 517, 518, 5, 82, 0, 0, 518, 519, 5, 65, 0, 0, 519, 520, 5, 89, 0, 0, 520, 521, 5, 95, 0, 0, 521, 522, 5, 67, 0, 0, 522, 523, 5, 79, 0, 0, 523, 524, 5, 78, 0, 0, 524, 525, 5, 84, 0, 0, 525, 526, 5, 65, 0, 0, 526, 527, 5, 73, 0, 0, 527, 528, 5, 78, 0, 0, 528, 529, 5, 83, 0, 0, 529, 530, 5, 95, 0, 0, 530, 531, 5, 65, 0, 0, 531, 532, 5, 76, 0, 0, 532, 534, 5, 76, 0, 0, 533, 497, 1, 0, 0, 0, 533, 515, 1, 0, 0, 0, 534, 82, 1, 0, 0, 0, 535, 536, 5, 97, 0, 0, 536, 537, 5, 114, 0, 0, 537, 538, 5, 114, 0, 0, 538, 539, 5, 97, 0, 0, 539, 540, 5, 121, 0, 0, 540, 541, 5, 95, 0, 0, 541, 542, 5, 99, 0, 0, 542, 543, 5, 111, 0, 0, 543, 544, 5, 110, 0, 0, 544, 545, 5, 116, 0, 0, 545, 546, 5, 97, 0, 0, 546, 547, 5, 105, 0, 0, 547, 548, 5, 110, 0, 0, 548, 549, 5, 115, 0, 0, 549, 550, 5, 95, 0, 0, 550, 551, 5, 97, 0, 0, 551, 552, 5, 110, 0, 0, 552, 572, 5, 121, 0, 0, 553, 554, 5, 65, 0, 0, 554, 555, 5, 82, 0, 0, 555, 556, 5, 82, 0, 0, 556, 557, 5, 65, 0, 0, 557, 558, 5, 89, 0, 0, 558, 559, 5, 95, 0, 0, 559, 560, 5, 67, 0, 0, 560, 561, 5, 79, 0, 0, 561, 562, 5, 78, 0, 0, 562, 563, 5, 84, 0, 0, 563, 564, 5, 65, 0, 0, 564, 565, 5, 73, 0, 0, 565, 566, 5, 78, 0, 0, 566, 567, 5, 83, 0, 0, 567, 568, 5, 95, 0, 0, 568, 569, 5, 65, 0, 0, 569, 570, 5, 78, 0, 0, 570, 572, 5, 89, 0, 0, 571, 535, 1, 0, 0, 0, 571, 553, 1, 0, 0, 0, 572, 84, 1, 0, 0, 0, 573, 574, 5, 97, 0, 0, 574, 575, 5, 114, 0, 0, 575, 576, 5, 114, 0, 0, 576, 577, 5, 97, 0, 0, 577, 578, 5, 121, 0, 0, 578, 579, 5, 95, 0, 0, 579, 580, 5, 108, 0, 0, 580, 581, 5, 101, 0, 0, 581, 582, 5, 110, 0, 0, 582, 583, 5, 103, 0, 0, 583, 584, 5, 116, 0, 0, 584, 598, 5, 104, 0, 0, 585, 586, 5, 65, 0, 0, 586, 587, 5, 82, 0, 0, 587, 588, 5, 82, 0, 0, 588, 589, 5, 65, 0, 0, 589, 590, 5, 89, 0, 0, 590, 591, 5, 95, 0, 0, 591, 592, 5, 76, 0, 0, 592, 593, 5, 69, 0, 0, 593, 594, 5, 78, 0, 0, 594, 595, 5, 71, 0, 0, 595, 596, 5, 84, 0, 0, 596, 598, 5, 72, 0, 0, 597, 573, 1, 0, 0, 0, 597, 585, 1, 0, 0, 0, 598, 86, 1, 0, 0, 0, 599, 600, 5, 116, 0, 0, 600, 601, 5, 114, 0, 0, 601, 602, 5, 117, 0, 0, 602, 627, 5, 101, 0, 0, 603, 604, 5, 84, 0, 0, 604, 605, 5, 114, 0, 0, 605, 606, 5, 117, 0, 0, 606, 627, 5, 101, 0, 0, 607, 608, 5, 84, 0, 0, 608, 609, 5, 82, 0, 0, 609, 610, 5, 85, 0, 0, 610, 627, 5, 69, 0, 0, 611, 612, 5, 102, 0, 0, 612, 613, 5, 97, 0, 0, 613, 614, 5, 108, 0, 0, 614, 615, 5, 115, 0, 0, 615, 627, 5, 101, 0, 0, 616, 617, 5, 70, 0, 0, 617, 618, 5, 97, 0, 0, 618, 619, 5, 108, 0, 0, 619, 620, 5, 115, 0, 0, 620, 627, 5, 101, 0, 0, 621, 622, 5, 70, 0, 0, 622, 623, 5, 65, 0, 0, 623, 624, 5, 76, 0, 0, 624, 625, 5, 83, 0, 0, 625, 627, 5, 69, 0, 0, 626, 599, 1, 0, 0, 0, 626, 603, 1, 0, 0, 0, 626, 607, 1, 0, 0, 0, 626, 611, 1, 0, 0, 0, 626, 616, 1, 0, 0, 0, 626, 621, 1, 0, 0, 0, 627, 88, 1, 0, 0, 0, 628, 633, 3, 117, 58, 0, 629, 633, 3, 119, 59, 0, 630, 633, 3, 121, 60, 0, 631, 633, 3, 115, 57, 0, 632, 628, 1, 0, 0, 0, 632, 629, 1, 0, 0, 0, 632, 630, 1, 0, 0, 0, 632, 631, 1, 0, 0, 0, 633, 90, 1, 0, 0, 0, 634, 637, 3, 133, 66, 0, 635, 637, 3, 135, 67, 0, 636, 634, 1, 0, 0, 0, 636, 635, 1, 0, 0, 0, 637, 92, 1, 0, 0, 0, 638, 643, 3, 111, 55, 0, 639, 642, 3, 111, 55, 0, 640, 642, 3, 113, 56, 0, 641, 639, 1, 0, 0, 0, 641, 640, 1, 0, 0, 0, 642, 645, 1, 0, 0, 0, 643, 641, 1, 0, 0, 0, 643, 644, 1, 0, 0, 0, 644, 94, 1, 0, 0, 0, 645, 643, 1, 0, 0, 0, 646, 647, 5, 36, 0, 0, 647, 648, 5, 109, 0, 0, 648, 649, 5, 101, 0, 0, 649, 650, 5, 116, 0, 0, 650, 651, 5, 97, 0, 0, 651, 96, 1, 0, 0, 0, 652, 654, 3, 101, 50, 0, 653, 652, 1, 0, 0, 0, 653, 654, 1, 0, 0, 0, 654, 665, 1, 0, 0, 0, 655, 657, 5, 34, 0, 0, 656, 658, 3, 103, 51, 0, 657, 656, 1, 0, 0, 0, 657, 658, 1, 0, 0, 0, 658, 659, 1, 0, 0, 0, 659, 666, 5, 34, 0, 0, 660, 662, 5, 39, 0, 0, 661, 663, 3, 105, 52, 0, 662, 661, 1, 0, 0, 0, 662, 663, 1, 0, 0, 0, 663, 664, 1, 0, 0, 0, 664, 666, 5, 39, 0, 0, 665, 655, 1, 0, 0, 0, 665, 660, 1, 0, 0, 0, 666, 98, 1, 0, 0, 0, 667, 670, 3, 93, 46, 0, 668, 670, 3, 95, 47, 0, 669, 667, 1, 0, 0, 0, 669, 668, 1, 0, 0, 0, 670, 678, 1, 0, 0, 0, 671, 674, 5, 91, 0, 0, 672, 675, 3, 97, 48, 0, 673, 675, 3, 117, 58, 0, 674, 672, 1, 0, 0, 0, 674, 673, 1, 0, 0, 0, 675, 676, 1, 0, 0, 0, 676, 677, 5, 93, 0, 0, 677, 679, 1, 0, 0, 0, 678, 671, 1, 0, 0, 0, 679, 680, 1, 0, 0, 0, 680, 678, 1, 0, 0, 0, 680, 681, 1, 0, 0, 0, 681, 100, 1, 0, 0, 0, 682, 683, 5, 117, 0, 0, 683, 686, 5, 56, 0, 0, 684, 686, 7, 0, 0, 0, 685, 682, 1, 0, 0, 0, 685, 684, 1, 0, 0, 0, 686, 102, 1, 0, 0, 0, 687, 689, 3, 107, 53, 0, 688, 687, 1, 0, 0, 0, 689, 690, 1, 0, 0, 0, 690, 688, 1, 0, 0, 0, 690, 691, 1, 0, 0, 0, 691, 104, 1, 0, 0, 0, 692, 694, 3, 109, 54, 0, 693, 692, 1, 0, 0, 0, 694, 695, 1, 0, 0, 0, 695, 693, 1, 0, 0, 0, 695, 696, 1, 0, 0, 0, 696, 106, 1, 0, 0, 0, 697, 705, 8, 1, 0, 0, 698, 705, 3, 149, 74, 0, 699, 700, 5, 92, 0, 0, 700, 705, 5, 10, 0, 0, 701, 702, 5, 92, 0, 0, 702, 703, 5, 13, 0, 0, 703, 705, 5, 10, 0, 0, 704, 697, 1, 0, 0, 0, 704, 698, 1, 0, 0, 0, 704, 699, 1, 0, 0, 0, 704, 701, 1, 0, 0, 0, 705, 108, 1, 0, 0, 0, 706, 714, 8, 2, 0, 0, 707, 714, 3, 149, 74, 0, 708, 709, 5, 92, 0, 0, 709, 714, 5, 10, 0, 0, 710, 711, 5, 92, 0, 0, 711, 712, 5, 13, 0, 0, 712, 714, 5, 10, 0, 0, 713, 706, 1, 0, 0, 0, 713, 707, 1, 0, 0, 0, 713, 708, 1, 0, 0, 0, 713, 710, 1, 0, 0, 0, 714, 110, 1, 0, 0, 0, 715, 716, 7, 3, 0, 0, 716, 112, 1, 0, 0, 0, 717, 718, 7, 4, 0, 0, 718, 114, 1, 0, 0, 0, 719, 720, 5, 48, 0, 0, 720, 722, 7, 5, 0, 0, 721, 723, 7, 6, 0, 0, 722, 721, 1, 0, 0, 0, 723, 724, 1, 0, 0, 0, 724, 722, 1, 0, 0, 0, 724, 725, 1, 0, 0, 0, 725, 116, 1, 0, 0, 0, 726, 730, 3, 123, 61, 0, 727, 729, 3, 113, 56, 0, 728, 727, 1, 0, 0, 0, 729, 732, 1, 0, 0, 0, 730, 728, 1, 0, 0, 0, 730, 731, 1, 0, 0, 0, 731, 735, 1, 0, 0, 0, 732, 730, 1, 0, 0, 0, 733, 735, 5, 48, 0, 0, 734, 726, 1, 0, 0, 0, 734, 733, 1, 0, 0, 0, 735, 118, 1, 0, 0, 0, 736, 740, 5, 48, 0, 0, 737, 739, 3, 125, 62, 0, 738, 737, 1, 0, 0, 0, 739, 742, 1, 0, 0, 0, 740, 738, 1, 0, 0, 0, 740, 741, 1, 0, 0, 0, 741, 120, 1, 0, 0, 0, 742, 740, 1, 0, 0, 0, 743, 744, 5, 48, 0, 0, 744, 745, 7, 7, 0, 0, 745, 746, 3, 145, 72, 0, 746, 122, 1, 0, 0, 0, 747, 748, 7, 8, 0, 0, 748, 124, 1, 0, 0, 0, 749, 750, 7, 9, 0, 0, 750, 126, 1, 0, 0, 0, 751, 752, 7, 10, 0, 0, 752, 128, 1, 0, 0, 0, 753, 754, 3, 127, 63, 0, 754, 755, 3, 127, 63, 0, 755, 756, 3, 127, 63, 0, 756, 757, 3, 127, 63, 0, 757, 130, 1, 0, 0, 0, 758, 759, 5, 92, 0, 0, 759, 760, 5, 117, 0, 0, 760, 761, 1, 0, 0, 0, 761, 769, 3, 129, 64, 0, 762, 763, 5, 92, 0, 0, 763, 764, 5, 85, 0, 0, 764, 765, 1, 0, 0, 0, 765, 766, 3, 129, 64, 0, 766, 767, 3, 129, 64, 0, 767, 769, 1, 0, 0, 0, 768, 758, 1, 0, 0, 0, 768, 762, 1, 0, 0, 0, 769, 132, 1, 0, 0, 0, 770, 772, 3, 137, 68, 0, 771, 773, 3, 139, 69, 0, 772, 771, 1, 0, 0, 0, 772, 773, 1, 0, 0, 0, 773, 778, 1, 0, 0, 0, 774, 775, 3, 141, 70, 0, 775, 776, 3, 139, 69, 0, 776, 778, 1, 0, 0, 0, 777, 770, 1, 0, 0, 0, 777, 774, 1, 0, 0, 0, 778, 134, 1, 0, 0, 0, 779, 780, 5, 48, 0, 0, 780, 783, 7, 7, 0, 0, 781, 784, 3, 143, 71, 0, 782, 784, 3, 145, 72, 0, 783, 781, 1, 0, 0, 0, 783, 782, 1, 0, 0, 0, 784, 785, 1, 0, 0, 0, 785, 786, 3, 147, 73, 0, 786, 136, 1, 0, 0, 0, 787, 789, 3, 141, 70, 0, 788, 787, 1, 0, 0, 0, 788, 789, 1, 0, 0, 0, 789, 790, 1, 0, 0, 0, 790, 791, 5, 46, 0, 0, 791, 796, 3, 141, 70, 0, 792, 793, 3, 141, 70, 0, 793, 794, 5, 46, 0, 0, 794, 796, 1, 0, 0, 0, 795, 788, 1, 0, 0, 0, 795, 792, 1, 0, 0, 0, 796, 138, 1, 0, 0, 0, 797, 799, 7, 11, 0, 0, 798, 800, 7, 12, 0, 0, 799, 798, 1, 0, 0, 0, 799, 800, 1, 0, 0, 0, 800, 801, 1, 0, 0, 0, 801, 802, 3, 141, 70, 0, 802, 140, 1, 0, 0, 0, 803, 805, 3, 113, 56, 0, 804, 803, 1, 0, 0, 0, 805, 806, 1, 0, 0, 0, 806, 804, 1, 0, 0, 0, 806, 807, 1, 0, 0, 0, 807, 142, 1, 0, 0, 0, 808, 810, 3, 145, 72, 0, 809, 808, 1, 0, 0, 0, 809, 810, 1, 0, 0, 0, 810, 811, 1, 0, 0, 0, 811, 812, 5, 46, 0, 0, 812, 817, 3, 145, 72, 0, 813, 814, 3, 145, 72, 0, 814, 815, 5, 46, 0, 0, 815, 817, 1, 0, 0, 0, 816, 809, 1, 0, 0, 0, 816, 813, 1, 0, 0, 0, 817, 144, 1, 0, 0, 0, 818, 820, 3, 127, 63, 0, 819, 818, 1, 0, 0, 0, 820, 821, 1, 0, 0, 0, 821, 819, 1, 0, 0, 0, 821, 822, 1, 0, 0, 0, 822, 146, 1, 0, 0, 0, 823, 825, 7, 13, 0, 0, 824, 826, 7, 12, 0, 0, 825, 824, 1, 0, 0, 0, 825, 826, 1, 0, 0, 0, 826, 827, 1, 0, 0, 0, 827, 828, 3, 141, 70, 0, 828, 148, 1, 0, 0, 0, 829, 830, 5, 92, 0, 0, 830, 845, 7, 14, 0, 0, 831, 832, 5, 92, 0, 0, 832, 834, 3, 125, 62, 0, 833, 835, 3, 125, 62, 0, 834, 833, 1, 0, 0, 0, 834, 835, 1, 0, 0, 0, 835, 837, 1, 0, 0, 0, 836, 838, 3, 125, 62, 0, 837, 836, 1, 0, 0, 0, 837, 838, 1, 0, 0, 0, 838, 845, 1, 0, 0, 0, 839, 840, 5, 92, 0, 0, 840, 841, 5, 120, 0, 0, 841, 842, 1, 0, 0, 0, 842, 845, 3, 145, 72, 0, 843, 845, 3, 131, 65, 0, 844, 829, 1, 0, 0, 0, 844, 831, 1, 0, 0, 0, 844, 839, 1, 0, 0, 0, 844, 843, 1, 0, 0, 0, 845, 150, 1, 0, 0, 0, 846, 848, 7, 15, 0, 0, 847, 846, 1, 0, 0, 0, 848, 849, 1, 0, 0, 0, 849, 847, 1, 0, 0, 0, 849, 850, 1, 0, 0, 0, 850, 851, 1, 0, 0, 0, 851, 852, 6, 75, 0, 0, 852, 152, 1, 0, 0, 0, 853, 855, 5, 13, 0, 0, 854, 856, 5, 10, 0, 0, 855, 854, 1, 0, 0, 0, 855, 856, 1, 0, 0, 0, 856, 859, 1, 0, 0, 0, 857, 859, 5, 10, 0, 0, 858, 853, 1, 0, 0, 0, 858, 857, 1, 0, 0, 0, 859, 860, 1, 0, 0, 0, 860, 861, 6, 76, 0, 0, 861, 154, 1, 0, 0, 0, 59, 0, 193, 207, 229, 255, 290, 298, 314, 338, 349, 355, 360, 362, 393, 429, 465, 495, 533, 571, 597, 626, 632, 636, 641, 643, 653, 657, 662, 665, 669, 674, 680, 685, 690, 695, 704, 713, 724, 730, 734, 740, 768, 772, 777, 783, 788, 795, 799, 806, 809, 816, 821, 825, 834, 837, 844, 849, 855, 858, 1, 6, 0, 0] \ No newline at end of file +[4, 0, 59, 1036, 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, 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, 208, 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, 222, 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, 244, 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, 270, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 3, 28, 305, 8, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 313, 8, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 3, 30, 329, 8, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 353, 8, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 364, 8, 33, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 370, 8, 34, 1, 35, 1, 35, 1, 35, 5, 35, 375, 8, 35, 10, 35, 12, 35, 378, 9, 35, 1, 35, 1, 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, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 408, 8, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 3, 37, 444, 8, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 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, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 510, 8, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 3, 40, 548, 8, 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, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 586, 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, 3, 42, 612, 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, 3, 43, 632, 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, 3, 44, 654, 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, 3, 45, 678, 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, 3, 46, 700, 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, 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, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, 752, 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, 772, 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, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 3, 50, 801, 8, 50, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 807, 8, 51, 1, 52, 1, 52, 3, 52, 811, 8, 52, 1, 53, 1, 53, 1, 53, 5, 53, 816, 8, 53, 10, 53, 12, 53, 819, 9, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 3, 55, 828, 8, 55, 1, 55, 1, 55, 3, 55, 832, 8, 55, 1, 55, 1, 55, 1, 55, 3, 55, 837, 8, 55, 1, 55, 3, 55, 840, 8, 55, 1, 56, 1, 56, 3, 56, 844, 8, 56, 1, 56, 1, 56, 1, 56, 3, 56, 849, 8, 56, 1, 56, 1, 56, 4, 56, 853, 8, 56, 11, 56, 12, 56, 854, 1, 57, 1, 57, 1, 57, 3, 57, 860, 8, 57, 1, 58, 4, 58, 863, 8, 58, 11, 58, 12, 58, 864, 1, 59, 4, 59, 868, 8, 59, 11, 59, 12, 59, 869, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 3, 60, 879, 8, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 3, 61, 888, 8, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 4, 64, 897, 8, 64, 11, 64, 12, 64, 898, 1, 65, 1, 65, 5, 65, 903, 8, 65, 10, 65, 12, 65, 906, 9, 65, 1, 65, 3, 65, 909, 8, 65, 1, 66, 1, 66, 5, 66, 913, 8, 66, 10, 66, 12, 66, 916, 9, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 3, 72, 943, 8, 72, 1, 73, 1, 73, 3, 73, 947, 8, 73, 1, 73, 1, 73, 1, 73, 3, 73, 952, 8, 73, 1, 74, 1, 74, 1, 74, 1, 74, 3, 74, 958, 8, 74, 1, 74, 1, 74, 1, 75, 3, 75, 963, 8, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 3, 75, 970, 8, 75, 1, 76, 1, 76, 3, 76, 974, 8, 76, 1, 76, 1, 76, 1, 77, 4, 77, 979, 8, 77, 11, 77, 12, 77, 980, 1, 78, 3, 78, 984, 8, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 3, 78, 991, 8, 78, 1, 79, 4, 79, 994, 8, 79, 11, 79, 12, 79, 995, 1, 80, 1, 80, 3, 80, 1000, 8, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 3, 81, 1009, 8, 81, 1, 81, 3, 81, 1012, 8, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 3, 81, 1019, 8, 81, 1, 82, 4, 82, 1022, 8, 82, 11, 82, 12, 82, 1023, 1, 82, 1, 82, 1, 83, 1, 83, 3, 83, 1030, 8, 83, 1, 83, 3, 83, 1033, 8, 83, 1, 83, 1, 83, 0, 0, 84, 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, 0, 117, 0, 119, 0, 121, 0, 123, 0, 125, 0, 127, 0, 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, 58, 167, 59, 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, 1090, 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, 165, 1, 0, 0, 0, 0, 167, 1, 0, 0, 0, 1, 169, 1, 0, 0, 0, 3, 171, 1, 0, 0, 0, 5, 173, 1, 0, 0, 0, 7, 175, 1, 0, 0, 0, 9, 177, 1, 0, 0, 0, 11, 179, 1, 0, 0, 0, 13, 181, 1, 0, 0, 0, 15, 183, 1, 0, 0, 0, 17, 185, 1, 0, 0, 0, 19, 188, 1, 0, 0, 0, 21, 190, 1, 0, 0, 0, 23, 193, 1, 0, 0, 0, 25, 196, 1, 0, 0, 0, 27, 207, 1, 0, 0, 0, 29, 221, 1, 0, 0, 0, 31, 243, 1, 0, 0, 0, 33, 269, 1, 0, 0, 0, 35, 271, 1, 0, 0, 0, 37, 273, 1, 0, 0, 0, 39, 275, 1, 0, 0, 0, 41, 277, 1, 0, 0, 0, 43, 279, 1, 0, 0, 0, 45, 281, 1, 0, 0, 0, 47, 284, 1, 0, 0, 0, 49, 287, 1, 0, 0, 0, 51, 290, 1, 0, 0, 0, 53, 292, 1, 0, 0, 0, 55, 294, 1, 0, 0, 0, 57, 304, 1, 0, 0, 0, 59, 312, 1, 0, 0, 0, 61, 328, 1, 0, 0, 0, 63, 352, 1, 0, 0, 0, 65, 354, 1, 0, 0, 0, 67, 363, 1, 0, 0, 0, 69, 369, 1, 0, 0, 0, 71, 371, 1, 0, 0, 0, 73, 407, 1, 0, 0, 0, 75, 443, 1, 0, 0, 0, 77, 479, 1, 0, 0, 0, 79, 509, 1, 0, 0, 0, 81, 547, 1, 0, 0, 0, 83, 585, 1, 0, 0, 0, 85, 611, 1, 0, 0, 0, 87, 631, 1, 0, 0, 0, 89, 653, 1, 0, 0, 0, 91, 677, 1, 0, 0, 0, 93, 699, 1, 0, 0, 0, 95, 723, 1, 0, 0, 0, 97, 751, 1, 0, 0, 0, 99, 771, 1, 0, 0, 0, 101, 800, 1, 0, 0, 0, 103, 806, 1, 0, 0, 0, 105, 810, 1, 0, 0, 0, 107, 812, 1, 0, 0, 0, 109, 820, 1, 0, 0, 0, 111, 827, 1, 0, 0, 0, 113, 843, 1, 0, 0, 0, 115, 859, 1, 0, 0, 0, 117, 862, 1, 0, 0, 0, 119, 867, 1, 0, 0, 0, 121, 878, 1, 0, 0, 0, 123, 887, 1, 0, 0, 0, 125, 889, 1, 0, 0, 0, 127, 891, 1, 0, 0, 0, 129, 893, 1, 0, 0, 0, 131, 908, 1, 0, 0, 0, 133, 910, 1, 0, 0, 0, 135, 917, 1, 0, 0, 0, 137, 921, 1, 0, 0, 0, 139, 923, 1, 0, 0, 0, 141, 925, 1, 0, 0, 0, 143, 927, 1, 0, 0, 0, 145, 942, 1, 0, 0, 0, 147, 951, 1, 0, 0, 0, 149, 953, 1, 0, 0, 0, 151, 969, 1, 0, 0, 0, 153, 971, 1, 0, 0, 0, 155, 978, 1, 0, 0, 0, 157, 990, 1, 0, 0, 0, 159, 993, 1, 0, 0, 0, 161, 997, 1, 0, 0, 0, 163, 1018, 1, 0, 0, 0, 165, 1021, 1, 0, 0, 0, 167, 1032, 1, 0, 0, 0, 169, 170, 5, 40, 0, 0, 170, 2, 1, 0, 0, 0, 171, 172, 5, 41, 0, 0, 172, 4, 1, 0, 0, 0, 173, 174, 5, 91, 0, 0, 174, 6, 1, 0, 0, 0, 175, 176, 5, 44, 0, 0, 176, 8, 1, 0, 0, 0, 177, 178, 5, 93, 0, 0, 178, 10, 1, 0, 0, 0, 179, 180, 5, 123, 0, 0, 180, 12, 1, 0, 0, 0, 181, 182, 5, 125, 0, 0, 182, 14, 1, 0, 0, 0, 183, 184, 5, 60, 0, 0, 184, 16, 1, 0, 0, 0, 185, 186, 5, 60, 0, 0, 186, 187, 5, 61, 0, 0, 187, 18, 1, 0, 0, 0, 188, 189, 5, 62, 0, 0, 189, 20, 1, 0, 0, 0, 190, 191, 5, 62, 0, 0, 191, 192, 5, 61, 0, 0, 192, 22, 1, 0, 0, 0, 193, 194, 5, 61, 0, 0, 194, 195, 5, 61, 0, 0, 195, 24, 1, 0, 0, 0, 196, 197, 5, 33, 0, 0, 197, 198, 5, 61, 0, 0, 198, 26, 1, 0, 0, 0, 199, 200, 5, 108, 0, 0, 200, 201, 5, 105, 0, 0, 201, 202, 5, 107, 0, 0, 202, 208, 5, 101, 0, 0, 203, 204, 5, 76, 0, 0, 204, 205, 5, 73, 0, 0, 205, 206, 5, 75, 0, 0, 206, 208, 5, 69, 0, 0, 207, 199, 1, 0, 0, 0, 207, 203, 1, 0, 0, 0, 208, 28, 1, 0, 0, 0, 209, 210, 5, 101, 0, 0, 210, 211, 5, 120, 0, 0, 211, 212, 5, 105, 0, 0, 212, 213, 5, 115, 0, 0, 213, 214, 5, 116, 0, 0, 214, 222, 5, 115, 0, 0, 215, 216, 5, 69, 0, 0, 216, 217, 5, 88, 0, 0, 217, 218, 5, 73, 0, 0, 218, 219, 5, 83, 0, 0, 219, 220, 5, 84, 0, 0, 220, 222, 5, 83, 0, 0, 221, 209, 1, 0, 0, 0, 221, 215, 1, 0, 0, 0, 222, 30, 1, 0, 0, 0, 223, 224, 5, 116, 0, 0, 224, 225, 5, 101, 0, 0, 225, 226, 5, 120, 0, 0, 226, 227, 5, 116, 0, 0, 227, 228, 5, 95, 0, 0, 228, 229, 5, 109, 0, 0, 229, 230, 5, 97, 0, 0, 230, 231, 5, 116, 0, 0, 231, 232, 5, 99, 0, 0, 232, 244, 5, 104, 0, 0, 233, 234, 5, 84, 0, 0, 234, 235, 5, 69, 0, 0, 235, 236, 5, 88, 0, 0, 236, 237, 5, 84, 0, 0, 237, 238, 5, 95, 0, 0, 238, 239, 5, 77, 0, 0, 239, 240, 5, 65, 0, 0, 240, 241, 5, 84, 0, 0, 241, 242, 5, 67, 0, 0, 242, 244, 5, 72, 0, 0, 243, 223, 1, 0, 0, 0, 243, 233, 1, 0, 0, 0, 244, 32, 1, 0, 0, 0, 245, 246, 5, 112, 0, 0, 246, 247, 5, 104, 0, 0, 247, 248, 5, 114, 0, 0, 248, 249, 5, 97, 0, 0, 249, 250, 5, 115, 0, 0, 250, 251, 5, 101, 0, 0, 251, 252, 5, 95, 0, 0, 252, 253, 5, 109, 0, 0, 253, 254, 5, 97, 0, 0, 254, 255, 5, 116, 0, 0, 255, 256, 5, 99, 0, 0, 256, 270, 5, 104, 0, 0, 257, 258, 5, 80, 0, 0, 258, 259, 5, 72, 0, 0, 259, 260, 5, 82, 0, 0, 260, 261, 5, 65, 0, 0, 261, 262, 5, 83, 0, 0, 262, 263, 5, 69, 0, 0, 263, 264, 5, 95, 0, 0, 264, 265, 5, 77, 0, 0, 265, 266, 5, 65, 0, 0, 266, 267, 5, 84, 0, 0, 267, 268, 5, 67, 0, 0, 268, 270, 5, 72, 0, 0, 269, 245, 1, 0, 0, 0, 269, 257, 1, 0, 0, 0, 270, 34, 1, 0, 0, 0, 271, 272, 5, 43, 0, 0, 272, 36, 1, 0, 0, 0, 273, 274, 5, 45, 0, 0, 274, 38, 1, 0, 0, 0, 275, 276, 5, 42, 0, 0, 276, 40, 1, 0, 0, 0, 277, 278, 5, 47, 0, 0, 278, 42, 1, 0, 0, 0, 279, 280, 5, 37, 0, 0, 280, 44, 1, 0, 0, 0, 281, 282, 5, 42, 0, 0, 282, 283, 5, 42, 0, 0, 283, 46, 1, 0, 0, 0, 284, 285, 5, 60, 0, 0, 285, 286, 5, 60, 0, 0, 286, 48, 1, 0, 0, 0, 287, 288, 5, 62, 0, 0, 288, 289, 5, 62, 0, 0, 289, 50, 1, 0, 0, 0, 290, 291, 5, 38, 0, 0, 291, 52, 1, 0, 0, 0, 292, 293, 5, 124, 0, 0, 293, 54, 1, 0, 0, 0, 294, 295, 5, 94, 0, 0, 295, 56, 1, 0, 0, 0, 296, 297, 5, 38, 0, 0, 297, 305, 5, 38, 0, 0, 298, 299, 5, 97, 0, 0, 299, 300, 5, 110, 0, 0, 300, 305, 5, 100, 0, 0, 301, 302, 5, 65, 0, 0, 302, 303, 5, 78, 0, 0, 303, 305, 5, 68, 0, 0, 304, 296, 1, 0, 0, 0, 304, 298, 1, 0, 0, 0, 304, 301, 1, 0, 0, 0, 305, 58, 1, 0, 0, 0, 306, 307, 5, 124, 0, 0, 307, 313, 5, 124, 0, 0, 308, 309, 5, 111, 0, 0, 309, 313, 5, 114, 0, 0, 310, 311, 5, 79, 0, 0, 311, 313, 5, 82, 0, 0, 312, 306, 1, 0, 0, 0, 312, 308, 1, 0, 0, 0, 312, 310, 1, 0, 0, 0, 313, 60, 1, 0, 0, 0, 314, 315, 5, 105, 0, 0, 315, 316, 5, 115, 0, 0, 316, 317, 5, 32, 0, 0, 317, 318, 5, 110, 0, 0, 318, 319, 5, 117, 0, 0, 319, 320, 5, 108, 0, 0, 320, 329, 5, 108, 0, 0, 321, 322, 5, 73, 0, 0, 322, 323, 5, 83, 0, 0, 323, 324, 5, 32, 0, 0, 324, 325, 5, 78, 0, 0, 325, 326, 5, 85, 0, 0, 326, 327, 5, 76, 0, 0, 327, 329, 5, 76, 0, 0, 328, 314, 1, 0, 0, 0, 328, 321, 1, 0, 0, 0, 329, 62, 1, 0, 0, 0, 330, 331, 5, 105, 0, 0, 331, 332, 5, 115, 0, 0, 332, 333, 5, 32, 0, 0, 333, 334, 5, 110, 0, 0, 334, 335, 5, 111, 0, 0, 335, 336, 5, 116, 0, 0, 336, 337, 5, 32, 0, 0, 337, 338, 5, 110, 0, 0, 338, 339, 5, 117, 0, 0, 339, 340, 5, 108, 0, 0, 340, 353, 5, 108, 0, 0, 341, 342, 5, 73, 0, 0, 342, 343, 5, 83, 0, 0, 343, 344, 5, 32, 0, 0, 344, 345, 5, 78, 0, 0, 345, 346, 5, 79, 0, 0, 346, 347, 5, 84, 0, 0, 347, 348, 5, 32, 0, 0, 348, 349, 5, 78, 0, 0, 349, 350, 5, 85, 0, 0, 350, 351, 5, 76, 0, 0, 351, 353, 5, 76, 0, 0, 352, 330, 1, 0, 0, 0, 352, 341, 1, 0, 0, 0, 353, 64, 1, 0, 0, 0, 354, 355, 5, 126, 0, 0, 355, 66, 1, 0, 0, 0, 356, 364, 5, 33, 0, 0, 357, 358, 5, 110, 0, 0, 358, 359, 5, 111, 0, 0, 359, 364, 5, 116, 0, 0, 360, 361, 5, 78, 0, 0, 361, 362, 5, 79, 0, 0, 362, 364, 5, 84, 0, 0, 363, 356, 1, 0, 0, 0, 363, 357, 1, 0, 0, 0, 363, 360, 1, 0, 0, 0, 364, 68, 1, 0, 0, 0, 365, 366, 5, 105, 0, 0, 366, 370, 5, 110, 0, 0, 367, 368, 5, 73, 0, 0, 368, 370, 5, 78, 0, 0, 369, 365, 1, 0, 0, 0, 369, 367, 1, 0, 0, 0, 370, 70, 1, 0, 0, 0, 371, 376, 5, 91, 0, 0, 372, 375, 3, 165, 82, 0, 373, 375, 3, 167, 83, 0, 374, 372, 1, 0, 0, 0, 374, 373, 1, 0, 0, 0, 375, 378, 1, 0, 0, 0, 376, 374, 1, 0, 0, 0, 376, 377, 1, 0, 0, 0, 377, 379, 1, 0, 0, 0, 378, 376, 1, 0, 0, 0, 379, 380, 5, 93, 0, 0, 380, 72, 1, 0, 0, 0, 381, 382, 5, 106, 0, 0, 382, 383, 5, 115, 0, 0, 383, 384, 5, 111, 0, 0, 384, 385, 5, 110, 0, 0, 385, 386, 5, 95, 0, 0, 386, 387, 5, 99, 0, 0, 387, 388, 5, 111, 0, 0, 388, 389, 5, 110, 0, 0, 389, 390, 5, 116, 0, 0, 390, 391, 5, 97, 0, 0, 391, 392, 5, 105, 0, 0, 392, 393, 5, 110, 0, 0, 393, 408, 5, 115, 0, 0, 394, 395, 5, 74, 0, 0, 395, 396, 5, 83, 0, 0, 396, 397, 5, 79, 0, 0, 397, 398, 5, 78, 0, 0, 398, 399, 5, 95, 0, 0, 399, 400, 5, 67, 0, 0, 400, 401, 5, 79, 0, 0, 401, 402, 5, 78, 0, 0, 402, 403, 5, 84, 0, 0, 403, 404, 5, 65, 0, 0, 404, 405, 5, 73, 0, 0, 405, 406, 5, 78, 0, 0, 406, 408, 5, 83, 0, 0, 407, 381, 1, 0, 0, 0, 407, 394, 1, 0, 0, 0, 408, 74, 1, 0, 0, 0, 409, 410, 5, 106, 0, 0, 410, 411, 5, 115, 0, 0, 411, 412, 5, 111, 0, 0, 412, 413, 5, 110, 0, 0, 413, 414, 5, 95, 0, 0, 414, 415, 5, 99, 0, 0, 415, 416, 5, 111, 0, 0, 416, 417, 5, 110, 0, 0, 417, 418, 5, 116, 0, 0, 418, 419, 5, 97, 0, 0, 419, 420, 5, 105, 0, 0, 420, 421, 5, 110, 0, 0, 421, 422, 5, 115, 0, 0, 422, 423, 5, 95, 0, 0, 423, 424, 5, 97, 0, 0, 424, 425, 5, 108, 0, 0, 425, 444, 5, 108, 0, 0, 426, 427, 5, 74, 0, 0, 427, 428, 5, 83, 0, 0, 428, 429, 5, 79, 0, 0, 429, 430, 5, 78, 0, 0, 430, 431, 5, 95, 0, 0, 431, 432, 5, 67, 0, 0, 432, 433, 5, 79, 0, 0, 433, 434, 5, 78, 0, 0, 434, 435, 5, 84, 0, 0, 435, 436, 5, 65, 0, 0, 436, 437, 5, 73, 0, 0, 437, 438, 5, 78, 0, 0, 438, 439, 5, 83, 0, 0, 439, 440, 5, 95, 0, 0, 440, 441, 5, 65, 0, 0, 441, 442, 5, 76, 0, 0, 442, 444, 5, 76, 0, 0, 443, 409, 1, 0, 0, 0, 443, 426, 1, 0, 0, 0, 444, 76, 1, 0, 0, 0, 445, 446, 5, 106, 0, 0, 446, 447, 5, 115, 0, 0, 447, 448, 5, 111, 0, 0, 448, 449, 5, 110, 0, 0, 449, 450, 5, 95, 0, 0, 450, 451, 5, 99, 0, 0, 451, 452, 5, 111, 0, 0, 452, 453, 5, 110, 0, 0, 453, 454, 5, 116, 0, 0, 454, 455, 5, 97, 0, 0, 455, 456, 5, 105, 0, 0, 456, 457, 5, 110, 0, 0, 457, 458, 5, 115, 0, 0, 458, 459, 5, 95, 0, 0, 459, 460, 5, 97, 0, 0, 460, 461, 5, 110, 0, 0, 461, 480, 5, 121, 0, 0, 462, 463, 5, 74, 0, 0, 463, 464, 5, 83, 0, 0, 464, 465, 5, 79, 0, 0, 465, 466, 5, 78, 0, 0, 466, 467, 5, 95, 0, 0, 467, 468, 5, 67, 0, 0, 468, 469, 5, 79, 0, 0, 469, 470, 5, 78, 0, 0, 470, 471, 5, 84, 0, 0, 471, 472, 5, 65, 0, 0, 472, 473, 5, 73, 0, 0, 473, 474, 5, 78, 0, 0, 474, 475, 5, 83, 0, 0, 475, 476, 5, 95, 0, 0, 476, 477, 5, 65, 0, 0, 477, 478, 5, 78, 0, 0, 478, 480, 5, 89, 0, 0, 479, 445, 1, 0, 0, 0, 479, 462, 1, 0, 0, 0, 480, 78, 1, 0, 0, 0, 481, 482, 5, 97, 0, 0, 482, 483, 5, 114, 0, 0, 483, 484, 5, 114, 0, 0, 484, 485, 5, 97, 0, 0, 485, 486, 5, 121, 0, 0, 486, 487, 5, 95, 0, 0, 487, 488, 5, 99, 0, 0, 488, 489, 5, 111, 0, 0, 489, 490, 5, 110, 0, 0, 490, 491, 5, 116, 0, 0, 491, 492, 5, 97, 0, 0, 492, 493, 5, 105, 0, 0, 493, 494, 5, 110, 0, 0, 494, 510, 5, 115, 0, 0, 495, 496, 5, 65, 0, 0, 496, 497, 5, 82, 0, 0, 497, 498, 5, 82, 0, 0, 498, 499, 5, 65, 0, 0, 499, 500, 5, 89, 0, 0, 500, 501, 5, 95, 0, 0, 501, 502, 5, 67, 0, 0, 502, 503, 5, 79, 0, 0, 503, 504, 5, 78, 0, 0, 504, 505, 5, 84, 0, 0, 505, 506, 5, 65, 0, 0, 506, 507, 5, 73, 0, 0, 507, 508, 5, 78, 0, 0, 508, 510, 5, 83, 0, 0, 509, 481, 1, 0, 0, 0, 509, 495, 1, 0, 0, 0, 510, 80, 1, 0, 0, 0, 511, 512, 5, 97, 0, 0, 512, 513, 5, 114, 0, 0, 513, 514, 5, 114, 0, 0, 514, 515, 5, 97, 0, 0, 515, 516, 5, 121, 0, 0, 516, 517, 5, 95, 0, 0, 517, 518, 5, 99, 0, 0, 518, 519, 5, 111, 0, 0, 519, 520, 5, 110, 0, 0, 520, 521, 5, 116, 0, 0, 521, 522, 5, 97, 0, 0, 522, 523, 5, 105, 0, 0, 523, 524, 5, 110, 0, 0, 524, 525, 5, 115, 0, 0, 525, 526, 5, 95, 0, 0, 526, 527, 5, 97, 0, 0, 527, 528, 5, 108, 0, 0, 528, 548, 5, 108, 0, 0, 529, 530, 5, 65, 0, 0, 530, 531, 5, 82, 0, 0, 531, 532, 5, 82, 0, 0, 532, 533, 5, 65, 0, 0, 533, 534, 5, 89, 0, 0, 534, 535, 5, 95, 0, 0, 535, 536, 5, 67, 0, 0, 536, 537, 5, 79, 0, 0, 537, 538, 5, 78, 0, 0, 538, 539, 5, 84, 0, 0, 539, 540, 5, 65, 0, 0, 540, 541, 5, 73, 0, 0, 541, 542, 5, 78, 0, 0, 542, 543, 5, 83, 0, 0, 543, 544, 5, 95, 0, 0, 544, 545, 5, 65, 0, 0, 545, 546, 5, 76, 0, 0, 546, 548, 5, 76, 0, 0, 547, 511, 1, 0, 0, 0, 547, 529, 1, 0, 0, 0, 548, 82, 1, 0, 0, 0, 549, 550, 5, 97, 0, 0, 550, 551, 5, 114, 0, 0, 551, 552, 5, 114, 0, 0, 552, 553, 5, 97, 0, 0, 553, 554, 5, 121, 0, 0, 554, 555, 5, 95, 0, 0, 555, 556, 5, 99, 0, 0, 556, 557, 5, 111, 0, 0, 557, 558, 5, 110, 0, 0, 558, 559, 5, 116, 0, 0, 559, 560, 5, 97, 0, 0, 560, 561, 5, 105, 0, 0, 561, 562, 5, 110, 0, 0, 562, 563, 5, 115, 0, 0, 563, 564, 5, 95, 0, 0, 564, 565, 5, 97, 0, 0, 565, 566, 5, 110, 0, 0, 566, 586, 5, 121, 0, 0, 567, 568, 5, 65, 0, 0, 568, 569, 5, 82, 0, 0, 569, 570, 5, 82, 0, 0, 570, 571, 5, 65, 0, 0, 571, 572, 5, 89, 0, 0, 572, 573, 5, 95, 0, 0, 573, 574, 5, 67, 0, 0, 574, 575, 5, 79, 0, 0, 575, 576, 5, 78, 0, 0, 576, 577, 5, 84, 0, 0, 577, 578, 5, 65, 0, 0, 578, 579, 5, 73, 0, 0, 579, 580, 5, 78, 0, 0, 580, 581, 5, 83, 0, 0, 581, 582, 5, 95, 0, 0, 582, 583, 5, 65, 0, 0, 583, 584, 5, 78, 0, 0, 584, 586, 5, 89, 0, 0, 585, 549, 1, 0, 0, 0, 585, 567, 1, 0, 0, 0, 586, 84, 1, 0, 0, 0, 587, 588, 5, 97, 0, 0, 588, 589, 5, 114, 0, 0, 589, 590, 5, 114, 0, 0, 590, 591, 5, 97, 0, 0, 591, 592, 5, 121, 0, 0, 592, 593, 5, 95, 0, 0, 593, 594, 5, 108, 0, 0, 594, 595, 5, 101, 0, 0, 595, 596, 5, 110, 0, 0, 596, 597, 5, 103, 0, 0, 597, 598, 5, 116, 0, 0, 598, 612, 5, 104, 0, 0, 599, 600, 5, 65, 0, 0, 600, 601, 5, 82, 0, 0, 601, 602, 5, 82, 0, 0, 602, 603, 5, 65, 0, 0, 603, 604, 5, 89, 0, 0, 604, 605, 5, 95, 0, 0, 605, 606, 5, 76, 0, 0, 606, 607, 5, 69, 0, 0, 607, 608, 5, 78, 0, 0, 608, 609, 5, 71, 0, 0, 609, 610, 5, 84, 0, 0, 610, 612, 5, 72, 0, 0, 611, 587, 1, 0, 0, 0, 611, 599, 1, 0, 0, 0, 612, 86, 1, 0, 0, 0, 613, 614, 5, 115, 0, 0, 614, 615, 5, 116, 0, 0, 615, 616, 5, 95, 0, 0, 616, 617, 5, 101, 0, 0, 617, 618, 5, 113, 0, 0, 618, 619, 5, 117, 0, 0, 619, 620, 5, 97, 0, 0, 620, 621, 5, 108, 0, 0, 621, 632, 5, 115, 0, 0, 622, 623, 5, 83, 0, 0, 623, 624, 5, 84, 0, 0, 624, 625, 5, 95, 0, 0, 625, 626, 5, 69, 0, 0, 626, 627, 5, 81, 0, 0, 627, 628, 5, 85, 0, 0, 628, 629, 5, 65, 0, 0, 629, 630, 5, 76, 0, 0, 630, 632, 5, 83, 0, 0, 631, 613, 1, 0, 0, 0, 631, 622, 1, 0, 0, 0, 632, 88, 1, 0, 0, 0, 633, 634, 5, 115, 0, 0, 634, 635, 5, 116, 0, 0, 635, 636, 5, 95, 0, 0, 636, 637, 5, 116, 0, 0, 637, 638, 5, 111, 0, 0, 638, 639, 5, 117, 0, 0, 639, 640, 5, 99, 0, 0, 640, 641, 5, 104, 0, 0, 641, 642, 5, 101, 0, 0, 642, 654, 5, 115, 0, 0, 643, 644, 5, 83, 0, 0, 644, 645, 5, 84, 0, 0, 645, 646, 5, 95, 0, 0, 646, 647, 5, 84, 0, 0, 647, 648, 5, 79, 0, 0, 648, 649, 5, 85, 0, 0, 649, 650, 5, 67, 0, 0, 650, 651, 5, 72, 0, 0, 651, 652, 5, 69, 0, 0, 652, 654, 5, 83, 0, 0, 653, 633, 1, 0, 0, 0, 653, 643, 1, 0, 0, 0, 654, 90, 1, 0, 0, 0, 655, 656, 5, 115, 0, 0, 656, 657, 5, 116, 0, 0, 657, 658, 5, 95, 0, 0, 658, 659, 5, 111, 0, 0, 659, 660, 5, 118, 0, 0, 660, 661, 5, 101, 0, 0, 661, 662, 5, 114, 0, 0, 662, 663, 5, 108, 0, 0, 663, 664, 5, 97, 0, 0, 664, 665, 5, 112, 0, 0, 665, 678, 5, 115, 0, 0, 666, 667, 5, 83, 0, 0, 667, 668, 5, 84, 0, 0, 668, 669, 5, 95, 0, 0, 669, 670, 5, 79, 0, 0, 670, 671, 5, 86, 0, 0, 671, 672, 5, 69, 0, 0, 672, 673, 5, 82, 0, 0, 673, 674, 5, 76, 0, 0, 674, 675, 5, 65, 0, 0, 675, 676, 5, 80, 0, 0, 676, 678, 5, 83, 0, 0, 677, 655, 1, 0, 0, 0, 677, 666, 1, 0, 0, 0, 678, 92, 1, 0, 0, 0, 679, 680, 5, 115, 0, 0, 680, 681, 5, 116, 0, 0, 681, 682, 5, 95, 0, 0, 682, 683, 5, 99, 0, 0, 683, 684, 5, 114, 0, 0, 684, 685, 5, 111, 0, 0, 685, 686, 5, 115, 0, 0, 686, 687, 5, 115, 0, 0, 687, 688, 5, 101, 0, 0, 688, 700, 5, 115, 0, 0, 689, 690, 5, 83, 0, 0, 690, 691, 5, 84, 0, 0, 691, 692, 5, 95, 0, 0, 692, 693, 5, 67, 0, 0, 693, 694, 5, 82, 0, 0, 694, 695, 5, 79, 0, 0, 695, 696, 5, 83, 0, 0, 696, 697, 5, 83, 0, 0, 697, 698, 5, 69, 0, 0, 698, 700, 5, 83, 0, 0, 699, 679, 1, 0, 0, 0, 699, 689, 1, 0, 0, 0, 700, 94, 1, 0, 0, 0, 701, 702, 5, 115, 0, 0, 702, 703, 5, 116, 0, 0, 703, 704, 5, 95, 0, 0, 704, 705, 5, 99, 0, 0, 705, 706, 5, 111, 0, 0, 706, 707, 5, 110, 0, 0, 707, 708, 5, 116, 0, 0, 708, 709, 5, 97, 0, 0, 709, 710, 5, 105, 0, 0, 710, 711, 5, 110, 0, 0, 711, 724, 5, 115, 0, 0, 712, 713, 5, 83, 0, 0, 713, 714, 5, 84, 0, 0, 714, 715, 5, 95, 0, 0, 715, 716, 5, 67, 0, 0, 716, 717, 5, 79, 0, 0, 717, 718, 5, 78, 0, 0, 718, 719, 5, 84, 0, 0, 719, 720, 5, 65, 0, 0, 720, 721, 5, 73, 0, 0, 721, 722, 5, 78, 0, 0, 722, 724, 5, 83, 0, 0, 723, 701, 1, 0, 0, 0, 723, 712, 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, 105, 0, 0, 729, 730, 5, 110, 0, 0, 730, 731, 5, 116, 0, 0, 731, 732, 5, 101, 0, 0, 732, 733, 5, 114, 0, 0, 733, 734, 5, 115, 0, 0, 734, 735, 5, 101, 0, 0, 735, 736, 5, 99, 0, 0, 736, 737, 5, 116, 0, 0, 737, 752, 5, 115, 0, 0, 738, 739, 5, 83, 0, 0, 739, 740, 5, 84, 0, 0, 740, 741, 5, 95, 0, 0, 741, 742, 5, 73, 0, 0, 742, 743, 5, 78, 0, 0, 743, 744, 5, 84, 0, 0, 744, 745, 5, 69, 0, 0, 745, 746, 5, 82, 0, 0, 746, 747, 5, 83, 0, 0, 747, 748, 5, 69, 0, 0, 748, 749, 5, 67, 0, 0, 749, 750, 5, 84, 0, 0, 750, 752, 5, 83, 0, 0, 751, 725, 1, 0, 0, 0, 751, 738, 1, 0, 0, 0, 752, 98, 1, 0, 0, 0, 753, 754, 5, 115, 0, 0, 754, 755, 5, 116, 0, 0, 755, 756, 5, 95, 0, 0, 756, 757, 5, 119, 0, 0, 757, 758, 5, 105, 0, 0, 758, 759, 5, 116, 0, 0, 759, 760, 5, 104, 0, 0, 760, 761, 5, 105, 0, 0, 761, 772, 5, 110, 0, 0, 762, 763, 5, 83, 0, 0, 763, 764, 5, 84, 0, 0, 764, 765, 5, 95, 0, 0, 765, 766, 5, 87, 0, 0, 766, 767, 5, 73, 0, 0, 767, 768, 5, 84, 0, 0, 768, 769, 5, 72, 0, 0, 769, 770, 5, 73, 0, 0, 770, 772, 5, 78, 0, 0, 771, 753, 1, 0, 0, 0, 771, 762, 1, 0, 0, 0, 772, 100, 1, 0, 0, 0, 773, 774, 5, 116, 0, 0, 774, 775, 5, 114, 0, 0, 775, 776, 5, 117, 0, 0, 776, 801, 5, 101, 0, 0, 777, 778, 5, 84, 0, 0, 778, 779, 5, 114, 0, 0, 779, 780, 5, 117, 0, 0, 780, 801, 5, 101, 0, 0, 781, 782, 5, 84, 0, 0, 782, 783, 5, 82, 0, 0, 783, 784, 5, 85, 0, 0, 784, 801, 5, 69, 0, 0, 785, 786, 5, 102, 0, 0, 786, 787, 5, 97, 0, 0, 787, 788, 5, 108, 0, 0, 788, 789, 5, 115, 0, 0, 789, 801, 5, 101, 0, 0, 790, 791, 5, 70, 0, 0, 791, 792, 5, 97, 0, 0, 792, 793, 5, 108, 0, 0, 793, 794, 5, 115, 0, 0, 794, 801, 5, 101, 0, 0, 795, 796, 5, 70, 0, 0, 796, 797, 5, 65, 0, 0, 797, 798, 5, 76, 0, 0, 798, 799, 5, 83, 0, 0, 799, 801, 5, 69, 0, 0, 800, 773, 1, 0, 0, 0, 800, 777, 1, 0, 0, 0, 800, 781, 1, 0, 0, 0, 800, 785, 1, 0, 0, 0, 800, 790, 1, 0, 0, 0, 800, 795, 1, 0, 0, 0, 801, 102, 1, 0, 0, 0, 802, 807, 3, 131, 65, 0, 803, 807, 3, 133, 66, 0, 804, 807, 3, 135, 67, 0, 805, 807, 3, 129, 64, 0, 806, 802, 1, 0, 0, 0, 806, 803, 1, 0, 0, 0, 806, 804, 1, 0, 0, 0, 806, 805, 1, 0, 0, 0, 807, 104, 1, 0, 0, 0, 808, 811, 3, 147, 73, 0, 809, 811, 3, 149, 74, 0, 810, 808, 1, 0, 0, 0, 810, 809, 1, 0, 0, 0, 811, 106, 1, 0, 0, 0, 812, 817, 3, 125, 62, 0, 813, 816, 3, 125, 62, 0, 814, 816, 3, 127, 63, 0, 815, 813, 1, 0, 0, 0, 815, 814, 1, 0, 0, 0, 816, 819, 1, 0, 0, 0, 817, 815, 1, 0, 0, 0, 817, 818, 1, 0, 0, 0, 818, 108, 1, 0, 0, 0, 819, 817, 1, 0, 0, 0, 820, 821, 5, 36, 0, 0, 821, 822, 5, 109, 0, 0, 822, 823, 5, 101, 0, 0, 823, 824, 5, 116, 0, 0, 824, 825, 5, 97, 0, 0, 825, 110, 1, 0, 0, 0, 826, 828, 3, 115, 57, 0, 827, 826, 1, 0, 0, 0, 827, 828, 1, 0, 0, 0, 828, 839, 1, 0, 0, 0, 829, 831, 5, 34, 0, 0, 830, 832, 3, 117, 58, 0, 831, 830, 1, 0, 0, 0, 831, 832, 1, 0, 0, 0, 832, 833, 1, 0, 0, 0, 833, 840, 5, 34, 0, 0, 834, 836, 5, 39, 0, 0, 835, 837, 3, 119, 59, 0, 836, 835, 1, 0, 0, 0, 836, 837, 1, 0, 0, 0, 837, 838, 1, 0, 0, 0, 838, 840, 5, 39, 0, 0, 839, 829, 1, 0, 0, 0, 839, 834, 1, 0, 0, 0, 840, 112, 1, 0, 0, 0, 841, 844, 3, 107, 53, 0, 842, 844, 3, 109, 54, 0, 843, 841, 1, 0, 0, 0, 843, 842, 1, 0, 0, 0, 844, 852, 1, 0, 0, 0, 845, 848, 5, 91, 0, 0, 846, 849, 3, 111, 55, 0, 847, 849, 3, 131, 65, 0, 848, 846, 1, 0, 0, 0, 848, 847, 1, 0, 0, 0, 849, 850, 1, 0, 0, 0, 850, 851, 5, 93, 0, 0, 851, 853, 1, 0, 0, 0, 852, 845, 1, 0, 0, 0, 853, 854, 1, 0, 0, 0, 854, 852, 1, 0, 0, 0, 854, 855, 1, 0, 0, 0, 855, 114, 1, 0, 0, 0, 856, 857, 5, 117, 0, 0, 857, 860, 5, 56, 0, 0, 858, 860, 7, 0, 0, 0, 859, 856, 1, 0, 0, 0, 859, 858, 1, 0, 0, 0, 860, 116, 1, 0, 0, 0, 861, 863, 3, 121, 60, 0, 862, 861, 1, 0, 0, 0, 863, 864, 1, 0, 0, 0, 864, 862, 1, 0, 0, 0, 864, 865, 1, 0, 0, 0, 865, 118, 1, 0, 0, 0, 866, 868, 3, 123, 61, 0, 867, 866, 1, 0, 0, 0, 868, 869, 1, 0, 0, 0, 869, 867, 1, 0, 0, 0, 869, 870, 1, 0, 0, 0, 870, 120, 1, 0, 0, 0, 871, 879, 8, 1, 0, 0, 872, 879, 3, 163, 81, 0, 873, 874, 5, 92, 0, 0, 874, 879, 5, 10, 0, 0, 875, 876, 5, 92, 0, 0, 876, 877, 5, 13, 0, 0, 877, 879, 5, 10, 0, 0, 878, 871, 1, 0, 0, 0, 878, 872, 1, 0, 0, 0, 878, 873, 1, 0, 0, 0, 878, 875, 1, 0, 0, 0, 879, 122, 1, 0, 0, 0, 880, 888, 8, 2, 0, 0, 881, 888, 3, 163, 81, 0, 882, 883, 5, 92, 0, 0, 883, 888, 5, 10, 0, 0, 884, 885, 5, 92, 0, 0, 885, 886, 5, 13, 0, 0, 886, 888, 5, 10, 0, 0, 887, 880, 1, 0, 0, 0, 887, 881, 1, 0, 0, 0, 887, 882, 1, 0, 0, 0, 887, 884, 1, 0, 0, 0, 888, 124, 1, 0, 0, 0, 889, 890, 7, 3, 0, 0, 890, 126, 1, 0, 0, 0, 891, 892, 7, 4, 0, 0, 892, 128, 1, 0, 0, 0, 893, 894, 5, 48, 0, 0, 894, 896, 7, 5, 0, 0, 895, 897, 7, 6, 0, 0, 896, 895, 1, 0, 0, 0, 897, 898, 1, 0, 0, 0, 898, 896, 1, 0, 0, 0, 898, 899, 1, 0, 0, 0, 899, 130, 1, 0, 0, 0, 900, 904, 3, 137, 68, 0, 901, 903, 3, 127, 63, 0, 902, 901, 1, 0, 0, 0, 903, 906, 1, 0, 0, 0, 904, 902, 1, 0, 0, 0, 904, 905, 1, 0, 0, 0, 905, 909, 1, 0, 0, 0, 906, 904, 1, 0, 0, 0, 907, 909, 5, 48, 0, 0, 908, 900, 1, 0, 0, 0, 908, 907, 1, 0, 0, 0, 909, 132, 1, 0, 0, 0, 910, 914, 5, 48, 0, 0, 911, 913, 3, 139, 69, 0, 912, 911, 1, 0, 0, 0, 913, 916, 1, 0, 0, 0, 914, 912, 1, 0, 0, 0, 914, 915, 1, 0, 0, 0, 915, 134, 1, 0, 0, 0, 916, 914, 1, 0, 0, 0, 917, 918, 5, 48, 0, 0, 918, 919, 7, 7, 0, 0, 919, 920, 3, 159, 79, 0, 920, 136, 1, 0, 0, 0, 921, 922, 7, 8, 0, 0, 922, 138, 1, 0, 0, 0, 923, 924, 7, 9, 0, 0, 924, 140, 1, 0, 0, 0, 925, 926, 7, 10, 0, 0, 926, 142, 1, 0, 0, 0, 927, 928, 3, 141, 70, 0, 928, 929, 3, 141, 70, 0, 929, 930, 3, 141, 70, 0, 930, 931, 3, 141, 70, 0, 931, 144, 1, 0, 0, 0, 932, 933, 5, 92, 0, 0, 933, 934, 5, 117, 0, 0, 934, 935, 1, 0, 0, 0, 935, 943, 3, 143, 71, 0, 936, 937, 5, 92, 0, 0, 937, 938, 5, 85, 0, 0, 938, 939, 1, 0, 0, 0, 939, 940, 3, 143, 71, 0, 940, 941, 3, 143, 71, 0, 941, 943, 1, 0, 0, 0, 942, 932, 1, 0, 0, 0, 942, 936, 1, 0, 0, 0, 943, 146, 1, 0, 0, 0, 944, 946, 3, 151, 75, 0, 945, 947, 3, 153, 76, 0, 946, 945, 1, 0, 0, 0, 946, 947, 1, 0, 0, 0, 947, 952, 1, 0, 0, 0, 948, 949, 3, 155, 77, 0, 949, 950, 3, 153, 76, 0, 950, 952, 1, 0, 0, 0, 951, 944, 1, 0, 0, 0, 951, 948, 1, 0, 0, 0, 952, 148, 1, 0, 0, 0, 953, 954, 5, 48, 0, 0, 954, 957, 7, 7, 0, 0, 955, 958, 3, 157, 78, 0, 956, 958, 3, 159, 79, 0, 957, 955, 1, 0, 0, 0, 957, 956, 1, 0, 0, 0, 958, 959, 1, 0, 0, 0, 959, 960, 3, 161, 80, 0, 960, 150, 1, 0, 0, 0, 961, 963, 3, 155, 77, 0, 962, 961, 1, 0, 0, 0, 962, 963, 1, 0, 0, 0, 963, 964, 1, 0, 0, 0, 964, 965, 5, 46, 0, 0, 965, 970, 3, 155, 77, 0, 966, 967, 3, 155, 77, 0, 967, 968, 5, 46, 0, 0, 968, 970, 1, 0, 0, 0, 969, 962, 1, 0, 0, 0, 969, 966, 1, 0, 0, 0, 970, 152, 1, 0, 0, 0, 971, 973, 7, 11, 0, 0, 972, 974, 7, 12, 0, 0, 973, 972, 1, 0, 0, 0, 973, 974, 1, 0, 0, 0, 974, 975, 1, 0, 0, 0, 975, 976, 3, 155, 77, 0, 976, 154, 1, 0, 0, 0, 977, 979, 3, 127, 63, 0, 978, 977, 1, 0, 0, 0, 979, 980, 1, 0, 0, 0, 980, 978, 1, 0, 0, 0, 980, 981, 1, 0, 0, 0, 981, 156, 1, 0, 0, 0, 982, 984, 3, 159, 79, 0, 983, 982, 1, 0, 0, 0, 983, 984, 1, 0, 0, 0, 984, 985, 1, 0, 0, 0, 985, 986, 5, 46, 0, 0, 986, 991, 3, 159, 79, 0, 987, 988, 3, 159, 79, 0, 988, 989, 5, 46, 0, 0, 989, 991, 1, 0, 0, 0, 990, 983, 1, 0, 0, 0, 990, 987, 1, 0, 0, 0, 991, 158, 1, 0, 0, 0, 992, 994, 3, 141, 70, 0, 993, 992, 1, 0, 0, 0, 994, 995, 1, 0, 0, 0, 995, 993, 1, 0, 0, 0, 995, 996, 1, 0, 0, 0, 996, 160, 1, 0, 0, 0, 997, 999, 7, 13, 0, 0, 998, 1000, 7, 12, 0, 0, 999, 998, 1, 0, 0, 0, 999, 1000, 1, 0, 0, 0, 1000, 1001, 1, 0, 0, 0, 1001, 1002, 3, 155, 77, 0, 1002, 162, 1, 0, 0, 0, 1003, 1004, 5, 92, 0, 0, 1004, 1019, 7, 14, 0, 0, 1005, 1006, 5, 92, 0, 0, 1006, 1008, 3, 139, 69, 0, 1007, 1009, 3, 139, 69, 0, 1008, 1007, 1, 0, 0, 0, 1008, 1009, 1, 0, 0, 0, 1009, 1011, 1, 0, 0, 0, 1010, 1012, 3, 139, 69, 0, 1011, 1010, 1, 0, 0, 0, 1011, 1012, 1, 0, 0, 0, 1012, 1019, 1, 0, 0, 0, 1013, 1014, 5, 92, 0, 0, 1014, 1015, 5, 120, 0, 0, 1015, 1016, 1, 0, 0, 0, 1016, 1019, 3, 159, 79, 0, 1017, 1019, 3, 145, 72, 0, 1018, 1003, 1, 0, 0, 0, 1018, 1005, 1, 0, 0, 0, 1018, 1013, 1, 0, 0, 0, 1018, 1017, 1, 0, 0, 0, 1019, 164, 1, 0, 0, 0, 1020, 1022, 7, 15, 0, 0, 1021, 1020, 1, 0, 0, 0, 1022, 1023, 1, 0, 0, 0, 1023, 1021, 1, 0, 0, 0, 1023, 1024, 1, 0, 0, 0, 1024, 1025, 1, 0, 0, 0, 1025, 1026, 6, 82, 0, 0, 1026, 166, 1, 0, 0, 0, 1027, 1029, 5, 13, 0, 0, 1028, 1030, 5, 10, 0, 0, 1029, 1028, 1, 0, 0, 0, 1029, 1030, 1, 0, 0, 0, 1030, 1033, 1, 0, 0, 0, 1031, 1033, 5, 10, 0, 0, 1032, 1027, 1, 0, 0, 0, 1032, 1031, 1, 0, 0, 0, 1033, 1034, 1, 0, 0, 0, 1034, 1035, 6, 83, 0, 0, 1035, 168, 1, 0, 0, 0, 66, 0, 207, 221, 243, 269, 304, 312, 328, 352, 363, 369, 374, 376, 407, 443, 479, 509, 547, 585, 611, 631, 653, 677, 699, 723, 751, 771, 800, 806, 810, 815, 817, 827, 831, 836, 839, 843, 848, 854, 859, 864, 869, 878, 887, 898, 904, 908, 914, 942, 946, 951, 957, 962, 969, 973, 980, 983, 990, 995, 999, 1008, 1011, 1018, 1023, 1029, 1032, 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 820be82be1..fbefcddabe 100644 --- a/internal/parser/planparserv2/generated/PlanLexer.tokens +++ b/internal/parser/planparserv2/generated/PlanLexer.tokens @@ -41,15 +41,22 @@ ArrayContains=40 ArrayContainsAll=41 ArrayContainsAny=42 ArrayLength=43 -BooleanConstant=44 -IntegerConstant=45 -FloatingConstant=46 -Identifier=47 -Meta=48 -StringLiteral=49 -JSONIdentifier=50 -Whitespace=51 -Newline=52 +STEuqals=44 +STTouches=45 +STOverlaps=46 +STCrosses=47 +STContains=48 +STIntersects=49 +STWithin=50 +BooleanConstant=51 +IntegerConstant=52 +FloatingConstant=53 +Identifier=54 +Meta=55 +StringLiteral=56 +JSONIdentifier=57 +Whitespace=58 +Newline=59 '('=1 ')'=2 '['=3 @@ -75,4 +82,4 @@ Newline=52 '|'=27 '^'=28 '~'=33 -'$meta'=48 +'$meta'=55 diff --git a/internal/parser/planparserv2/generated/plan_base_visitor.go b/internal/parser/planparserv2/generated/plan_base_visitor.go index 2c7fa5aaa2..792ad5d072 100644 --- a/internal/parser/planparserv2/generated/plan_base_visitor.go +++ b/internal/parser/planparserv2/generated/plan_base_visitor.go @@ -43,6 +43,10 @@ func (v *BasePlanVisitor) VisitIdentifier(ctx *IdentifierContext) interface{} { return v.VisitChildren(ctx) } +func (v *BasePlanVisitor) VisitSTIntersects(ctx *STIntersectsContext) interface{} { + return v.VisitChildren(ctx) +} + func (v *BasePlanVisitor) VisitLike(ctx *LikeContext) interface{} { return v.VisitChildren(ctx) } @@ -71,6 +75,10 @@ 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) } @@ -103,6 +111,14 @@ 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) } @@ -111,6 +127,10 @@ func (v *BasePlanVisitor) VisitJSONContains(ctx *JSONContainsContext) interface{ return v.VisitChildren(ctx) } +func (v *BasePlanVisitor) VisitSTWithin(ctx *STWithinContext) interface{} { + return v.VisitChildren(ctx) +} + func (v *BasePlanVisitor) VisitRange(ctx *RangeContext) interface{} { return v.VisitChildren(ctx) } @@ -143,6 +163,10 @@ func (v *BasePlanVisitor) VisitBitAnd(ctx *BitAndContext) interface{} { return v.VisitChildren(ctx) } +func (v *BasePlanVisitor) VisitSTEuqals(ctx *STEuqalsContext) interface{} { + return v.VisitChildren(ctx) +} + func (v *BasePlanVisitor) VisitIsNull(ctx *IsNullContext) interface{} { return v.VisitChildren(ctx) } @@ -150,3 +174,7 @@ func (v *BasePlanVisitor) VisitIsNull(ctx *IsNullContext) interface{} { func (v *BasePlanVisitor) VisitPower(ctx *PowerContext) interface{} { return v.VisitChildren(ctx) } + +func (v *BasePlanVisitor) VisitSTOverlaps(ctx *STOverlapsContext) interface{} { + return v.VisitChildren(ctx) +} diff --git a/internal/parser/planparserv2/generated/plan_lexer.go b/internal/parser/planparserv2/generated/plan_lexer.go index 9c916d8c75..d585a4b210 100644 --- a/internal/parser/planparserv2/generated/plan_lexer.go +++ b/internal/parser/planparserv2/generated/plan_lexer.go @@ -46,7 +46,8 @@ func planlexerLexerInit() { "", "'('", "')'", "'['", "','", "']'", "'{'", "'}'", "'<'", "'<='", "'>'", "'>='", "'=='", "'!='", "", "", "", "", "'+'", "'-'", "'*'", "'/'", "'%'", "'**'", "'<<'", "'>>'", "'&'", "'|'", "'^'", "", "", "", - "", "'~'", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "'$meta'", + "", "'~'", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "'$meta'", } staticData.SymbolicNames = []string{ "", "", "", "", "", "", "LBRACE", "RBRACE", "LT", "LE", "GT", "GE", @@ -54,9 +55,10 @@ func planlexerLexerInit() { "MUL", "DIV", "MOD", "POW", "SHL", "SHR", "BAND", "BOR", "BXOR", "AND", "OR", "ISNULL", "ISNOTNULL", "BNOT", "NOT", "IN", "EmptyArray", "JSONContains", "JSONContainsAll", "JSONContainsAny", "ArrayContains", "ArrayContainsAll", - "ArrayContainsAny", "ArrayLength", "BooleanConstant", "IntegerConstant", - "FloatingConstant", "Identifier", "Meta", "StringLiteral", "JSONIdentifier", - "Whitespace", "Newline", + "ArrayContainsAny", "ArrayLength", "STEuqals", "STTouches", "STOverlaps", + "STCrosses", "STContains", "STIntersects", "STWithin", "BooleanConstant", + "IntegerConstant", "FloatingConstant", "Identifier", "Meta", "StringLiteral", + "JSONIdentifier", "Whitespace", "Newline", } staticData.RuleNames = []string{ "T__0", "T__1", "T__2", "T__3", "T__4", "LBRACE", "RBRACE", "LT", "LE", @@ -64,408 +66,487 @@ 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", "BooleanConstant", - "IntegerConstant", "FloatingConstant", "Identifier", "Meta", "StringLiteral", - "JSONIdentifier", "EncodingPrefix", "DoubleSCharSequence", "SingleSCharSequence", - "DoubleSChar", "SingleSChar", "Nondigit", "Digit", "BinaryConstant", - "DecimalConstant", "OctalConstant", "HexadecimalConstant", "NonzeroDigit", - "OctalDigit", "HexadecimalDigit", "HexQuad", "UniversalCharacterName", + "ArrayContainsAll", "ArrayContainsAny", "ArrayLength", "STEuqals", "STTouches", + "STOverlaps", "STCrosses", "STContains", "STIntersects", "STWithin", + "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", } staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ - 4, 0, 52, 862, 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, 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, 194, 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, 208, 8, 14, 1, 15, 1, + 4, 0, 59, 1036, 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, 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, 208, 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, 222, + 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, - 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 230, 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, 256, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, - 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 23, 1, - 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, - 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 3, 28, 291, 8, - 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 299, 8, 29, 1, 30, - 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, - 30, 1, 30, 1, 30, 3, 30, 315, 8, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, + 3, 15, 244, 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, 270, 8, 16, 1, 17, 1, + 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, + 1, 22, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, + 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, + 3, 28, 305, 8, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 313, + 8, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, + 30, 1, 30, 1, 30, 1, 30, 1, 30, 3, 30, 329, 8, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, - 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 339, 8, 31, 1, 32, - 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 350, 8, - 33, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 356, 8, 34, 1, 35, 1, 35, 1, 35, - 5, 35, 361, 8, 35, 10, 35, 12, 35, 364, 9, 35, 1, 35, 1, 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, + 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 353, + 8, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, + 33, 364, 8, 33, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 370, 8, 34, 1, 35, 1, + 35, 1, 35, 5, 35, 375, 8, 35, 10, 35, 12, 35, 378, 9, 35, 1, 35, 1, 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, 3, 36, 394, 8, 36, 1, 37, 1, 37, 1, 37, 1, 37, + 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, 408, 8, 36, 1, 37, 1, 37, 1, + 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, - 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 3, 37, 430, - 8, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, + 3, 37, 444, 8, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, - 38, 1, 38, 1, 38, 1, 38, 3, 38, 466, 8, 38, 1, 39, 1, 39, 1, 39, 1, 39, + 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 480, 8, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, - 1, 39, 1, 39, 1, 39, 3, 39, 496, 8, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, + 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 510, 8, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, - 3, 40, 534, 8, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, + 1, 40, 1, 40, 3, 40, 548, 8, 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, 1, - 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 572, 8, 41, - 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, + 586, 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, 3, 42, 598, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, + 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 612, 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, 3, 43, 627, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 633, 8, - 44, 1, 45, 1, 45, 3, 45, 637, 8, 45, 1, 46, 1, 46, 1, 46, 5, 46, 642, 8, - 46, 10, 46, 12, 46, 645, 9, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, - 1, 48, 3, 48, 654, 8, 48, 1, 48, 1, 48, 3, 48, 658, 8, 48, 1, 48, 1, 48, - 1, 48, 3, 48, 663, 8, 48, 1, 48, 3, 48, 666, 8, 48, 1, 49, 1, 49, 3, 49, - 670, 8, 49, 1, 49, 1, 49, 1, 49, 3, 49, 675, 8, 49, 1, 49, 1, 49, 4, 49, - 679, 8, 49, 11, 49, 12, 49, 680, 1, 50, 1, 50, 1, 50, 3, 50, 686, 8, 50, - 1, 51, 4, 51, 689, 8, 51, 11, 51, 12, 51, 690, 1, 52, 4, 52, 694, 8, 52, - 11, 52, 12, 52, 695, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, - 53, 705, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, - 714, 8, 54, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 4, 57, 723, - 8, 57, 11, 57, 12, 57, 724, 1, 58, 1, 58, 5, 58, 729, 8, 58, 10, 58, 12, - 58, 732, 9, 58, 1, 58, 3, 58, 735, 8, 58, 1, 59, 1, 59, 5, 59, 739, 8, - 59, 10, 59, 12, 59, 742, 9, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, - 1, 62, 1, 62, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, - 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 769, - 8, 65, 1, 66, 1, 66, 3, 66, 773, 8, 66, 1, 66, 1, 66, 1, 66, 3, 66, 778, - 8, 66, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 784, 8, 67, 1, 67, 1, 67, 1, - 68, 3, 68, 789, 8, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 796, 8, - 68, 1, 69, 1, 69, 3, 69, 800, 8, 69, 1, 69, 1, 69, 1, 70, 4, 70, 805, 8, - 70, 11, 70, 12, 70, 806, 1, 71, 3, 71, 810, 8, 71, 1, 71, 1, 71, 1, 71, - 1, 71, 1, 71, 3, 71, 817, 8, 71, 1, 72, 4, 72, 820, 8, 72, 11, 72, 12, - 72, 821, 1, 73, 1, 73, 3, 73, 826, 8, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, - 74, 1, 74, 1, 74, 3, 74, 835, 8, 74, 1, 74, 3, 74, 838, 8, 74, 1, 74, 1, - 74, 1, 74, 1, 74, 1, 74, 3, 74, 845, 8, 74, 1, 75, 4, 75, 848, 8, 75, 11, - 75, 12, 75, 849, 1, 75, 1, 75, 1, 76, 1, 76, 3, 76, 856, 8, 76, 1, 76, - 3, 76, 859, 8, 76, 1, 76, 1, 76, 0, 0, 77, 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, - 0, 103, 0, 105, 0, 107, 0, 109, 0, 111, 0, 113, 0, 115, 0, 117, 0, 119, - 0, 121, 0, 123, 0, 125, 0, 127, 0, 129, 0, 131, 0, 133, 0, 135, 0, 137, - 0, 139, 0, 141, 0, 143, 0, 145, 0, 147, 0, 149, 0, 151, 51, 153, 52, 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, 909, 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, 151, 1, 0, 0, 0, 0, 153, 1, 0, 0, - 0, 1, 155, 1, 0, 0, 0, 3, 157, 1, 0, 0, 0, 5, 159, 1, 0, 0, 0, 7, 161, - 1, 0, 0, 0, 9, 163, 1, 0, 0, 0, 11, 165, 1, 0, 0, 0, 13, 167, 1, 0, 0, - 0, 15, 169, 1, 0, 0, 0, 17, 171, 1, 0, 0, 0, 19, 174, 1, 0, 0, 0, 21, 176, - 1, 0, 0, 0, 23, 179, 1, 0, 0, 0, 25, 182, 1, 0, 0, 0, 27, 193, 1, 0, 0, - 0, 29, 207, 1, 0, 0, 0, 31, 229, 1, 0, 0, 0, 33, 255, 1, 0, 0, 0, 35, 257, - 1, 0, 0, 0, 37, 259, 1, 0, 0, 0, 39, 261, 1, 0, 0, 0, 41, 263, 1, 0, 0, - 0, 43, 265, 1, 0, 0, 0, 45, 267, 1, 0, 0, 0, 47, 270, 1, 0, 0, 0, 49, 273, - 1, 0, 0, 0, 51, 276, 1, 0, 0, 0, 53, 278, 1, 0, 0, 0, 55, 280, 1, 0, 0, - 0, 57, 290, 1, 0, 0, 0, 59, 298, 1, 0, 0, 0, 61, 314, 1, 0, 0, 0, 63, 338, - 1, 0, 0, 0, 65, 340, 1, 0, 0, 0, 67, 349, 1, 0, 0, 0, 69, 355, 1, 0, 0, - 0, 71, 357, 1, 0, 0, 0, 73, 393, 1, 0, 0, 0, 75, 429, 1, 0, 0, 0, 77, 465, - 1, 0, 0, 0, 79, 495, 1, 0, 0, 0, 81, 533, 1, 0, 0, 0, 83, 571, 1, 0, 0, - 0, 85, 597, 1, 0, 0, 0, 87, 626, 1, 0, 0, 0, 89, 632, 1, 0, 0, 0, 91, 636, - 1, 0, 0, 0, 93, 638, 1, 0, 0, 0, 95, 646, 1, 0, 0, 0, 97, 653, 1, 0, 0, - 0, 99, 669, 1, 0, 0, 0, 101, 685, 1, 0, 0, 0, 103, 688, 1, 0, 0, 0, 105, - 693, 1, 0, 0, 0, 107, 704, 1, 0, 0, 0, 109, 713, 1, 0, 0, 0, 111, 715, - 1, 0, 0, 0, 113, 717, 1, 0, 0, 0, 115, 719, 1, 0, 0, 0, 117, 734, 1, 0, - 0, 0, 119, 736, 1, 0, 0, 0, 121, 743, 1, 0, 0, 0, 123, 747, 1, 0, 0, 0, - 125, 749, 1, 0, 0, 0, 127, 751, 1, 0, 0, 0, 129, 753, 1, 0, 0, 0, 131, - 768, 1, 0, 0, 0, 133, 777, 1, 0, 0, 0, 135, 779, 1, 0, 0, 0, 137, 795, - 1, 0, 0, 0, 139, 797, 1, 0, 0, 0, 141, 804, 1, 0, 0, 0, 143, 816, 1, 0, - 0, 0, 145, 819, 1, 0, 0, 0, 147, 823, 1, 0, 0, 0, 149, 844, 1, 0, 0, 0, - 151, 847, 1, 0, 0, 0, 153, 858, 1, 0, 0, 0, 155, 156, 5, 40, 0, 0, 156, - 2, 1, 0, 0, 0, 157, 158, 5, 41, 0, 0, 158, 4, 1, 0, 0, 0, 159, 160, 5, - 91, 0, 0, 160, 6, 1, 0, 0, 0, 161, 162, 5, 44, 0, 0, 162, 8, 1, 0, 0, 0, - 163, 164, 5, 93, 0, 0, 164, 10, 1, 0, 0, 0, 165, 166, 5, 123, 0, 0, 166, - 12, 1, 0, 0, 0, 167, 168, 5, 125, 0, 0, 168, 14, 1, 0, 0, 0, 169, 170, - 5, 60, 0, 0, 170, 16, 1, 0, 0, 0, 171, 172, 5, 60, 0, 0, 172, 173, 5, 61, - 0, 0, 173, 18, 1, 0, 0, 0, 174, 175, 5, 62, 0, 0, 175, 20, 1, 0, 0, 0, - 176, 177, 5, 62, 0, 0, 177, 178, 5, 61, 0, 0, 178, 22, 1, 0, 0, 0, 179, - 180, 5, 61, 0, 0, 180, 181, 5, 61, 0, 0, 181, 24, 1, 0, 0, 0, 182, 183, - 5, 33, 0, 0, 183, 184, 5, 61, 0, 0, 184, 26, 1, 0, 0, 0, 185, 186, 5, 108, - 0, 0, 186, 187, 5, 105, 0, 0, 187, 188, 5, 107, 0, 0, 188, 194, 5, 101, - 0, 0, 189, 190, 5, 76, 0, 0, 190, 191, 5, 73, 0, 0, 191, 192, 5, 75, 0, - 0, 192, 194, 5, 69, 0, 0, 193, 185, 1, 0, 0, 0, 193, 189, 1, 0, 0, 0, 194, - 28, 1, 0, 0, 0, 195, 196, 5, 101, 0, 0, 196, 197, 5, 120, 0, 0, 197, 198, - 5, 105, 0, 0, 198, 199, 5, 115, 0, 0, 199, 200, 5, 116, 0, 0, 200, 208, - 5, 115, 0, 0, 201, 202, 5, 69, 0, 0, 202, 203, 5, 88, 0, 0, 203, 204, 5, - 73, 0, 0, 204, 205, 5, 83, 0, 0, 205, 206, 5, 84, 0, 0, 206, 208, 5, 83, - 0, 0, 207, 195, 1, 0, 0, 0, 207, 201, 1, 0, 0, 0, 208, 30, 1, 0, 0, 0, - 209, 210, 5, 116, 0, 0, 210, 211, 5, 101, 0, 0, 211, 212, 5, 120, 0, 0, - 212, 213, 5, 116, 0, 0, 213, 214, 5, 95, 0, 0, 214, 215, 5, 109, 0, 0, - 215, 216, 5, 97, 0, 0, 216, 217, 5, 116, 0, 0, 217, 218, 5, 99, 0, 0, 218, - 230, 5, 104, 0, 0, 219, 220, 5, 84, 0, 0, 220, 221, 5, 69, 0, 0, 221, 222, - 5, 88, 0, 0, 222, 223, 5, 84, 0, 0, 223, 224, 5, 95, 0, 0, 224, 225, 5, - 77, 0, 0, 225, 226, 5, 65, 0, 0, 226, 227, 5, 84, 0, 0, 227, 228, 5, 67, - 0, 0, 228, 230, 5, 72, 0, 0, 229, 209, 1, 0, 0, 0, 229, 219, 1, 0, 0, 0, - 230, 32, 1, 0, 0, 0, 231, 232, 5, 112, 0, 0, 232, 233, 5, 104, 0, 0, 233, - 234, 5, 114, 0, 0, 234, 235, 5, 97, 0, 0, 235, 236, 5, 115, 0, 0, 236, - 237, 5, 101, 0, 0, 237, 238, 5, 95, 0, 0, 238, 239, 5, 109, 0, 0, 239, - 240, 5, 97, 0, 0, 240, 241, 5, 116, 0, 0, 241, 242, 5, 99, 0, 0, 242, 256, - 5, 104, 0, 0, 243, 244, 5, 80, 0, 0, 244, 245, 5, 72, 0, 0, 245, 246, 5, - 82, 0, 0, 246, 247, 5, 65, 0, 0, 247, 248, 5, 83, 0, 0, 248, 249, 5, 69, - 0, 0, 249, 250, 5, 95, 0, 0, 250, 251, 5, 77, 0, 0, 251, 252, 5, 65, 0, - 0, 252, 253, 5, 84, 0, 0, 253, 254, 5, 67, 0, 0, 254, 256, 5, 72, 0, 0, - 255, 231, 1, 0, 0, 0, 255, 243, 1, 0, 0, 0, 256, 34, 1, 0, 0, 0, 257, 258, - 5, 43, 0, 0, 258, 36, 1, 0, 0, 0, 259, 260, 5, 45, 0, 0, 260, 38, 1, 0, - 0, 0, 261, 262, 5, 42, 0, 0, 262, 40, 1, 0, 0, 0, 263, 264, 5, 47, 0, 0, - 264, 42, 1, 0, 0, 0, 265, 266, 5, 37, 0, 0, 266, 44, 1, 0, 0, 0, 267, 268, - 5, 42, 0, 0, 268, 269, 5, 42, 0, 0, 269, 46, 1, 0, 0, 0, 270, 271, 5, 60, - 0, 0, 271, 272, 5, 60, 0, 0, 272, 48, 1, 0, 0, 0, 273, 274, 5, 62, 0, 0, - 274, 275, 5, 62, 0, 0, 275, 50, 1, 0, 0, 0, 276, 277, 5, 38, 0, 0, 277, - 52, 1, 0, 0, 0, 278, 279, 5, 124, 0, 0, 279, 54, 1, 0, 0, 0, 280, 281, - 5, 94, 0, 0, 281, 56, 1, 0, 0, 0, 282, 283, 5, 38, 0, 0, 283, 291, 5, 38, - 0, 0, 284, 285, 5, 97, 0, 0, 285, 286, 5, 110, 0, 0, 286, 291, 5, 100, - 0, 0, 287, 288, 5, 65, 0, 0, 288, 289, 5, 78, 0, 0, 289, 291, 5, 68, 0, - 0, 290, 282, 1, 0, 0, 0, 290, 284, 1, 0, 0, 0, 290, 287, 1, 0, 0, 0, 291, - 58, 1, 0, 0, 0, 292, 293, 5, 124, 0, 0, 293, 299, 5, 124, 0, 0, 294, 295, - 5, 111, 0, 0, 295, 299, 5, 114, 0, 0, 296, 297, 5, 79, 0, 0, 297, 299, - 5, 82, 0, 0, 298, 292, 1, 0, 0, 0, 298, 294, 1, 0, 0, 0, 298, 296, 1, 0, - 0, 0, 299, 60, 1, 0, 0, 0, 300, 301, 5, 105, 0, 0, 301, 302, 5, 115, 0, - 0, 302, 303, 5, 32, 0, 0, 303, 304, 5, 110, 0, 0, 304, 305, 5, 117, 0, - 0, 305, 306, 5, 108, 0, 0, 306, 315, 5, 108, 0, 0, 307, 308, 5, 73, 0, - 0, 308, 309, 5, 83, 0, 0, 309, 310, 5, 32, 0, 0, 310, 311, 5, 78, 0, 0, - 311, 312, 5, 85, 0, 0, 312, 313, 5, 76, 0, 0, 313, 315, 5, 76, 0, 0, 314, - 300, 1, 0, 0, 0, 314, 307, 1, 0, 0, 0, 315, 62, 1, 0, 0, 0, 316, 317, 5, - 105, 0, 0, 317, 318, 5, 115, 0, 0, 318, 319, 5, 32, 0, 0, 319, 320, 5, - 110, 0, 0, 320, 321, 5, 111, 0, 0, 321, 322, 5, 116, 0, 0, 322, 323, 5, - 32, 0, 0, 323, 324, 5, 110, 0, 0, 324, 325, 5, 117, 0, 0, 325, 326, 5, - 108, 0, 0, 326, 339, 5, 108, 0, 0, 327, 328, 5, 73, 0, 0, 328, 329, 5, - 83, 0, 0, 329, 330, 5, 32, 0, 0, 330, 331, 5, 78, 0, 0, 331, 332, 5, 79, - 0, 0, 332, 333, 5, 84, 0, 0, 333, 334, 5, 32, 0, 0, 334, 335, 5, 78, 0, - 0, 335, 336, 5, 85, 0, 0, 336, 337, 5, 76, 0, 0, 337, 339, 5, 76, 0, 0, - 338, 316, 1, 0, 0, 0, 338, 327, 1, 0, 0, 0, 339, 64, 1, 0, 0, 0, 340, 341, - 5, 126, 0, 0, 341, 66, 1, 0, 0, 0, 342, 350, 5, 33, 0, 0, 343, 344, 5, - 110, 0, 0, 344, 345, 5, 111, 0, 0, 345, 350, 5, 116, 0, 0, 346, 347, 5, - 78, 0, 0, 347, 348, 5, 79, 0, 0, 348, 350, 5, 84, 0, 0, 349, 342, 1, 0, - 0, 0, 349, 343, 1, 0, 0, 0, 349, 346, 1, 0, 0, 0, 350, 68, 1, 0, 0, 0, - 351, 352, 5, 105, 0, 0, 352, 356, 5, 110, 0, 0, 353, 354, 5, 73, 0, 0, - 354, 356, 5, 78, 0, 0, 355, 351, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 356, - 70, 1, 0, 0, 0, 357, 362, 5, 91, 0, 0, 358, 361, 3, 151, 75, 0, 359, 361, - 3, 153, 76, 0, 360, 358, 1, 0, 0, 0, 360, 359, 1, 0, 0, 0, 361, 364, 1, - 0, 0, 0, 362, 360, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, 365, 1, 0, 0, - 0, 364, 362, 1, 0, 0, 0, 365, 366, 5, 93, 0, 0, 366, 72, 1, 0, 0, 0, 367, - 368, 5, 106, 0, 0, 368, 369, 5, 115, 0, 0, 369, 370, 5, 111, 0, 0, 370, - 371, 5, 110, 0, 0, 371, 372, 5, 95, 0, 0, 372, 373, 5, 99, 0, 0, 373, 374, - 5, 111, 0, 0, 374, 375, 5, 110, 0, 0, 375, 376, 5, 116, 0, 0, 376, 377, - 5, 97, 0, 0, 377, 378, 5, 105, 0, 0, 378, 379, 5, 110, 0, 0, 379, 394, - 5, 115, 0, 0, 380, 381, 5, 74, 0, 0, 381, 382, 5, 83, 0, 0, 382, 383, 5, - 79, 0, 0, 383, 384, 5, 78, 0, 0, 384, 385, 5, 95, 0, 0, 385, 386, 5, 67, - 0, 0, 386, 387, 5, 79, 0, 0, 387, 388, 5, 78, 0, 0, 388, 389, 5, 84, 0, - 0, 389, 390, 5, 65, 0, 0, 390, 391, 5, 73, 0, 0, 391, 392, 5, 78, 0, 0, - 392, 394, 5, 83, 0, 0, 393, 367, 1, 0, 0, 0, 393, 380, 1, 0, 0, 0, 394, - 74, 1, 0, 0, 0, 395, 396, 5, 106, 0, 0, 396, 397, 5, 115, 0, 0, 397, 398, - 5, 111, 0, 0, 398, 399, 5, 110, 0, 0, 399, 400, 5, 95, 0, 0, 400, 401, - 5, 99, 0, 0, 401, 402, 5, 111, 0, 0, 402, 403, 5, 110, 0, 0, 403, 404, - 5, 116, 0, 0, 404, 405, 5, 97, 0, 0, 405, 406, 5, 105, 0, 0, 406, 407, - 5, 110, 0, 0, 407, 408, 5, 115, 0, 0, 408, 409, 5, 95, 0, 0, 409, 410, - 5, 97, 0, 0, 410, 411, 5, 108, 0, 0, 411, 430, 5, 108, 0, 0, 412, 413, - 5, 74, 0, 0, 413, 414, 5, 83, 0, 0, 414, 415, 5, 79, 0, 0, 415, 416, 5, - 78, 0, 0, 416, 417, 5, 95, 0, 0, 417, 418, 5, 67, 0, 0, 418, 419, 5, 79, - 0, 0, 419, 420, 5, 78, 0, 0, 420, 421, 5, 84, 0, 0, 421, 422, 5, 65, 0, - 0, 422, 423, 5, 73, 0, 0, 423, 424, 5, 78, 0, 0, 424, 425, 5, 83, 0, 0, - 425, 426, 5, 95, 0, 0, 426, 427, 5, 65, 0, 0, 427, 428, 5, 76, 0, 0, 428, - 430, 5, 76, 0, 0, 429, 395, 1, 0, 0, 0, 429, 412, 1, 0, 0, 0, 430, 76, - 1, 0, 0, 0, 431, 432, 5, 106, 0, 0, 432, 433, 5, 115, 0, 0, 433, 434, 5, - 111, 0, 0, 434, 435, 5, 110, 0, 0, 435, 436, 5, 95, 0, 0, 436, 437, 5, - 99, 0, 0, 437, 438, 5, 111, 0, 0, 438, 439, 5, 110, 0, 0, 439, 440, 5, - 116, 0, 0, 440, 441, 5, 97, 0, 0, 441, 442, 5, 105, 0, 0, 442, 443, 5, - 110, 0, 0, 443, 444, 5, 115, 0, 0, 444, 445, 5, 95, 0, 0, 445, 446, 5, - 97, 0, 0, 446, 447, 5, 110, 0, 0, 447, 466, 5, 121, 0, 0, 448, 449, 5, - 74, 0, 0, 449, 450, 5, 83, 0, 0, 450, 451, 5, 79, 0, 0, 451, 452, 5, 78, - 0, 0, 452, 453, 5, 95, 0, 0, 453, 454, 5, 67, 0, 0, 454, 455, 5, 79, 0, - 0, 455, 456, 5, 78, 0, 0, 456, 457, 5, 84, 0, 0, 457, 458, 5, 65, 0, 0, - 458, 459, 5, 73, 0, 0, 459, 460, 5, 78, 0, 0, 460, 461, 5, 83, 0, 0, 461, - 462, 5, 95, 0, 0, 462, 463, 5, 65, 0, 0, 463, 464, 5, 78, 0, 0, 464, 466, - 5, 89, 0, 0, 465, 431, 1, 0, 0, 0, 465, 448, 1, 0, 0, 0, 466, 78, 1, 0, - 0, 0, 467, 468, 5, 97, 0, 0, 468, 469, 5, 114, 0, 0, 469, 470, 5, 114, - 0, 0, 470, 471, 5, 97, 0, 0, 471, 472, 5, 121, 0, 0, 472, 473, 5, 95, 0, - 0, 473, 474, 5, 99, 0, 0, 474, 475, 5, 111, 0, 0, 475, 476, 5, 110, 0, - 0, 476, 477, 5, 116, 0, 0, 477, 478, 5, 97, 0, 0, 478, 479, 5, 105, 0, - 0, 479, 480, 5, 110, 0, 0, 480, 496, 5, 115, 0, 0, 481, 482, 5, 65, 0, - 0, 482, 483, 5, 82, 0, 0, 483, 484, 5, 82, 0, 0, 484, 485, 5, 65, 0, 0, - 485, 486, 5, 89, 0, 0, 486, 487, 5, 95, 0, 0, 487, 488, 5, 67, 0, 0, 488, - 489, 5, 79, 0, 0, 489, 490, 5, 78, 0, 0, 490, 491, 5, 84, 0, 0, 491, 492, - 5, 65, 0, 0, 492, 493, 5, 73, 0, 0, 493, 494, 5, 78, 0, 0, 494, 496, 5, - 83, 0, 0, 495, 467, 1, 0, 0, 0, 495, 481, 1, 0, 0, 0, 496, 80, 1, 0, 0, - 0, 497, 498, 5, 97, 0, 0, 498, 499, 5, 114, 0, 0, 499, 500, 5, 114, 0, - 0, 500, 501, 5, 97, 0, 0, 501, 502, 5, 121, 0, 0, 502, 503, 5, 95, 0, 0, - 503, 504, 5, 99, 0, 0, 504, 505, 5, 111, 0, 0, 505, 506, 5, 110, 0, 0, - 506, 507, 5, 116, 0, 0, 507, 508, 5, 97, 0, 0, 508, 509, 5, 105, 0, 0, - 509, 510, 5, 110, 0, 0, 510, 511, 5, 115, 0, 0, 511, 512, 5, 95, 0, 0, - 512, 513, 5, 97, 0, 0, 513, 514, 5, 108, 0, 0, 514, 534, 5, 108, 0, 0, - 515, 516, 5, 65, 0, 0, 516, 517, 5, 82, 0, 0, 517, 518, 5, 82, 0, 0, 518, - 519, 5, 65, 0, 0, 519, 520, 5, 89, 0, 0, 520, 521, 5, 95, 0, 0, 521, 522, - 5, 67, 0, 0, 522, 523, 5, 79, 0, 0, 523, 524, 5, 78, 0, 0, 524, 525, 5, - 84, 0, 0, 525, 526, 5, 65, 0, 0, 526, 527, 5, 73, 0, 0, 527, 528, 5, 78, - 0, 0, 528, 529, 5, 83, 0, 0, 529, 530, 5, 95, 0, 0, 530, 531, 5, 65, 0, - 0, 531, 532, 5, 76, 0, 0, 532, 534, 5, 76, 0, 0, 533, 497, 1, 0, 0, 0, - 533, 515, 1, 0, 0, 0, 534, 82, 1, 0, 0, 0, 535, 536, 5, 97, 0, 0, 536, - 537, 5, 114, 0, 0, 537, 538, 5, 114, 0, 0, 538, 539, 5, 97, 0, 0, 539, - 540, 5, 121, 0, 0, 540, 541, 5, 95, 0, 0, 541, 542, 5, 99, 0, 0, 542, 543, - 5, 111, 0, 0, 543, 544, 5, 110, 0, 0, 544, 545, 5, 116, 0, 0, 545, 546, - 5, 97, 0, 0, 546, 547, 5, 105, 0, 0, 547, 548, 5, 110, 0, 0, 548, 549, - 5, 115, 0, 0, 549, 550, 5, 95, 0, 0, 550, 551, 5, 97, 0, 0, 551, 552, 5, - 110, 0, 0, 552, 572, 5, 121, 0, 0, 553, 554, 5, 65, 0, 0, 554, 555, 5, - 82, 0, 0, 555, 556, 5, 82, 0, 0, 556, 557, 5, 65, 0, 0, 557, 558, 5, 89, - 0, 0, 558, 559, 5, 95, 0, 0, 559, 560, 5, 67, 0, 0, 560, 561, 5, 79, 0, - 0, 561, 562, 5, 78, 0, 0, 562, 563, 5, 84, 0, 0, 563, 564, 5, 65, 0, 0, - 564, 565, 5, 73, 0, 0, 565, 566, 5, 78, 0, 0, 566, 567, 5, 83, 0, 0, 567, - 568, 5, 95, 0, 0, 568, 569, 5, 65, 0, 0, 569, 570, 5, 78, 0, 0, 570, 572, - 5, 89, 0, 0, 571, 535, 1, 0, 0, 0, 571, 553, 1, 0, 0, 0, 572, 84, 1, 0, - 0, 0, 573, 574, 5, 97, 0, 0, 574, 575, 5, 114, 0, 0, 575, 576, 5, 114, - 0, 0, 576, 577, 5, 97, 0, 0, 577, 578, 5, 121, 0, 0, 578, 579, 5, 95, 0, - 0, 579, 580, 5, 108, 0, 0, 580, 581, 5, 101, 0, 0, 581, 582, 5, 110, 0, - 0, 582, 583, 5, 103, 0, 0, 583, 584, 5, 116, 0, 0, 584, 598, 5, 104, 0, - 0, 585, 586, 5, 65, 0, 0, 586, 587, 5, 82, 0, 0, 587, 588, 5, 82, 0, 0, - 588, 589, 5, 65, 0, 0, 589, 590, 5, 89, 0, 0, 590, 591, 5, 95, 0, 0, 591, - 592, 5, 76, 0, 0, 592, 593, 5, 69, 0, 0, 593, 594, 5, 78, 0, 0, 594, 595, - 5, 71, 0, 0, 595, 596, 5, 84, 0, 0, 596, 598, 5, 72, 0, 0, 597, 573, 1, - 0, 0, 0, 597, 585, 1, 0, 0, 0, 598, 86, 1, 0, 0, 0, 599, 600, 5, 116, 0, - 0, 600, 601, 5, 114, 0, 0, 601, 602, 5, 117, 0, 0, 602, 627, 5, 101, 0, - 0, 603, 604, 5, 84, 0, 0, 604, 605, 5, 114, 0, 0, 605, 606, 5, 117, 0, - 0, 606, 627, 5, 101, 0, 0, 607, 608, 5, 84, 0, 0, 608, 609, 5, 82, 0, 0, - 609, 610, 5, 85, 0, 0, 610, 627, 5, 69, 0, 0, 611, 612, 5, 102, 0, 0, 612, - 613, 5, 97, 0, 0, 613, 614, 5, 108, 0, 0, 614, 615, 5, 115, 0, 0, 615, - 627, 5, 101, 0, 0, 616, 617, 5, 70, 0, 0, 617, 618, 5, 97, 0, 0, 618, 619, - 5, 108, 0, 0, 619, 620, 5, 115, 0, 0, 620, 627, 5, 101, 0, 0, 621, 622, - 5, 70, 0, 0, 622, 623, 5, 65, 0, 0, 623, 624, 5, 76, 0, 0, 624, 625, 5, - 83, 0, 0, 625, 627, 5, 69, 0, 0, 626, 599, 1, 0, 0, 0, 626, 603, 1, 0, - 0, 0, 626, 607, 1, 0, 0, 0, 626, 611, 1, 0, 0, 0, 626, 616, 1, 0, 0, 0, - 626, 621, 1, 0, 0, 0, 627, 88, 1, 0, 0, 0, 628, 633, 3, 117, 58, 0, 629, - 633, 3, 119, 59, 0, 630, 633, 3, 121, 60, 0, 631, 633, 3, 115, 57, 0, 632, - 628, 1, 0, 0, 0, 632, 629, 1, 0, 0, 0, 632, 630, 1, 0, 0, 0, 632, 631, - 1, 0, 0, 0, 633, 90, 1, 0, 0, 0, 634, 637, 3, 133, 66, 0, 635, 637, 3, - 135, 67, 0, 636, 634, 1, 0, 0, 0, 636, 635, 1, 0, 0, 0, 637, 92, 1, 0, - 0, 0, 638, 643, 3, 111, 55, 0, 639, 642, 3, 111, 55, 0, 640, 642, 3, 113, - 56, 0, 641, 639, 1, 0, 0, 0, 641, 640, 1, 0, 0, 0, 642, 645, 1, 0, 0, 0, - 643, 641, 1, 0, 0, 0, 643, 644, 1, 0, 0, 0, 644, 94, 1, 0, 0, 0, 645, 643, - 1, 0, 0, 0, 646, 647, 5, 36, 0, 0, 647, 648, 5, 109, 0, 0, 648, 649, 5, - 101, 0, 0, 649, 650, 5, 116, 0, 0, 650, 651, 5, 97, 0, 0, 651, 96, 1, 0, - 0, 0, 652, 654, 3, 101, 50, 0, 653, 652, 1, 0, 0, 0, 653, 654, 1, 0, 0, - 0, 654, 665, 1, 0, 0, 0, 655, 657, 5, 34, 0, 0, 656, 658, 3, 103, 51, 0, - 657, 656, 1, 0, 0, 0, 657, 658, 1, 0, 0, 0, 658, 659, 1, 0, 0, 0, 659, - 666, 5, 34, 0, 0, 660, 662, 5, 39, 0, 0, 661, 663, 3, 105, 52, 0, 662, - 661, 1, 0, 0, 0, 662, 663, 1, 0, 0, 0, 663, 664, 1, 0, 0, 0, 664, 666, - 5, 39, 0, 0, 665, 655, 1, 0, 0, 0, 665, 660, 1, 0, 0, 0, 666, 98, 1, 0, - 0, 0, 667, 670, 3, 93, 46, 0, 668, 670, 3, 95, 47, 0, 669, 667, 1, 0, 0, - 0, 669, 668, 1, 0, 0, 0, 670, 678, 1, 0, 0, 0, 671, 674, 5, 91, 0, 0, 672, - 675, 3, 97, 48, 0, 673, 675, 3, 117, 58, 0, 674, 672, 1, 0, 0, 0, 674, - 673, 1, 0, 0, 0, 675, 676, 1, 0, 0, 0, 676, 677, 5, 93, 0, 0, 677, 679, - 1, 0, 0, 0, 678, 671, 1, 0, 0, 0, 679, 680, 1, 0, 0, 0, 680, 678, 1, 0, - 0, 0, 680, 681, 1, 0, 0, 0, 681, 100, 1, 0, 0, 0, 682, 683, 5, 117, 0, - 0, 683, 686, 5, 56, 0, 0, 684, 686, 7, 0, 0, 0, 685, 682, 1, 0, 0, 0, 685, - 684, 1, 0, 0, 0, 686, 102, 1, 0, 0, 0, 687, 689, 3, 107, 53, 0, 688, 687, - 1, 0, 0, 0, 689, 690, 1, 0, 0, 0, 690, 688, 1, 0, 0, 0, 690, 691, 1, 0, - 0, 0, 691, 104, 1, 0, 0, 0, 692, 694, 3, 109, 54, 0, 693, 692, 1, 0, 0, - 0, 694, 695, 1, 0, 0, 0, 695, 693, 1, 0, 0, 0, 695, 696, 1, 0, 0, 0, 696, - 106, 1, 0, 0, 0, 697, 705, 8, 1, 0, 0, 698, 705, 3, 149, 74, 0, 699, 700, - 5, 92, 0, 0, 700, 705, 5, 10, 0, 0, 701, 702, 5, 92, 0, 0, 702, 703, 5, - 13, 0, 0, 703, 705, 5, 10, 0, 0, 704, 697, 1, 0, 0, 0, 704, 698, 1, 0, - 0, 0, 704, 699, 1, 0, 0, 0, 704, 701, 1, 0, 0, 0, 705, 108, 1, 0, 0, 0, - 706, 714, 8, 2, 0, 0, 707, 714, 3, 149, 74, 0, 708, 709, 5, 92, 0, 0, 709, - 714, 5, 10, 0, 0, 710, 711, 5, 92, 0, 0, 711, 712, 5, 13, 0, 0, 712, 714, - 5, 10, 0, 0, 713, 706, 1, 0, 0, 0, 713, 707, 1, 0, 0, 0, 713, 708, 1, 0, - 0, 0, 713, 710, 1, 0, 0, 0, 714, 110, 1, 0, 0, 0, 715, 716, 7, 3, 0, 0, - 716, 112, 1, 0, 0, 0, 717, 718, 7, 4, 0, 0, 718, 114, 1, 0, 0, 0, 719, - 720, 5, 48, 0, 0, 720, 722, 7, 5, 0, 0, 721, 723, 7, 6, 0, 0, 722, 721, - 1, 0, 0, 0, 723, 724, 1, 0, 0, 0, 724, 722, 1, 0, 0, 0, 724, 725, 1, 0, - 0, 0, 725, 116, 1, 0, 0, 0, 726, 730, 3, 123, 61, 0, 727, 729, 3, 113, - 56, 0, 728, 727, 1, 0, 0, 0, 729, 732, 1, 0, 0, 0, 730, 728, 1, 0, 0, 0, - 730, 731, 1, 0, 0, 0, 731, 735, 1, 0, 0, 0, 732, 730, 1, 0, 0, 0, 733, - 735, 5, 48, 0, 0, 734, 726, 1, 0, 0, 0, 734, 733, 1, 0, 0, 0, 735, 118, - 1, 0, 0, 0, 736, 740, 5, 48, 0, 0, 737, 739, 3, 125, 62, 0, 738, 737, 1, - 0, 0, 0, 739, 742, 1, 0, 0, 0, 740, 738, 1, 0, 0, 0, 740, 741, 1, 0, 0, - 0, 741, 120, 1, 0, 0, 0, 742, 740, 1, 0, 0, 0, 743, 744, 5, 48, 0, 0, 744, - 745, 7, 7, 0, 0, 745, 746, 3, 145, 72, 0, 746, 122, 1, 0, 0, 0, 747, 748, - 7, 8, 0, 0, 748, 124, 1, 0, 0, 0, 749, 750, 7, 9, 0, 0, 750, 126, 1, 0, - 0, 0, 751, 752, 7, 10, 0, 0, 752, 128, 1, 0, 0, 0, 753, 754, 3, 127, 63, - 0, 754, 755, 3, 127, 63, 0, 755, 756, 3, 127, 63, 0, 756, 757, 3, 127, - 63, 0, 757, 130, 1, 0, 0, 0, 758, 759, 5, 92, 0, 0, 759, 760, 5, 117, 0, - 0, 760, 761, 1, 0, 0, 0, 761, 769, 3, 129, 64, 0, 762, 763, 5, 92, 0, 0, - 763, 764, 5, 85, 0, 0, 764, 765, 1, 0, 0, 0, 765, 766, 3, 129, 64, 0, 766, - 767, 3, 129, 64, 0, 767, 769, 1, 0, 0, 0, 768, 758, 1, 0, 0, 0, 768, 762, - 1, 0, 0, 0, 769, 132, 1, 0, 0, 0, 770, 772, 3, 137, 68, 0, 771, 773, 3, - 139, 69, 0, 772, 771, 1, 0, 0, 0, 772, 773, 1, 0, 0, 0, 773, 778, 1, 0, - 0, 0, 774, 775, 3, 141, 70, 0, 775, 776, 3, 139, 69, 0, 776, 778, 1, 0, - 0, 0, 777, 770, 1, 0, 0, 0, 777, 774, 1, 0, 0, 0, 778, 134, 1, 0, 0, 0, - 779, 780, 5, 48, 0, 0, 780, 783, 7, 7, 0, 0, 781, 784, 3, 143, 71, 0, 782, - 784, 3, 145, 72, 0, 783, 781, 1, 0, 0, 0, 783, 782, 1, 0, 0, 0, 784, 785, - 1, 0, 0, 0, 785, 786, 3, 147, 73, 0, 786, 136, 1, 0, 0, 0, 787, 789, 3, - 141, 70, 0, 788, 787, 1, 0, 0, 0, 788, 789, 1, 0, 0, 0, 789, 790, 1, 0, - 0, 0, 790, 791, 5, 46, 0, 0, 791, 796, 3, 141, 70, 0, 792, 793, 3, 141, - 70, 0, 793, 794, 5, 46, 0, 0, 794, 796, 1, 0, 0, 0, 795, 788, 1, 0, 0, - 0, 795, 792, 1, 0, 0, 0, 796, 138, 1, 0, 0, 0, 797, 799, 7, 11, 0, 0, 798, - 800, 7, 12, 0, 0, 799, 798, 1, 0, 0, 0, 799, 800, 1, 0, 0, 0, 800, 801, - 1, 0, 0, 0, 801, 802, 3, 141, 70, 0, 802, 140, 1, 0, 0, 0, 803, 805, 3, - 113, 56, 0, 804, 803, 1, 0, 0, 0, 805, 806, 1, 0, 0, 0, 806, 804, 1, 0, - 0, 0, 806, 807, 1, 0, 0, 0, 807, 142, 1, 0, 0, 0, 808, 810, 3, 145, 72, - 0, 809, 808, 1, 0, 0, 0, 809, 810, 1, 0, 0, 0, 810, 811, 1, 0, 0, 0, 811, - 812, 5, 46, 0, 0, 812, 817, 3, 145, 72, 0, 813, 814, 3, 145, 72, 0, 814, - 815, 5, 46, 0, 0, 815, 817, 1, 0, 0, 0, 816, 809, 1, 0, 0, 0, 816, 813, - 1, 0, 0, 0, 817, 144, 1, 0, 0, 0, 818, 820, 3, 127, 63, 0, 819, 818, 1, - 0, 0, 0, 820, 821, 1, 0, 0, 0, 821, 819, 1, 0, 0, 0, 821, 822, 1, 0, 0, - 0, 822, 146, 1, 0, 0, 0, 823, 825, 7, 13, 0, 0, 824, 826, 7, 12, 0, 0, - 825, 824, 1, 0, 0, 0, 825, 826, 1, 0, 0, 0, 826, 827, 1, 0, 0, 0, 827, - 828, 3, 141, 70, 0, 828, 148, 1, 0, 0, 0, 829, 830, 5, 92, 0, 0, 830, 845, - 7, 14, 0, 0, 831, 832, 5, 92, 0, 0, 832, 834, 3, 125, 62, 0, 833, 835, - 3, 125, 62, 0, 834, 833, 1, 0, 0, 0, 834, 835, 1, 0, 0, 0, 835, 837, 1, - 0, 0, 0, 836, 838, 3, 125, 62, 0, 837, 836, 1, 0, 0, 0, 837, 838, 1, 0, - 0, 0, 838, 845, 1, 0, 0, 0, 839, 840, 5, 92, 0, 0, 840, 841, 5, 120, 0, - 0, 841, 842, 1, 0, 0, 0, 842, 845, 3, 145, 72, 0, 843, 845, 3, 131, 65, - 0, 844, 829, 1, 0, 0, 0, 844, 831, 1, 0, 0, 0, 844, 839, 1, 0, 0, 0, 844, - 843, 1, 0, 0, 0, 845, 150, 1, 0, 0, 0, 846, 848, 7, 15, 0, 0, 847, 846, - 1, 0, 0, 0, 848, 849, 1, 0, 0, 0, 849, 847, 1, 0, 0, 0, 849, 850, 1, 0, - 0, 0, 850, 851, 1, 0, 0, 0, 851, 852, 6, 75, 0, 0, 852, 152, 1, 0, 0, 0, - 853, 855, 5, 13, 0, 0, 854, 856, 5, 10, 0, 0, 855, 854, 1, 0, 0, 0, 855, - 856, 1, 0, 0, 0, 856, 859, 1, 0, 0, 0, 857, 859, 5, 10, 0, 0, 858, 853, - 1, 0, 0, 0, 858, 857, 1, 0, 0, 0, 859, 860, 1, 0, 0, 0, 860, 861, 6, 76, - 0, 0, 861, 154, 1, 0, 0, 0, 59, 0, 193, 207, 229, 255, 290, 298, 314, 338, - 349, 355, 360, 362, 393, 429, 465, 495, 533, 571, 597, 626, 632, 636, 641, - 643, 653, 657, 662, 665, 669, 674, 680, 685, 690, 695, 704, 713, 724, 730, - 734, 740, 768, 772, 777, 783, 788, 795, 799, 806, 809, 816, 821, 825, 834, - 837, 844, 849, 855, 858, 1, 6, 0, 0, + 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 632, 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, 3, 44, 654, 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, 3, 45, 678, 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, 3, 46, 700, 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, 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, 1, 48, 1, 48, 1, 48, 1, 48, + 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, 752, 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, 772, 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, 1, 50, 1, 50, 1, + 50, 1, 50, 1, 50, 3, 50, 801, 8, 50, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, + 807, 8, 51, 1, 52, 1, 52, 3, 52, 811, 8, 52, 1, 53, 1, 53, 1, 53, 5, 53, + 816, 8, 53, 10, 53, 12, 53, 819, 9, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, + 54, 1, 54, 1, 55, 3, 55, 828, 8, 55, 1, 55, 1, 55, 3, 55, 832, 8, 55, 1, + 55, 1, 55, 1, 55, 3, 55, 837, 8, 55, 1, 55, 3, 55, 840, 8, 55, 1, 56, 1, + 56, 3, 56, 844, 8, 56, 1, 56, 1, 56, 1, 56, 3, 56, 849, 8, 56, 1, 56, 1, + 56, 4, 56, 853, 8, 56, 11, 56, 12, 56, 854, 1, 57, 1, 57, 1, 57, 3, 57, + 860, 8, 57, 1, 58, 4, 58, 863, 8, 58, 11, 58, 12, 58, 864, 1, 59, 4, 59, + 868, 8, 59, 11, 59, 12, 59, 869, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, + 60, 1, 60, 3, 60, 879, 8, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, + 1, 61, 3, 61, 888, 8, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 64, 1, 64, 1, + 64, 4, 64, 897, 8, 64, 11, 64, 12, 64, 898, 1, 65, 1, 65, 5, 65, 903, 8, + 65, 10, 65, 12, 65, 906, 9, 65, 1, 65, 3, 65, 909, 8, 65, 1, 66, 1, 66, + 5, 66, 913, 8, 66, 10, 66, 12, 66, 916, 9, 66, 1, 67, 1, 67, 1, 67, 1, + 67, 1, 68, 1, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, + 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, + 72, 3, 72, 943, 8, 72, 1, 73, 1, 73, 3, 73, 947, 8, 73, 1, 73, 1, 73, 1, + 73, 3, 73, 952, 8, 73, 1, 74, 1, 74, 1, 74, 1, 74, 3, 74, 958, 8, 74, 1, + 74, 1, 74, 1, 75, 3, 75, 963, 8, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, + 3, 75, 970, 8, 75, 1, 76, 1, 76, 3, 76, 974, 8, 76, 1, 76, 1, 76, 1, 77, + 4, 77, 979, 8, 77, 11, 77, 12, 77, 980, 1, 78, 3, 78, 984, 8, 78, 1, 78, + 1, 78, 1, 78, 1, 78, 1, 78, 3, 78, 991, 8, 78, 1, 79, 4, 79, 994, 8, 79, + 11, 79, 12, 79, 995, 1, 80, 1, 80, 3, 80, 1000, 8, 80, 1, 80, 1, 80, 1, + 81, 1, 81, 1, 81, 1, 81, 1, 81, 3, 81, 1009, 8, 81, 1, 81, 3, 81, 1012, + 8, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 3, 81, 1019, 8, 81, 1, 82, 4, + 82, 1022, 8, 82, 11, 82, 12, 82, 1023, 1, 82, 1, 82, 1, 83, 1, 83, 3, 83, + 1030, 8, 83, 1, 83, 3, 83, 1033, 8, 83, 1, 83, 1, 83, 0, 0, 84, 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, 0, 117, 0, 119, 0, 121, 0, 123, 0, 125, 0, 127, 0, 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, 58, 167, + 59, 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, 1090, 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, 165, 1, 0, 0, 0, 0, 167, 1, + 0, 0, 0, 1, 169, 1, 0, 0, 0, 3, 171, 1, 0, 0, 0, 5, 173, 1, 0, 0, 0, 7, + 175, 1, 0, 0, 0, 9, 177, 1, 0, 0, 0, 11, 179, 1, 0, 0, 0, 13, 181, 1, 0, + 0, 0, 15, 183, 1, 0, 0, 0, 17, 185, 1, 0, 0, 0, 19, 188, 1, 0, 0, 0, 21, + 190, 1, 0, 0, 0, 23, 193, 1, 0, 0, 0, 25, 196, 1, 0, 0, 0, 27, 207, 1, + 0, 0, 0, 29, 221, 1, 0, 0, 0, 31, 243, 1, 0, 0, 0, 33, 269, 1, 0, 0, 0, + 35, 271, 1, 0, 0, 0, 37, 273, 1, 0, 0, 0, 39, 275, 1, 0, 0, 0, 41, 277, + 1, 0, 0, 0, 43, 279, 1, 0, 0, 0, 45, 281, 1, 0, 0, 0, 47, 284, 1, 0, 0, + 0, 49, 287, 1, 0, 0, 0, 51, 290, 1, 0, 0, 0, 53, 292, 1, 0, 0, 0, 55, 294, + 1, 0, 0, 0, 57, 304, 1, 0, 0, 0, 59, 312, 1, 0, 0, 0, 61, 328, 1, 0, 0, + 0, 63, 352, 1, 0, 0, 0, 65, 354, 1, 0, 0, 0, 67, 363, 1, 0, 0, 0, 69, 369, + 1, 0, 0, 0, 71, 371, 1, 0, 0, 0, 73, 407, 1, 0, 0, 0, 75, 443, 1, 0, 0, + 0, 77, 479, 1, 0, 0, 0, 79, 509, 1, 0, 0, 0, 81, 547, 1, 0, 0, 0, 83, 585, + 1, 0, 0, 0, 85, 611, 1, 0, 0, 0, 87, 631, 1, 0, 0, 0, 89, 653, 1, 0, 0, + 0, 91, 677, 1, 0, 0, 0, 93, 699, 1, 0, 0, 0, 95, 723, 1, 0, 0, 0, 97, 751, + 1, 0, 0, 0, 99, 771, 1, 0, 0, 0, 101, 800, 1, 0, 0, 0, 103, 806, 1, 0, + 0, 0, 105, 810, 1, 0, 0, 0, 107, 812, 1, 0, 0, 0, 109, 820, 1, 0, 0, 0, + 111, 827, 1, 0, 0, 0, 113, 843, 1, 0, 0, 0, 115, 859, 1, 0, 0, 0, 117, + 862, 1, 0, 0, 0, 119, 867, 1, 0, 0, 0, 121, 878, 1, 0, 0, 0, 123, 887, + 1, 0, 0, 0, 125, 889, 1, 0, 0, 0, 127, 891, 1, 0, 0, 0, 129, 893, 1, 0, + 0, 0, 131, 908, 1, 0, 0, 0, 133, 910, 1, 0, 0, 0, 135, 917, 1, 0, 0, 0, + 137, 921, 1, 0, 0, 0, 139, 923, 1, 0, 0, 0, 141, 925, 1, 0, 0, 0, 143, + 927, 1, 0, 0, 0, 145, 942, 1, 0, 0, 0, 147, 951, 1, 0, 0, 0, 149, 953, + 1, 0, 0, 0, 151, 969, 1, 0, 0, 0, 153, 971, 1, 0, 0, 0, 155, 978, 1, 0, + 0, 0, 157, 990, 1, 0, 0, 0, 159, 993, 1, 0, 0, 0, 161, 997, 1, 0, 0, 0, + 163, 1018, 1, 0, 0, 0, 165, 1021, 1, 0, 0, 0, 167, 1032, 1, 0, 0, 0, 169, + 170, 5, 40, 0, 0, 170, 2, 1, 0, 0, 0, 171, 172, 5, 41, 0, 0, 172, 4, 1, + 0, 0, 0, 173, 174, 5, 91, 0, 0, 174, 6, 1, 0, 0, 0, 175, 176, 5, 44, 0, + 0, 176, 8, 1, 0, 0, 0, 177, 178, 5, 93, 0, 0, 178, 10, 1, 0, 0, 0, 179, + 180, 5, 123, 0, 0, 180, 12, 1, 0, 0, 0, 181, 182, 5, 125, 0, 0, 182, 14, + 1, 0, 0, 0, 183, 184, 5, 60, 0, 0, 184, 16, 1, 0, 0, 0, 185, 186, 5, 60, + 0, 0, 186, 187, 5, 61, 0, 0, 187, 18, 1, 0, 0, 0, 188, 189, 5, 62, 0, 0, + 189, 20, 1, 0, 0, 0, 190, 191, 5, 62, 0, 0, 191, 192, 5, 61, 0, 0, 192, + 22, 1, 0, 0, 0, 193, 194, 5, 61, 0, 0, 194, 195, 5, 61, 0, 0, 195, 24, + 1, 0, 0, 0, 196, 197, 5, 33, 0, 0, 197, 198, 5, 61, 0, 0, 198, 26, 1, 0, + 0, 0, 199, 200, 5, 108, 0, 0, 200, 201, 5, 105, 0, 0, 201, 202, 5, 107, + 0, 0, 202, 208, 5, 101, 0, 0, 203, 204, 5, 76, 0, 0, 204, 205, 5, 73, 0, + 0, 205, 206, 5, 75, 0, 0, 206, 208, 5, 69, 0, 0, 207, 199, 1, 0, 0, 0, + 207, 203, 1, 0, 0, 0, 208, 28, 1, 0, 0, 0, 209, 210, 5, 101, 0, 0, 210, + 211, 5, 120, 0, 0, 211, 212, 5, 105, 0, 0, 212, 213, 5, 115, 0, 0, 213, + 214, 5, 116, 0, 0, 214, 222, 5, 115, 0, 0, 215, 216, 5, 69, 0, 0, 216, + 217, 5, 88, 0, 0, 217, 218, 5, 73, 0, 0, 218, 219, 5, 83, 0, 0, 219, 220, + 5, 84, 0, 0, 220, 222, 5, 83, 0, 0, 221, 209, 1, 0, 0, 0, 221, 215, 1, + 0, 0, 0, 222, 30, 1, 0, 0, 0, 223, 224, 5, 116, 0, 0, 224, 225, 5, 101, + 0, 0, 225, 226, 5, 120, 0, 0, 226, 227, 5, 116, 0, 0, 227, 228, 5, 95, + 0, 0, 228, 229, 5, 109, 0, 0, 229, 230, 5, 97, 0, 0, 230, 231, 5, 116, + 0, 0, 231, 232, 5, 99, 0, 0, 232, 244, 5, 104, 0, 0, 233, 234, 5, 84, 0, + 0, 234, 235, 5, 69, 0, 0, 235, 236, 5, 88, 0, 0, 236, 237, 5, 84, 0, 0, + 237, 238, 5, 95, 0, 0, 238, 239, 5, 77, 0, 0, 239, 240, 5, 65, 0, 0, 240, + 241, 5, 84, 0, 0, 241, 242, 5, 67, 0, 0, 242, 244, 5, 72, 0, 0, 243, 223, + 1, 0, 0, 0, 243, 233, 1, 0, 0, 0, 244, 32, 1, 0, 0, 0, 245, 246, 5, 112, + 0, 0, 246, 247, 5, 104, 0, 0, 247, 248, 5, 114, 0, 0, 248, 249, 5, 97, + 0, 0, 249, 250, 5, 115, 0, 0, 250, 251, 5, 101, 0, 0, 251, 252, 5, 95, + 0, 0, 252, 253, 5, 109, 0, 0, 253, 254, 5, 97, 0, 0, 254, 255, 5, 116, + 0, 0, 255, 256, 5, 99, 0, 0, 256, 270, 5, 104, 0, 0, 257, 258, 5, 80, 0, + 0, 258, 259, 5, 72, 0, 0, 259, 260, 5, 82, 0, 0, 260, 261, 5, 65, 0, 0, + 261, 262, 5, 83, 0, 0, 262, 263, 5, 69, 0, 0, 263, 264, 5, 95, 0, 0, 264, + 265, 5, 77, 0, 0, 265, 266, 5, 65, 0, 0, 266, 267, 5, 84, 0, 0, 267, 268, + 5, 67, 0, 0, 268, 270, 5, 72, 0, 0, 269, 245, 1, 0, 0, 0, 269, 257, 1, + 0, 0, 0, 270, 34, 1, 0, 0, 0, 271, 272, 5, 43, 0, 0, 272, 36, 1, 0, 0, + 0, 273, 274, 5, 45, 0, 0, 274, 38, 1, 0, 0, 0, 275, 276, 5, 42, 0, 0, 276, + 40, 1, 0, 0, 0, 277, 278, 5, 47, 0, 0, 278, 42, 1, 0, 0, 0, 279, 280, 5, + 37, 0, 0, 280, 44, 1, 0, 0, 0, 281, 282, 5, 42, 0, 0, 282, 283, 5, 42, + 0, 0, 283, 46, 1, 0, 0, 0, 284, 285, 5, 60, 0, 0, 285, 286, 5, 60, 0, 0, + 286, 48, 1, 0, 0, 0, 287, 288, 5, 62, 0, 0, 288, 289, 5, 62, 0, 0, 289, + 50, 1, 0, 0, 0, 290, 291, 5, 38, 0, 0, 291, 52, 1, 0, 0, 0, 292, 293, 5, + 124, 0, 0, 293, 54, 1, 0, 0, 0, 294, 295, 5, 94, 0, 0, 295, 56, 1, 0, 0, + 0, 296, 297, 5, 38, 0, 0, 297, 305, 5, 38, 0, 0, 298, 299, 5, 97, 0, 0, + 299, 300, 5, 110, 0, 0, 300, 305, 5, 100, 0, 0, 301, 302, 5, 65, 0, 0, + 302, 303, 5, 78, 0, 0, 303, 305, 5, 68, 0, 0, 304, 296, 1, 0, 0, 0, 304, + 298, 1, 0, 0, 0, 304, 301, 1, 0, 0, 0, 305, 58, 1, 0, 0, 0, 306, 307, 5, + 124, 0, 0, 307, 313, 5, 124, 0, 0, 308, 309, 5, 111, 0, 0, 309, 313, 5, + 114, 0, 0, 310, 311, 5, 79, 0, 0, 311, 313, 5, 82, 0, 0, 312, 306, 1, 0, + 0, 0, 312, 308, 1, 0, 0, 0, 312, 310, 1, 0, 0, 0, 313, 60, 1, 0, 0, 0, + 314, 315, 5, 105, 0, 0, 315, 316, 5, 115, 0, 0, 316, 317, 5, 32, 0, 0, + 317, 318, 5, 110, 0, 0, 318, 319, 5, 117, 0, 0, 319, 320, 5, 108, 0, 0, + 320, 329, 5, 108, 0, 0, 321, 322, 5, 73, 0, 0, 322, 323, 5, 83, 0, 0, 323, + 324, 5, 32, 0, 0, 324, 325, 5, 78, 0, 0, 325, 326, 5, 85, 0, 0, 326, 327, + 5, 76, 0, 0, 327, 329, 5, 76, 0, 0, 328, 314, 1, 0, 0, 0, 328, 321, 1, + 0, 0, 0, 329, 62, 1, 0, 0, 0, 330, 331, 5, 105, 0, 0, 331, 332, 5, 115, + 0, 0, 332, 333, 5, 32, 0, 0, 333, 334, 5, 110, 0, 0, 334, 335, 5, 111, + 0, 0, 335, 336, 5, 116, 0, 0, 336, 337, 5, 32, 0, 0, 337, 338, 5, 110, + 0, 0, 338, 339, 5, 117, 0, 0, 339, 340, 5, 108, 0, 0, 340, 353, 5, 108, + 0, 0, 341, 342, 5, 73, 0, 0, 342, 343, 5, 83, 0, 0, 343, 344, 5, 32, 0, + 0, 344, 345, 5, 78, 0, 0, 345, 346, 5, 79, 0, 0, 346, 347, 5, 84, 0, 0, + 347, 348, 5, 32, 0, 0, 348, 349, 5, 78, 0, 0, 349, 350, 5, 85, 0, 0, 350, + 351, 5, 76, 0, 0, 351, 353, 5, 76, 0, 0, 352, 330, 1, 0, 0, 0, 352, 341, + 1, 0, 0, 0, 353, 64, 1, 0, 0, 0, 354, 355, 5, 126, 0, 0, 355, 66, 1, 0, + 0, 0, 356, 364, 5, 33, 0, 0, 357, 358, 5, 110, 0, 0, 358, 359, 5, 111, + 0, 0, 359, 364, 5, 116, 0, 0, 360, 361, 5, 78, 0, 0, 361, 362, 5, 79, 0, + 0, 362, 364, 5, 84, 0, 0, 363, 356, 1, 0, 0, 0, 363, 357, 1, 0, 0, 0, 363, + 360, 1, 0, 0, 0, 364, 68, 1, 0, 0, 0, 365, 366, 5, 105, 0, 0, 366, 370, + 5, 110, 0, 0, 367, 368, 5, 73, 0, 0, 368, 370, 5, 78, 0, 0, 369, 365, 1, + 0, 0, 0, 369, 367, 1, 0, 0, 0, 370, 70, 1, 0, 0, 0, 371, 376, 5, 91, 0, + 0, 372, 375, 3, 165, 82, 0, 373, 375, 3, 167, 83, 0, 374, 372, 1, 0, 0, + 0, 374, 373, 1, 0, 0, 0, 375, 378, 1, 0, 0, 0, 376, 374, 1, 0, 0, 0, 376, + 377, 1, 0, 0, 0, 377, 379, 1, 0, 0, 0, 378, 376, 1, 0, 0, 0, 379, 380, + 5, 93, 0, 0, 380, 72, 1, 0, 0, 0, 381, 382, 5, 106, 0, 0, 382, 383, 5, + 115, 0, 0, 383, 384, 5, 111, 0, 0, 384, 385, 5, 110, 0, 0, 385, 386, 5, + 95, 0, 0, 386, 387, 5, 99, 0, 0, 387, 388, 5, 111, 0, 0, 388, 389, 5, 110, + 0, 0, 389, 390, 5, 116, 0, 0, 390, 391, 5, 97, 0, 0, 391, 392, 5, 105, + 0, 0, 392, 393, 5, 110, 0, 0, 393, 408, 5, 115, 0, 0, 394, 395, 5, 74, + 0, 0, 395, 396, 5, 83, 0, 0, 396, 397, 5, 79, 0, 0, 397, 398, 5, 78, 0, + 0, 398, 399, 5, 95, 0, 0, 399, 400, 5, 67, 0, 0, 400, 401, 5, 79, 0, 0, + 401, 402, 5, 78, 0, 0, 402, 403, 5, 84, 0, 0, 403, 404, 5, 65, 0, 0, 404, + 405, 5, 73, 0, 0, 405, 406, 5, 78, 0, 0, 406, 408, 5, 83, 0, 0, 407, 381, + 1, 0, 0, 0, 407, 394, 1, 0, 0, 0, 408, 74, 1, 0, 0, 0, 409, 410, 5, 106, + 0, 0, 410, 411, 5, 115, 0, 0, 411, 412, 5, 111, 0, 0, 412, 413, 5, 110, + 0, 0, 413, 414, 5, 95, 0, 0, 414, 415, 5, 99, 0, 0, 415, 416, 5, 111, 0, + 0, 416, 417, 5, 110, 0, 0, 417, 418, 5, 116, 0, 0, 418, 419, 5, 97, 0, + 0, 419, 420, 5, 105, 0, 0, 420, 421, 5, 110, 0, 0, 421, 422, 5, 115, 0, + 0, 422, 423, 5, 95, 0, 0, 423, 424, 5, 97, 0, 0, 424, 425, 5, 108, 0, 0, + 425, 444, 5, 108, 0, 0, 426, 427, 5, 74, 0, 0, 427, 428, 5, 83, 0, 0, 428, + 429, 5, 79, 0, 0, 429, 430, 5, 78, 0, 0, 430, 431, 5, 95, 0, 0, 431, 432, + 5, 67, 0, 0, 432, 433, 5, 79, 0, 0, 433, 434, 5, 78, 0, 0, 434, 435, 5, + 84, 0, 0, 435, 436, 5, 65, 0, 0, 436, 437, 5, 73, 0, 0, 437, 438, 5, 78, + 0, 0, 438, 439, 5, 83, 0, 0, 439, 440, 5, 95, 0, 0, 440, 441, 5, 65, 0, + 0, 441, 442, 5, 76, 0, 0, 442, 444, 5, 76, 0, 0, 443, 409, 1, 0, 0, 0, + 443, 426, 1, 0, 0, 0, 444, 76, 1, 0, 0, 0, 445, 446, 5, 106, 0, 0, 446, + 447, 5, 115, 0, 0, 447, 448, 5, 111, 0, 0, 448, 449, 5, 110, 0, 0, 449, + 450, 5, 95, 0, 0, 450, 451, 5, 99, 0, 0, 451, 452, 5, 111, 0, 0, 452, 453, + 5, 110, 0, 0, 453, 454, 5, 116, 0, 0, 454, 455, 5, 97, 0, 0, 455, 456, + 5, 105, 0, 0, 456, 457, 5, 110, 0, 0, 457, 458, 5, 115, 0, 0, 458, 459, + 5, 95, 0, 0, 459, 460, 5, 97, 0, 0, 460, 461, 5, 110, 0, 0, 461, 480, 5, + 121, 0, 0, 462, 463, 5, 74, 0, 0, 463, 464, 5, 83, 0, 0, 464, 465, 5, 79, + 0, 0, 465, 466, 5, 78, 0, 0, 466, 467, 5, 95, 0, 0, 467, 468, 5, 67, 0, + 0, 468, 469, 5, 79, 0, 0, 469, 470, 5, 78, 0, 0, 470, 471, 5, 84, 0, 0, + 471, 472, 5, 65, 0, 0, 472, 473, 5, 73, 0, 0, 473, 474, 5, 78, 0, 0, 474, + 475, 5, 83, 0, 0, 475, 476, 5, 95, 0, 0, 476, 477, 5, 65, 0, 0, 477, 478, + 5, 78, 0, 0, 478, 480, 5, 89, 0, 0, 479, 445, 1, 0, 0, 0, 479, 462, 1, + 0, 0, 0, 480, 78, 1, 0, 0, 0, 481, 482, 5, 97, 0, 0, 482, 483, 5, 114, + 0, 0, 483, 484, 5, 114, 0, 0, 484, 485, 5, 97, 0, 0, 485, 486, 5, 121, + 0, 0, 486, 487, 5, 95, 0, 0, 487, 488, 5, 99, 0, 0, 488, 489, 5, 111, 0, + 0, 489, 490, 5, 110, 0, 0, 490, 491, 5, 116, 0, 0, 491, 492, 5, 97, 0, + 0, 492, 493, 5, 105, 0, 0, 493, 494, 5, 110, 0, 0, 494, 510, 5, 115, 0, + 0, 495, 496, 5, 65, 0, 0, 496, 497, 5, 82, 0, 0, 497, 498, 5, 82, 0, 0, + 498, 499, 5, 65, 0, 0, 499, 500, 5, 89, 0, 0, 500, 501, 5, 95, 0, 0, 501, + 502, 5, 67, 0, 0, 502, 503, 5, 79, 0, 0, 503, 504, 5, 78, 0, 0, 504, 505, + 5, 84, 0, 0, 505, 506, 5, 65, 0, 0, 506, 507, 5, 73, 0, 0, 507, 508, 5, + 78, 0, 0, 508, 510, 5, 83, 0, 0, 509, 481, 1, 0, 0, 0, 509, 495, 1, 0, + 0, 0, 510, 80, 1, 0, 0, 0, 511, 512, 5, 97, 0, 0, 512, 513, 5, 114, 0, + 0, 513, 514, 5, 114, 0, 0, 514, 515, 5, 97, 0, 0, 515, 516, 5, 121, 0, + 0, 516, 517, 5, 95, 0, 0, 517, 518, 5, 99, 0, 0, 518, 519, 5, 111, 0, 0, + 519, 520, 5, 110, 0, 0, 520, 521, 5, 116, 0, 0, 521, 522, 5, 97, 0, 0, + 522, 523, 5, 105, 0, 0, 523, 524, 5, 110, 0, 0, 524, 525, 5, 115, 0, 0, + 525, 526, 5, 95, 0, 0, 526, 527, 5, 97, 0, 0, 527, 528, 5, 108, 0, 0, 528, + 548, 5, 108, 0, 0, 529, 530, 5, 65, 0, 0, 530, 531, 5, 82, 0, 0, 531, 532, + 5, 82, 0, 0, 532, 533, 5, 65, 0, 0, 533, 534, 5, 89, 0, 0, 534, 535, 5, + 95, 0, 0, 535, 536, 5, 67, 0, 0, 536, 537, 5, 79, 0, 0, 537, 538, 5, 78, + 0, 0, 538, 539, 5, 84, 0, 0, 539, 540, 5, 65, 0, 0, 540, 541, 5, 73, 0, + 0, 541, 542, 5, 78, 0, 0, 542, 543, 5, 83, 0, 0, 543, 544, 5, 95, 0, 0, + 544, 545, 5, 65, 0, 0, 545, 546, 5, 76, 0, 0, 546, 548, 5, 76, 0, 0, 547, + 511, 1, 0, 0, 0, 547, 529, 1, 0, 0, 0, 548, 82, 1, 0, 0, 0, 549, 550, 5, + 97, 0, 0, 550, 551, 5, 114, 0, 0, 551, 552, 5, 114, 0, 0, 552, 553, 5, + 97, 0, 0, 553, 554, 5, 121, 0, 0, 554, 555, 5, 95, 0, 0, 555, 556, 5, 99, + 0, 0, 556, 557, 5, 111, 0, 0, 557, 558, 5, 110, 0, 0, 558, 559, 5, 116, + 0, 0, 559, 560, 5, 97, 0, 0, 560, 561, 5, 105, 0, 0, 561, 562, 5, 110, + 0, 0, 562, 563, 5, 115, 0, 0, 563, 564, 5, 95, 0, 0, 564, 565, 5, 97, 0, + 0, 565, 566, 5, 110, 0, 0, 566, 586, 5, 121, 0, 0, 567, 568, 5, 65, 0, + 0, 568, 569, 5, 82, 0, 0, 569, 570, 5, 82, 0, 0, 570, 571, 5, 65, 0, 0, + 571, 572, 5, 89, 0, 0, 572, 573, 5, 95, 0, 0, 573, 574, 5, 67, 0, 0, 574, + 575, 5, 79, 0, 0, 575, 576, 5, 78, 0, 0, 576, 577, 5, 84, 0, 0, 577, 578, + 5, 65, 0, 0, 578, 579, 5, 73, 0, 0, 579, 580, 5, 78, 0, 0, 580, 581, 5, + 83, 0, 0, 581, 582, 5, 95, 0, 0, 582, 583, 5, 65, 0, 0, 583, 584, 5, 78, + 0, 0, 584, 586, 5, 89, 0, 0, 585, 549, 1, 0, 0, 0, 585, 567, 1, 0, 0, 0, + 586, 84, 1, 0, 0, 0, 587, 588, 5, 97, 0, 0, 588, 589, 5, 114, 0, 0, 589, + 590, 5, 114, 0, 0, 590, 591, 5, 97, 0, 0, 591, 592, 5, 121, 0, 0, 592, + 593, 5, 95, 0, 0, 593, 594, 5, 108, 0, 0, 594, 595, 5, 101, 0, 0, 595, + 596, 5, 110, 0, 0, 596, 597, 5, 103, 0, 0, 597, 598, 5, 116, 0, 0, 598, + 612, 5, 104, 0, 0, 599, 600, 5, 65, 0, 0, 600, 601, 5, 82, 0, 0, 601, 602, + 5, 82, 0, 0, 602, 603, 5, 65, 0, 0, 603, 604, 5, 89, 0, 0, 604, 605, 5, + 95, 0, 0, 605, 606, 5, 76, 0, 0, 606, 607, 5, 69, 0, 0, 607, 608, 5, 78, + 0, 0, 608, 609, 5, 71, 0, 0, 609, 610, 5, 84, 0, 0, 610, 612, 5, 72, 0, + 0, 611, 587, 1, 0, 0, 0, 611, 599, 1, 0, 0, 0, 612, 86, 1, 0, 0, 0, 613, + 614, 5, 115, 0, 0, 614, 615, 5, 116, 0, 0, 615, 616, 5, 95, 0, 0, 616, + 617, 5, 101, 0, 0, 617, 618, 5, 113, 0, 0, 618, 619, 5, 117, 0, 0, 619, + 620, 5, 97, 0, 0, 620, 621, 5, 108, 0, 0, 621, 632, 5, 115, 0, 0, 622, + 623, 5, 83, 0, 0, 623, 624, 5, 84, 0, 0, 624, 625, 5, 95, 0, 0, 625, 626, + 5, 69, 0, 0, 626, 627, 5, 81, 0, 0, 627, 628, 5, 85, 0, 0, 628, 629, 5, + 65, 0, 0, 629, 630, 5, 76, 0, 0, 630, 632, 5, 83, 0, 0, 631, 613, 1, 0, + 0, 0, 631, 622, 1, 0, 0, 0, 632, 88, 1, 0, 0, 0, 633, 634, 5, 115, 0, 0, + 634, 635, 5, 116, 0, 0, 635, 636, 5, 95, 0, 0, 636, 637, 5, 116, 0, 0, + 637, 638, 5, 111, 0, 0, 638, 639, 5, 117, 0, 0, 639, 640, 5, 99, 0, 0, + 640, 641, 5, 104, 0, 0, 641, 642, 5, 101, 0, 0, 642, 654, 5, 115, 0, 0, + 643, 644, 5, 83, 0, 0, 644, 645, 5, 84, 0, 0, 645, 646, 5, 95, 0, 0, 646, + 647, 5, 84, 0, 0, 647, 648, 5, 79, 0, 0, 648, 649, 5, 85, 0, 0, 649, 650, + 5, 67, 0, 0, 650, 651, 5, 72, 0, 0, 651, 652, 5, 69, 0, 0, 652, 654, 5, + 83, 0, 0, 653, 633, 1, 0, 0, 0, 653, 643, 1, 0, 0, 0, 654, 90, 1, 0, 0, + 0, 655, 656, 5, 115, 0, 0, 656, 657, 5, 116, 0, 0, 657, 658, 5, 95, 0, + 0, 658, 659, 5, 111, 0, 0, 659, 660, 5, 118, 0, 0, 660, 661, 5, 101, 0, + 0, 661, 662, 5, 114, 0, 0, 662, 663, 5, 108, 0, 0, 663, 664, 5, 97, 0, + 0, 664, 665, 5, 112, 0, 0, 665, 678, 5, 115, 0, 0, 666, 667, 5, 83, 0, + 0, 667, 668, 5, 84, 0, 0, 668, 669, 5, 95, 0, 0, 669, 670, 5, 79, 0, 0, + 670, 671, 5, 86, 0, 0, 671, 672, 5, 69, 0, 0, 672, 673, 5, 82, 0, 0, 673, + 674, 5, 76, 0, 0, 674, 675, 5, 65, 0, 0, 675, 676, 5, 80, 0, 0, 676, 678, + 5, 83, 0, 0, 677, 655, 1, 0, 0, 0, 677, 666, 1, 0, 0, 0, 678, 92, 1, 0, + 0, 0, 679, 680, 5, 115, 0, 0, 680, 681, 5, 116, 0, 0, 681, 682, 5, 95, + 0, 0, 682, 683, 5, 99, 0, 0, 683, 684, 5, 114, 0, 0, 684, 685, 5, 111, + 0, 0, 685, 686, 5, 115, 0, 0, 686, 687, 5, 115, 0, 0, 687, 688, 5, 101, + 0, 0, 688, 700, 5, 115, 0, 0, 689, 690, 5, 83, 0, 0, 690, 691, 5, 84, 0, + 0, 691, 692, 5, 95, 0, 0, 692, 693, 5, 67, 0, 0, 693, 694, 5, 82, 0, 0, + 694, 695, 5, 79, 0, 0, 695, 696, 5, 83, 0, 0, 696, 697, 5, 83, 0, 0, 697, + 698, 5, 69, 0, 0, 698, 700, 5, 83, 0, 0, 699, 679, 1, 0, 0, 0, 699, 689, + 1, 0, 0, 0, 700, 94, 1, 0, 0, 0, 701, 702, 5, 115, 0, 0, 702, 703, 5, 116, + 0, 0, 703, 704, 5, 95, 0, 0, 704, 705, 5, 99, 0, 0, 705, 706, 5, 111, 0, + 0, 706, 707, 5, 110, 0, 0, 707, 708, 5, 116, 0, 0, 708, 709, 5, 97, 0, + 0, 709, 710, 5, 105, 0, 0, 710, 711, 5, 110, 0, 0, 711, 724, 5, 115, 0, + 0, 712, 713, 5, 83, 0, 0, 713, 714, 5, 84, 0, 0, 714, 715, 5, 95, 0, 0, + 715, 716, 5, 67, 0, 0, 716, 717, 5, 79, 0, 0, 717, 718, 5, 78, 0, 0, 718, + 719, 5, 84, 0, 0, 719, 720, 5, 65, 0, 0, 720, 721, 5, 73, 0, 0, 721, 722, + 5, 78, 0, 0, 722, 724, 5, 83, 0, 0, 723, 701, 1, 0, 0, 0, 723, 712, 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, 105, 0, 0, 729, 730, 5, 110, + 0, 0, 730, 731, 5, 116, 0, 0, 731, 732, 5, 101, 0, 0, 732, 733, 5, 114, + 0, 0, 733, 734, 5, 115, 0, 0, 734, 735, 5, 101, 0, 0, 735, 736, 5, 99, + 0, 0, 736, 737, 5, 116, 0, 0, 737, 752, 5, 115, 0, 0, 738, 739, 5, 83, + 0, 0, 739, 740, 5, 84, 0, 0, 740, 741, 5, 95, 0, 0, 741, 742, 5, 73, 0, + 0, 742, 743, 5, 78, 0, 0, 743, 744, 5, 84, 0, 0, 744, 745, 5, 69, 0, 0, + 745, 746, 5, 82, 0, 0, 746, 747, 5, 83, 0, 0, 747, 748, 5, 69, 0, 0, 748, + 749, 5, 67, 0, 0, 749, 750, 5, 84, 0, 0, 750, 752, 5, 83, 0, 0, 751, 725, + 1, 0, 0, 0, 751, 738, 1, 0, 0, 0, 752, 98, 1, 0, 0, 0, 753, 754, 5, 115, + 0, 0, 754, 755, 5, 116, 0, 0, 755, 756, 5, 95, 0, 0, 756, 757, 5, 119, + 0, 0, 757, 758, 5, 105, 0, 0, 758, 759, 5, 116, 0, 0, 759, 760, 5, 104, + 0, 0, 760, 761, 5, 105, 0, 0, 761, 772, 5, 110, 0, 0, 762, 763, 5, 83, + 0, 0, 763, 764, 5, 84, 0, 0, 764, 765, 5, 95, 0, 0, 765, 766, 5, 87, 0, + 0, 766, 767, 5, 73, 0, 0, 767, 768, 5, 84, 0, 0, 768, 769, 5, 72, 0, 0, + 769, 770, 5, 73, 0, 0, 770, 772, 5, 78, 0, 0, 771, 753, 1, 0, 0, 0, 771, + 762, 1, 0, 0, 0, 772, 100, 1, 0, 0, 0, 773, 774, 5, 116, 0, 0, 774, 775, + 5, 114, 0, 0, 775, 776, 5, 117, 0, 0, 776, 801, 5, 101, 0, 0, 777, 778, + 5, 84, 0, 0, 778, 779, 5, 114, 0, 0, 779, 780, 5, 117, 0, 0, 780, 801, + 5, 101, 0, 0, 781, 782, 5, 84, 0, 0, 782, 783, 5, 82, 0, 0, 783, 784, 5, + 85, 0, 0, 784, 801, 5, 69, 0, 0, 785, 786, 5, 102, 0, 0, 786, 787, 5, 97, + 0, 0, 787, 788, 5, 108, 0, 0, 788, 789, 5, 115, 0, 0, 789, 801, 5, 101, + 0, 0, 790, 791, 5, 70, 0, 0, 791, 792, 5, 97, 0, 0, 792, 793, 5, 108, 0, + 0, 793, 794, 5, 115, 0, 0, 794, 801, 5, 101, 0, 0, 795, 796, 5, 70, 0, + 0, 796, 797, 5, 65, 0, 0, 797, 798, 5, 76, 0, 0, 798, 799, 5, 83, 0, 0, + 799, 801, 5, 69, 0, 0, 800, 773, 1, 0, 0, 0, 800, 777, 1, 0, 0, 0, 800, + 781, 1, 0, 0, 0, 800, 785, 1, 0, 0, 0, 800, 790, 1, 0, 0, 0, 800, 795, + 1, 0, 0, 0, 801, 102, 1, 0, 0, 0, 802, 807, 3, 131, 65, 0, 803, 807, 3, + 133, 66, 0, 804, 807, 3, 135, 67, 0, 805, 807, 3, 129, 64, 0, 806, 802, + 1, 0, 0, 0, 806, 803, 1, 0, 0, 0, 806, 804, 1, 0, 0, 0, 806, 805, 1, 0, + 0, 0, 807, 104, 1, 0, 0, 0, 808, 811, 3, 147, 73, 0, 809, 811, 3, 149, + 74, 0, 810, 808, 1, 0, 0, 0, 810, 809, 1, 0, 0, 0, 811, 106, 1, 0, 0, 0, + 812, 817, 3, 125, 62, 0, 813, 816, 3, 125, 62, 0, 814, 816, 3, 127, 63, + 0, 815, 813, 1, 0, 0, 0, 815, 814, 1, 0, 0, 0, 816, 819, 1, 0, 0, 0, 817, + 815, 1, 0, 0, 0, 817, 818, 1, 0, 0, 0, 818, 108, 1, 0, 0, 0, 819, 817, + 1, 0, 0, 0, 820, 821, 5, 36, 0, 0, 821, 822, 5, 109, 0, 0, 822, 823, 5, + 101, 0, 0, 823, 824, 5, 116, 0, 0, 824, 825, 5, 97, 0, 0, 825, 110, 1, + 0, 0, 0, 826, 828, 3, 115, 57, 0, 827, 826, 1, 0, 0, 0, 827, 828, 1, 0, + 0, 0, 828, 839, 1, 0, 0, 0, 829, 831, 5, 34, 0, 0, 830, 832, 3, 117, 58, + 0, 831, 830, 1, 0, 0, 0, 831, 832, 1, 0, 0, 0, 832, 833, 1, 0, 0, 0, 833, + 840, 5, 34, 0, 0, 834, 836, 5, 39, 0, 0, 835, 837, 3, 119, 59, 0, 836, + 835, 1, 0, 0, 0, 836, 837, 1, 0, 0, 0, 837, 838, 1, 0, 0, 0, 838, 840, + 5, 39, 0, 0, 839, 829, 1, 0, 0, 0, 839, 834, 1, 0, 0, 0, 840, 112, 1, 0, + 0, 0, 841, 844, 3, 107, 53, 0, 842, 844, 3, 109, 54, 0, 843, 841, 1, 0, + 0, 0, 843, 842, 1, 0, 0, 0, 844, 852, 1, 0, 0, 0, 845, 848, 5, 91, 0, 0, + 846, 849, 3, 111, 55, 0, 847, 849, 3, 131, 65, 0, 848, 846, 1, 0, 0, 0, + 848, 847, 1, 0, 0, 0, 849, 850, 1, 0, 0, 0, 850, 851, 5, 93, 0, 0, 851, + 853, 1, 0, 0, 0, 852, 845, 1, 0, 0, 0, 853, 854, 1, 0, 0, 0, 854, 852, + 1, 0, 0, 0, 854, 855, 1, 0, 0, 0, 855, 114, 1, 0, 0, 0, 856, 857, 5, 117, + 0, 0, 857, 860, 5, 56, 0, 0, 858, 860, 7, 0, 0, 0, 859, 856, 1, 0, 0, 0, + 859, 858, 1, 0, 0, 0, 860, 116, 1, 0, 0, 0, 861, 863, 3, 121, 60, 0, 862, + 861, 1, 0, 0, 0, 863, 864, 1, 0, 0, 0, 864, 862, 1, 0, 0, 0, 864, 865, + 1, 0, 0, 0, 865, 118, 1, 0, 0, 0, 866, 868, 3, 123, 61, 0, 867, 866, 1, + 0, 0, 0, 868, 869, 1, 0, 0, 0, 869, 867, 1, 0, 0, 0, 869, 870, 1, 0, 0, + 0, 870, 120, 1, 0, 0, 0, 871, 879, 8, 1, 0, 0, 872, 879, 3, 163, 81, 0, + 873, 874, 5, 92, 0, 0, 874, 879, 5, 10, 0, 0, 875, 876, 5, 92, 0, 0, 876, + 877, 5, 13, 0, 0, 877, 879, 5, 10, 0, 0, 878, 871, 1, 0, 0, 0, 878, 872, + 1, 0, 0, 0, 878, 873, 1, 0, 0, 0, 878, 875, 1, 0, 0, 0, 879, 122, 1, 0, + 0, 0, 880, 888, 8, 2, 0, 0, 881, 888, 3, 163, 81, 0, 882, 883, 5, 92, 0, + 0, 883, 888, 5, 10, 0, 0, 884, 885, 5, 92, 0, 0, 885, 886, 5, 13, 0, 0, + 886, 888, 5, 10, 0, 0, 887, 880, 1, 0, 0, 0, 887, 881, 1, 0, 0, 0, 887, + 882, 1, 0, 0, 0, 887, 884, 1, 0, 0, 0, 888, 124, 1, 0, 0, 0, 889, 890, + 7, 3, 0, 0, 890, 126, 1, 0, 0, 0, 891, 892, 7, 4, 0, 0, 892, 128, 1, 0, + 0, 0, 893, 894, 5, 48, 0, 0, 894, 896, 7, 5, 0, 0, 895, 897, 7, 6, 0, 0, + 896, 895, 1, 0, 0, 0, 897, 898, 1, 0, 0, 0, 898, 896, 1, 0, 0, 0, 898, + 899, 1, 0, 0, 0, 899, 130, 1, 0, 0, 0, 900, 904, 3, 137, 68, 0, 901, 903, + 3, 127, 63, 0, 902, 901, 1, 0, 0, 0, 903, 906, 1, 0, 0, 0, 904, 902, 1, + 0, 0, 0, 904, 905, 1, 0, 0, 0, 905, 909, 1, 0, 0, 0, 906, 904, 1, 0, 0, + 0, 907, 909, 5, 48, 0, 0, 908, 900, 1, 0, 0, 0, 908, 907, 1, 0, 0, 0, 909, + 132, 1, 0, 0, 0, 910, 914, 5, 48, 0, 0, 911, 913, 3, 139, 69, 0, 912, 911, + 1, 0, 0, 0, 913, 916, 1, 0, 0, 0, 914, 912, 1, 0, 0, 0, 914, 915, 1, 0, + 0, 0, 915, 134, 1, 0, 0, 0, 916, 914, 1, 0, 0, 0, 917, 918, 5, 48, 0, 0, + 918, 919, 7, 7, 0, 0, 919, 920, 3, 159, 79, 0, 920, 136, 1, 0, 0, 0, 921, + 922, 7, 8, 0, 0, 922, 138, 1, 0, 0, 0, 923, 924, 7, 9, 0, 0, 924, 140, + 1, 0, 0, 0, 925, 926, 7, 10, 0, 0, 926, 142, 1, 0, 0, 0, 927, 928, 3, 141, + 70, 0, 928, 929, 3, 141, 70, 0, 929, 930, 3, 141, 70, 0, 930, 931, 3, 141, + 70, 0, 931, 144, 1, 0, 0, 0, 932, 933, 5, 92, 0, 0, 933, 934, 5, 117, 0, + 0, 934, 935, 1, 0, 0, 0, 935, 943, 3, 143, 71, 0, 936, 937, 5, 92, 0, 0, + 937, 938, 5, 85, 0, 0, 938, 939, 1, 0, 0, 0, 939, 940, 3, 143, 71, 0, 940, + 941, 3, 143, 71, 0, 941, 943, 1, 0, 0, 0, 942, 932, 1, 0, 0, 0, 942, 936, + 1, 0, 0, 0, 943, 146, 1, 0, 0, 0, 944, 946, 3, 151, 75, 0, 945, 947, 3, + 153, 76, 0, 946, 945, 1, 0, 0, 0, 946, 947, 1, 0, 0, 0, 947, 952, 1, 0, + 0, 0, 948, 949, 3, 155, 77, 0, 949, 950, 3, 153, 76, 0, 950, 952, 1, 0, + 0, 0, 951, 944, 1, 0, 0, 0, 951, 948, 1, 0, 0, 0, 952, 148, 1, 0, 0, 0, + 953, 954, 5, 48, 0, 0, 954, 957, 7, 7, 0, 0, 955, 958, 3, 157, 78, 0, 956, + 958, 3, 159, 79, 0, 957, 955, 1, 0, 0, 0, 957, 956, 1, 0, 0, 0, 958, 959, + 1, 0, 0, 0, 959, 960, 3, 161, 80, 0, 960, 150, 1, 0, 0, 0, 961, 963, 3, + 155, 77, 0, 962, 961, 1, 0, 0, 0, 962, 963, 1, 0, 0, 0, 963, 964, 1, 0, + 0, 0, 964, 965, 5, 46, 0, 0, 965, 970, 3, 155, 77, 0, 966, 967, 3, 155, + 77, 0, 967, 968, 5, 46, 0, 0, 968, 970, 1, 0, 0, 0, 969, 962, 1, 0, 0, + 0, 969, 966, 1, 0, 0, 0, 970, 152, 1, 0, 0, 0, 971, 973, 7, 11, 0, 0, 972, + 974, 7, 12, 0, 0, 973, 972, 1, 0, 0, 0, 973, 974, 1, 0, 0, 0, 974, 975, + 1, 0, 0, 0, 975, 976, 3, 155, 77, 0, 976, 154, 1, 0, 0, 0, 977, 979, 3, + 127, 63, 0, 978, 977, 1, 0, 0, 0, 979, 980, 1, 0, 0, 0, 980, 978, 1, 0, + 0, 0, 980, 981, 1, 0, 0, 0, 981, 156, 1, 0, 0, 0, 982, 984, 3, 159, 79, + 0, 983, 982, 1, 0, 0, 0, 983, 984, 1, 0, 0, 0, 984, 985, 1, 0, 0, 0, 985, + 986, 5, 46, 0, 0, 986, 991, 3, 159, 79, 0, 987, 988, 3, 159, 79, 0, 988, + 989, 5, 46, 0, 0, 989, 991, 1, 0, 0, 0, 990, 983, 1, 0, 0, 0, 990, 987, + 1, 0, 0, 0, 991, 158, 1, 0, 0, 0, 992, 994, 3, 141, 70, 0, 993, 992, 1, + 0, 0, 0, 994, 995, 1, 0, 0, 0, 995, 993, 1, 0, 0, 0, 995, 996, 1, 0, 0, + 0, 996, 160, 1, 0, 0, 0, 997, 999, 7, 13, 0, 0, 998, 1000, 7, 12, 0, 0, + 999, 998, 1, 0, 0, 0, 999, 1000, 1, 0, 0, 0, 1000, 1001, 1, 0, 0, 0, 1001, + 1002, 3, 155, 77, 0, 1002, 162, 1, 0, 0, 0, 1003, 1004, 5, 92, 0, 0, 1004, + 1019, 7, 14, 0, 0, 1005, 1006, 5, 92, 0, 0, 1006, 1008, 3, 139, 69, 0, + 1007, 1009, 3, 139, 69, 0, 1008, 1007, 1, 0, 0, 0, 1008, 1009, 1, 0, 0, + 0, 1009, 1011, 1, 0, 0, 0, 1010, 1012, 3, 139, 69, 0, 1011, 1010, 1, 0, + 0, 0, 1011, 1012, 1, 0, 0, 0, 1012, 1019, 1, 0, 0, 0, 1013, 1014, 5, 92, + 0, 0, 1014, 1015, 5, 120, 0, 0, 1015, 1016, 1, 0, 0, 0, 1016, 1019, 3, + 159, 79, 0, 1017, 1019, 3, 145, 72, 0, 1018, 1003, 1, 0, 0, 0, 1018, 1005, + 1, 0, 0, 0, 1018, 1013, 1, 0, 0, 0, 1018, 1017, 1, 0, 0, 0, 1019, 164, + 1, 0, 0, 0, 1020, 1022, 7, 15, 0, 0, 1021, 1020, 1, 0, 0, 0, 1022, 1023, + 1, 0, 0, 0, 1023, 1021, 1, 0, 0, 0, 1023, 1024, 1, 0, 0, 0, 1024, 1025, + 1, 0, 0, 0, 1025, 1026, 6, 82, 0, 0, 1026, 166, 1, 0, 0, 0, 1027, 1029, + 5, 13, 0, 0, 1028, 1030, 5, 10, 0, 0, 1029, 1028, 1, 0, 0, 0, 1029, 1030, + 1, 0, 0, 0, 1030, 1033, 1, 0, 0, 0, 1031, 1033, 5, 10, 0, 0, 1032, 1027, + 1, 0, 0, 0, 1032, 1031, 1, 0, 0, 0, 1033, 1034, 1, 0, 0, 0, 1034, 1035, + 6, 83, 0, 0, 1035, 168, 1, 0, 0, 0, 66, 0, 207, 221, 243, 269, 304, 312, + 328, 352, 363, 369, 374, 376, 407, 443, 479, 509, 547, 585, 611, 631, 653, + 677, 699, 723, 751, 771, 800, 806, 810, 815, 817, 827, 831, 836, 839, 843, + 848, 854, 859, 864, 869, 878, 887, 898, 904, 908, 914, 942, 946, 951, 957, + 962, 969, 973, 980, 983, 990, 995, 999, 1008, 1011, 1018, 1023, 1029, 1032, + 1, 6, 0, 0, } deserializer := antlr.NewATNDeserializer(nil) staticData.atn = deserializer.Deserialize(staticData.serializedATN) @@ -549,13 +630,20 @@ const ( PlanLexerArrayContainsAll = 41 PlanLexerArrayContainsAny = 42 PlanLexerArrayLength = 43 - PlanLexerBooleanConstant = 44 - PlanLexerIntegerConstant = 45 - PlanLexerFloatingConstant = 46 - PlanLexerIdentifier = 47 - PlanLexerMeta = 48 - PlanLexerStringLiteral = 49 - PlanLexerJSONIdentifier = 50 - PlanLexerWhitespace = 51 - PlanLexerNewline = 52 + PlanLexerSTEuqals = 44 + PlanLexerSTTouches = 45 + PlanLexerSTOverlaps = 46 + PlanLexerSTCrosses = 47 + PlanLexerSTContains = 48 + PlanLexerSTIntersects = 49 + PlanLexerSTWithin = 50 + PlanLexerBooleanConstant = 51 + PlanLexerIntegerConstant = 52 + PlanLexerFloatingConstant = 53 + PlanLexerIdentifier = 54 + PlanLexerMeta = 55 + PlanLexerStringLiteral = 56 + PlanLexerJSONIdentifier = 57 + PlanLexerWhitespace = 58 + PlanLexerNewline = 59 ) diff --git a/internal/parser/planparserv2/generated/plan_parser.go b/internal/parser/planparserv2/generated/plan_parser.go index 8ede4618de..69c55f4768 100644 --- a/internal/parser/planparserv2/generated/plan_parser.go +++ b/internal/parser/planparserv2/generated/plan_parser.go @@ -35,7 +35,8 @@ func planParserInit() { "", "'('", "')'", "'['", "','", "']'", "'{'", "'}'", "'<'", "'<='", "'>'", "'>='", "'=='", "'!='", "", "", "", "", "'+'", "'-'", "'*'", "'/'", "'%'", "'**'", "'<<'", "'>>'", "'&'", "'|'", "'^'", "", "", "", - "", "'~'", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "'$meta'", + "", "'~'", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "'$meta'", } staticData.SymbolicNames = []string{ "", "", "", "", "", "", "LBRACE", "RBRACE", "LT", "LE", "GT", "GE", @@ -43,90 +44,111 @@ func planParserInit() { "MUL", "DIV", "MOD", "POW", "SHL", "SHR", "BAND", "BOR", "BXOR", "AND", "OR", "ISNULL", "ISNOTNULL", "BNOT", "NOT", "IN", "EmptyArray", "JSONContains", "JSONContainsAll", "JSONContainsAny", "ArrayContains", "ArrayContainsAll", - "ArrayContainsAny", "ArrayLength", "BooleanConstant", "IntegerConstant", - "FloatingConstant", "Identifier", "Meta", "StringLiteral", "JSONIdentifier", - "Whitespace", "Newline", + "ArrayContainsAny", "ArrayLength", "STEuqals", "STTouches", "STOverlaps", + "STCrosses", "STContains", "STIntersects", "STWithin", "BooleanConstant", + "IntegerConstant", "FloatingConstant", "Identifier", "Meta", "StringLiteral", + "JSONIdentifier", "Whitespace", "Newline", } staticData.RuleNames = []string{ "expr", } staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ - 4, 1, 52, 156, 2, 0, 7, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 4, 1, 59, 198, 2, 0, 7, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 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, 21, 8, 0, 10, 0, 12, 0, 24, 9, 0, 1, 0, 3, 0, 27, 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, 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, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 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, 82, 8, 0, 10, 0, 12, 0, 85, 9, 0, 1, 0, 3, 0, 88, 8, - 0, 3, 0, 90, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 97, 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, 113, 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, 151, 8, 0, 10, 0, 12, 0, 154, 9, 0, 1, 0, - 0, 1, 0, 1, 0, 0, 13, 1, 0, 47, 48, 2, 0, 18, 19, 33, 34, 2, 0, 37, 37, - 40, 40, 2, 0, 38, 38, 41, 41, 2, 0, 39, 39, 42, 42, 2, 0, 47, 47, 50, 50, - 1, 0, 20, 22, 1, 0, 18, 19, 1, 0, 24, 25, 1, 0, 8, 9, 1, 0, 10, 11, 1, - 0, 8, 11, 1, 0, 12, 13, 196, 0, 96, 1, 0, 0, 0, 2, 3, 6, 0, -1, 0, 3, 97, - 5, 45, 0, 0, 4, 97, 5, 46, 0, 0, 5, 97, 5, 44, 0, 0, 6, 97, 5, 49, 0, 0, - 7, 97, 7, 0, 0, 0, 8, 97, 5, 50, 0, 0, 9, 10, 5, 6, 0, 0, 10, 11, 5, 47, - 0, 0, 11, 97, 5, 7, 0, 0, 12, 13, 5, 1, 0, 0, 13, 14, 3, 0, 0, 0, 14, 15, - 5, 2, 0, 0, 15, 97, 1, 0, 0, 0, 16, 17, 5, 3, 0, 0, 17, 22, 3, 0, 0, 0, - 18, 19, 5, 4, 0, 0, 19, 21, 3, 0, 0, 0, 20, 18, 1, 0, 0, 0, 21, 24, 1, - 0, 0, 0, 22, 20, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 26, 1, 0, 0, 0, 24, - 22, 1, 0, 0, 0, 25, 27, 5, 4, 0, 0, 26, 25, 1, 0, 0, 0, 26, 27, 1, 0, 0, - 0, 27, 28, 1, 0, 0, 0, 28, 29, 5, 5, 0, 0, 29, 97, 1, 0, 0, 0, 30, 97, - 5, 36, 0, 0, 31, 32, 5, 15, 0, 0, 32, 97, 3, 0, 0, 26, 33, 34, 5, 16, 0, - 0, 34, 35, 5, 1, 0, 0, 35, 36, 5, 47, 0, 0, 36, 37, 5, 4, 0, 0, 37, 38, - 5, 49, 0, 0, 38, 97, 5, 2, 0, 0, 39, 40, 5, 17, 0, 0, 40, 41, 5, 1, 0, - 0, 41, 42, 5, 47, 0, 0, 42, 43, 5, 4, 0, 0, 43, 46, 5, 49, 0, 0, 44, 45, - 5, 4, 0, 0, 45, 47, 3, 0, 0, 0, 46, 44, 1, 0, 0, 0, 46, 47, 1, 0, 0, 0, - 47, 48, 1, 0, 0, 0, 48, 97, 5, 2, 0, 0, 49, 50, 7, 1, 0, 0, 50, 97, 3, - 0, 0, 21, 51, 52, 7, 2, 0, 0, 52, 53, 5, 1, 0, 0, 53, 54, 3, 0, 0, 0, 54, - 55, 5, 4, 0, 0, 55, 56, 3, 0, 0, 0, 56, 57, 5, 2, 0, 0, 57, 97, 1, 0, 0, - 0, 58, 59, 7, 3, 0, 0, 59, 60, 5, 1, 0, 0, 60, 61, 3, 0, 0, 0, 61, 62, - 5, 4, 0, 0, 62, 63, 3, 0, 0, 0, 63, 64, 5, 2, 0, 0, 64, 97, 1, 0, 0, 0, - 65, 66, 7, 4, 0, 0, 66, 67, 5, 1, 0, 0, 67, 68, 3, 0, 0, 0, 68, 69, 5, - 4, 0, 0, 69, 70, 3, 0, 0, 0, 70, 71, 5, 2, 0, 0, 71, 97, 1, 0, 0, 0, 72, - 73, 5, 43, 0, 0, 73, 74, 5, 1, 0, 0, 74, 75, 7, 5, 0, 0, 75, 97, 5, 2, - 0, 0, 76, 77, 5, 47, 0, 0, 77, 89, 5, 1, 0, 0, 78, 83, 3, 0, 0, 0, 79, - 80, 5, 4, 0, 0, 80, 82, 3, 0, 0, 0, 81, 79, 1, 0, 0, 0, 82, 85, 1, 0, 0, - 0, 83, 81, 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 87, 1, 0, 0, 0, 85, 83, - 1, 0, 0, 0, 86, 88, 5, 4, 0, 0, 87, 86, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, - 88, 90, 1, 0, 0, 0, 89, 78, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 91, 1, - 0, 0, 0, 91, 97, 5, 2, 0, 0, 92, 93, 7, 5, 0, 0, 93, 97, 5, 31, 0, 0, 94, - 95, 7, 5, 0, 0, 95, 97, 5, 32, 0, 0, 96, 2, 1, 0, 0, 0, 96, 4, 1, 0, 0, - 0, 96, 5, 1, 0, 0, 0, 96, 6, 1, 0, 0, 0, 96, 7, 1, 0, 0, 0, 96, 8, 1, 0, - 0, 0, 96, 9, 1, 0, 0, 0, 96, 12, 1, 0, 0, 0, 96, 16, 1, 0, 0, 0, 96, 30, - 1, 0, 0, 0, 96, 31, 1, 0, 0, 0, 96, 33, 1, 0, 0, 0, 96, 39, 1, 0, 0, 0, - 96, 49, 1, 0, 0, 0, 96, 51, 1, 0, 0, 0, 96, 58, 1, 0, 0, 0, 96, 65, 1, - 0, 0, 0, 96, 72, 1, 0, 0, 0, 96, 76, 1, 0, 0, 0, 96, 92, 1, 0, 0, 0, 96, - 94, 1, 0, 0, 0, 97, 152, 1, 0, 0, 0, 98, 99, 10, 22, 0, 0, 99, 100, 5, - 23, 0, 0, 100, 151, 3, 0, 0, 23, 101, 102, 10, 20, 0, 0, 102, 103, 7, 6, - 0, 0, 103, 151, 3, 0, 0, 21, 104, 105, 10, 19, 0, 0, 105, 106, 7, 7, 0, - 0, 106, 151, 3, 0, 0, 20, 107, 108, 10, 18, 0, 0, 108, 109, 7, 8, 0, 0, - 109, 151, 3, 0, 0, 19, 110, 112, 10, 17, 0, 0, 111, 113, 5, 34, 0, 0, 112, - 111, 1, 0, 0, 0, 112, 113, 1, 0, 0, 0, 113, 114, 1, 0, 0, 0, 114, 115, - 5, 35, 0, 0, 115, 151, 3, 0, 0, 18, 116, 117, 10, 11, 0, 0, 117, 118, 7, - 9, 0, 0, 118, 119, 7, 5, 0, 0, 119, 120, 7, 9, 0, 0, 120, 151, 3, 0, 0, - 12, 121, 122, 10, 10, 0, 0, 122, 123, 7, 10, 0, 0, 123, 124, 7, 5, 0, 0, - 124, 125, 7, 10, 0, 0, 125, 151, 3, 0, 0, 11, 126, 127, 10, 9, 0, 0, 127, - 128, 7, 11, 0, 0, 128, 151, 3, 0, 0, 10, 129, 130, 10, 8, 0, 0, 130, 131, - 7, 12, 0, 0, 131, 151, 3, 0, 0, 9, 132, 133, 10, 7, 0, 0, 133, 134, 5, - 26, 0, 0, 134, 151, 3, 0, 0, 8, 135, 136, 10, 6, 0, 0, 136, 137, 5, 28, - 0, 0, 137, 151, 3, 0, 0, 7, 138, 139, 10, 5, 0, 0, 139, 140, 5, 27, 0, - 0, 140, 151, 3, 0, 0, 6, 141, 142, 10, 4, 0, 0, 142, 143, 5, 29, 0, 0, - 143, 151, 3, 0, 0, 5, 144, 145, 10, 3, 0, 0, 145, 146, 5, 30, 0, 0, 146, - 151, 3, 0, 0, 4, 147, 148, 10, 25, 0, 0, 148, 149, 5, 14, 0, 0, 149, 151, - 5, 49, 0, 0, 150, 98, 1, 0, 0, 0, 150, 101, 1, 0, 0, 0, 150, 104, 1, 0, - 0, 0, 150, 107, 1, 0, 0, 0, 150, 110, 1, 0, 0, 0, 150, 116, 1, 0, 0, 0, - 150, 121, 1, 0, 0, 0, 150, 126, 1, 0, 0, 0, 150, 129, 1, 0, 0, 0, 150, - 132, 1, 0, 0, 0, 150, 135, 1, 0, 0, 0, 150, 138, 1, 0, 0, 0, 150, 141, - 1, 0, 0, 0, 150, 144, 1, 0, 0, 0, 150, 147, 1, 0, 0, 0, 151, 154, 1, 0, - 0, 0, 152, 150, 1, 0, 0, 0, 152, 153, 1, 0, 0, 0, 153, 1, 1, 0, 0, 0, 154, - 152, 1, 0, 0, 0, 10, 22, 26, 46, 83, 87, 89, 96, 112, 150, 152, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 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, 124, 8, 0, 10, 0, + 12, 0, 127, 9, 0, 1, 0, 3, 0, 130, 8, 0, 3, 0, 132, 8, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 3, 0, 139, 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, 155, 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, 193, + 8, 0, 10, 0, 12, 0, 196, 9, 0, 1, 0, 0, 1, 0, 1, 0, 0, 13, 1, 0, 54, 55, + 2, 0, 18, 19, 33, 34, 2, 0, 37, 37, 40, 40, 2, 0, 38, 38, 41, 41, 2, 0, + 39, 39, 42, 42, 2, 0, 54, 54, 57, 57, 1, 0, 20, 22, 1, 0, 18, 19, 1, 0, + 24, 25, 1, 0, 8, 9, 1, 0, 10, 11, 1, 0, 8, 11, 1, 0, 12, 13, 245, 0, 138, + 1, 0, 0, 0, 2, 3, 6, 0, -1, 0, 3, 139, 5, 52, 0, 0, 4, 139, 5, 53, 0, 0, + 5, 139, 5, 51, 0, 0, 6, 139, 5, 56, 0, 0, 7, 139, 7, 0, 0, 0, 8, 139, 5, + 57, 0, 0, 9, 10, 5, 6, 0, 0, 10, 11, 5, 54, 0, 0, 11, 139, 5, 7, 0, 0, + 12, 13, 5, 1, 0, 0, 13, 14, 3, 0, 0, 0, 14, 15, 5, 2, 0, 0, 15, 139, 1, + 0, 0, 0, 16, 17, 5, 3, 0, 0, 17, 22, 3, 0, 0, 0, 18, 19, 5, 4, 0, 0, 19, + 21, 3, 0, 0, 0, 20, 18, 1, 0, 0, 0, 21, 24, 1, 0, 0, 0, 22, 20, 1, 0, 0, + 0, 22, 23, 1, 0, 0, 0, 23, 26, 1, 0, 0, 0, 24, 22, 1, 0, 0, 0, 25, 27, + 5, 4, 0, 0, 26, 25, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, + 28, 29, 5, 5, 0, 0, 29, 139, 1, 0, 0, 0, 30, 139, 5, 36, 0, 0, 31, 32, + 5, 15, 0, 0, 32, 139, 3, 0, 0, 33, 33, 34, 5, 16, 0, 0, 34, 35, 5, 1, 0, + 0, 35, 36, 5, 54, 0, 0, 36, 37, 5, 4, 0, 0, 37, 38, 5, 56, 0, 0, 38, 139, + 5, 2, 0, 0, 39, 40, 5, 17, 0, 0, 40, 41, 5, 1, 0, 0, 41, 42, 5, 54, 0, + 0, 42, 43, 5, 4, 0, 0, 43, 46, 5, 56, 0, 0, 44, 45, 5, 4, 0, 0, 45, 47, + 3, 0, 0, 0, 46, 44, 1, 0, 0, 0, 46, 47, 1, 0, 0, 0, 47, 48, 1, 0, 0, 0, + 48, 139, 5, 2, 0, 0, 49, 50, 7, 1, 0, 0, 50, 139, 3, 0, 0, 28, 51, 52, + 7, 2, 0, 0, 52, 53, 5, 1, 0, 0, 53, 54, 3, 0, 0, 0, 54, 55, 5, 4, 0, 0, + 55, 56, 3, 0, 0, 0, 56, 57, 5, 2, 0, 0, 57, 139, 1, 0, 0, 0, 58, 59, 7, + 3, 0, 0, 59, 60, 5, 1, 0, 0, 60, 61, 3, 0, 0, 0, 61, 62, 5, 4, 0, 0, 62, + 63, 3, 0, 0, 0, 63, 64, 5, 2, 0, 0, 64, 139, 1, 0, 0, 0, 65, 66, 7, 4, + 0, 0, 66, 67, 5, 1, 0, 0, 67, 68, 3, 0, 0, 0, 68, 69, 5, 4, 0, 0, 69, 70, + 3, 0, 0, 0, 70, 71, 5, 2, 0, 0, 71, 139, 1, 0, 0, 0, 72, 73, 5, 44, 0, + 0, 73, 74, 5, 1, 0, 0, 74, 75, 5, 54, 0, 0, 75, 76, 5, 4, 0, 0, 76, 77, + 5, 56, 0, 0, 77, 139, 5, 2, 0, 0, 78, 79, 5, 45, 0, 0, 79, 80, 5, 1, 0, + 0, 80, 81, 5, 54, 0, 0, 81, 82, 5, 4, 0, 0, 82, 83, 5, 56, 0, 0, 83, 139, + 5, 2, 0, 0, 84, 85, 5, 46, 0, 0, 85, 86, 5, 1, 0, 0, 86, 87, 5, 54, 0, + 0, 87, 88, 5, 4, 0, 0, 88, 89, 5, 56, 0, 0, 89, 139, 5, 2, 0, 0, 90, 91, + 5, 47, 0, 0, 91, 92, 5, 1, 0, 0, 92, 93, 5, 54, 0, 0, 93, 94, 5, 4, 0, + 0, 94, 95, 5, 56, 0, 0, 95, 139, 5, 2, 0, 0, 96, 97, 5, 48, 0, 0, 97, 98, + 5, 1, 0, 0, 98, 99, 5, 54, 0, 0, 99, 100, 5, 4, 0, 0, 100, 101, 5, 56, + 0, 0, 101, 139, 5, 2, 0, 0, 102, 103, 5, 49, 0, 0, 103, 104, 5, 1, 0, 0, + 104, 105, 5, 54, 0, 0, 105, 106, 5, 4, 0, 0, 106, 107, 5, 56, 0, 0, 107, + 139, 5, 2, 0, 0, 108, 109, 5, 50, 0, 0, 109, 110, 5, 1, 0, 0, 110, 111, + 5, 54, 0, 0, 111, 112, 5, 4, 0, 0, 112, 113, 5, 56, 0, 0, 113, 139, 5, + 2, 0, 0, 114, 115, 5, 43, 0, 0, 115, 116, 5, 1, 0, 0, 116, 117, 7, 5, 0, + 0, 117, 139, 5, 2, 0, 0, 118, 119, 5, 54, 0, 0, 119, 131, 5, 1, 0, 0, 120, + 125, 3, 0, 0, 0, 121, 122, 5, 4, 0, 0, 122, 124, 3, 0, 0, 0, 123, 121, + 1, 0, 0, 0, 124, 127, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 125, 126, 1, 0, + 0, 0, 126, 129, 1, 0, 0, 0, 127, 125, 1, 0, 0, 0, 128, 130, 5, 4, 0, 0, + 129, 128, 1, 0, 0, 0, 129, 130, 1, 0, 0, 0, 130, 132, 1, 0, 0, 0, 131, + 120, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 139, + 5, 2, 0, 0, 134, 135, 7, 5, 0, 0, 135, 139, 5, 31, 0, 0, 136, 137, 7, 5, + 0, 0, 137, 139, 5, 32, 0, 0, 138, 2, 1, 0, 0, 0, 138, 4, 1, 0, 0, 0, 138, + 5, 1, 0, 0, 0, 138, 6, 1, 0, 0, 0, 138, 7, 1, 0, 0, 0, 138, 8, 1, 0, 0, + 0, 138, 9, 1, 0, 0, 0, 138, 12, 1, 0, 0, 0, 138, 16, 1, 0, 0, 0, 138, 30, + 1, 0, 0, 0, 138, 31, 1, 0, 0, 0, 138, 33, 1, 0, 0, 0, 138, 39, 1, 0, 0, + 0, 138, 49, 1, 0, 0, 0, 138, 51, 1, 0, 0, 0, 138, 58, 1, 0, 0, 0, 138, + 65, 1, 0, 0, 0, 138, 72, 1, 0, 0, 0, 138, 78, 1, 0, 0, 0, 138, 84, 1, 0, + 0, 0, 138, 90, 1, 0, 0, 0, 138, 96, 1, 0, 0, 0, 138, 102, 1, 0, 0, 0, 138, + 108, 1, 0, 0, 0, 138, 114, 1, 0, 0, 0, 138, 118, 1, 0, 0, 0, 138, 134, + 1, 0, 0, 0, 138, 136, 1, 0, 0, 0, 139, 194, 1, 0, 0, 0, 140, 141, 10, 29, + 0, 0, 141, 142, 5, 23, 0, 0, 142, 193, 3, 0, 0, 30, 143, 144, 10, 27, 0, + 0, 144, 145, 7, 6, 0, 0, 145, 193, 3, 0, 0, 28, 146, 147, 10, 26, 0, 0, + 147, 148, 7, 7, 0, 0, 148, 193, 3, 0, 0, 27, 149, 150, 10, 25, 0, 0, 150, + 151, 7, 8, 0, 0, 151, 193, 3, 0, 0, 26, 152, 154, 10, 24, 0, 0, 153, 155, + 5, 34, 0, 0, 154, 153, 1, 0, 0, 0, 154, 155, 1, 0, 0, 0, 155, 156, 1, 0, + 0, 0, 156, 157, 5, 35, 0, 0, 157, 193, 3, 0, 0, 25, 158, 159, 10, 11, 0, + 0, 159, 160, 7, 9, 0, 0, 160, 161, 7, 5, 0, 0, 161, 162, 7, 9, 0, 0, 162, + 193, 3, 0, 0, 12, 163, 164, 10, 10, 0, 0, 164, 165, 7, 10, 0, 0, 165, 166, + 7, 5, 0, 0, 166, 167, 7, 10, 0, 0, 167, 193, 3, 0, 0, 11, 168, 169, 10, + 9, 0, 0, 169, 170, 7, 11, 0, 0, 170, 193, 3, 0, 0, 10, 171, 172, 10, 8, + 0, 0, 172, 173, 7, 12, 0, 0, 173, 193, 3, 0, 0, 9, 174, 175, 10, 7, 0, + 0, 175, 176, 5, 26, 0, 0, 176, 193, 3, 0, 0, 8, 177, 178, 10, 6, 0, 0, + 178, 179, 5, 28, 0, 0, 179, 193, 3, 0, 0, 7, 180, 181, 10, 5, 0, 0, 181, + 182, 5, 27, 0, 0, 182, 193, 3, 0, 0, 6, 183, 184, 10, 4, 0, 0, 184, 185, + 5, 29, 0, 0, 185, 193, 3, 0, 0, 5, 186, 187, 10, 3, 0, 0, 187, 188, 5, + 30, 0, 0, 188, 193, 3, 0, 0, 4, 189, 190, 10, 32, 0, 0, 190, 191, 5, 14, + 0, 0, 191, 193, 5, 56, 0, 0, 192, 140, 1, 0, 0, 0, 192, 143, 1, 0, 0, 0, + 192, 146, 1, 0, 0, 0, 192, 149, 1, 0, 0, 0, 192, 152, 1, 0, 0, 0, 192, + 158, 1, 0, 0, 0, 192, 163, 1, 0, 0, 0, 192, 168, 1, 0, 0, 0, 192, 171, + 1, 0, 0, 0, 192, 174, 1, 0, 0, 0, 192, 177, 1, 0, 0, 0, 192, 180, 1, 0, + 0, 0, 192, 183, 1, 0, 0, 0, 192, 186, 1, 0, 0, 0, 192, 189, 1, 0, 0, 0, + 193, 196, 1, 0, 0, 0, 194, 192, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, + 1, 1, 0, 0, 0, 196, 194, 1, 0, 0, 0, 10, 22, 26, 46, 125, 129, 131, 138, + 154, 192, 194, } deserializer := antlr.NewATNDeserializer(nil) staticData.atn = deserializer.Deserialize(staticData.serializedATN) @@ -208,15 +230,22 @@ const ( PlanParserArrayContainsAll = 41 PlanParserArrayContainsAny = 42 PlanParserArrayLength = 43 - PlanParserBooleanConstant = 44 - PlanParserIntegerConstant = 45 - PlanParserFloatingConstant = 46 - PlanParserIdentifier = 47 - PlanParserMeta = 48 - PlanParserStringLiteral = 49 - PlanParserJSONIdentifier = 50 - PlanParserWhitespace = 51 - PlanParserNewline = 52 + PlanParserSTEuqals = 44 + PlanParserSTTouches = 45 + PlanParserSTOverlaps = 46 + PlanParserSTCrosses = 47 + PlanParserSTContains = 48 + PlanParserSTIntersects = 49 + PlanParserSTWithin = 50 + PlanParserBooleanConstant = 51 + PlanParserIntegerConstant = 52 + PlanParserFloatingConstant = 53 + PlanParserIdentifier = 54 + PlanParserMeta = 55 + PlanParserStringLiteral = 56 + PlanParserJSONIdentifier = 57 + PlanParserWhitespace = 58 + PlanParserNewline = 59 ) // PlanParserRULE_expr is the PlanParser rule. @@ -728,6 +757,46 @@ func (s *IdentifierContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } +type STIntersectsContext struct { + ExprContext +} + +func NewSTIntersectsContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STIntersectsContext { + var p = new(STIntersectsContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *STIntersectsContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *STIntersectsContext) STIntersects() antlr.TerminalNode { + return s.GetToken(PlanParserSTIntersects, 0) +} + +func (s *STIntersectsContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *STIntersectsContext) StringLiteral() antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, 0) +} + +func (s *STIntersectsContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitSTIntersects(s) + + default: + return t.VisitChildren(s) + } +} + type LikeContext struct { ExprContext } @@ -1162,6 +1231,46 @@ func (s *CallContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } +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 @@ -1678,6 +1787,86 @@ func (s *TextMatchContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } +type STTouchesContext struct { + ExprContext +} + +func NewSTTouchesContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STTouchesContext { + var p = new(STTouchesContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *STTouchesContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *STTouchesContext) STTouches() antlr.TerminalNode { + return s.GetToken(PlanParserSTTouches, 0) +} + +func (s *STTouchesContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *STTouchesContext) StringLiteral() antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, 0) +} + +func (s *STTouchesContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitSTTouches(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 TermContext struct { ExprContext op antlr.Token @@ -1837,6 +2026,46 @@ func (s *JSONContainsContext) Accept(visitor antlr.ParseTreeVisitor) interface{} } } +type STWithinContext struct { + ExprContext +} + +func NewSTWithinContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STWithinContext { + var p = new(STWithinContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *STWithinContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *STWithinContext) STWithin() antlr.TerminalNode { + return s.GetToken(PlanParserSTWithin, 0) +} + +func (s *STWithinContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *STWithinContext) StringLiteral() antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, 0) +} + +func (s *STWithinContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitSTWithin(s) + + default: + return t.VisitChildren(s) + } +} + type RangeContext struct { ExprContext op1 antlr.Token @@ -2377,6 +2606,46 @@ func (s *BitAndContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { } } +type STEuqalsContext struct { + ExprContext +} + +func NewSTEuqalsContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *STEuqalsContext { + var p = new(STEuqalsContext) + + InitEmptyExprContext(&p.ExprContext) + p.parser = parser + p.CopyAll(ctx.(*ExprContext)) + + return p +} + +func (s *STEuqalsContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *STEuqalsContext) STEuqals() antlr.TerminalNode { + return s.GetToken(PlanParserSTEuqals, 0) +} + +func (s *STEuqalsContext) Identifier() antlr.TerminalNode { + return s.GetToken(PlanParserIdentifier, 0) +} + +func (s *STEuqalsContext) StringLiteral() antlr.TerminalNode { + return s.GetToken(PlanParserStringLiteral, 0) +} + +func (s *STEuqalsContext) Accept(visitor antlr.ParseTreeVisitor) interface{} { + switch t := visitor.(type) { + case PlanVisitor: + return t.VisitSTEuqals(s) + + default: + return t.VisitChildren(s) + } +} + type IsNullContext struct { ExprContext } @@ -2490,6 +2759,46 @@ 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) } @@ -2508,7 +2817,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { var _alt int p.EnterOuterAlt(localctx, 1) - p.SetState(96) + p.SetState(138) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -2756,7 +3065,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { p.SetState(32) - p.expr(26) + p.expr(33) } case 12: @@ -2911,7 +3220,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { p.SetState(50) - p.expr(21) + p.expr(28) } case 15: @@ -3059,12 +3368,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } case 18: - localctx = NewArrayLengthContext(p, localctx) + localctx = NewSTEuqalsContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { p.SetState(72) - p.Match(PlanParserArrayLength) + p.Match(PlanParserSTEuqals) if p.HasError() { // Recognition error - abort rule goto errorExit @@ -3080,6 +3389,377 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { p.SetState(74) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(75) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(76) + p.Match(PlanParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(77) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 19: + localctx = NewSTTouchesContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(78) + p.Match(PlanParserSTTouches) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(79) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(80) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(81) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(82) + p.Match(PlanParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(83) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 20: + localctx = NewSTOverlapsContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(84) + p.Match(PlanParserSTOverlaps) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(85) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(86) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(87) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(88) + p.Match(PlanParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(89) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 21: + localctx = NewSTCrossesContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(90) + p.Match(PlanParserSTCrosses) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(91) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(92) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(93) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(94) + p.Match(PlanParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(95) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 22: + localctx = NewSTContainsContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(96) + p.Match(PlanParserSTContains) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(97) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(98) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(99) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(100) + p.Match(PlanParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(101) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 23: + localctx = NewSTIntersectsContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(102) + p.Match(PlanParserSTIntersects) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(103) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(104) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(105) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(106) + p.Match(PlanParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(107) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 24: + localctx = NewSTWithinContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(108) + p.Match(PlanParserSTWithin) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(109) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(110) + p.Match(PlanParserIdentifier) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(111) + p.Match(PlanParserT__3) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(112) + p.Match(PlanParserStringLiteral) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(113) + p.Match(PlanParserT__1) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + + case 25: + localctx = NewArrayLengthContext(p, localctx) + p.SetParserRuleContext(localctx) + _prevctx = localctx + { + p.SetState(114) + p.Match(PlanParserArrayLength) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(115) + p.Match(PlanParserT__0) + if p.HasError() { + // Recognition error - abort rule + goto errorExit + } + } + { + p.SetState(116) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { @@ -3090,7 +3770,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(75) + p.SetState(117) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -3098,12 +3778,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 19: + case 26: localctx = NewCallContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(76) + p.SetState(118) p.Match(PlanParserIdentifier) if p.HasError() { // Recognition error - abort rule @@ -3111,26 +3791,26 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(77) + p.SetState(119) p.Match(PlanParserT__0) if p.HasError() { // Recognition error - abort rule goto errorExit } } - p.SetState(89) + p.SetState(131) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit } _la = p.GetTokenStream().LA(1) - if (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&2251756865028170) != 0 { + if (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&288230333203054666) != 0 { { - p.SetState(78) + p.SetState(120) p.expr(0) } - p.SetState(83) + p.SetState(125) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3142,7 +3822,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { if _alt == 1 { { - p.SetState(79) + p.SetState(121) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -3150,12 +3830,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(80) + p.SetState(122) p.expr(0) } } - p.SetState(85) + p.SetState(127) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3165,7 +3845,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { goto errorExit } } - p.SetState(87) + p.SetState(129) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3174,7 +3854,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { if _la == PlanParserT__3 { { - p.SetState(86) + p.SetState(128) p.Match(PlanParserT__3) if p.HasError() { // Recognition error - abort rule @@ -3186,7 +3866,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { - p.SetState(91) + p.SetState(133) p.Match(PlanParserT__1) if p.HasError() { // Recognition error - abort rule @@ -3194,12 +3874,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 20: + case 27: localctx = NewIsNullContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(92) + p.SetState(134) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { @@ -3210,7 +3890,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(93) + p.SetState(135) p.Match(PlanParserISNULL) if p.HasError() { // Recognition error - abort rule @@ -3218,12 +3898,12 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - case 21: + case 28: localctx = NewIsNotNullContext(p, localctx) p.SetParserRuleContext(localctx) _prevctx = localctx { - p.SetState(94) + p.SetState(136) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { @@ -3234,7 +3914,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(95) + p.SetState(137) p.Match(PlanParserISNOTNULL) if p.HasError() { // Recognition error - abort rule @@ -3246,7 +3926,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { goto errorExit } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(152) + p.SetState(194) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3261,7 +3941,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { p.TriggerExitRuleEvent() } _prevctx = localctx - p.SetState(150) + p.SetState(192) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3271,14 +3951,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(98) + p.SetState(140) - if !(p.Precpred(p.GetParserRuleContext(), 22)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 22)", "")) + if !(p.Precpred(p.GetParserRuleContext(), 29)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 29)", "")) goto errorExit } { - p.SetState(99) + p.SetState(141) p.Match(PlanParserPOW) if p.HasError() { // Recognition error - abort rule @@ -3286,21 +3966,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(100) - p.expr(23) + p.SetState(142) + p.expr(30) } case 2: localctx = NewMulDivModContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(101) + p.SetState(143) - if !(p.Precpred(p.GetParserRuleContext(), 20)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 20)", "")) + if !(p.Precpred(p.GetParserRuleContext(), 27)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 27)", "")) goto errorExit } { - p.SetState(102) + p.SetState(144) var _lt = p.GetTokenStream().LT(1) @@ -3318,21 +3998,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(103) - p.expr(21) + p.SetState(145) + p.expr(28) } case 3: localctx = NewAddSubContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(104) + p.SetState(146) - if !(p.Precpred(p.GetParserRuleContext(), 19)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 19)", "")) + if !(p.Precpred(p.GetParserRuleContext(), 26)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 26)", "")) goto errorExit } { - p.SetState(105) + p.SetState(147) var _lt = p.GetTokenStream().LT(1) @@ -3350,21 +4030,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(106) - p.expr(20) + p.SetState(148) + p.expr(27) } case 4: localctx = NewShiftContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(107) + p.SetState(149) - if !(p.Precpred(p.GetParserRuleContext(), 18)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 18)", "")) + if !(p.Precpred(p.GetParserRuleContext(), 25)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 25)", "")) goto errorExit } { - p.SetState(108) + p.SetState(150) var _lt = p.GetTokenStream().LT(1) @@ -3382,20 +4062,20 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(109) - p.expr(19) + p.SetState(151) + p.expr(26) } case 5: localctx = NewTermContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(110) + p.SetState(152) - if !(p.Precpred(p.GetParserRuleContext(), 17)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 17)", "")) + if !(p.Precpred(p.GetParserRuleContext(), 24)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 24)", "")) goto errorExit } - p.SetState(112) + p.SetState(154) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3404,7 +4084,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { if _la == PlanParserNOT { { - p.SetState(111) + p.SetState(153) var _m = p.Match(PlanParserNOT) @@ -3417,7 +4097,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } { - p.SetState(114) + p.SetState(156) p.Match(PlanParserIN) if p.HasError() { // Recognition error - abort rule @@ -3425,21 +4105,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(115) - p.expr(18) + p.SetState(157) + p.expr(25) } case 6: localctx = NewRangeContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(116) + p.SetState(158) if !(p.Precpred(p.GetParserRuleContext(), 11)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 11)", "")) goto errorExit } { - p.SetState(117) + p.SetState(159) var _lt = p.GetTokenStream().LT(1) @@ -3457,7 +4137,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(118) + p.SetState(160) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { @@ -3468,7 +4148,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(119) + p.SetState(161) var _lt = p.GetTokenStream().LT(1) @@ -3486,21 +4166,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(120) + p.SetState(162) p.expr(12) } case 7: localctx = NewReverseRangeContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(121) + p.SetState(163) if !(p.Precpred(p.GetParserRuleContext(), 10)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 10)", "")) goto errorExit } { - p.SetState(122) + p.SetState(164) var _lt = p.GetTokenStream().LT(1) @@ -3518,7 +4198,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(123) + p.SetState(165) _la = p.GetTokenStream().LA(1) if !(_la == PlanParserIdentifier || _la == PlanParserJSONIdentifier) { @@ -3529,7 +4209,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(124) + p.SetState(166) var _lt = p.GetTokenStream().LT(1) @@ -3547,21 +4227,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(125) + p.SetState(167) p.expr(11) } case 8: localctx = NewRelationalContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(126) + p.SetState(168) if !(p.Precpred(p.GetParserRuleContext(), 9)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 9)", "")) goto errorExit } { - p.SetState(127) + p.SetState(169) var _lt = p.GetTokenStream().LT(1) @@ -3579,21 +4259,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(128) + p.SetState(170) p.expr(10) } case 9: localctx = NewEqualityContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(129) + p.SetState(171) if !(p.Precpred(p.GetParserRuleContext(), 8)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 8)", "")) goto errorExit } { - p.SetState(130) + p.SetState(172) var _lt = p.GetTokenStream().LT(1) @@ -3611,21 +4291,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(131) + p.SetState(173) p.expr(9) } case 10: localctx = NewBitAndContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(132) + p.SetState(174) if !(p.Precpred(p.GetParserRuleContext(), 7)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 7)", "")) goto errorExit } { - p.SetState(133) + p.SetState(175) p.Match(PlanParserBAND) if p.HasError() { // Recognition error - abort rule @@ -3633,21 +4313,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(134) + p.SetState(176) p.expr(8) } case 11: localctx = NewBitXorContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(135) + p.SetState(177) if !(p.Precpred(p.GetParserRuleContext(), 6)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 6)", "")) goto errorExit } { - p.SetState(136) + p.SetState(178) p.Match(PlanParserBXOR) if p.HasError() { // Recognition error - abort rule @@ -3655,21 +4335,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(137) + p.SetState(179) p.expr(7) } case 12: localctx = NewBitOrContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(138) + p.SetState(180) if !(p.Precpred(p.GetParserRuleContext(), 5)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", "")) goto errorExit } { - p.SetState(139) + p.SetState(181) p.Match(PlanParserBOR) if p.HasError() { // Recognition error - abort rule @@ -3677,21 +4357,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(140) + p.SetState(182) p.expr(6) } case 13: localctx = NewLogicalAndContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(141) + p.SetState(183) if !(p.Precpred(p.GetParserRuleContext(), 4)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", "")) goto errorExit } { - p.SetState(142) + p.SetState(184) p.Match(PlanParserAND) if p.HasError() { // Recognition error - abort rule @@ -3699,21 +4379,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(143) + p.SetState(185) p.expr(5) } case 14: localctx = NewLogicalOrContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(144) + p.SetState(186) if !(p.Precpred(p.GetParserRuleContext(), 3)) { p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) goto errorExit } { - p.SetState(145) + p.SetState(187) p.Match(PlanParserOR) if p.HasError() { // Recognition error - abort rule @@ -3721,21 +4401,21 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(146) + p.SetState(188) p.expr(4) } case 15: localctx = NewLikeContext(p, NewExprContext(p, _parentctx, _parentState)) p.PushNewRecursionContext(localctx, _startState, PlanParserRULE_expr) - p.SetState(147) + p.SetState(189) - if !(p.Precpred(p.GetParserRuleContext(), 25)) { - p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 25)", "")) + if !(p.Precpred(p.GetParserRuleContext(), 32)) { + p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 32)", "")) goto errorExit } { - p.SetState(148) + p.SetState(190) p.Match(PlanParserLIKE) if p.HasError() { // Recognition error - abort rule @@ -3743,7 +4423,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } { - p.SetState(149) + p.SetState(191) p.Match(PlanParserStringLiteral) if p.HasError() { // Recognition error - abort rule @@ -3756,7 +4436,7 @@ func (p *PlanParser) expr(_p int) (localctx IExprContext) { } } - p.SetState(154) + p.SetState(196) p.GetErrorHandler().Sync(p) if p.HasError() { goto errorExit @@ -3797,19 +4477,19 @@ func (p *PlanParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex in func (p *PlanParser) Expr_Sempred(localctx antlr.RuleContext, predIndex int) bool { switch predIndex { case 0: - return p.Precpred(p.GetParserRuleContext(), 22) + return p.Precpred(p.GetParserRuleContext(), 29) case 1: - return p.Precpred(p.GetParserRuleContext(), 20) + return p.Precpred(p.GetParserRuleContext(), 27) case 2: - return p.Precpred(p.GetParserRuleContext(), 19) + return p.Precpred(p.GetParserRuleContext(), 26) case 3: - return p.Precpred(p.GetParserRuleContext(), 18) + return p.Precpred(p.GetParserRuleContext(), 25) case 4: - return p.Precpred(p.GetParserRuleContext(), 17) + return p.Precpred(p.GetParserRuleContext(), 24) case 5: return p.Precpred(p.GetParserRuleContext(), 11) @@ -3839,7 +4519,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(), 25) + return p.Precpred(p.GetParserRuleContext(), 32) 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 264996e51c..004535c141 100644 --- a/internal/parser/planparserv2/generated/plan_visitor.go +++ b/internal/parser/planparserv2/generated/plan_visitor.go @@ -34,6 +34,9 @@ type PlanVisitor interface { // Visit a parse tree produced by PlanParser#Identifier. VisitIdentifier(ctx *IdentifierContext) interface{} + // Visit a parse tree produced by PlanParser#STIntersects. + VisitSTIntersects(ctx *STIntersectsContext) interface{} + // Visit a parse tree produced by PlanParser#Like. VisitLike(ctx *LikeContext) interface{} @@ -55,6 +58,9 @@ type PlanVisitor 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{} @@ -79,12 +85,21 @@ type PlanVisitor 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{} // Visit a parse tree produced by PlanParser#JSONContains. VisitJSONContains(ctx *JSONContainsContext) interface{} + // Visit a parse tree produced by PlanParser#STWithin. + VisitSTWithin(ctx *STWithinContext) interface{} + // Visit a parse tree produced by PlanParser#Range. VisitRange(ctx *RangeContext) interface{} @@ -109,9 +124,15 @@ type PlanVisitor 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#Power. VisitPower(ctx *PowerContext) interface{} + + // Visit a parse tree produced by PlanParser#STOverlaps. + VisitSTOverlaps(ctx *STOverlapsContext) interface{} } diff --git a/internal/parser/planparserv2/parser_visitor.go b/internal/parser/planparserv2/parser_visitor.go index f0dcb1d54c..f1ba868b1e 100644 --- a/internal/parser/planparserv2/parser_visitor.go +++ b/internal/parser/planparserv2/parser_visitor.go @@ -1535,3 +1535,218 @@ func (v *ParserVisitor) VisitTemplateVariable(ctx *parser.TemplateVariableContex }, } } + +func (v *ParserVisitor) VisitSTEuqals(ctx *parser.STEuqalsContext) interface{} { + childExpr, err := v.translateIdentifier(ctx.Identifier().GetText()) + if err != nil { + return err + } + columnInfo := toColumnInfo(childExpr) + if columnInfo == nil || + (!typeutil.IsGeometryType(columnInfo.GetDataType())) { + return fmt.Errorf( + "STEuqals operation are only supported on geometry fields now, got: %s", ctx.GetText()) + } + element := ctx.StringLiteral().GetText() + if err := getError(element); err != nil { + return err + } + expr := &planpb.Expr{ + Expr: &planpb.Expr_GisfunctionFilterExpr{ + GisfunctionFilterExpr: &planpb.GISFunctionFilterExpr{ + ColumnInfo: columnInfo, + WktString: element[1 : len(element)-1], + Op: planpb.GISFunctionFilterExpr_Equals, + }, + }, + } + return &ExprWithType{ + expr: expr, + dataType: schemapb.DataType_Bool, + } +} + +func (v *ParserVisitor) VisitSTTouches(ctx *parser.STTouchesContext) interface{} { + childExpr, err := v.translateIdentifier(ctx.Identifier().GetText()) + if err != nil { + return err + } + columnInfo := toColumnInfo(childExpr) + if columnInfo == nil || + (!typeutil.IsGeometryType(columnInfo.GetDataType())) { + return fmt.Errorf( + "STTouches operation are only supported on geometry fields now, got: %s", ctx.GetText()) + } + element := ctx.StringLiteral().GetText() + if err := getError(element); err != nil { + return err + } + expr := &planpb.Expr{ + Expr: &planpb.Expr_GisfunctionFilterExpr{ + GisfunctionFilterExpr: &planpb.GISFunctionFilterExpr{ + ColumnInfo: columnInfo, + WktString: element[1 : len(element)-1], + Op: planpb.GISFunctionFilterExpr_Touches, + }, + }, + } + return &ExprWithType{ + expr: expr, + dataType: schemapb.DataType_Bool, + } +} + +func (v *ParserVisitor) VisitSTOverlaps(ctx *parser.STOverlapsContext) interface{} { + childExpr, err := v.translateIdentifier(ctx.Identifier().GetText()) + if err != nil { + return err + } + columnInfo := toColumnInfo(childExpr) + if columnInfo == nil || + (!typeutil.IsGeometryType(columnInfo.GetDataType())) { + return fmt.Errorf( + "STOverlaps operation are only supported on geometry fields now, got: %s", ctx.GetText()) + } + element := ctx.StringLiteral().GetText() + // log.Warn(element) + if err := getError(element); err != nil { + return err + } + expr := &planpb.Expr{ + Expr: &planpb.Expr_GisfunctionFilterExpr{ + GisfunctionFilterExpr: &planpb.GISFunctionFilterExpr{ + ColumnInfo: columnInfo, + WktString: element[1 : len(element)-1], + Op: planpb.GISFunctionFilterExpr_Overlaps, + }, + }, + } + return &ExprWithType{ + expr: expr, + dataType: schemapb.DataType_Bool, + } +} + +func (v *ParserVisitor) VisitSTCrosses(ctx *parser.STCrossesContext) interface{} { + childExpr, err := v.translateIdentifier(ctx.Identifier().GetText()) + if err != nil { + return err + } + columnInfo := toColumnInfo(childExpr) + if columnInfo == nil || + (!typeutil.IsGeometryType(columnInfo.GetDataType())) { + return fmt.Errorf( + "STCrosses operation are only supported on geometry fields now, got: %s", ctx.GetText()) + } + element := ctx.StringLiteral().GetText() + // log.Warn(element) + if err := getError(element); err != nil { + return err + } + expr := &planpb.Expr{ + Expr: &planpb.Expr_GisfunctionFilterExpr{ + GisfunctionFilterExpr: &planpb.GISFunctionFilterExpr{ + ColumnInfo: columnInfo, + WktString: element[1 : len(element)-1], + Op: planpb.GISFunctionFilterExpr_Crosses, + }, + }, + } + return &ExprWithType{ + expr: expr, + dataType: schemapb.DataType_Bool, + } +} + +func (v *ParserVisitor) VisitSTContains(ctx *parser.STContainsContext) interface{} { + childExpr, err := v.translateIdentifier(ctx.Identifier().GetText()) + if err != nil { + return err + } + columnInfo := toColumnInfo(childExpr) + if columnInfo == nil || + (!typeutil.IsGeometryType(columnInfo.GetDataType())) { + return fmt.Errorf( + "STContains operation are only supported on geometry fields now, got: %s", ctx.GetText()) + } + element := ctx.StringLiteral().GetText() // the wkt input + // log.Warn(element) + if err := getError(element); err != nil { + return err + } + expr := &planpb.Expr{ + Expr: &planpb.Expr_GisfunctionFilterExpr{ + GisfunctionFilterExpr: &planpb.GISFunctionFilterExpr{ + ColumnInfo: columnInfo, + WktString: element[1 : len(element)-1], + Op: planpb.GISFunctionFilterExpr_Contains, + }, + }, + } + return &ExprWithType{ + expr: expr, + dataType: schemapb.DataType_Bool, + } +} + +func (v *ParserVisitor) VisitSTIntersects(ctx *parser.STIntersectsContext) interface{} { + childExpr, err := v.translateIdentifier(ctx.Identifier().GetText()) + if err != nil { + return err + } + columnInfo := toColumnInfo(childExpr) + if columnInfo == nil || + (!typeutil.IsGeometryType(columnInfo.GetDataType())) { + return fmt.Errorf( + "STIntersects operation are only supported on geometry fields now, got: %s", ctx.GetText()) + } + element := ctx.StringLiteral().GetText() // the wkt input + // log.Warn(element) + if err := getError(element); err != nil { + return err + } + expr := &planpb.Expr{ + Expr: &planpb.Expr_GisfunctionFilterExpr{ + GisfunctionFilterExpr: &planpb.GISFunctionFilterExpr{ + ColumnInfo: columnInfo, + WktString: element[1 : len(element)-1], + Op: planpb.GISFunctionFilterExpr_Intersects, + }, + }, + } + return &ExprWithType{ + expr: expr, + dataType: schemapb.DataType_Bool, + } +} + +func (v *ParserVisitor) VisitSTWithin(ctx *parser.STWithinContext) interface{} { + childExpr, err := v.translateIdentifier(ctx.Identifier().GetText()) + if err != nil { + return err + } + columnInfo := toColumnInfo(childExpr) + if columnInfo == nil || + (!typeutil.IsGeometryType(columnInfo.GetDataType())) { + return fmt.Errorf( + "STWithin operation are only supported on geometry fields now, got: %s", ctx.GetText()) + } + element := ctx.StringLiteral().GetText() // the wkt input + // log.Warn(element) + if err := getError(element); err != nil { + return err + } + expr := &planpb.Expr{ + Expr: &planpb.Expr_GisfunctionFilterExpr{ + GisfunctionFilterExpr: &planpb.GISFunctionFilterExpr{ + ColumnInfo: columnInfo, + WktString: element[1 : len(element)-1], + Op: planpb.GISFunctionFilterExpr_Within, + }, + }, + } + return &ExprWithType{ + expr: expr, + dataType: schemapb.DataType_Bool, + } +} diff --git a/internal/parser/planparserv2/utils.go b/internal/parser/planparserv2/utils.go index 8a2630384c..eb79000636 100644 --- a/internal/parser/planparserv2/utils.go +++ b/internal/parser/planparserv2/utils.go @@ -156,6 +156,11 @@ func getTargetType(lDataType, rDataType schemapb.DataType) (schemapb.DataType, e return schemapb.DataType_Int64, nil } } + if typeutil.IsGeometryType(lDataType) { + if typeutil.IsGeometryType(rDataType) || typeutil.IsJSONType(rDataType) { + return schemapb.DataType_Geometry, nil + } + } if typeutil.IsFloatingType(lDataType) { if typeutil.IsJSONType(rDataType) || typeutil.IsArithmetic(rDataType) { return schemapb.DataType_Double, nil diff --git a/internal/proxy/task_insert_test.go b/internal/proxy/task_insert_test.go index 85881e5584..fdf93789c2 100644 --- a/internal/proxy/task_insert_test.go +++ b/internal/proxy/task_insert_test.go @@ -47,6 +47,7 @@ func TestInsertTask_CheckAligned(t *testing.T) { float16VectorFieldSchema := &schemapb.FieldSchema{DataType: schemapb.DataType_Float16Vector} bfloat16VectorFieldSchema := &schemapb.FieldSchema{DataType: schemapb.DataType_BFloat16Vector} varCharFieldSchema := &schemapb.FieldSchema{DataType: schemapb.DataType_VarChar} + geometryFieldSchema := &schemapb.FieldSchema{DataType: schemapb.DataType_Geometry} numRows := 20 dim := 128 @@ -78,6 +79,7 @@ func TestInsertTask_CheckAligned(t *testing.T) { float16VectorFieldSchema, bfloat16VectorFieldSchema, varCharFieldSchema, + geometryFieldSchema, }, }, } @@ -97,6 +99,7 @@ func TestInsertTask_CheckAligned(t *testing.T) { newFloat16VectorFieldData("Float16Vector", numRows, dim), newBFloat16VectorFieldData("BFloat16Vector", numRows, dim), newScalarFieldData(varCharFieldSchema, "VarChar", numRows), + newScalarFieldData(geometryFieldSchema, "Geometry", numRows), } err = case2.insertMsg.CheckAligned() assert.NoError(t, err) diff --git a/internal/proxy/task_query.go b/internal/proxy/task_query.go index de320eb320..6334c8acd5 100644 --- a/internal/proxy/task_query.go +++ b/internal/proxy/task_query.go @@ -568,6 +568,10 @@ func (t *queryTask) PostExecute(ctx context.Context) error { log.Warn("fail to reduce query result", zap.Error(err)) return err } + if err := validateGeometryFieldSearchResult(&t.result.FieldsData); err != nil { + log.Warn("fail to validate geometry field search result", zap.Error(err)) + return err + } t.result.OutputFields = t.userOutputFields primaryFieldSchema, err := t.schema.GetPkField() if err != nil { diff --git a/internal/proxy/task_search.go b/internal/proxy/task_search.go index 5bf1bbe4f2..d2ea1696e4 100644 --- a/internal/proxy/task_search.go +++ b/internal/proxy/task_search.go @@ -790,6 +790,10 @@ func (t *searchTask) PostExecute(ctx context.Context) error { } } + if err := validateGeometryFieldSearchResult(&t.result.Results.FieldsData); err != nil { + log.Warn("fail to validate geometry field search result", zap.Error(err)) + return err + } // reduce done, get final result limit := t.SearchRequest.GetTopk() - t.SearchRequest.GetOffset() resultSizeInsufficient := false diff --git a/internal/proxy/task_test.go b/internal/proxy/task_test.go index 8bd109075b..9f6fe90bf6 100644 --- a/internal/proxy/task_test.go +++ b/internal/proxy/task_test.go @@ -70,6 +70,7 @@ const ( testBinaryVecField = "bvec" testFloat16VecField = "f16vec" testBFloat16VecField = "bf16vec" + testGeometryField = "geometry" testVecDim = 128 testMaxVarCharLength = 100 ) @@ -85,6 +86,7 @@ func genCollectionSchema(collectionName string) *schemapb.CollectionSchema { testBinaryVecField, testFloat16VecField, testBFloat16VecField, + testGeometryField, testVecDim, collectionName) } @@ -233,6 +235,7 @@ func constructCollectionSchemaByDataType(collectionName string, fieldName2DataTy func constructCollectionSchemaWithAllType( boolField, int32Field, int64Field, floatField, doubleField string, floatVecField, binaryVecField, float16VecField, bfloat16VecField string, + geometryField string, dim int, collectionName string, ) *schemapb.CollectionSchema { @@ -346,6 +349,16 @@ func constructCollectionSchemaWithAllType( IndexParams: nil, AutoID: false, } + g := &schemapb.FieldSchema{ + FieldID: 0, + Name: geometryField, + IsPrimaryKey: false, + Description: "", + DataType: schemapb.DataType_Geometry, + TypeParams: nil, + IndexParams: nil, + AutoID: false, + } if enableMultipleVectorFields { return &schemapb.CollectionSchema{ @@ -362,6 +375,7 @@ func constructCollectionSchemaWithAllType( bVec, f16Vec, bf16Vec, + g, }, } } @@ -378,6 +392,7 @@ func constructCollectionSchemaWithAllType( d, fVec, // bVec, + g, }, } } diff --git a/internal/proxy/validate_util.go b/internal/proxy/validate_util.go index 05202e7b3e..69e83a7017 100644 --- a/internal/proxy/validate_util.go +++ b/internal/proxy/validate_util.go @@ -5,6 +5,8 @@ import ( "math" "reflect" + "github.com/twpayne/go-geom/encoding/wkb" + "github.com/twpayne/go-geom/encoding/wkt" "go.uber.org/zap" "github.com/milvus-io/milvus-proto/go-api/v2/schemapb" @@ -51,6 +53,52 @@ func withMaxCapCheck() validateOption { } } +func validateGeometryFieldSearchResult(array *[]*schemapb.FieldData) error { + if array == nil { + log.Warn("geometry field search result is nil") + return nil + } + + for idx, fieldData := range *array { + if fieldData.Type == schemapb.DataType_Geometry { + wkbArray := fieldData.GetScalars().GetGeometryData().GetData() + wktArray := make([]string, len(wkbArray)) + for i, data := range wkbArray { + geomT, err := wkb.Unmarshal(data) + if err != nil { + log.Warn("translate the wkb format search result into geometry failed") + return err + } + // now remove MaxDecimalDigits limit + wktStr, err := wkt.Marshal(geomT) + if err != nil { + log.Warn("translate the geomery into its wkt failed") + return err + } + wktArray[i] = wktStr + } + // modify the field data + (*array)[idx] = &schemapb.FieldData{ + Type: fieldData.GetType(), + FieldName: fieldData.GetFieldName(), + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryWktData{ + GeometryWktData: &schemapb.GeometryWktArray{ + Data: wktArray, + }, + }, + }, + }, + FieldId: fieldData.GetFieldId(), + IsDynamic: fieldData.GetIsDynamic(), + } + } + } + + return nil +} + func (v *validateUtil) apply(opts ...validateOption) { for _, opt := range opts { opt(v) @@ -92,6 +140,10 @@ func (v *validateUtil) Validate(data []*schemapb.FieldData, helper *typeutil.Sch if err := v.checkVarCharFieldData(field, fieldSchema); err != nil { return err } + case schemapb.DataType_Geometry: + if err := v.checkGeometryFieldData(field, fieldSchema); err != nil { + return err + } case schemapb.DataType_JSON: if err := v.checkJSONFieldData(field, fieldSchema); err != nil { return err @@ -368,6 +420,13 @@ func (v *validateUtil) fillWithNullValue(field *schemapb.FieldData, fieldSchema } } + case *schemapb.ScalarField_GeometryData: + if fieldSchema.GetNullable() { + sd.GeometryData.Data, err = fillWithNullValueImpl(sd.GeometryData.Data, field.GetValidData()) + if err != nil { + return err + } + } default: return merr.WrapErrParameterInvalidMsg(fmt.Sprintf("undefined data type:%s", field.Type.String())) } @@ -467,6 +526,17 @@ func (v *validateUtil) fillWithDefaultValue(field *schemapb.FieldData, fieldSche return err } + case *schemapb.ScalarField_GeometryData: + if len(field.GetValidData()) != numRows { + msg := fmt.Sprintf("the length of valid_data of field(%s) is wrong", field.GetFieldName()) + return merr.WrapErrParameterInvalid(numRows, len(field.GetValidData()), msg) + } + defaultValue := fieldSchema.GetDefaultValue().GetBytesData() + sd.GeometryData.Data, err = fillWithDefaultValueImpl(sd.GeometryData.Data, defaultValue, field.GetValidData()) + if err != nil { + return err + } + default: return merr.WrapErrParameterInvalidMsg(fmt.Sprintf("undefined data type:%s", field.Type.String())) } @@ -636,6 +706,44 @@ func (v *validateUtil) checkVarCharFieldData(field *schemapb.FieldData, fieldSch return nil } +func (v *validateUtil) checkGeometryFieldData(field *schemapb.FieldData, fieldSchema *schemapb.FieldSchema) error { + geometryArray := field.GetScalars().GetGeometryWktData().GetData() + wkbArray := make([][]byte, len(geometryArray)) + if geometryArray == nil && fieldSchema.GetDefaultValue() == nil && !fieldSchema.GetNullable() { + msg := fmt.Sprintf("geometry field '%v' is illegal, array type mismatch", field.GetFieldName()) + return merr.WrapErrParameterInvalid("need geometry array", "got nil", msg) + } + + for index, wktdata := range geometryArray { + // ignore parsed geom, the check is during insert task pre execute,so geo data became wkb + // fmt.Println(strings.Trim(string(wktdata), "\"")) + geomT, err := wkt.Unmarshal(wktdata) + if err != nil { + log.Warn("insert invalid Geometry data!! The wkt data has errors", zap.Error(err)) + return merr.WrapErrIoFailedReason(err.Error()) + } + wkbArray[index], err = wkb.Marshal(geomT, wkb.NDR) + if err != nil { + log.Warn("insert invalid Geometry data!! Transform to wkb failed, has errors", zap.Error(err)) + return merr.WrapErrIoFailedReason(err.Error()) + } + } + // replace the field data with wkb data array + *field = schemapb.FieldData{ + Type: field.GetType(), + FieldName: field.GetFieldName(), + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{GeometryData: &schemapb.GeometryArray{Data: wkbArray}}, + }, + }, + FieldId: field.GetFieldId(), + IsDynamic: field.GetIsDynamic(), + ValidData: field.GetValidData(), + } + return nil +} + func (v *validateUtil) checkJSONFieldData(field *schemapb.FieldData, fieldSchema *schemapb.FieldSchema) error { jsonArray := field.GetScalars().GetJsonData().GetData() if jsonArray == nil && fieldSchema.GetDefaultValue() == nil && !fieldSchema.GetNullable() { @@ -896,7 +1004,7 @@ func newValidateUtil(opts ...validateOption) *validateUtil { } func ValidateAutoIndexMmapConfig(isVectorField bool, indexParams map[string]string) error { - return common.ValidateAutoIndexMmapConfig(Params.AutoIndexConfig.Enable.GetAsBool(), isVectorField, indexParams) + return common.ValidateAutoIndexMmapConfig(paramtable.Get().AutoIndexConfig.Enable.GetAsBool(), isVectorField, indexParams) } func wasBm25FunctionInputField(coll *schemapb.CollectionSchema, field *schemapb.FieldSchema) bool { diff --git a/internal/storage/data_codec.go b/internal/storage/data_codec.go index 417b7d35c5..a464fc1560 100644 --- a/internal/storage/data_codec.go +++ b/internal/storage/data_codec.go @@ -368,6 +368,16 @@ func AddFieldDataToPayload(eventWriter *insertEventWriter, dataType schemapb.Dat return err } } + case schemapb.DataType_Geometry: + for i, singleGeometry := range singleData.(*GeometryFieldData).Data { + isValid := true + if len(singleData.(*GeometryFieldData).ValidData) != 0 { + isValid = singleData.(*GeometryFieldData).ValidData[i] + } + if err = eventWriter.AddOneGeometryToPayload(singleGeometry, isValid); err != nil { + return err + } + } case schemapb.DataType_BinaryVector: if err = eventWriter.AddBinaryVectorToPayload(singleData.(*BinaryVectorFieldData).Data, singleData.(*BinaryVectorFieldData).Dim); err != nil { return err @@ -601,6 +611,17 @@ func AddInsertData(dataType schemapb.DataType, data interface{}, insertData *Ins jsonFieldData.ValidData = append(jsonFieldData.ValidData, validData...) insertData.Data[fieldID] = jsonFieldData return len(singleData), nil + case schemapb.DataType_Geometry: + singleData := data.([][]byte) + if fieldData == nil { + fieldData = &GeometryFieldData{Data: make([][]byte, 0, rowNum)} + } + geometryFieldData := fieldData.(*GeometryFieldData) + + geometryFieldData.Data = append(geometryFieldData.Data, singleData...) + geometryFieldData.ValidData = append(geometryFieldData.ValidData, validData...) + insertData.Data[fieldID] = geometryFieldData + return len(singleData), nil case schemapb.DataType_BinaryVector: singleData := data.([]byte) diff --git a/internal/storage/data_sorter.go b/internal/storage/data_sorter.go index 79bb1bdb67..022c86a24d 100644 --- a/internal/storage/data_sorter.go +++ b/internal/storage/data_sorter.go @@ -114,6 +114,9 @@ func (ds *DataSorter) Swap(i, j int) { case schemapb.DataType_JSON: data := singleData.(*JSONFieldData).Data data[i], data[j] = data[j], data[i] + case schemapb.DataType_Geometry: + data := singleData.(*GeometryFieldData).Data + data[i], data[j] = data[j], data[i] case schemapb.DataType_SparseFloatVector: fieldData := singleData.(*SparseFloatVectorFieldData) fieldData.Contents[i], fieldData.Contents[j] = fieldData.Contents[j], fieldData.Contents[i] diff --git a/internal/storage/insert_data.go b/internal/storage/insert_data.go index d4790e92b8..5298680626 100644 --- a/internal/storage/insert_data.go +++ b/internal/storage/insert_data.go @@ -309,6 +309,16 @@ func NewFieldData(dataType schemapb.DataType, fieldSchema *schemapb.FieldSchema, data.ValidData = make([]bool, 0, cap) } return data, nil + + case schemapb.DataType_Geometry: + data := &GeometryFieldData{ + Data: make([][]byte, 0, cap), + Nullable: fieldSchema.GetNullable(), + } + if fieldSchema.GetNullable() { + data.ValidData = make([]bool, 0, cap) + } + return data, nil case schemapb.DataType_Array: data := &ArrayFieldData{ Data: make([]*schemapb.ScalarField, 0, cap), @@ -386,6 +396,11 @@ type JSONFieldData struct { ValidData []bool Nullable bool } +type GeometryFieldData struct { + Data [][]byte + ValidData []bool + Nullable bool +} type BinaryVectorFieldData struct { Data []byte Dim int @@ -428,6 +443,7 @@ func (data *DoubleFieldData) RowNum() int { return len(data.Data) } func (data *StringFieldData) RowNum() int { return len(data.Data) } func (data *ArrayFieldData) RowNum() int { return len(data.Data) } func (data *JSONFieldData) RowNum() int { return len(data.Data) } +func (data *GeometryFieldData) RowNum() int { return len(data.Data) } func (data *BinaryVectorFieldData) RowNum() int { return len(data.Data) * 8 / data.Dim } func (data *FloatVectorFieldData) RowNum() int { return len(data.Data) / data.Dim } func (data *Float16VectorFieldData) RowNum() int { return len(data.Data) / 2 / data.Dim } @@ -507,6 +523,13 @@ func (data *JSONFieldData) GetRow(i int) any { return data.Data[i] } +func (data *GeometryFieldData) GetRow(i int) any { + if data.GetNullable() && !data.ValidData[i] { + return nil + } + return data.Data[i] +} + func (data *BinaryVectorFieldData) GetRow(i int) any { return data.Data[i*data.Dim/8 : (i+1)*data.Dim/8] } @@ -537,6 +560,7 @@ func (data *DoubleFieldData) GetDataRows() any { return data.Data } func (data *StringFieldData) GetDataRows() any { return data.Data } func (data *ArrayFieldData) GetDataRows() any { return data.Data } func (data *JSONFieldData) GetDataRows() any { return data.Data } +func (data *GeometryFieldData) GetDataRows() any { return data.Data } func (data *BinaryVectorFieldData) GetDataRows() any { return data.Data } func (data *FloatVectorFieldData) GetDataRows() any { return data.Data } func (data *Float16VectorFieldData) GetDataRows() any { return data.Data } @@ -714,6 +738,23 @@ func (data *JSONFieldData) AppendRow(row interface{}) error { return nil } +func (data *GeometryFieldData) AppendRow(row interface{}) error { + if data.GetNullable() && row == nil { + data.Data = append(data.Data, make([][]byte, 1)...) + data.ValidData = append(data.ValidData, false) + return nil + } + v, ok := row.([]byte) + if !ok { + return merr.WrapErrParameterInvalid("[]byte", row, "Wrong row type") + } + if data.GetNullable() { + data.ValidData = append(data.ValidData, true) + } + data.Data = append(data.Data, v) + return nil +} + func (data *BinaryVectorFieldData) AppendRow(row interface{}) error { v, ok := row.([]byte) if !ok || len(v) != data.Dim/8 { @@ -846,6 +887,14 @@ func (data *JSONFieldData) AppendRows(dataRows interface{}, validDataRows interf return data.AppendValidDataRows(validDataRows) } +func (data *GeometryFieldData) AppendRows(dataRows interface{}, validDataRows interface{}) error { + err := data.AppendDataRows(dataRows) + if err != nil { + return err + } + return data.AppendValidDataRows(validDataRows) +} + // AppendDataRows appends FLATTEN vectors to field data. func (data *BinaryVectorFieldData) AppendRows(dataRows interface{}, validDataRows interface{}) error { err := data.AppendDataRows(dataRows) @@ -980,6 +1029,15 @@ func (data *JSONFieldData) AppendDataRows(rows interface{}) error { return nil } +func (data *GeometryFieldData) AppendDataRows(rows interface{}) error { + v, ok := rows.([][]byte) + if !ok { + return merr.WrapErrParameterInvalid("[][]byte", rows, "Wrong rows type") + } + data.Data = append(data.Data, v...) + return nil +} + // AppendDataRows appends FLATTEN vectors to field data. func (data *BinaryVectorFieldData) AppendDataRows(rows interface{}) error { v, ok := rows.([]byte) @@ -1164,6 +1222,18 @@ func (data *JSONFieldData) AppendValidDataRows(rows interface{}) error { return nil } +func (data *GeometryFieldData) AppendValidDataRows(rows interface{}) error { + if rows == nil { + return nil + } + v, ok := rows.([]bool) + if !ok { + return merr.WrapErrParameterInvalid("[]bool", rows, "Wrong rows type") + } + data.ValidData = append(data.ValidData, v...) + return nil +} + // AppendValidDataRows appends FLATTEN vectors to field data. func (data *BinaryVectorFieldData) AppendValidDataRows(rows interface{}) error { if rows != nil { @@ -1282,6 +1352,10 @@ func (data *DoubleFieldData) GetDataType() schemapb.DataType { return schemapb.D func (data *StringFieldData) GetDataType() schemapb.DataType { return data.DataType } func (data *ArrayFieldData) GetDataType() schemapb.DataType { return schemapb.DataType_Array } func (data *JSONFieldData) GetDataType() schemapb.DataType { return schemapb.DataType_JSON } +func (data *GeometryFieldData) GetDataType() schemapb.DataType { + return schemapb.DataType_Geometry +} + func (data *BinaryVectorFieldData) GetDataType() schemapb.DataType { return schemapb.DataType_BinaryVector } @@ -1347,6 +1421,15 @@ func (data *JSONFieldData) GetMemorySize() int { return size + binary.Size(data.ValidData) + binary.Size(data.Nullable) } +func (data *GeometryFieldData) GetMemorySize() int { + var size int + // what's the meaning of 16? + for _, val := range data.Data { + size += len(val) + 16 + } + return size + binary.Size(data.ValidData) + binary.Size(data.Nullable) +} + func (data *BoolFieldData) GetRowSize(i int) int { return 1 } func (data *Int8FieldData) GetRowSize(i int) int { return 1 } func (data *Int16FieldData) GetRowSize(i int) int { return 2 } @@ -1360,6 +1443,7 @@ func (data *Float16VectorFieldData) GetRowSize(i int) int { return data.Dim * 2 func (data *BFloat16VectorFieldData) GetRowSize(i int) int { return data.Dim * 2 } func (data *StringFieldData) GetRowSize(i int) int { return len(data.Data[i]) + 16 } func (data *JSONFieldData) GetRowSize(i int) int { return len(data.Data[i]) + 16 } +func (data *GeometryFieldData) GetRowSize(i int) int { return len(data.Data[i]) + 16 } func (data *ArrayFieldData) GetRowSize(i int) int { switch data.ElementType { case schemapb.DataType_Bool: @@ -1445,3 +1529,7 @@ func (data *ArrayFieldData) GetNullable() bool { func (data *JSONFieldData) GetNullable() bool { return data.Nullable } + +func (data *GeometryFieldData) GetNullable() bool { + return data.Nullable +} diff --git a/internal/storage/payload.go b/internal/storage/payload.go index f62a569fc0..e97c6f5b14 100644 --- a/internal/storage/payload.go +++ b/internal/storage/payload.go @@ -38,6 +38,7 @@ type PayloadWriterInterface interface { AddOneStringToPayload(msgs string, isValid bool) error AddOneArrayToPayload(msg *schemapb.ScalarField, isValid bool) error AddOneJSONToPayload(msg []byte, isValid bool) error + AddOneGeometryToPayload(msg []byte, isValid bool) error AddBinaryVectorToPayload(binVec []byte, dim int) error AddFloatVectorToPayload(binVec []float32, dim int) error AddFloat16VectorToPayload(binVec []byte, dim int) error @@ -65,6 +66,7 @@ type PayloadReaderInterface interface { GetStringFromPayload() ([]string, []bool, error) GetArrayFromPayload() ([]*schemapb.ScalarField, []bool, error) GetJSONFromPayload() ([][]byte, []bool, error) + GetGeometryFromPayload() ([][]byte, []bool, error) GetBinaryVectorFromPayload() ([]byte, int, error) GetFloat16VectorFromPayload() ([]byte, int, error) GetBFloat16VectorFromPayload() ([]byte, int, error) diff --git a/internal/storage/payload_reader.go b/internal/storage/payload_reader.go index 154fa2af5e..c7c5e3a592 100644 --- a/internal/storage/payload_reader.go +++ b/internal/storage/payload_reader.go @@ -98,6 +98,9 @@ func (r *PayloadReader) GetDataFromPayload() (interface{}, []bool, int, error) { case schemapb.DataType_JSON: val, validData, err := r.GetJSONFromPayload() return val, validData, 0, err + case schemapb.DataType_Geometry: + val, validData, err := r.GetGeometryFromPayload() + return val, validData, 0, err default: return nil, nil, 0, merr.WrapErrParameterInvalidMsg("unknown type") } @@ -432,6 +435,25 @@ func (r *PayloadReader) GetJSONFromPayload() ([][]byte, []bool, error) { return value, nil, nil } +func (r *PayloadReader) GetGeometryFromPayload() ([][]byte, []bool, error) { + if r.colType != schemapb.DataType_Geometry { + return nil, nil, merr.WrapErrParameterInvalidMsg(fmt.Sprintf("failed to get Geometry from datatype %v", r.colType.String())) + } + + if r.nullable { + return readNullableByteAndConvert(r, func(bytes []byte) []byte { + return bytes + }) + } + value, err := readByteAndConvert(r, func(bytes parquet.ByteArray) []byte { + return bytes + }) + if err != nil { + return nil, nil, err + } + return value, nil, nil +} + func (r *PayloadReader) GetByteArrayDataSet() (*DataSet[parquet.ByteArray, *file.ByteArrayColumnChunkReader], error) { if r.colType != schemapb.DataType_String && r.colType != schemapb.DataType_VarChar { return nil, fmt.Errorf("failed to get string from datatype %v", r.colType.String()) diff --git a/internal/storage/payload_writer.go b/internal/storage/payload_writer.go index 0f1bc13c39..c2cff00f1a 100644 --- a/internal/storage/payload_writer.go +++ b/internal/storage/payload_writer.go @@ -206,6 +206,25 @@ func (w *NativePayloadWriter) AddDataToPayload(data interface{}, validData []boo isValid = validData[0] } return w.AddOneJSONToPayload(val, isValid) + case schemapb.DataType_Geometry: + val, ok := data.([]byte) + if !ok { + return merr.WrapErrParameterInvalidMsg("incorrect data type") + } + isValid := true + if len(validData) > 1 { + return merr.WrapErrParameterInvalidMsg("wrong input length when add data to payload") + } + if len(validData) == 0 && w.nullable { + return merr.WrapErrParameterInvalidMsg("need pass valid_data when nullable==true") + } + if len(validData) == 1 { + if !w.nullable { + return merr.WrapErrParameterInvalidMsg("no need pass valid_data when nullable==false") + } + isValid = validData[0] + } + return w.AddOneGeometryToPayload(val, isValid) case schemapb.DataType_BinaryVector: val, ok := data.([]byte) if !ok { @@ -546,6 +565,29 @@ func (w *NativePayloadWriter) AddOneJSONToPayload(data []byte, isValid bool) err return nil } +func (w *NativePayloadWriter) AddOneGeometryToPayload(data []byte, isValid bool) error { + if w.finished { + return errors.New("can't append data to finished geometry payload") + } + + if !w.nullable && !isValid { + return merr.WrapErrParameterInvalidMsg("not support null when nullable is false") + } + + builder, ok := w.builder.(*array.BinaryBuilder) + if !ok { + return errors.New("failed to cast geometryBuilder") + } + + if !isValid { + builder.AppendNull() + } else { + builder.Append(data) + } + + return nil +} + func (w *NativePayloadWriter) AddBinaryVectorToPayload(data []byte, dim int) error { if w.finished { return errors.New("can't append data to finished binary vector payload") @@ -752,6 +794,8 @@ func milvusDataTypeToArrowType(dataType schemapb.DataType, dim int) arrow.DataTy return &arrow.BinaryType{} case schemapb.DataType_JSON: return &arrow.BinaryType{} + case schemapb.DataType_Geometry: + return &arrow.BinaryType{} case schemapb.DataType_FloatVector: return &arrow.FixedSizeBinaryType{ ByteWidth: dim * 4, diff --git a/internal/storage/print_binlog.go b/internal/storage/print_binlog.go index 28f335a7cd..fba766f29c 100644 --- a/internal/storage/print_binlog.go +++ b/internal/storage/print_binlog.go @@ -21,6 +21,8 @@ import ( "os" "github.com/cockroachdb/errors" + "github.com/twpayne/go-geom/encoding/wkb" + "github.com/twpayne/go-geom/encoding/wkt" "golang.org/x/exp/mmap" "google.golang.org/protobuf/proto" @@ -368,6 +370,24 @@ func printPayloadValues(colType schemapb.DataType, reader PayloadReaderInterface for i, v := range valids { fmt.Printf("\t\t%d : %v\n", i, v) } + // print the wkb bytes + case schemapb.DataType_Geometry: + rows, err := reader.GetPayloadLengthFromReader() + if err != nil { + return err + } + val, valids, err := reader.GetGeometryFromPayload() + if err != nil { + return err + } + for i := 0; i < rows; i++ { + geomT, _ := wkb.Unmarshal(val[i]) + wktStr, _ := wkt.Marshal(geomT) + fmt.Printf("\t\t%d : %s\n", i, wktStr) + } + for i, v := range valids { + fmt.Printf("\t\t%d : %v\n", i, v) + } case schemapb.DataType_SparseFloatVector: sparseData, _, err := reader.GetSparseFloatVectorFromPayload() if err != nil { diff --git a/internal/storage/print_binlog_test.go b/internal/storage/print_binlog_test.go index a60dcaae71..ebf8c50a9f 100644 --- a/internal/storage/print_binlog_test.go +++ b/internal/storage/print_binlog_test.go @@ -210,6 +210,13 @@ func TestPrintBinlogFiles(t *testing.T) { {Key: common.DimKey, Value: "4"}, }, }, + { + FieldID: 113, + Name: "field_geometry", + IsPrimaryKey: false, + Description: "description_15", + DataType: schemapb.DataType_Geometry, + }, }, }, } @@ -268,6 +275,13 @@ func TestPrintBinlogFiles(t *testing.T) { Data: []byte("12345678"), Dim: 4, }, + 113: &GeometryFieldData{ + Data: [][]byte{ + // POINT (30.123 -10.456) and LINESTRING (30.123 -10.456, 10.789 30.123, -40.567 40.890) + {0x01, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40}, + {0x01, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40, 0x03, 0xA6, 0xB4, 0xA6, 0xA4, 0xD2, 0xC5, 0xC0, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A}, + }, + }, }, } @@ -325,6 +339,13 @@ func TestPrintBinlogFiles(t *testing.T) { Data: []byte("abcdefgh"), Dim: 4, }, + 113: &GeometryFieldData{ + Data: [][]byte{ + // POINT (30.123 -10.456) and LINESTRING (30.123 -10.456, 10.789 30.123, -40.567 40.890) + {0x01, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40}, + {0x01, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40, 0x03, 0xA6, 0xB4, 0xA6, 0xA4, 0xD2, 0xC5, 0xC0, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A}, + }, + }, }, } firstBlobs, err := insertCodec.Serialize(1, 1, insertDataFirst) diff --git a/internal/storage/serde.go b/internal/storage/serde.go index db836483f1..c241327c25 100644 --- a/internal/storage/serde.go +++ b/internal/storage/serde.go @@ -416,6 +416,7 @@ var serdeMap = func() map[schemapb.DataType]serdeEntry { m[schemapb.DataType_Array] = byteEntry m[schemapb.DataType_JSON] = byteEntry + m[schemapb.DataType_Geometry] = byteEntry fixedSizeDeserializer := func(a arrow.Array, i int) (any, bool) { if a.IsNull(i) { diff --git a/internal/storage/utils.go b/internal/storage/utils.go index 37ec984206..1be5ccaf26 100644 --- a/internal/storage/utils.go +++ b/internal/storage/utils.go @@ -673,6 +673,13 @@ func ColumnBasedInsertMsgToInsertData(msg *msgstream.InsertMsg, collSchema *sche Data: lo.Map(srcData, func(v []byte, _ int) []byte { return v }), ValidData: lo.Map(validData, func(v bool, _ int) bool { return v }), } + case schemapb.DataType_Geometry: + srcData := srcField.GetScalars().GetGeometryData().GetData() + validData := srcField.GetValidData() + fieldData = &GeometryFieldData{ + Data: lo.Map(srcData, func(v []byte, _ int) []byte { return v }), + ValidData: lo.Map(validData, func(v bool, _ int) bool { return v }), + } default: return nil, merr.WrapErrServiceInternal("data type not handled", field.GetDataType().String()) @@ -1193,6 +1200,21 @@ func TransferInsertDataToInsertRecord(insertData *InsertData) (*segcorepb.Insert }, ValidData: rawData.ValidData, } + case *GeometryFieldData: + fieldData = &schemapb.FieldData{ + Type: schemapb.DataType_Geometry, + FieldId: fieldID, + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: rawData.Data, + }, + }, + }, + }, + ValidData: rawData.ValidData, + } case *FloatVectorFieldData: fieldData = &schemapb.FieldData{ Type: schemapb.DataType_FloatVector, diff --git a/internal/storage/utils_test.go b/internal/storage/utils_test.go index 3e5da98589..56d8d99cab 100644 --- a/internal/storage/utils_test.go +++ b/internal/storage/utils_test.go @@ -1003,7 +1003,7 @@ func genColumnBasedInsertMsg(schema *schemapb.CollectionSchema, numRows, fVecDim case schemapb.DataType_JSON: data := testutils.GenerateBytesArray(numRows) f := &schemapb.FieldData{ - Type: schemapb.DataType_Array, + Type: schemapb.DataType_JSON, FieldName: field.GetName(), Field: &schemapb.FieldData_Scalars{ Scalars: &schemapb.ScalarField{ @@ -1023,6 +1023,29 @@ func genColumnBasedInsertMsg(schema *schemapb.CollectionSchema, numRows, fVecDim for _, d := range data { columns[idx] = append(columns[idx], d) } + case schemapb.DataType_Geometry: + data := testutils.GenerateGeometryWktArray(numRows) + f := &schemapb.FieldData{ + Type: schemapb.DataType_Geometry, + FieldName: field.GetName(), + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: data, + }, + }, + }, + }, + FieldId: field.FieldID, + } + if field.GetNullable() { + f.ValidData = testutils.GenerateBoolArray(numRows) + } + msg.FieldsData = append(msg.FieldsData, f) + for _, d := range data { + columns[idx] = append(columns[idx], d) + } } } diff --git a/internal/util/importutilv2/parquet/field_reader.go b/internal/util/importutilv2/parquet/field_reader.go index 33bded7914..4a4fc7ac32 100644 --- a/internal/util/importutilv2/parquet/field_reader.go +++ b/internal/util/importutilv2/parquet/field_reader.go @@ -160,6 +160,12 @@ func (c *FieldReader) Next(count int64) (any, any, error) { } data, err := ReadJSONData(c, count) return data, nil, err + case schemapb.DataType_Geometry: + if c.field.GetNullable() { + return ReadNullableGeometryData(c, count) + } + data, err := ReadGeometryData(c, count) + return data, nil, err case schemapb.DataType_BinaryVector, schemapb.DataType_Float16Vector, schemapb.DataType_BFloat16Vector: // vector not support default_value if c.field.GetNullable() { @@ -704,6 +710,42 @@ func ReadNullableJSONData(pcr *FieldReader, count int64) (any, []bool, error) { return byteArr, validData, nil } +func ReadNullableGeometryData(pcr *FieldReader, count int64) (any, []bool, error) { + // Geometry field read data from string array Parquet + data, validData, err := ReadNullableStringData(pcr, count) + if err != nil { + return nil, nil, err + } + if data == nil { + return nil, nil, nil + } + byteArr := make([][]byte, 0) + for i, str := range data.([]string) { + if !validData[i] { + byteArr = append(byteArr, []byte(nil)) + continue + } + byteArr = append(byteArr, []byte(str)) + } + return byteArr, validData, nil +} + +func ReadGeometryData(pcr *FieldReader, count int64) (any, error) { + // Geometry field read data from string array Parquet + data, err := ReadStringData(pcr, count) + if err != nil { + return nil, err + } + if data == nil { + return nil, nil + } + byteArr := make([][]byte, 0) + for _, str := range data.([]string) { + byteArr = append(byteArr, []byte(str)) + } + return byteArr, nil +} + func ReadBinaryData(pcr *FieldReader, count int64) (any, error) { dataType := pcr.field.GetDataType() chunked, err := pcr.columnReader.NextBatch(count) diff --git a/internal/util/importutilv2/parquet/reader_test.go b/internal/util/importutilv2/parquet/reader_test.go index a45cd099ce..0fae8e60b7 100644 --- a/internal/util/importutilv2/parquet/reader_test.go +++ b/internal/util/importutilv2/parquet/reader_test.go @@ -529,6 +529,7 @@ func (s *ReaderSuite) TestReadScalarFields() { s.run(schemapb.DataType_String, schemapb.DataType_None, false, 0) s.run(schemapb.DataType_VarChar, schemapb.DataType_None, false, 0) s.run(schemapb.DataType_JSON, schemapb.DataType_None, false, 0) + s.run(schemapb.DataType_Geometry, schemapb.DataType_None, false, 0) s.run(schemapb.DataType_Array, schemapb.DataType_Bool, false, 0) s.run(schemapb.DataType_Array, schemapb.DataType_Int8, false, 0) @@ -567,6 +568,7 @@ func (s *ReaderSuite) TestReadScalarFields() { s.run(schemapb.DataType_String, schemapb.DataType_None, true, 100) s.run(schemapb.DataType_VarChar, schemapb.DataType_None, true, 100) s.run(schemapb.DataType_JSON, schemapb.DataType_None, true, 100) + s.run(schemapb.DataType_Geometry, schemapb.DataType_None, true, 100) s.run(schemapb.DataType_Array, schemapb.DataType_Bool, true, 100) s.run(schemapb.DataType_Array, schemapb.DataType_Int8, true, 100) diff --git a/internal/util/importutilv2/parquet/util.go b/internal/util/importutilv2/parquet/util.go index 1d1176523e..50a3110a05 100644 --- a/internal/util/importutilv2/parquet/util.go +++ b/internal/util/importutilv2/parquet/util.go @@ -216,6 +216,8 @@ func convertToArrowDataType(field *schemapb.FieldSchema, isArray bool) (arrow.Da return &arrow.StringType{}, nil case schemapb.DataType_JSON: return &arrow.StringType{}, nil + case schemapb.DataType_Geometry: + return &arrow.StringType{}, nil case schemapb.DataType_Array: elemType, err := convertToArrowDataType(field, true) if err != nil { diff --git a/internal/util/indexparamcheck/inverted_checker_test.go b/internal/util/indexparamcheck/inverted_checker_test.go index a5726a3a1d..c88fd24c0e 100644 --- a/internal/util/indexparamcheck/inverted_checker_test.go +++ b/internal/util/indexparamcheck/inverted_checker_test.go @@ -21,6 +21,7 @@ func Test_INVERTEDIndexChecker(t *testing.T) { assert.NoError(t, c.CheckValidDataType(IndexINVERTED, &schemapb.FieldSchema{DataType: schemapb.DataType_Array})) assert.NoError(t, c.CheckValidDataType(IndexINVERTED, &schemapb.FieldSchema{DataType: schemapb.DataType_JSON})) + assert.Error(t, c.CheckValidDataType(IndexINVERTED, &schemapb.FieldSchema{DataType: schemapb.DataType_Geometry})) assert.Error(t, c.CheckValidDataType(IndexINVERTED, &schemapb.FieldSchema{DataType: schemapb.DataType_FloatVector})) } diff --git a/internal/util/testutil/test_util.go b/internal/util/testutil/test_util.go index 322eb3bf1c..674850fba1 100644 --- a/internal/util/testutil/test_util.go +++ b/internal/util/testutil/test_util.go @@ -176,6 +176,9 @@ func CreateInsertData(schema *schemapb.CollectionSchema, rows int, nullPercent . insertData.Data[f.FieldID].AppendDataRows(testutils.GenerateStringArray(rows)) case schemapb.DataType_JSON: insertData.Data[f.FieldID].AppendDataRows(testutils.GenerateJSONArray(rows)) + case schemapb.DataType_Geometry: + // wkb bytes array + insertData.Data[f.FieldID].AppendDataRows(testutils.GenerateGeometryArray(rows)) case schemapb.DataType_Array: switch f.GetElementType() { case schemapb.DataType_Bool: @@ -528,6 +531,14 @@ func BuildArrayData(schema *schemapb.CollectionSchema, insertData *storage.Inser return string(bs) }), validData) columns = append(columns, builder.NewStringArray()) + case schemapb.DataType_Geometry: + builder := array.NewStringBuilder(mem) + wkbData := insertData.Data[fieldID].(*storage.GeometryFieldData).Data + validData := insertData.Data[fieldID].(*storage.GeometryFieldData).ValidData + builder.AppendValues(lo.Map(wkbData, func(bs []byte, _ int) string { + return string(bs) + }), validData) + columns = append(columns, builder.NewStringArray()) case schemapb.DataType_Array: data := insertData.Data[fieldID].(*storage.ArrayFieldData).Data validData := insertData.Data[fieldID].(*storage.ArrayFieldData).ValidData diff --git a/internal/util/typeutil/schema.go b/internal/util/typeutil/schema.go index 67d7c6e3ce..e56b6d38ab 100644 --- a/internal/util/typeutil/schema.go +++ b/internal/util/typeutil/schema.go @@ -62,6 +62,11 @@ func ConvertToArrowSchema(fields []*schemapb.FieldSchema) (*arrow.Schema, error) Name: field.Name, Type: arrow.BinaryTypes.Binary, }) + case schemapb.DataType_Geometry: + arrowFields = append(arrowFields, arrow.Field{ + Name: field.Name, + Type: arrow.BinaryTypes.Binary, + }) case schemapb.DataType_BinaryVector: dim, err := storage.GetDimFromParams(field.TypeParams) if err != nil { diff --git a/internal/util/typeutil/storage.go b/internal/util/typeutil/storage.go index 1dd3523ce3..3cb2eb6272 100644 --- a/internal/util/typeutil/storage.go +++ b/internal/util/typeutil/storage.go @@ -77,6 +77,8 @@ func BuildRecord(b *array.RecordBuilder, data *storage.InsertData, fields []*sch } case schemapb.DataType_JSON: fBuilder.(*array.BinaryBuilder).AppendValues(data.Data[field.FieldID].(*storage.JSONFieldData).Data, nil) + case schemapb.DataType_Geometry: + fBuilder.(*array.BinaryBuilder).AppendValues(data.Data[field.FieldID].(*storage.GeometryFieldData).Data, nil) case schemapb.DataType_BinaryVector: vecData := data.Data[field.FieldID].(*storage.BinaryVectorFieldData) for i := 0; i < len(vecData.Data); i += vecData.Dim / 8 { diff --git a/pkg/go.mod b/pkg/go.mod index ea45621d68..99f3109f61 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -14,7 +14,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/json-iterator/go v1.1.12 github.com/klauspost/compress v1.17.7 - github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17 + github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786 github.com/nats-io/nats-server/v2 v2.10.12 github.com/nats-io/nats.go v1.34.1 github.com/panjf2000/ants/v2 v2.11.3 @@ -22,8 +22,8 @@ require ( github.com/quasilyte/go-ruleguard/dsl v0.3.22 github.com/remeh/sizedwaitgroup v1.0.0 github.com/samber/lo v1.27.0 - github.com/shirou/gopsutil/v3 v3.22.9 - github.com/sirupsen/logrus v1.9.0 + github.com/shirou/gopsutil/v3 v3.24.2 + github.com/sirupsen/logrus v1.9.3 github.com/spaolacci/murmur3 v1.1.0 github.com/spf13/cast v1.3.1 github.com/streamnative/pulsarctl v0.5.0 @@ -31,6 +31,7 @@ require ( github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c github.com/tidwall/gjson v1.17.0 github.com/tikv/client-go/v2 v2.0.4 + github.com/twpayne/go-geom v1.5.7 github.com/uber/jaeger-client-go v2.30.0+incompatible github.com/x448/float16 v0.8.4 go.etcd.io/etcd/api/v3 v3.5.5 @@ -47,9 +48,9 @@ require ( go.uber.org/atomic v1.10.0 go.uber.org/automaxprocs v1.5.3 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.36.0 - golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 - golang.org/x/net v0.38.0 + golang.org/x/crypto v0.25.0 + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 + golang.org/x/net v0.27.0 golang.org/x/sync v0.12.0 golang.org/x/sys v0.31.0 google.golang.org/grpc v1.65.0 @@ -78,7 +79,7 @@ require ( github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect - github.com/docker/go-units v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c // indirect @@ -88,7 +89,7 @@ require ( github.com/getsentry/sentry-go v0.12.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/godbus/dbus/v5 v5.0.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -109,7 +110,7 @@ require ( github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/linkedin/goavro/v2 v2.11.1 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.8 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect @@ -130,12 +131,13 @@ require ( github.com/pingcap/log v1.1.1-0.20221015072633-39906604fb81 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stathat/consistent v1.0.0 // indirect @@ -144,12 +146,12 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 // indirect - github.com/tklauser/go-sysconf v0.3.10 // indirect - github.com/tklauser/numcpus v0.4.0 // indirect + github.com/tklauser/go-sysconf v0.3.13 // indirect + github.com/tklauser/numcpus v0.7.0 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect github.com/twmb/murmur3 v1.1.3 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect - github.com/yusufpapurcu/wmi v1.2.2 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect go.etcd.io/etcd/client/v2 v2.305.5 // indirect diff --git a/pkg/go.sum b/pkg/go.sum index 982c9828e5..302f49fe50 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -50,6 +50,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= @@ -61,6 +63,10 @@ github.com/actgardner/gogen-avro/v10 v10.1.0/go.mod h1:o+ybmVjEa27AAr35FRqU98DJu github.com/actgardner/gogen-avro/v10 v10.2.1/go.mod h1:QUhjeHPchheYmMDni/Nx7VB0RsT/ee8YIgGY/xpEQgQ= github.com/actgardner/gogen-avro/v9 v9.1.0/go.mod h1:nyTj6wPqDJoxM3qdnjcLv+EnMDSDFqE0qDpva2QRmKc= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY= +github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -159,8 +165,8 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA= github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= @@ -224,8 +230,9 @@ github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -378,6 +385,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/heetch/avro v0.3.1/go.mod h1:4xn38Oz/+hiEUTpbVfGVLfvOg0yKLlRP7Q9+gJJILgA= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= @@ -456,12 +465,13 @@ github.com/linkedin/goavro/v2 v2.10.0/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF github.com/linkedin/goavro/v2 v2.10.1/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= github.com/linkedin/goavro/v2 v2.11.1 h1:4cuAtbDfqkKnBXp9E+tRkIJGa6W6iAjwonwt8O1f4U0= github.com/linkedin/goavro/v2 v2.11.1/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI= +github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -488,8 +498,8 @@ github.com/milvus-io/cgosymbolizer v0.0.0-20240722103217-b7dee0e50119 h1:9VXijWu github.com/milvus-io/cgosymbolizer v0.0.0-20240722103217-b7dee0e50119/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg= github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b h1:TfeY0NxYxZzUfIfYe5qYDBzt4ZYRqzUjTR6CvUzjat8= github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b/go.mod h1:iwW+9cWfIzzDseEBCCeDSN5SD16Tidvy8cwQ7ZY8Qj4= -github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17 h1:LDOodBVtc2AYxcgc51vDwe+gJp96s6yhJLfdGbLrK+0= -github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= +github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786 h1:GspXs2i+sm2GE4n46VRWBjSCQjqtJDIwwcye+gFyxZA= +github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= github.com/milvus-io/pulsar-client-go v0.12.1 h1:O2JZp1tsYiO7C0MQ4hrUY/aJXnn2Gry6hpm7UodghmE= github.com/milvus-io/pulsar-client-go v0.12.1/go.mod h1:dkutuH4oS2pXiGm+Ti7fQZ4MRjrMPZ8IJeEGAWMeckk= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= @@ -573,8 +583,9 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -633,15 +644,19 @@ github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtm github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA= -github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= +github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y= +github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -670,6 +685,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -681,6 +697,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= @@ -698,15 +715,19 @@ github.com/tikv/client-go/v2 v2.0.4 h1:cPtMXTExqjzk8L40qhrgB/mXiBXKP5LRU0vwjtI2X github.com/tikv/client-go/v2 v2.0.4/go.mod h1:v52O5zDtv2BBus4lm5yrSQhxGW4Z4RaXWfg0U1Kuyqo= github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 h1:ckPpxKcl75mO2N6a4cJXiZH43hvcHPpqc9dh1TmH1nc= github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07/go.mod h1:CipBxPfxPUME+BImx9MUYXCnAVLS3VJUr3mnSJwh40A= -github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= -github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= -github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= -github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= +github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= +github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twmb/murmur3 v1.1.3 h1:D83U0XYKcHRYwYIpBKf3Pks91Z0Byda/9SJ8B6EMRcA= github.com/twmb/murmur3 v1.1.3/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= +github.com/twpayne/go-geom v1.5.7 h1:7fdceDUr03/MP7rAKOaTV6x9njMiQdxB/D0PDzMTCDc= +github.com/twpayne/go-geom v1.5.7/go.mod h1:y4fTAQtLedXW8eG2Yo4tYrIGN1yIwwKkmA+K3iSHKBA= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -738,8 +759,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= @@ -833,8 +854,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -845,8 +866,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -922,8 +943,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1018,11 +1039,13 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/pkg/proto/plan.proto b/pkg/proto/plan.proto index 88c86a9cce..8a9941e4a2 100644 --- a/pkg/proto/plan.proto +++ b/pkg/proto/plan.proto @@ -167,6 +167,22 @@ message NullExpr { NullOp op = 2; } +message GISFunctionFilterExpr{ + ColumnInfo column_info = 1; + string wkt_string = 2; + enum GISOp { + Invalid = 0; + Equals = 1; + Touches = 2; + Overlaps = 3; + Crosses = 4; + Contains = 5; + Intersects = 6; + Within = 7; + } + GISOp op = 3; +} + message UnaryExpr { enum UnaryOp { Invalid = 0; @@ -228,6 +244,7 @@ message Expr { JSONContainsExpr json_contains_expr = 13; CallExpr call_expr = 14; NullExpr null_expr = 15; + GISFunctionFilterExpr gisfunction_filter_expr = 16; }; bool is_template = 20; } diff --git a/pkg/proto/planpb/plan.pb.go b/pkg/proto/planpb/plan.pb.go index 77b3d0e08f..ed878344cf 100644 --- a/pkg/proto/planpb/plan.pb.go +++ b/pkg/proto/planpb/plan.pb.go @@ -330,6 +330,70 @@ func (NullExpr_NullOp) EnumDescriptor() ([]byte, []int) { return file_plan_proto_rawDescGZIP(), []int{14, 0} } +type GISFunctionFilterExpr_GISOp int32 + +const ( + GISFunctionFilterExpr_Invalid GISFunctionFilterExpr_GISOp = 0 + GISFunctionFilterExpr_Equals GISFunctionFilterExpr_GISOp = 1 + GISFunctionFilterExpr_Touches GISFunctionFilterExpr_GISOp = 2 + GISFunctionFilterExpr_Overlaps GISFunctionFilterExpr_GISOp = 3 + GISFunctionFilterExpr_Crosses GISFunctionFilterExpr_GISOp = 4 + GISFunctionFilterExpr_Contains GISFunctionFilterExpr_GISOp = 5 + GISFunctionFilterExpr_Intersects GISFunctionFilterExpr_GISOp = 6 + GISFunctionFilterExpr_Within GISFunctionFilterExpr_GISOp = 7 +) + +// Enum value maps for GISFunctionFilterExpr_GISOp. +var ( + GISFunctionFilterExpr_GISOp_name = map[int32]string{ + 0: "Invalid", + 1: "Equals", + 2: "Touches", + 3: "Overlaps", + 4: "Crosses", + 5: "Contains", + 6: "Intersects", + 7: "Within", + } + GISFunctionFilterExpr_GISOp_value = map[string]int32{ + "Invalid": 0, + "Equals": 1, + "Touches": 2, + "Overlaps": 3, + "Crosses": 4, + "Contains": 5, + "Intersects": 6, + "Within": 7, + } +) + +func (x GISFunctionFilterExpr_GISOp) Enum() *GISFunctionFilterExpr_GISOp { + p := new(GISFunctionFilterExpr_GISOp) + *p = x + return p +} + +func (x GISFunctionFilterExpr_GISOp) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GISFunctionFilterExpr_GISOp) Descriptor() protoreflect.EnumDescriptor { + return file_plan_proto_enumTypes[5].Descriptor() +} + +func (GISFunctionFilterExpr_GISOp) Type() protoreflect.EnumType { + return &file_plan_proto_enumTypes[5] +} + +func (x GISFunctionFilterExpr_GISOp) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GISFunctionFilterExpr_GISOp.Descriptor instead. +func (GISFunctionFilterExpr_GISOp) EnumDescriptor() ([]byte, []int) { + return file_plan_proto_rawDescGZIP(), []int{15, 0} +} + type UnaryExpr_UnaryOp int32 const ( @@ -360,11 +424,11 @@ func (x UnaryExpr_UnaryOp) String() string { } func (UnaryExpr_UnaryOp) Descriptor() protoreflect.EnumDescriptor { - return file_plan_proto_enumTypes[5].Descriptor() + return file_plan_proto_enumTypes[6].Descriptor() } func (UnaryExpr_UnaryOp) Type() protoreflect.EnumType { - return &file_plan_proto_enumTypes[5] + return &file_plan_proto_enumTypes[6] } func (x UnaryExpr_UnaryOp) Number() protoreflect.EnumNumber { @@ -373,7 +437,7 @@ func (x UnaryExpr_UnaryOp) Number() protoreflect.EnumNumber { // Deprecated: Use UnaryExpr_UnaryOp.Descriptor instead. func (UnaryExpr_UnaryOp) EnumDescriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{15, 0} + return file_plan_proto_rawDescGZIP(), []int{16, 0} } type BinaryExpr_BinaryOp int32 @@ -409,11 +473,11 @@ func (x BinaryExpr_BinaryOp) String() string { } func (BinaryExpr_BinaryOp) Descriptor() protoreflect.EnumDescriptor { - return file_plan_proto_enumTypes[6].Descriptor() + return file_plan_proto_enumTypes[7].Descriptor() } func (BinaryExpr_BinaryOp) Type() protoreflect.EnumType { - return &file_plan_proto_enumTypes[6] + return &file_plan_proto_enumTypes[7] } func (x BinaryExpr_BinaryOp) Number() protoreflect.EnumNumber { @@ -422,7 +486,7 @@ func (x BinaryExpr_BinaryOp) Number() protoreflect.EnumNumber { // Deprecated: Use BinaryExpr_BinaryOp.Descriptor instead. func (BinaryExpr_BinaryOp) EnumDescriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{16, 0} + return file_plan_proto_rawDescGZIP(), []int{17, 0} } type GenericValue struct { @@ -1566,6 +1630,69 @@ func (x *NullExpr) GetOp() NullExpr_NullOp { return NullExpr_Invalid } +type GISFunctionFilterExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"` + WktString string `protobuf:"bytes,2,opt,name=wkt_string,json=wktString,proto3" json:"wkt_string,omitempty"` + Op GISFunctionFilterExpr_GISOp `protobuf:"varint,3,opt,name=op,proto3,enum=milvus.proto.plan.GISFunctionFilterExpr_GISOp" json:"op,omitempty"` +} + +func (x *GISFunctionFilterExpr) Reset() { + *x = GISFunctionFilterExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_plan_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GISFunctionFilterExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GISFunctionFilterExpr) ProtoMessage() {} + +func (x *GISFunctionFilterExpr) ProtoReflect() protoreflect.Message { + mi := &file_plan_proto_msgTypes[15] + 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 GISFunctionFilterExpr.ProtoReflect.Descriptor instead. +func (*GISFunctionFilterExpr) Descriptor() ([]byte, []int) { + return file_plan_proto_rawDescGZIP(), []int{15} +} + +func (x *GISFunctionFilterExpr) GetColumnInfo() *ColumnInfo { + if x != nil { + return x.ColumnInfo + } + return nil +} + +func (x *GISFunctionFilterExpr) GetWktString() string { + if x != nil { + return x.WktString + } + return "" +} + +func (x *GISFunctionFilterExpr) GetOp() GISFunctionFilterExpr_GISOp { + if x != nil { + return x.Op + } + return GISFunctionFilterExpr_Invalid +} + type UnaryExpr struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1578,7 +1705,7 @@ type UnaryExpr struct { func (x *UnaryExpr) Reset() { *x = UnaryExpr{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[15] + mi := &file_plan_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1591,7 +1718,7 @@ func (x *UnaryExpr) String() string { func (*UnaryExpr) ProtoMessage() {} func (x *UnaryExpr) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[15] + mi := &file_plan_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1604,7 +1731,7 @@ func (x *UnaryExpr) ProtoReflect() protoreflect.Message { // Deprecated: Use UnaryExpr.ProtoReflect.Descriptor instead. func (*UnaryExpr) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{15} + return file_plan_proto_rawDescGZIP(), []int{16} } func (x *UnaryExpr) GetOp() UnaryExpr_UnaryOp { @@ -1634,7 +1761,7 @@ type BinaryExpr struct { func (x *BinaryExpr) Reset() { *x = BinaryExpr{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[16] + mi := &file_plan_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1647,7 +1774,7 @@ func (x *BinaryExpr) String() string { func (*BinaryExpr) ProtoMessage() {} func (x *BinaryExpr) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[16] + mi := &file_plan_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1660,7 +1787,7 @@ func (x *BinaryExpr) ProtoReflect() protoreflect.Message { // Deprecated: Use BinaryExpr.ProtoReflect.Descriptor instead. func (*BinaryExpr) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{16} + return file_plan_proto_rawDescGZIP(), []int{17} } func (x *BinaryExpr) GetOp() BinaryExpr_BinaryOp { @@ -1697,7 +1824,7 @@ type BinaryArithOp struct { func (x *BinaryArithOp) Reset() { *x = BinaryArithOp{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[17] + mi := &file_plan_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1710,7 +1837,7 @@ func (x *BinaryArithOp) String() string { func (*BinaryArithOp) ProtoMessage() {} func (x *BinaryArithOp) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[17] + mi := &file_plan_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1723,7 +1850,7 @@ func (x *BinaryArithOp) ProtoReflect() protoreflect.Message { // Deprecated: Use BinaryArithOp.ProtoReflect.Descriptor instead. func (*BinaryArithOp) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{17} + return file_plan_proto_rawDescGZIP(), []int{18} } func (x *BinaryArithOp) GetColumnInfo() *ColumnInfo { @@ -1760,7 +1887,7 @@ type BinaryArithExpr struct { func (x *BinaryArithExpr) Reset() { *x = BinaryArithExpr{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[18] + mi := &file_plan_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1773,7 +1900,7 @@ func (x *BinaryArithExpr) String() string { func (*BinaryArithExpr) ProtoMessage() {} func (x *BinaryArithExpr) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[18] + mi := &file_plan_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1786,7 +1913,7 @@ func (x *BinaryArithExpr) ProtoReflect() protoreflect.Message { // Deprecated: Use BinaryArithExpr.ProtoReflect.Descriptor instead. func (*BinaryArithExpr) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{18} + return file_plan_proto_rawDescGZIP(), []int{19} } func (x *BinaryArithExpr) GetLeft() *Expr { @@ -1827,7 +1954,7 @@ type BinaryArithOpEvalRangeExpr struct { func (x *BinaryArithOpEvalRangeExpr) Reset() { *x = BinaryArithOpEvalRangeExpr{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[19] + mi := &file_plan_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1840,7 +1967,7 @@ func (x *BinaryArithOpEvalRangeExpr) String() string { func (*BinaryArithOpEvalRangeExpr) ProtoMessage() {} func (x *BinaryArithOpEvalRangeExpr) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[19] + mi := &file_plan_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1853,7 +1980,7 @@ func (x *BinaryArithOpEvalRangeExpr) ProtoReflect() protoreflect.Message { // Deprecated: Use BinaryArithOpEvalRangeExpr.ProtoReflect.Descriptor instead. func (*BinaryArithOpEvalRangeExpr) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{19} + return file_plan_proto_rawDescGZIP(), []int{20} } func (x *BinaryArithOpEvalRangeExpr) GetColumnInfo() *ColumnInfo { @@ -1914,7 +2041,7 @@ type AlwaysTrueExpr struct { func (x *AlwaysTrueExpr) Reset() { *x = AlwaysTrueExpr{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[20] + mi := &file_plan_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1927,7 +2054,7 @@ func (x *AlwaysTrueExpr) String() string { func (*AlwaysTrueExpr) ProtoMessage() {} func (x *AlwaysTrueExpr) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[20] + mi := &file_plan_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1940,7 +2067,7 @@ func (x *AlwaysTrueExpr) ProtoReflect() protoreflect.Message { // Deprecated: Use AlwaysTrueExpr.ProtoReflect.Descriptor instead. func (*AlwaysTrueExpr) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{20} + return file_plan_proto_rawDescGZIP(), []int{21} } type Expr struct { @@ -1965,6 +2092,7 @@ type Expr struct { // *Expr_JsonContainsExpr // *Expr_CallExpr // *Expr_NullExpr + // *Expr_GisfunctionFilterExpr Expr isExpr_Expr `protobuf_oneof:"expr"` IsTemplate bool `protobuf:"varint,20,opt,name=is_template,json=isTemplate,proto3" json:"is_template,omitempty"` } @@ -1972,7 +2100,7 @@ type Expr struct { func (x *Expr) Reset() { *x = Expr{} if protoimpl.UnsafeEnabled { - mi := &file_plan_proto_msgTypes[21] + mi := &file_plan_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1985,7 +2113,7 @@ func (x *Expr) String() string { func (*Expr) ProtoMessage() {} func (x *Expr) ProtoReflect() protoreflect.Message { - mi := &file_plan_proto_msgTypes[21] + mi := &file_plan_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1998,7 +2126,7 @@ func (x *Expr) ProtoReflect() protoreflect.Message { // Deprecated: Use Expr.ProtoReflect.Descriptor instead. func (*Expr) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{21} + return file_plan_proto_rawDescGZIP(), []int{22} } func (m *Expr) GetExpr() isExpr_Expr { @@ -2113,6 +2241,13 @@ func (x *Expr) GetNullExpr() *NullExpr { return nil } +func (x *Expr) GetGisfunctionFilterExpr() *GISFunctionFilterExpr { + if x, ok := x.GetExpr().(*Expr_GisfunctionFilterExpr); ok { + return x.GisfunctionFilterExpr + } + return nil +} + func (x *Expr) GetIsTemplate() bool { if x != nil { return x.IsTemplate @@ -2184,6 +2319,10 @@ type Expr_NullExpr struct { NullExpr *NullExpr `protobuf:"bytes,15,opt,name=null_expr,json=nullExpr,proto3,oneof"` } +type Expr_GisfunctionFilterExpr struct { + GisfunctionFilterExpr *GISFunctionFilterExpr `protobuf:"bytes,16,opt,name=gisfunction_filter_expr,json=gisfunctionFilterExpr,proto3,oneof"` +} + func (*Expr_TermExpr) isExpr_Expr() {} func (*Expr_UnaryExpr) isExpr_Expr() {} @@ -2214,6 +2353,8 @@ func (*Expr_CallExpr) isExpr_Expr() {} func (*Expr_NullExpr) isExpr_Expr() {} +func (*Expr_GisfunctionFilterExpr) isExpr_Expr() {} + type VectorANNS struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2229,7 +2370,7 @@ type VectorANNS struct { func (x *VectorANNS) Reset() { *x = VectorANNS{} 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) } @@ -2242,7 +2383,7 @@ func (x *VectorANNS) String() string { func (*VectorANNS) ProtoMessage() {} func (x *VectorANNS) 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 { @@ -2255,7 +2396,7 @@ func (x *VectorANNS) ProtoReflect() protoreflect.Message { // Deprecated: Use VectorANNS.ProtoReflect.Descriptor instead. func (*VectorANNS) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{22} + return file_plan_proto_rawDescGZIP(), []int{23} } func (x *VectorANNS) GetVectorType() VectorType { @@ -2306,7 +2447,7 @@ type QueryPlanNode struct { func (x *QueryPlanNode) Reset() { *x = QueryPlanNode{} 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) } @@ -2319,7 +2460,7 @@ func (x *QueryPlanNode) String() string { func (*QueryPlanNode) ProtoMessage() {} func (x *QueryPlanNode) 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 { @@ -2332,7 +2473,7 @@ func (x *QueryPlanNode) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryPlanNode.ProtoReflect.Descriptor instead. func (*QueryPlanNode) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{23} + return file_plan_proto_rawDescGZIP(), []int{24} } func (x *QueryPlanNode) GetPredicates() *Expr { @@ -2374,7 +2515,7 @@ type PlanNode struct { func (x *PlanNode) Reset() { *x = PlanNode{} 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) } @@ -2387,7 +2528,7 @@ func (x *PlanNode) String() string { func (*PlanNode) ProtoMessage() {} func (x *PlanNode) 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 { @@ -2400,7 +2541,7 @@ func (x *PlanNode) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanNode.ProtoReflect.Descriptor instead. func (*PlanNode) Descriptor() ([]byte, []int) { - return file_plan_proto_rawDescGZIP(), []int{24} + return file_plan_proto_rawDescGZIP(), []int{25} } func (m *PlanNode) GetNode() isPlanNode_Node { @@ -2691,228 +2832,253 @@ var file_plan_proto_rawDesc = []byte{ 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, 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, + 0x0d, 0x0a, 0x09, 0x49, 0x73, 0x4e, 0x6f, 0x74, 0x4e, 0x75, 0x6c, 0x6c, 0x10, 0x02, 0x22, 0xaa, + 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, 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, + 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, 0x22, 0x72, 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, 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, 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, + 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, 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, 0x10, 0x0a, 0x0e, 0x41, 0x6c, 0x77, 0x61, - 0x79, 0x73, 0x54, 0x72, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x22, 0xf9, 0x08, 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, + 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, 0x10, 0x0a, 0x0e, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x54, + 0x72, 0x75, 0x65, 0x45, 0x78, 0x70, 0x72, 0x22, 0xdd, 0x09, 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, 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, 0x10, 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, - 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, 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, + 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, 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, 0x9a, 0x02, 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, 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, 0x9a, 0x02, 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, 0x42, - 0x06, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 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, 0x6d, - 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, 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, + 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, + 0x42, 0x06, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 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, + 0x6d, 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, 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 ( @@ -2927,114 +3093,119 @@ func file_plan_proto_rawDescGZIP() []byte { return file_plan_proto_rawDescData } -var file_plan_proto_enumTypes = make([]protoimpl.EnumInfo, 7) -var file_plan_proto_msgTypes = make([]protoimpl.MessageInfo, 25) +var file_plan_proto_enumTypes = make([]protoimpl.EnumInfo, 8) +var file_plan_proto_msgTypes = make([]protoimpl.MessageInfo, 26) var file_plan_proto_goTypes = []interface{}{ (OpType)(0), // 0: milvus.proto.plan.OpType (ArithOpType)(0), // 1: milvus.proto.plan.ArithOpType (VectorType)(0), // 2: milvus.proto.plan.VectorType (JSONContainsExpr_JSONOp)(0), // 3: milvus.proto.plan.JSONContainsExpr.JSONOp (NullExpr_NullOp)(0), // 4: milvus.proto.plan.NullExpr.NullOp - (UnaryExpr_UnaryOp)(0), // 5: milvus.proto.plan.UnaryExpr.UnaryOp - (BinaryExpr_BinaryOp)(0), // 6: milvus.proto.plan.BinaryExpr.BinaryOp - (*GenericValue)(nil), // 7: milvus.proto.plan.GenericValue - (*Array)(nil), // 8: milvus.proto.plan.Array - (*SearchIteratorV2Info)(nil), // 9: milvus.proto.plan.SearchIteratorV2Info - (*QueryInfo)(nil), // 10: milvus.proto.plan.QueryInfo - (*ColumnInfo)(nil), // 11: milvus.proto.plan.ColumnInfo - (*ColumnExpr)(nil), // 12: milvus.proto.plan.ColumnExpr - (*ExistsExpr)(nil), // 13: milvus.proto.plan.ExistsExpr - (*ValueExpr)(nil), // 14: milvus.proto.plan.ValueExpr - (*UnaryRangeExpr)(nil), // 15: milvus.proto.plan.UnaryRangeExpr - (*BinaryRangeExpr)(nil), // 16: milvus.proto.plan.BinaryRangeExpr - (*CallExpr)(nil), // 17: milvus.proto.plan.CallExpr - (*CompareExpr)(nil), // 18: milvus.proto.plan.CompareExpr - (*TermExpr)(nil), // 19: milvus.proto.plan.TermExpr - (*JSONContainsExpr)(nil), // 20: milvus.proto.plan.JSONContainsExpr - (*NullExpr)(nil), // 21: milvus.proto.plan.NullExpr - (*UnaryExpr)(nil), // 22: milvus.proto.plan.UnaryExpr - (*BinaryExpr)(nil), // 23: milvus.proto.plan.BinaryExpr - (*BinaryArithOp)(nil), // 24: milvus.proto.plan.BinaryArithOp - (*BinaryArithExpr)(nil), // 25: milvus.proto.plan.BinaryArithExpr - (*BinaryArithOpEvalRangeExpr)(nil), // 26: milvus.proto.plan.BinaryArithOpEvalRangeExpr - (*AlwaysTrueExpr)(nil), // 27: milvus.proto.plan.AlwaysTrueExpr - (*Expr)(nil), // 28: milvus.proto.plan.Expr - (*VectorANNS)(nil), // 29: milvus.proto.plan.VectorANNS - (*QueryPlanNode)(nil), // 30: milvus.proto.plan.QueryPlanNode - (*PlanNode)(nil), // 31: milvus.proto.plan.PlanNode - (schemapb.DataType)(0), // 32: milvus.proto.schema.DataType + (GISFunctionFilterExpr_GISOp)(0), // 5: milvus.proto.plan.GISFunctionFilterExpr.GISOp + (UnaryExpr_UnaryOp)(0), // 6: milvus.proto.plan.UnaryExpr.UnaryOp + (BinaryExpr_BinaryOp)(0), // 7: milvus.proto.plan.BinaryExpr.BinaryOp + (*GenericValue)(nil), // 8: milvus.proto.plan.GenericValue + (*Array)(nil), // 9: milvus.proto.plan.Array + (*SearchIteratorV2Info)(nil), // 10: milvus.proto.plan.SearchIteratorV2Info + (*QueryInfo)(nil), // 11: milvus.proto.plan.QueryInfo + (*ColumnInfo)(nil), // 12: milvus.proto.plan.ColumnInfo + (*ColumnExpr)(nil), // 13: milvus.proto.plan.ColumnExpr + (*ExistsExpr)(nil), // 14: milvus.proto.plan.ExistsExpr + (*ValueExpr)(nil), // 15: milvus.proto.plan.ValueExpr + (*UnaryRangeExpr)(nil), // 16: milvus.proto.plan.UnaryRangeExpr + (*BinaryRangeExpr)(nil), // 17: milvus.proto.plan.BinaryRangeExpr + (*CallExpr)(nil), // 18: milvus.proto.plan.CallExpr + (*CompareExpr)(nil), // 19: milvus.proto.plan.CompareExpr + (*TermExpr)(nil), // 20: milvus.proto.plan.TermExpr + (*JSONContainsExpr)(nil), // 21: milvus.proto.plan.JSONContainsExpr + (*NullExpr)(nil), // 22: milvus.proto.plan.NullExpr + (*GISFunctionFilterExpr)(nil), // 23: milvus.proto.plan.GISFunctionFilterExpr + (*UnaryExpr)(nil), // 24: milvus.proto.plan.UnaryExpr + (*BinaryExpr)(nil), // 25: milvus.proto.plan.BinaryExpr + (*BinaryArithOp)(nil), // 26: milvus.proto.plan.BinaryArithOp + (*BinaryArithExpr)(nil), // 27: milvus.proto.plan.BinaryArithExpr + (*BinaryArithOpEvalRangeExpr)(nil), // 28: milvus.proto.plan.BinaryArithOpEvalRangeExpr + (*AlwaysTrueExpr)(nil), // 29: milvus.proto.plan.AlwaysTrueExpr + (*Expr)(nil), // 30: milvus.proto.plan.Expr + (*VectorANNS)(nil), // 31: milvus.proto.plan.VectorANNS + (*QueryPlanNode)(nil), // 32: milvus.proto.plan.QueryPlanNode + (*PlanNode)(nil), // 33: milvus.proto.plan.PlanNode + (schemapb.DataType)(0), // 34: milvus.proto.schema.DataType } var file_plan_proto_depIdxs = []int32{ - 8, // 0: milvus.proto.plan.GenericValue.array_val:type_name -> milvus.proto.plan.Array - 7, // 1: milvus.proto.plan.Array.array:type_name -> milvus.proto.plan.GenericValue - 32, // 2: milvus.proto.plan.Array.element_type:type_name -> milvus.proto.schema.DataType - 9, // 3: milvus.proto.plan.QueryInfo.search_iterator_v2_info:type_name -> milvus.proto.plan.SearchIteratorV2Info - 32, // 4: milvus.proto.plan.ColumnInfo.data_type:type_name -> milvus.proto.schema.DataType - 32, // 5: milvus.proto.plan.ColumnInfo.element_type:type_name -> milvus.proto.schema.DataType - 11, // 6: milvus.proto.plan.ColumnExpr.info:type_name -> milvus.proto.plan.ColumnInfo - 11, // 7: milvus.proto.plan.ExistsExpr.info:type_name -> milvus.proto.plan.ColumnInfo - 7, // 8: milvus.proto.plan.ValueExpr.value:type_name -> milvus.proto.plan.GenericValue - 11, // 9: milvus.proto.plan.UnaryRangeExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo + 9, // 0: milvus.proto.plan.GenericValue.array_val:type_name -> milvus.proto.plan.Array + 8, // 1: milvus.proto.plan.Array.array:type_name -> milvus.proto.plan.GenericValue + 34, // 2: milvus.proto.plan.Array.element_type:type_name -> milvus.proto.schema.DataType + 10, // 3: milvus.proto.plan.QueryInfo.search_iterator_v2_info:type_name -> milvus.proto.plan.SearchIteratorV2Info + 34, // 4: milvus.proto.plan.ColumnInfo.data_type:type_name -> milvus.proto.schema.DataType + 34, // 5: milvus.proto.plan.ColumnInfo.element_type:type_name -> milvus.proto.schema.DataType + 12, // 6: milvus.proto.plan.ColumnExpr.info:type_name -> milvus.proto.plan.ColumnInfo + 12, // 7: milvus.proto.plan.ExistsExpr.info:type_name -> milvus.proto.plan.ColumnInfo + 8, // 8: milvus.proto.plan.ValueExpr.value:type_name -> milvus.proto.plan.GenericValue + 12, // 9: milvus.proto.plan.UnaryRangeExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo 0, // 10: milvus.proto.plan.UnaryRangeExpr.op:type_name -> milvus.proto.plan.OpType - 7, // 11: milvus.proto.plan.UnaryRangeExpr.value:type_name -> milvus.proto.plan.GenericValue - 7, // 12: milvus.proto.plan.UnaryRangeExpr.extra_values:type_name -> milvus.proto.plan.GenericValue - 11, // 13: milvus.proto.plan.BinaryRangeExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo - 7, // 14: milvus.proto.plan.BinaryRangeExpr.lower_value:type_name -> milvus.proto.plan.GenericValue - 7, // 15: milvus.proto.plan.BinaryRangeExpr.upper_value:type_name -> milvus.proto.plan.GenericValue - 28, // 16: milvus.proto.plan.CallExpr.function_parameters:type_name -> milvus.proto.plan.Expr - 11, // 17: milvus.proto.plan.CompareExpr.left_column_info:type_name -> milvus.proto.plan.ColumnInfo - 11, // 18: milvus.proto.plan.CompareExpr.right_column_info:type_name -> milvus.proto.plan.ColumnInfo + 8, // 11: milvus.proto.plan.UnaryRangeExpr.value:type_name -> milvus.proto.plan.GenericValue + 8, // 12: milvus.proto.plan.UnaryRangeExpr.extra_values:type_name -> milvus.proto.plan.GenericValue + 12, // 13: milvus.proto.plan.BinaryRangeExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo + 8, // 14: milvus.proto.plan.BinaryRangeExpr.lower_value:type_name -> milvus.proto.plan.GenericValue + 8, // 15: milvus.proto.plan.BinaryRangeExpr.upper_value:type_name -> milvus.proto.plan.GenericValue + 30, // 16: milvus.proto.plan.CallExpr.function_parameters:type_name -> milvus.proto.plan.Expr + 12, // 17: milvus.proto.plan.CompareExpr.left_column_info:type_name -> milvus.proto.plan.ColumnInfo + 12, // 18: milvus.proto.plan.CompareExpr.right_column_info:type_name -> milvus.proto.plan.ColumnInfo 0, // 19: milvus.proto.plan.CompareExpr.op:type_name -> milvus.proto.plan.OpType - 11, // 20: milvus.proto.plan.TermExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo - 7, // 21: milvus.proto.plan.TermExpr.values:type_name -> milvus.proto.plan.GenericValue - 11, // 22: milvus.proto.plan.JSONContainsExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo - 7, // 23: milvus.proto.plan.JSONContainsExpr.elements:type_name -> milvus.proto.plan.GenericValue + 12, // 20: milvus.proto.plan.TermExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo + 8, // 21: milvus.proto.plan.TermExpr.values:type_name -> milvus.proto.plan.GenericValue + 12, // 22: milvus.proto.plan.JSONContainsExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo + 8, // 23: milvus.proto.plan.JSONContainsExpr.elements:type_name -> milvus.proto.plan.GenericValue 3, // 24: milvus.proto.plan.JSONContainsExpr.op:type_name -> milvus.proto.plan.JSONContainsExpr.JSONOp - 11, // 25: milvus.proto.plan.NullExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo + 12, // 25: milvus.proto.plan.NullExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo 4, // 26: milvus.proto.plan.NullExpr.op:type_name -> milvus.proto.plan.NullExpr.NullOp - 5, // 27: milvus.proto.plan.UnaryExpr.op:type_name -> milvus.proto.plan.UnaryExpr.UnaryOp - 28, // 28: milvus.proto.plan.UnaryExpr.child:type_name -> milvus.proto.plan.Expr - 6, // 29: milvus.proto.plan.BinaryExpr.op:type_name -> milvus.proto.plan.BinaryExpr.BinaryOp - 28, // 30: milvus.proto.plan.BinaryExpr.left:type_name -> milvus.proto.plan.Expr - 28, // 31: milvus.proto.plan.BinaryExpr.right:type_name -> milvus.proto.plan.Expr - 11, // 32: milvus.proto.plan.BinaryArithOp.column_info:type_name -> milvus.proto.plan.ColumnInfo - 1, // 33: milvus.proto.plan.BinaryArithOp.arith_op:type_name -> milvus.proto.plan.ArithOpType - 7, // 34: milvus.proto.plan.BinaryArithOp.right_operand:type_name -> milvus.proto.plan.GenericValue - 28, // 35: milvus.proto.plan.BinaryArithExpr.left:type_name -> milvus.proto.plan.Expr - 28, // 36: milvus.proto.plan.BinaryArithExpr.right:type_name -> milvus.proto.plan.Expr - 1, // 37: milvus.proto.plan.BinaryArithExpr.op:type_name -> milvus.proto.plan.ArithOpType - 11, // 38: milvus.proto.plan.BinaryArithOpEvalRangeExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo - 1, // 39: milvus.proto.plan.BinaryArithOpEvalRangeExpr.arith_op:type_name -> milvus.proto.plan.ArithOpType - 7, // 40: milvus.proto.plan.BinaryArithOpEvalRangeExpr.right_operand:type_name -> milvus.proto.plan.GenericValue - 0, // 41: milvus.proto.plan.BinaryArithOpEvalRangeExpr.op:type_name -> milvus.proto.plan.OpType - 7, // 42: milvus.proto.plan.BinaryArithOpEvalRangeExpr.value:type_name -> milvus.proto.plan.GenericValue - 19, // 43: milvus.proto.plan.Expr.term_expr:type_name -> milvus.proto.plan.TermExpr - 22, // 44: milvus.proto.plan.Expr.unary_expr:type_name -> milvus.proto.plan.UnaryExpr - 23, // 45: milvus.proto.plan.Expr.binary_expr:type_name -> milvus.proto.plan.BinaryExpr - 18, // 46: milvus.proto.plan.Expr.compare_expr:type_name -> milvus.proto.plan.CompareExpr - 15, // 47: milvus.proto.plan.Expr.unary_range_expr:type_name -> milvus.proto.plan.UnaryRangeExpr - 16, // 48: milvus.proto.plan.Expr.binary_range_expr:type_name -> milvus.proto.plan.BinaryRangeExpr - 26, // 49: milvus.proto.plan.Expr.binary_arith_op_eval_range_expr:type_name -> milvus.proto.plan.BinaryArithOpEvalRangeExpr - 25, // 50: milvus.proto.plan.Expr.binary_arith_expr:type_name -> milvus.proto.plan.BinaryArithExpr - 14, // 51: milvus.proto.plan.Expr.value_expr:type_name -> milvus.proto.plan.ValueExpr - 12, // 52: milvus.proto.plan.Expr.column_expr:type_name -> milvus.proto.plan.ColumnExpr - 13, // 53: milvus.proto.plan.Expr.exists_expr:type_name -> milvus.proto.plan.ExistsExpr - 27, // 54: milvus.proto.plan.Expr.always_true_expr:type_name -> milvus.proto.plan.AlwaysTrueExpr - 20, // 55: milvus.proto.plan.Expr.json_contains_expr:type_name -> milvus.proto.plan.JSONContainsExpr - 17, // 56: milvus.proto.plan.Expr.call_expr:type_name -> milvus.proto.plan.CallExpr - 21, // 57: milvus.proto.plan.Expr.null_expr:type_name -> milvus.proto.plan.NullExpr - 2, // 58: milvus.proto.plan.VectorANNS.vector_type:type_name -> milvus.proto.plan.VectorType - 28, // 59: milvus.proto.plan.VectorANNS.predicates:type_name -> milvus.proto.plan.Expr - 10, // 60: milvus.proto.plan.VectorANNS.query_info:type_name -> milvus.proto.plan.QueryInfo - 28, // 61: milvus.proto.plan.QueryPlanNode.predicates:type_name -> milvus.proto.plan.Expr - 29, // 62: milvus.proto.plan.PlanNode.vector_anns:type_name -> milvus.proto.plan.VectorANNS - 28, // 63: milvus.proto.plan.PlanNode.predicates:type_name -> milvus.proto.plan.Expr - 30, // 64: milvus.proto.plan.PlanNode.query:type_name -> milvus.proto.plan.QueryPlanNode - 65, // [65:65] is the sub-list for method output_type - 65, // [65:65] is the sub-list for method input_type - 65, // [65:65] is the sub-list for extension type_name - 65, // [65:65] is the sub-list for extension extendee - 0, // [0:65] is the sub-list for field type_name + 12, // 27: milvus.proto.plan.GISFunctionFilterExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo + 5, // 28: milvus.proto.plan.GISFunctionFilterExpr.op:type_name -> milvus.proto.plan.GISFunctionFilterExpr.GISOp + 6, // 29: milvus.proto.plan.UnaryExpr.op:type_name -> milvus.proto.plan.UnaryExpr.UnaryOp + 30, // 30: milvus.proto.plan.UnaryExpr.child:type_name -> milvus.proto.plan.Expr + 7, // 31: milvus.proto.plan.BinaryExpr.op:type_name -> milvus.proto.plan.BinaryExpr.BinaryOp + 30, // 32: milvus.proto.plan.BinaryExpr.left:type_name -> milvus.proto.plan.Expr + 30, // 33: milvus.proto.plan.BinaryExpr.right:type_name -> milvus.proto.plan.Expr + 12, // 34: milvus.proto.plan.BinaryArithOp.column_info:type_name -> milvus.proto.plan.ColumnInfo + 1, // 35: milvus.proto.plan.BinaryArithOp.arith_op:type_name -> milvus.proto.plan.ArithOpType + 8, // 36: milvus.proto.plan.BinaryArithOp.right_operand:type_name -> milvus.proto.plan.GenericValue + 30, // 37: milvus.proto.plan.BinaryArithExpr.left:type_name -> milvus.proto.plan.Expr + 30, // 38: milvus.proto.plan.BinaryArithExpr.right:type_name -> milvus.proto.plan.Expr + 1, // 39: milvus.proto.plan.BinaryArithExpr.op:type_name -> milvus.proto.plan.ArithOpType + 12, // 40: milvus.proto.plan.BinaryArithOpEvalRangeExpr.column_info:type_name -> milvus.proto.plan.ColumnInfo + 1, // 41: milvus.proto.plan.BinaryArithOpEvalRangeExpr.arith_op:type_name -> milvus.proto.plan.ArithOpType + 8, // 42: milvus.proto.plan.BinaryArithOpEvalRangeExpr.right_operand:type_name -> milvus.proto.plan.GenericValue + 0, // 43: milvus.proto.plan.BinaryArithOpEvalRangeExpr.op:type_name -> milvus.proto.plan.OpType + 8, // 44: milvus.proto.plan.BinaryArithOpEvalRangeExpr.value:type_name -> milvus.proto.plan.GenericValue + 20, // 45: milvus.proto.plan.Expr.term_expr:type_name -> milvus.proto.plan.TermExpr + 24, // 46: milvus.proto.plan.Expr.unary_expr:type_name -> milvus.proto.plan.UnaryExpr + 25, // 47: milvus.proto.plan.Expr.binary_expr:type_name -> milvus.proto.plan.BinaryExpr + 19, // 48: milvus.proto.plan.Expr.compare_expr:type_name -> milvus.proto.plan.CompareExpr + 16, // 49: milvus.proto.plan.Expr.unary_range_expr:type_name -> milvus.proto.plan.UnaryRangeExpr + 17, // 50: milvus.proto.plan.Expr.binary_range_expr:type_name -> milvus.proto.plan.BinaryRangeExpr + 28, // 51: milvus.proto.plan.Expr.binary_arith_op_eval_range_expr:type_name -> milvus.proto.plan.BinaryArithOpEvalRangeExpr + 27, // 52: milvus.proto.plan.Expr.binary_arith_expr:type_name -> milvus.proto.plan.BinaryArithExpr + 15, // 53: milvus.proto.plan.Expr.value_expr:type_name -> milvus.proto.plan.ValueExpr + 13, // 54: milvus.proto.plan.Expr.column_expr:type_name -> milvus.proto.plan.ColumnExpr + 14, // 55: milvus.proto.plan.Expr.exists_expr:type_name -> milvus.proto.plan.ExistsExpr + 29, // 56: milvus.proto.plan.Expr.always_true_expr:type_name -> milvus.proto.plan.AlwaysTrueExpr + 21, // 57: milvus.proto.plan.Expr.json_contains_expr:type_name -> milvus.proto.plan.JSONContainsExpr + 18, // 58: milvus.proto.plan.Expr.call_expr:type_name -> milvus.proto.plan.CallExpr + 22, // 59: milvus.proto.plan.Expr.null_expr:type_name -> milvus.proto.plan.NullExpr + 23, // 60: milvus.proto.plan.Expr.gisfunction_filter_expr:type_name -> milvus.proto.plan.GISFunctionFilterExpr + 2, // 61: milvus.proto.plan.VectorANNS.vector_type:type_name -> milvus.proto.plan.VectorType + 30, // 62: milvus.proto.plan.VectorANNS.predicates:type_name -> milvus.proto.plan.Expr + 11, // 63: milvus.proto.plan.VectorANNS.query_info:type_name -> milvus.proto.plan.QueryInfo + 30, // 64: milvus.proto.plan.QueryPlanNode.predicates:type_name -> milvus.proto.plan.Expr + 31, // 65: milvus.proto.plan.PlanNode.vector_anns:type_name -> milvus.proto.plan.VectorANNS + 30, // 66: milvus.proto.plan.PlanNode.predicates:type_name -> milvus.proto.plan.Expr + 32, // 67: milvus.proto.plan.PlanNode.query:type_name -> milvus.proto.plan.QueryPlanNode + 68, // [68:68] is the sub-list for method output_type + 68, // [68:68] is the sub-list for method input_type + 68, // [68:68] is the sub-list for extension type_name + 68, // [68:68] is the sub-list for extension extendee + 0, // [0:68] is the sub-list for field type_name } func init() { file_plan_proto_init() } @@ -3224,7 +3395,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnaryExpr); i { + switch v := v.(*GISFunctionFilterExpr); i { case 0: return &v.state case 1: @@ -3236,7 +3407,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BinaryExpr); i { + switch v := v.(*UnaryExpr); i { case 0: return &v.state case 1: @@ -3248,7 +3419,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BinaryArithOp); i { + switch v := v.(*BinaryExpr); i { case 0: return &v.state case 1: @@ -3260,7 +3431,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BinaryArithExpr); i { + switch v := v.(*BinaryArithOp); i { case 0: return &v.state case 1: @@ -3272,7 +3443,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BinaryArithOpEvalRangeExpr); i { + switch v := v.(*BinaryArithExpr); i { case 0: return &v.state case 1: @@ -3284,7 +3455,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AlwaysTrueExpr); i { + switch v := v.(*BinaryArithOpEvalRangeExpr); i { case 0: return &v.state case 1: @@ -3296,7 +3467,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr); i { + switch v := v.(*AlwaysTrueExpr); i { case 0: return &v.state case 1: @@ -3308,7 +3479,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VectorANNS); i { + switch v := v.(*Expr); i { case 0: return &v.state case 1: @@ -3320,7 +3491,7 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryPlanNode); i { + switch v := v.(*VectorANNS); i { case 0: return &v.state case 1: @@ -3332,6 +3503,18 @@ func file_plan_proto_init() { } } file_plan_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryPlanNode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plan_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanNode); i { case 0: return &v.state @@ -3353,7 +3536,7 @@ func file_plan_proto_init() { } file_plan_proto_msgTypes[2].OneofWrappers = []interface{}{} file_plan_proto_msgTypes[3].OneofWrappers = []interface{}{} - file_plan_proto_msgTypes[21].OneofWrappers = []interface{}{ + file_plan_proto_msgTypes[22].OneofWrappers = []interface{}{ (*Expr_TermExpr)(nil), (*Expr_UnaryExpr)(nil), (*Expr_BinaryExpr)(nil), @@ -3369,8 +3552,9 @@ func file_plan_proto_init() { (*Expr_JsonContainsExpr)(nil), (*Expr_CallExpr)(nil), (*Expr_NullExpr)(nil), + (*Expr_GisfunctionFilterExpr)(nil), } - file_plan_proto_msgTypes[24].OneofWrappers = []interface{}{ + file_plan_proto_msgTypes[25].OneofWrappers = []interface{}{ (*PlanNode_VectorAnns)(nil), (*PlanNode_Predicates)(nil), (*PlanNode_Query)(nil), @@ -3380,8 +3564,8 @@ func file_plan_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_plan_proto_rawDesc, - NumEnums: 7, - NumMessages: 25, + NumEnums: 8, + NumMessages: 26, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/util/funcutil/func.go b/pkg/util/funcutil/func.go index 15555eb956..df9355556d 100644 --- a/pkg/util/funcutil/func.go +++ b/pkg/util/funcutil/func.go @@ -379,6 +379,8 @@ func GetNumRowOfFieldDataWithSchema(fieldData *schemapb.FieldData, helper *typeu fieldNumRows = getNumRowsOfScalarField(fieldData.GetScalars().GetArrayData().GetData()) case schemapb.DataType_JSON: fieldNumRows = getNumRowsOfScalarField(fieldData.GetScalars().GetJsonData().GetData()) + case schemapb.DataType_Geometry: + fieldNumRows = getNumRowsOfScalarField(fieldData.GetScalars().GetGeometryData().GetData()) case schemapb.DataType_FloatVector: dim := fieldData.GetVectors().GetDim() fieldNumRows, err = GetNumRowsOfFloatVectorField(fieldData.GetVectors().GetFloatVector().GetData(), dim) @@ -436,6 +438,8 @@ func GetNumRowOfFieldData(fieldData *schemapb.FieldData) (uint64, error) { fieldNumRows = getNumRowsOfScalarField(scalarField.GetArrayData().Data) case *schemapb.ScalarField_JsonData: fieldNumRows = getNumRowsOfScalarField(scalarField.GetJsonData().Data) + case *schemapb.ScalarField_GeometryData: + fieldNumRows = getNumRowsOfScalarField(scalarField.GetGeometryData().Data) default: return 0, fmt.Errorf("%s is not supported now", scalarType) } diff --git a/pkg/util/testutils/gen_data.go b/pkg/util/testutils/gen_data.go index 67cfdf2d15..493a553610 100644 --- a/pkg/util/testutils/gen_data.go +++ b/pkg/util/testutils/gen_data.go @@ -26,6 +26,8 @@ import ( "strconv" "strings" + "github.com/twpayne/go-geom/encoding/wkb" + "github.com/twpayne/go-geom/encoding/wkt" "github.com/x448/float16" "github.com/milvus-io/milvus-proto/go-api/v2/schemapb" @@ -149,6 +151,57 @@ func GenerateJSONArray(numRows int) [][]byte { return ret } +// milvus core compoent view geometry as wkb bytes +func GenerateGeometryArray(numRows int) [][]byte { + ret := make([][]byte, 0, numRows) + const ( + point = "POINT (30.123 -10.456)" + linestring = "LINESTRING (30.123 -10.456, 10.789 30.123, -40.567 40.890)" + polygon = "POLYGON ((30.123 -10.456, 40.678 40.890, 20.345 40.567, 10.123 20.456, 30.123 -10.456))" + multipoint = "MULTIPOINT ((10.111 40.222), (40.333 30.444), (20.555 20.666), (30.777 10.888))" + multilinestring = "MULTILINESTRING ((10.111 10.222, 20.333 20.444), (15.555 15.666, 25.777 25.888), (-30.999 20.000, 40.111 30.222))" + multipolygon = "MULTIPOLYGON (((30.123 -10.456, 40.678 40.890, 20.345 40.567, 10.123 20.456, 30.123 -10.456)),((15.123 5.456, 25.678 5.890, 25.345 15.567, 15.123 15.456, 15.123 5.456)))" + ) + wktArray := [6]string{point, linestring, polygon, multipoint, multilinestring, multipolygon} + for i := 0; i < numRows; i++ { + // data of wkt string bytes ,consider to be process by proxy + if i == numRows-1 { + geomT, _ := wkt.Unmarshal("POINT (-84.036 39.997)") // add a special point finally for test + wkbdata, _ := wkb.Marshal(geomT, wkb.NDR) + ret = append(ret, wkbdata) + continue + } + geomT, _ := wkt.Unmarshal(wktArray[i%6]) + wkbdata, _ := wkb.Marshal(geomT, wkb.NDR) + ret = append(ret, wkbdata) + } + return ret +} + +// milvus client and proxy's insert request input view geometry data as wkt strings +func GenerateGeometryWktArray(numRows int) [][]byte { + ret := make([][]byte, 0, numRows) + const ( + point = "POINT (30.123 -10.456)" + linestring = "LINESTRING (30.123 -10.456, 10.789 30.123, -40.567 40.890)" + polygon = "POLYGON ((30.123 -10.456, 40.678 40.890, 20.345 40.567, 10.123 20.456, 30.123 -10.456))" + multipoint = "MULTIPOINT ((10.111 40.222), (40.333 30.444), (20.555 20.666), (30.777 10.888))" + multilinestring = "MULTILINESTRING ((10.111 10.222, 20.333 20.444), (15.555 15.666, 25.777 25.888), (-30.999 20.000, 40.111 30.222))" + multipolygon = "MULTIPOLYGON (((30.123 -10.456, 40.678 40.890, 20.345 40.567, 10.123 20.456, 30.123 -10.456)),((15.123 5.456, 25.678 5.890, 25.345 15.567, 15.123 15.456, 15.123 5.456)))" + ) + wktArray := [6]string{point, linestring, polygon, multipoint, multilinestring, multipolygon} + for i := 0; i < numRows; i++ { + // data of wkt string bytes ,consider to be process by proxy + if i == numRows-1 { + ret = append(ret, []byte("POINT (-84.036 39.997)")) + continue + } + + ret = append(ret, []byte(wktArray[i%6])) + } + return ret +} + func GenerateArrayOfBoolArray(numRows int) []*schemapb.ScalarField { ret := make([]*schemapb.ScalarField, 0, numRows) for i := 0; i < numRows; i++ { @@ -715,6 +768,54 @@ func NewArrayFieldDataWithValue(fieldName string, fieldValue interface{}) *schem } } +func NewGeometryFieldData(fieldName string, numRows int) *schemapb.FieldData { + return &schemapb.FieldData{ + Type: schemapb.DataType_Geometry, + FieldName: fieldName, + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: GenerateGeometryArray(numRows), + }, + }, + }, + }, + } +} + +func NewGeometryFieldDataWktFormat(fieldName string, numRows int) *schemapb.FieldData { + return &schemapb.FieldData{ + Type: schemapb.DataType_Geometry, + FieldName: fieldName, + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: GenerateGeometryWktArray(numRows), + }, + }, + }, + }, + } +} + +func NewGeometryFieldDataWithValue(fieldName string, fieldValue interface{}) *schemapb.FieldData { + return &schemapb.FieldData{ + Type: schemapb.DataType_Geometry, + FieldName: fieldName, + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: fieldValue.([][]byte), + }, + }, + }, + }, + } +} + func NewBinaryVectorFieldData(fieldName string, numRows, dim int) *schemapb.FieldData { return &schemapb.FieldData{ Type: schemapb.DataType_BinaryVector, @@ -882,6 +983,8 @@ func GenerateScalarFieldData(dType schemapb.DataType, fieldName string, numRows return NewArrayFieldData(fieldName, numRows) case schemapb.DataType_JSON: return NewJSONFieldData(fieldName, numRows) + case schemapb.DataType_Geometry: + return NewGeometryFieldData(fieldName, numRows) default: panic("unsupported data type") } @@ -912,6 +1015,8 @@ func GenerateScalarFieldDataWithValue(dType schemapb.DataType, fieldName string, fieldData = NewArrayFieldDataWithValue(fieldName, fieldValue) case schemapb.DataType_JSON: fieldData = NewJSONFieldDataWithValue(fieldName, fieldValue) + case schemapb.DataType_Geometry: + fieldData = NewGeometryFieldDataWithValue(fieldName, fieldValue) default: panic("unsupported data type") } diff --git a/pkg/util/typeutil/gen_empty_field_data.go b/pkg/util/typeutil/gen_empty_field_data.go index 5d39df275c..a15f6ef784 100644 --- a/pkg/util/typeutil/gen_empty_field_data.go +++ b/pkg/util/typeutil/gen_empty_field_data.go @@ -123,6 +123,20 @@ func genEmptyJSONFieldData(field *schemapb.FieldSchema) *schemapb.FieldData { } } +func genEmptyGeometryFieldData(field *schemapb.FieldSchema) *schemapb.FieldData { + return &schemapb.FieldData{ + Type: field.GetDataType(), + FieldName: field.GetName(), + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{GeometryData: &schemapb.GeometryArray{Data: nil}}, + }, + }, + FieldId: field.GetFieldID(), + IsDynamic: field.GetIsDynamic(), + } +} + func genEmptyBinaryVectorFieldData(field *schemapb.FieldSchema) (*schemapb.FieldData, error) { dim, err := GetDim(field) if err != nil { @@ -246,6 +260,8 @@ func GenEmptyFieldData(field *schemapb.FieldSchema) (*schemapb.FieldData, error) return genEmptyArrayFieldData(field), nil case schemapb.DataType_JSON: return genEmptyJSONFieldData(field), nil + case schemapb.DataType_Geometry: + return genEmptyGeometryFieldData(field), nil case schemapb.DataType_BinaryVector: return genEmptyBinaryVectorFieldData(field) case schemapb.DataType_FloatVector: diff --git a/pkg/util/typeutil/schema.go b/pkg/util/typeutil/schema.go index 01d8c0250c..60f500e422 100644 --- a/pkg/util/typeutil/schema.go +++ b/pkg/util/typeutil/schema.go @@ -82,7 +82,8 @@ func getVarFieldLength(fieldSchema *schemapb.FieldSchema, policy getVariableFiel default: return 0, fmt.Errorf("unrecognized getVariableFieldLengthPolicy %v", policy) } - case schemapb.DataType_Array, schemapb.DataType_JSON: + // geometry field max length now consider the same as json field, which is 512 bytes + case schemapb.DataType_Array, schemapb.DataType_JSON, schemapb.DataType_Geometry: return DynamicFieldMaxLength, nil default: return 0, fmt.Errorf("field %s is not a variable-length type", fieldSchema.DataType.String()) @@ -114,7 +115,8 @@ func estimateSizeBy(schema *schemapb.CollectionSchema, policy getVariableFieldLe res += 4 case schemapb.DataType_Int64, schemapb.DataType_Double: res += 8 - case schemapb.DataType_VarChar, schemapb.DataType_Array, schemapb.DataType_JSON: + // geometry wkb as well as wkt max len now is the same as max varfield lenth ,consider extend it if needed + case schemapb.DataType_VarChar, schemapb.DataType_Array, schemapb.DataType_JSON, schemapb.DataType_Geometry: maxLengthPerRow, err := getVarFieldLength(fs, policy) if err != nil { return 0, err @@ -196,6 +198,10 @@ func CalcColumnSize(column *schemapb.FieldData) int { for _, str := range column.GetScalars().GetJsonData().GetData() { res += len(str) } + case schemapb.DataType_Geometry: + for _, str := range column.GetScalars().GetGeometryData().GetData() { + res += len(str) + } default: panic("Unknown data type:" + column.Type.String()) } @@ -233,6 +239,11 @@ func EstimateEntitySize(fieldsData []*schemapb.FieldData, rowOffset int) (int, e return 0, errors.New("offset out range of field datas") } res += len(fs.GetScalars().GetJsonData().GetData()[rowOffset]) + case schemapb.DataType_Geometry: + if rowOffset >= len(fs.GetScalars().GetGeometryData().GetData()) { + return 0, fmt.Errorf("offset out range of field datas") + } + res += len(fs.GetScalars().GetGeometryData().GetData()[rowOffset]) case schemapb.DataType_BinaryVector: res += int(fs.GetVectors().GetDim()) case schemapb.DataType_FloatVector: @@ -521,6 +532,10 @@ func IsJSONType(dataType schemapb.DataType) bool { return dataType == schemapb.DataType_JSON } +func IsGeometryType(dataType schemapb.DataType) bool { + return dataType == schemapb.DataType_Geometry +} + func IsArrayType(dataType schemapb.DataType) bool { return dataType == schemapb.DataType_Array } @@ -570,7 +585,7 @@ func IsArrayContainStringElementType(dataType schemapb.DataType, elementType sch } func IsVariableDataType(dataType schemapb.DataType) bool { - return IsStringType(dataType) || IsArrayType(dataType) || IsJSONType(dataType) + return IsStringType(dataType) || IsArrayType(dataType) || IsJSONType(dataType) || IsGeometryType(dataType) } func IsPrimitiveType(dataType schemapb.DataType) bool { @@ -637,6 +652,12 @@ func PrepareResultFieldData(sample []*schemapb.FieldData, topK int64) []*schemap Data: make([][]byte, 0, topK), }, } + case *schemapb.ScalarField_GeometryData: + scalar.Scalars.Data = &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: make([][]byte, 0, topK), + }, + } case *schemapb.ScalarField_ArrayData: scalar.Scalars.Data = &schemapb.ScalarField_ArrayData{ ArrayData: &schemapb.ArrayArray{ @@ -808,6 +829,17 @@ func AppendFieldData(dst, src []*schemapb.FieldData, idx int64) (appendSize int6 } /* #nosec G103 */ appendSize += int64(unsafe.Sizeof(srcScalar.JsonData.Data[idx])) + case *schemapb.ScalarField_GeometryData: + if dstScalar.GetGeometryData() == nil { + dstScalar.Data = &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: [][]byte{srcScalar.GeometryData.Data[idx]}, + }, + } + } else { + dstScalar.GetGeometryData().Data = append(dstScalar.GetGeometryData().Data, srcScalar.GeometryData.Data[idx]) + } + appendSize += int64(unsafe.Sizeof(srcScalar.GeometryData.Data[idx])) default: log.Error("Not supported field type", zap.String("field type", fieldData.Type.String())) } @@ -926,6 +958,8 @@ func DeleteFieldData(dst []*schemapb.FieldData) { dstScalar.GetStringData().Data = dstScalar.GetStringData().Data[:len(dstScalar.GetStringData().Data)-1] case *schemapb.ScalarField_JsonData: dstScalar.GetJsonData().Data = dstScalar.GetJsonData().Data[:len(dstScalar.GetJsonData().Data)-1] + case *schemapb.ScalarField_GeometryData: + dstScalar.GetGeometryData().Data = dstScalar.GetGeometryData().Data[:len(dstScalar.GetGeometryData().Data)-1] default: log.Error("wrong field type added", zap.String("field type", fieldData.Type.String())) } @@ -1063,6 +1097,16 @@ func MergeFieldData(dst []*schemapb.FieldData, src []*schemapb.FieldData) error } else { dstScalar.GetJsonData().Data = append(dstScalar.GetJsonData().Data, srcScalar.JsonData.Data...) } + case *schemapb.ScalarField_GeometryData: + if dstScalar.GetGeometryData() == nil { + dstScalar.Data = &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: srcScalar.GeometryData.Data, + }, + } + } else { + dstScalar.GetGeometryData().Data = append(dstScalar.GetGeometryData().Data, srcScalar.GeometryData.Data...) + } case *schemapb.ScalarField_BytesData: if dstScalar.GetBytesData() == nil { dstScalar.Data = &schemapb.ScalarField_BytesData{ diff --git a/pkg/util/typeutil/schema_test.go b/pkg/util/typeutil/schema_test.go index 70143bd2b4..3812d40673 100644 --- a/pkg/util/typeutil/schema_test.go +++ b/pkg/util/typeutil/schema_test.go @@ -166,13 +166,19 @@ func TestSchema(t *testing.T) { }, }, }, + { + FieldID: 113, + Name: "field_geometry", + IsPrimaryKey: false, + DataType: schemapb.DataType_Geometry, + }, // Do not test on sparse float vector field. }, } t.Run("EstimateSizePerRecord", func(t *testing.T) { size, err := EstimateSizePerRecord(schema) - assert.Equal(t, 680+DynamicFieldMaxLength*3, size) + assert.Equal(t, 680+DynamicFieldMaxLength*4, size) assert.NoError(t, err) }) @@ -991,6 +997,21 @@ func genFieldData(fieldName string, fieldID int64, fieldType schemapb.DataType, }, FieldId: fieldID, } + case schemapb.DataType_Geometry: + fieldData = &schemapb.FieldData{ + Type: schemapb.DataType_Geometry, + FieldName: fieldName, + Field: &schemapb.FieldData_Scalars{ + Scalars: &schemapb.ScalarField{ + Data: &schemapb.ScalarField_GeometryData{ + GeometryData: &schemapb.GeometryArray{ + Data: fieldValue.([][]byte), + }, + }, + }, + }, + FieldId: fieldID, + } default: log.Error("not supported field type", zap.String("field type", fieldType.String())) } @@ -1012,6 +1033,7 @@ func TestAppendFieldData(t *testing.T) { BFloat16VectorFieldName = "BFloat16VectorField" ArrayFieldName = "ArrayField" SparseFloatVectorFieldName = "SparseFloatVectorField" + GeometryFieldName = "GeometryField" BoolFieldID = common.StartOfUserFieldID + 1 Int32FieldID = common.StartOfUserFieldID + 2 Int64FieldID = common.StartOfUserFieldID + 3 @@ -1023,6 +1045,7 @@ func TestAppendFieldData(t *testing.T) { BFloat16VectorFieldID = common.StartOfUserFieldID + 9 ArrayFieldID = common.StartOfUserFieldID + 10 SparseFloatVectorFieldID = common.StartOfUserFieldID + 11 + GeometryFieldID = common.StartOfUserFieldID + 12 ) BoolArray := []bool{true, false} Int32Array := []int32{1, 2} @@ -1062,8 +1085,13 @@ func TestAppendFieldData(t *testing.T) { CreateSparseFloatRow([]uint32{60, 80, 230}, []float32{2.1, 2.2, 2.3}), }, } + // POINT (30.123 -10.456) and LINESTRING (30.123 -10.456, 10.789 30.123, -40.567 40.890) + GeometryArray := [][]byte{ + {0x01, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40}, + {0x01, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40, 0x03, 0xA6, 0xB4, 0xA6, 0xA4, 0xD2, 0xC5, 0xC0, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A}, + } - result := make([]*schemapb.FieldData, 11) + result := make([]*schemapb.FieldData, 12) var fieldDataArray1 []*schemapb.FieldData fieldDataArray1 = append(fieldDataArray1, genFieldData(BoolFieldName, BoolFieldID, schemapb.DataType_Bool, BoolArray[0:1], 1)) fieldDataArray1 = append(fieldDataArray1, genFieldData(Int32FieldName, Int32FieldID, schemapb.DataType_Int32, Int32Array[0:1], 1)) @@ -1076,6 +1104,7 @@ func TestAppendFieldData(t *testing.T) { fieldDataArray1 = append(fieldDataArray1, genFieldData(BFloat16VectorFieldName, BFloat16VectorFieldID, schemapb.DataType_BFloat16Vector, BFloat16Vector[0:Dim*2], Dim)) fieldDataArray1 = append(fieldDataArray1, genFieldData(ArrayFieldName, ArrayFieldID, schemapb.DataType_Array, ArrayArray[0:1], 1)) fieldDataArray1 = append(fieldDataArray1, genFieldData(SparseFloatVectorFieldName, SparseFloatVectorFieldID, schemapb.DataType_SparseFloatVector, SparseFloatVector.Contents[0], SparseFloatVector.Dim)) + fieldDataArray1 = append(fieldDataArray1, genFieldData(GeometryFieldName, GeometryFieldID, schemapb.DataType_Geometry, GeometryArray[0:1], 1)) var fieldDataArray2 []*schemapb.FieldData fieldDataArray2 = append(fieldDataArray2, genFieldData(BoolFieldName, BoolFieldID, schemapb.DataType_Bool, BoolArray[1:2], 1)) @@ -1089,6 +1118,7 @@ func TestAppendFieldData(t *testing.T) { fieldDataArray2 = append(fieldDataArray2, genFieldData(BFloat16VectorFieldName, BFloat16VectorFieldID, schemapb.DataType_BFloat16Vector, BFloat16Vector[2*Dim:4*Dim], Dim)) fieldDataArray2 = append(fieldDataArray2, genFieldData(ArrayFieldName, ArrayFieldID, schemapb.DataType_Array, ArrayArray[1:2], 1)) fieldDataArray2 = append(fieldDataArray2, genFieldData(SparseFloatVectorFieldName, SparseFloatVectorFieldID, schemapb.DataType_SparseFloatVector, SparseFloatVector.Contents[1], SparseFloatVector.Dim)) + fieldDataArray2 = append(fieldDataArray2, genFieldData(GeometryFieldName, GeometryFieldID, schemapb.DataType_Geometry, GeometryArray[1:2], 1)) AppendFieldData(result, fieldDataArray1, 0) AppendFieldData(result, fieldDataArray2, 0) @@ -1104,6 +1134,7 @@ func TestAppendFieldData(t *testing.T) { assert.Equal(t, BFloat16Vector, result[8].GetVectors().Data.(*schemapb.VectorField_Bfloat16Vector).Bfloat16Vector) assert.Equal(t, ArrayArray, result[9].GetScalars().GetArrayData().Data) assert.Equal(t, SparseFloatVector, result[10].GetVectors().GetSparseFloatVector()) + assert.Equal(t, GeometryArray, result[11].GetScalars().GetGeometryData().Data) } func TestDeleteFieldData(t *testing.T) { @@ -1115,6 +1146,7 @@ func TestDeleteFieldData(t *testing.T) { FloatFieldName = "FloatField" DoubleFieldName = "DoubleField" JSONFieldName = "JSONField" + GeometryFieldName = "GeometryField" BinaryVectorFieldName = "BinaryVectorField" FloatVectorFieldName = "FloatVectorField" Float16VectorFieldName = "Float16VectorField" @@ -1129,6 +1161,7 @@ func TestDeleteFieldData(t *testing.T) { FloatFieldID DoubleFieldID JSONFieldID + GeometryFiledID BinaryVectorFieldID FloatVectorFieldID Float16VectorFieldID @@ -1141,6 +1174,11 @@ func TestDeleteFieldData(t *testing.T) { FloatArray := []float32{1.0, 2.0} DoubleArray := []float64{11.0, 22.0} JSONArray := [][]byte{[]byte("{\"hello\":0}"), []byte("{\"key\":1}")} + // POINT (30.123 -10.456) and LINESTRING (30.123 -10.456, 10.789 30.123, -40.567 40.890) + GeometryArray := [][]byte{ + {0x01, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40}, + {0x01, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40, 0x03, 0xA6, 0xB4, 0xA6, 0xA4, 0xD2, 0xC5, 0xC0, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A}, + } BinaryVector := []byte{0x12, 0x34} FloatVector := []float32{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 11.0, 22.0, 33.0, 44.0, 55.0, 66.0, 77.0, 88.0} Float16Vector := []byte{ @@ -1159,8 +1197,8 @@ func TestDeleteFieldData(t *testing.T) { }, } - result1 := make([]*schemapb.FieldData, 11) - result2 := make([]*schemapb.FieldData, 11) + result1 := make([]*schemapb.FieldData, 12) + result2 := make([]*schemapb.FieldData, 12) var fieldDataArray1 []*schemapb.FieldData fieldDataArray1 = append(fieldDataArray1, genFieldData(BoolFieldName, BoolFieldID, schemapb.DataType_Bool, BoolArray[0:1], 1)) fieldDataArray1 = append(fieldDataArray1, genFieldData(Int32FieldName, Int32FieldID, schemapb.DataType_Int32, Int32Array[0:1], 1)) @@ -1168,6 +1206,7 @@ func TestDeleteFieldData(t *testing.T) { fieldDataArray1 = append(fieldDataArray1, genFieldData(FloatFieldName, FloatFieldID, schemapb.DataType_Float, FloatArray[0:1], 1)) fieldDataArray1 = append(fieldDataArray1, genFieldData(DoubleFieldName, DoubleFieldID, schemapb.DataType_Double, DoubleArray[0:1], 1)) fieldDataArray1 = append(fieldDataArray1, genFieldData(JSONFieldName, JSONFieldID, schemapb.DataType_JSON, JSONArray[0:1], 1)) + fieldDataArray1 = append(fieldDataArray1, genFieldData(GeometryFieldName, GeometryFiledID, schemapb.DataType_Geometry, GeometryArray[0:1], 1)) fieldDataArray1 = append(fieldDataArray1, genFieldData(BinaryVectorFieldName, BinaryVectorFieldID, schemapb.DataType_BinaryVector, BinaryVector[0:Dim/8], Dim)) fieldDataArray1 = append(fieldDataArray1, genFieldData(FloatVectorFieldName, FloatVectorFieldID, schemapb.DataType_FloatVector, FloatVector[0:Dim], Dim)) fieldDataArray1 = append(fieldDataArray1, genFieldData(Float16VectorFieldName, Float16VectorFieldID, schemapb.DataType_Float16Vector, Float16Vector[0:2*Dim], Dim)) @@ -1181,6 +1220,7 @@ func TestDeleteFieldData(t *testing.T) { fieldDataArray2 = append(fieldDataArray2, genFieldData(FloatFieldName, FloatFieldID, schemapb.DataType_Float, FloatArray[1:2], 1)) fieldDataArray2 = append(fieldDataArray2, genFieldData(DoubleFieldName, DoubleFieldID, schemapb.DataType_Double, DoubleArray[1:2], 1)) fieldDataArray2 = append(fieldDataArray2, genFieldData(JSONFieldName, JSONFieldID, schemapb.DataType_JSON, JSONArray[1:2], 1)) + fieldDataArray2 = append(fieldDataArray2, genFieldData(GeometryFieldName, GeometryFiledID, schemapb.DataType_Geometry, GeometryArray[1:2], 1)) fieldDataArray2 = append(fieldDataArray2, genFieldData(BinaryVectorFieldName, BinaryVectorFieldID, schemapb.DataType_BinaryVector, BinaryVector[Dim/8:2*Dim/8], Dim)) fieldDataArray2 = append(fieldDataArray2, genFieldData(FloatVectorFieldName, FloatVectorFieldID, schemapb.DataType_FloatVector, FloatVector[Dim:2*Dim], Dim)) fieldDataArray2 = append(fieldDataArray2, genFieldData(Float16VectorFieldName, Float16VectorFieldID, schemapb.DataType_Float16Vector, Float16Vector[2*Dim:4*Dim], Dim)) @@ -1196,6 +1236,7 @@ func TestDeleteFieldData(t *testing.T) { assert.Equal(t, FloatArray[0:1], result1[FloatFieldID-common.StartOfUserFieldID].GetScalars().GetFloatData().Data) assert.Equal(t, DoubleArray[0:1], result1[DoubleFieldID-common.StartOfUserFieldID].GetScalars().GetDoubleData().Data) assert.Equal(t, JSONArray[0:1], result1[JSONFieldID-common.StartOfUserFieldID].GetScalars().GetJsonData().Data) + assert.Equal(t, GeometryArray[0:1], result1[GeometryFiledID-common.StartOfUserFieldID].GetScalars().GetGeometryData().Data) assert.Equal(t, BinaryVector[0:Dim/8], result1[BinaryVectorFieldID-common.StartOfUserFieldID].GetVectors().Data.(*schemapb.VectorField_BinaryVector).BinaryVector) assert.Equal(t, FloatVector[0:Dim], result1[FloatVectorFieldID-common.StartOfUserFieldID].GetVectors().GetFloatVector().Data) assert.Equal(t, Float16Vector[0:2*Dim], result1[Float16VectorFieldID-common.StartOfUserFieldID].GetVectors().Data.(*schemapb.VectorField_Float16Vector).Float16Vector) @@ -1213,6 +1254,7 @@ func TestDeleteFieldData(t *testing.T) { assert.Equal(t, FloatArray[1:2], result2[FloatFieldID-common.StartOfUserFieldID].GetScalars().GetFloatData().Data) assert.Equal(t, DoubleArray[1:2], result2[DoubleFieldID-common.StartOfUserFieldID].GetScalars().GetDoubleData().Data) assert.Equal(t, JSONArray[1:2], result2[JSONFieldID-common.StartOfUserFieldID].GetScalars().GetJsonData().Data) + assert.Equal(t, GeometryArray[1:2], result2[GeometryFiledID-common.StartOfUserFieldID].GetScalars().GetGeometryData().Data) assert.Equal(t, BinaryVector[Dim/8:2*Dim/8], result2[BinaryVectorFieldID-common.StartOfUserFieldID].GetVectors().Data.(*schemapb.VectorField_BinaryVector).BinaryVector) assert.Equal(t, FloatVector[Dim:2*Dim], result2[FloatVectorFieldID-common.StartOfUserFieldID].GetVectors().GetFloatVector().Data) assert.Equal(t, Float16Vector[2*Dim:4*Dim], result2[Float16VectorFieldID-common.StartOfUserFieldID].GetVectors().Data.(*schemapb.VectorField_Float16Vector).Float16Vector) @@ -1502,6 +1544,11 @@ func TestCalcColumnSize(t *testing.T) { }, }, 110: [][]byte{[]byte(`{"key":"value"}`), []byte(`{"hello":"world"}`)}, + 111: [][]byte{ + // POINT (30.123 -10.456) and LINESTRING (30.123 -10.456, 10.789 30.123, -40.567 40.890) + {0x01, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40}, + {0x01, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40, 0x03, 0xA6, 0xB4, 0xA6, 0xA4, 0xD2, 0xC5, 0xC0, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A}, + }, } schema := &schemapb.CollectionSchema{ Name: "testColl", @@ -1573,6 +1620,11 @@ func TestCalcColumnSize(t *testing.T) { Name: "field_json", DataType: schemapb.DataType_JSON, }, + { + FieldID: 111, + Name: "field_geometry", + DataType: schemapb.DataType_Geometry, + }, }, } @@ -1598,6 +1650,11 @@ func TestCalcColumnSize(t *testing.T) { expected += len(v) } + case schemapb.DataType_Geometry: + data := values.([][]byte) + for _, v := range data { + expected += len(v) + } default: expected = binary.Size(fieldValues[field.GetFieldID()]) } @@ -1765,6 +1822,10 @@ func TestMergeFieldData(t *testing.T) { }, genFieldData("float16_vector", 111, schemapb.DataType_Float16Vector, []byte("12345678"), 4), genFieldData("bfloat16_vector", 112, schemapb.DataType_BFloat16Vector, []byte("12345678"), 4), + genFieldData("geometry", 113, schemapb.DataType_Geometry, [][]byte{ + {0x01, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40}, + {0x01, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40, 0x03, 0xA6, 0xB4, 0xA6, 0xA4, 0xD2, 0xC5, 0xC0, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A}, + }, 1), } srcFields := []*schemapb.FieldData{ @@ -1826,6 +1887,10 @@ func TestMergeFieldData(t *testing.T) { }, genFieldData("float16_vector", 111, schemapb.DataType_Float16Vector, []byte("abcdefgh"), 4), genFieldData("bfloat16_vector", 112, schemapb.DataType_BFloat16Vector, []byte("ABCDEFGH"), 4), + genFieldData("geometry", 113, schemapb.DataType_Geometry, [][]byte{ + {0x01, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40}, + {0x01, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40, 0x03, 0xA6, 0xB4, 0xA6, 0xA4, 0xD2, 0xC5, 0xC0, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A}, + }, 1), } err := MergeFieldData(dstFields, srcFields) @@ -1894,6 +1959,10 @@ func TestMergeFieldData(t *testing.T) { }, genFieldData("float16_vector", 111, schemapb.DataType_Float16Vector, []byte("12345678"), 4), genFieldData("bfloat16_vector", 112, schemapb.DataType_BFloat16Vector, []byte("12345678"), 4), + genFieldData("geometry", 113, schemapb.DataType_Geometry, [][]byte{ + {0x01, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40}, + {0x01, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A, 0x0D, 0x1B, 0x4F, 0x4F, 0x9A, 0x3D, 0x40, 0x03, 0xA6, 0xB4, 0xA6, 0xA4, 0xD2, 0xC5, 0xC0, 0xD2, 0x4A, 0x4D, 0x6A, 0x8B, 0x3C, 0x5C, 0x0A}, + }, 1), } dstFields := []*schemapb.FieldData{ @@ -1904,6 +1973,7 @@ func TestMergeFieldData(t *testing.T) { {Type: schemapb.DataType_SparseFloatVector, FieldName: "sparseFloat", Field: &schemapb.FieldData_Vectors{Vectors: &schemapb.VectorField{Data: &schemapb.VectorField_SparseFloatVector{}}}, FieldId: 104}, {Type: schemapb.DataType_Float16Vector, FieldName: "float16_vector", Field: &schemapb.FieldData_Vectors{Vectors: &schemapb.VectorField{Data: &schemapb.VectorField_Float16Vector{}}}, FieldId: 111}, {Type: schemapb.DataType_BFloat16Vector, FieldName: "bfloat16_vector", Field: &schemapb.FieldData_Vectors{Vectors: &schemapb.VectorField{Data: &schemapb.VectorField_Bfloat16Vector{}}}, FieldId: 112}, + {Type: schemapb.DataType_Geometry, FieldName: "geometry", Field: &schemapb.FieldData_Scalars{Scalars: &schemapb.ScalarField{Data: &schemapb.ScalarField_GeometryData{}}}, FieldId: 113}, } err := MergeFieldData(dstFields, srcFields) diff --git a/tests/go_client/common/consts.go b/tests/go_client/common/consts.go index bd64b79a3b..438e80dbec 100644 --- a/tests/go_client/common/consts.go +++ b/tests/go_client/common/consts.go @@ -41,7 +41,7 @@ const ( // cost for test cases const ( RowCount = "row_count" - DefaultTimeout = 120 + DefaultTimeout = 600 DefaultDim = 128 DefaultShards = int32(2) DefaultNb = 3000 diff --git a/tests/go_client/common/response_checker.go b/tests/go_client/common/response_checker.go index d463ec63c9..c05ae6a2a3 100644 --- a/tests/go_client/common/response_checker.go +++ b/tests/go_client/common/response_checker.go @@ -9,6 +9,8 @@ import ( "testing" "github.com/stretchr/testify/require" + // "github.com/twpayne/go-geom/encoding/wkb" + // "github.com/twpayne/go-geom/encoding/wkt" "go.uber.org/zap" "github.com/milvus-io/milvus/client/v2/column" @@ -76,6 +78,18 @@ func EqualColumn(t *testing.T, columnA column.Column, columnB column.Column) { default: log.Warn("columnA type", zap.String("name", columnB.Name()), zap.Any("type", _v)) } + // case entity.FieldTypeGeometry: + // // currently proxy transform wkb to wkt,the query output wkt has different precision with client input(omit trailing zeros),and omit omissible bracket + // columnAcompData := make([][]byte, 0) + // // simulate proxy replace wkb progress + // for _, bytes := range columnA.(*column.ColumnGeometryBytes).Data() { + // geomT, _ := wkt.Unmarshal(string(bytes)) + // wkbBytes, _ := wkb.Marshal(geomT, wkb.NDR) + // geomT, _ = wkb.Unmarshal(wkbBytes) + // realwktstr, _ := wkt.Marshal(geomT) + // columnAcompData = append(columnAcompData, []byte(realwktstr)) + // } + // require.ElementsMatch(t, columnAcompData, columnB.(*column.ColumnGeometryBytes).Data()) case entity.FieldTypeFloatVector: require.ElementsMatch(t, columnA.(*column.ColumnFloatVector).Data(), columnB.(*column.ColumnFloatVector).Data()) case entity.FieldTypeBinaryVector: diff --git a/tests/go_client/go.mod b/tests/go_client/go.mod index 56d33371e1..732f5a5f66 100644 --- a/tests/go_client/go.mod +++ b/tests/go_client/go.mod @@ -8,6 +8,7 @@ require ( github.com/quasilyte/go-ruleguard/dsl v0.3.22 github.com/samber/lo v1.27.0 github.com/stretchr/testify v1.10.0 + // github.com/twpayne/go-geom v1.6.1 github.com/x448/float16 v0.8.4 go.uber.org/zap v1.27.0 google.golang.org/grpc v1.65.0 @@ -28,13 +29,13 @@ require ( github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/go-units v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/getsentry/sentry-go v0.12.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/godbus/dbus/v5 v5.0.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -49,22 +50,23 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17 // indirect + github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/panjf2000/ants/v2 v2.11.3 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect - github.com/shirou/gopsutil/v3 v3.22.9 // indirect + github.com/shirou/gopsutil/v3 v3.24.2 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -73,12 +75,12 @@ require ( github.com/tidwall/gjson v1.17.1 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect - github.com/tklauser/go-sysconf v0.3.10 // indirect - github.com/tklauser/numcpus v0.4.0 // indirect + github.com/tklauser/go-sysconf v0.3.13 // indirect + github.com/tklauser/numcpus v0.7.0 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect - github.com/yusufpapurcu/wmi v1.2.2 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.etcd.io/etcd/api/v3 v3.5.5 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect diff --git a/tests/go_client/go.sum b/tests/go_client/go.sum index 553d2061ca..3df25cd23e 100644 --- a/tests/go_client/go.sum +++ b/tests/go_client/go.sum @@ -94,8 +94,8 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= @@ -140,8 +140,9 @@ github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -297,8 +298,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI= +github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -318,8 +320,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17 h1:LDOodBVtc2AYxcgc51vDwe+gJp96s6yhJLfdGbLrK+0= -github.com/milvus-io/milvus-proto/go-api/v2 v2.5.17/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= +github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786 h1:GspXs2i+sm2GE4n46VRWBjSCQjqtJDIwwcye+gFyxZA= +github.com/milvus-io/milvus-proto/go-api/v2 v2.5.18-0.20250822062940-e34629021786/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs= github.com/milvus-io/milvus/pkg/v2 v2.5.7 h1:b45jq1s1v03AekFucs2/dkkXohB57gEx7gspJuAkfbY= github.com/milvus-io/milvus/pkg/v2 v2.5.7/go.mod h1:pImw1IGNS7k/5yvlZV2tZi5vZu1VQRlQij+r39d+XnI= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -366,8 +368,9 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -417,8 +420,12 @@ github.com/samber/lo v1.27.0/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+R github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA= -github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= +github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y= +github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -449,6 +456,7 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -458,6 +466,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= @@ -469,10 +478,12 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= -github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= -github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= -github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= +github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= +github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -503,8 +514,8 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= @@ -691,10 +702,12 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/tests/go_client/testcases/helper/data_helper.go b/tests/go_client/testcases/helper/data_helper.go index 0d9ffe4deb..3363f0d0cf 100644 --- a/tests/go_client/testcases/helper/data_helper.go +++ b/tests/go_client/testcases/helper/data_helper.go @@ -292,6 +292,24 @@ func GenNestedJSONExprKey(depth int, jsonField string) string { return fmt.Sprintf("%s['%s']", jsonField, strings.Join(pathParts, "']['")) } +// func GenDefaultGeometryData(nb int, option GenDataOption) [][]byte { +// const ( +// point = "POINT (30.123 -10.456)" +// linestring = "LINESTRING (30.123 -10.456, 10.789 30.123, -40.567 40.890)" +// polygon = "POLYGON ((30.123 -10.456, 40.678 40.890, 20.345 40.567, 10.123 20.456, 30.123 -10.456))" +// multipoint = "MULTIPOINT ((10.111 40.222), (40.333 30.444), (20.555 20.666), (30.777 10.888))" +// multilinestring = "MULTILINESTRING ((10.111 10.222, 20.333 20.444), (15.555 15.666, 25.777 25.888), (-30.999 20.000, 40.111 30.222))" +// multipolygon = "MULTIPOLYGON (((30.123 -10.456, 40.678 40.890, 20.345 40.567, 10.123 20.456, 30.123 -10.456)),((15.123 5.456, 25.678 5.890, 25.345 15.567, 15.123 15.456, 15.123 5.456)))" +// ) +// wktArray := [6]string{point, linestring, polygon, multipoint, multilinestring, multipolygon} +// geometryValues := make([][]byte, 0, nb) +// start := option.start +// for i := start; i < start+nb; i++ { +// geometryValues = append(geometryValues, []byte(wktArray[i%6])) +// } +// return geometryValues +// } + // GenColumnData GenColumnDataOption except dynamic column func GenColumnData(nb int, fieldType entity.FieldType, option GenDataOption) column.Column { dim := option.dim @@ -392,6 +410,10 @@ func GenColumnData(nb int, fieldType entity.FieldType, option GenDataOption) col jsonValues := GenDefaultJSONData(nb, option) return column.NewColumnJSONBytes(fieldName, jsonValues) + // case entity.FieldTypeGeometry: + // geometryValues := GenDefaultGeometryData(nb, option) + // return column.NewColumnGeometryBytes(fieldName, geometryValues) + case entity.FieldTypeFloatVector: vecFloatValues := make([][]float32, 0, nb) for i := start; i < start+nb; i++ { diff --git a/tests/go_client/testcases/helper/field_helper.go b/tests/go_client/testcases/helper/field_helper.go index e29cb62ac2..d9ecc42078 100644 --- a/tests/go_client/testcases/helper/field_helper.go +++ b/tests/go_client/testcases/helper/field_helper.go @@ -78,6 +78,8 @@ func GetFieldNameByFieldType(t entity.FieldType, opts ...GetFieldNameOpt) string return common.DefaultDynamicFieldName } return common.DefaultJSONFieldName + // case entity.FieldTypeGeometry: + // return common.DefaultGeometryName case entity.FieldTypeArray: return GetFieldNameByElementType(opt.elementType) case entity.FieldTypeBinaryVector: diff --git a/tests/go_client/testcases/helper/helper.go b/tests/go_client/testcases/helper/helper.go index 2537c530cb..cf4740f592 100644 --- a/tests/go_client/testcases/helper/helper.go +++ b/tests/go_client/testcases/helper/helper.go @@ -59,6 +59,7 @@ func GetAllScalarFieldType() []entity.FieldType { entity.FieldTypeVarChar, entity.FieldTypeArray, entity.FieldTypeJSON, + // entity.FieldTypeGeometry, } } @@ -84,6 +85,7 @@ func GetInvalidPkFieldType() []entity.FieldType { entity.FieldTypeDouble, entity.FieldTypeString, entity.FieldTypeJSON, + // entity.FieldTypeGeometry, entity.FieldTypeArray, } return nonPkFieldTypes @@ -98,6 +100,7 @@ func GetInvalidPartitionKeyFieldType() []entity.FieldType { entity.FieldTypeFloat, entity.FieldTypeDouble, entity.FieldTypeJSON, + // entity.FieldTypeGeometry, entity.FieldTypeArray, entity.FieldTypeFloatVector, } diff --git a/tests/go_client/testcases/helper/index_helper.go b/tests/go_client/testcases/helper/index_helper.go index 043c791b2c..f86e9c3c58 100644 --- a/tests/go_client/testcases/helper/index_helper.go +++ b/tests/go_client/testcases/helper/index_helper.go @@ -89,7 +89,7 @@ func SupportScalarIndexFieldType(field entity.FieldType) bool { vectorFieldTypes := []entity.FieldType{ entity.FieldTypeBinaryVector, entity.FieldTypeFloatVector, entity.FieldTypeFloat16Vector, entity.FieldTypeBFloat16Vector, - entity.FieldTypeSparseVector, entity.FieldTypeJSON, + entity.FieldTypeSparseVector, entity.FieldTypeJSON, // entity.FieldTypeGeometry // geometry now not support scalar index } for _, vectorFieldType := range vectorFieldTypes { if field == vectorFieldType { diff --git a/tests/go_client/testcases/index_test.go b/tests/go_client/testcases/index_test.go index 5f4cdcaa1a..a7ad170dfe 100644 --- a/tests/go_client/testcases/index_test.go +++ b/tests/go_client/testcases/index_test.go @@ -242,7 +242,7 @@ func TestCreateAutoIndexAllFields(t *testing.T) { var expFields []string var idx index.Index for _, field := range schema.Fields { - if field.DataType == entity.FieldTypeJSON { + if field.DataType == entity.FieldTypeJSON { // || field.DataType == entity.FieldTypeGeometry idx = index.NewAutoIndex(entity.IP) opt := client.NewCreateIndexOption(schema.CollectionName, field.Name, idx) opt.WithExtraParam("json_path", field.Name) @@ -458,7 +458,7 @@ func TestCreateSortedScalarIndex(t *testing.T) { for _, field := range schema.Fields { if hp.SupportScalarIndexFieldType(field.DataType) { if field.DataType == entity.FieldTypeVarChar || field.DataType == entity.FieldTypeBool || - field.DataType == entity.FieldTypeJSON || field.DataType == entity.FieldTypeArray { + field.DataType == entity.FieldTypeJSON || field.DataType == entity.FieldTypeArray { // || field.DataType == entity.FieldTypeGeometry _, err := mc.CreateIndex(ctx, client.NewCreateIndexOption(schema.CollectionName, field.Name, idx)) common.CheckErr(t, err, false, "STL_SORT are only supported on numeric field") } else { diff --git a/tests/integration/compaction/mix_compaction_test.go b/tests/integration/compaction/mix_compaction_test.go index db4cdd295f..6099b1726d 100644 --- a/tests/integration/compaction/mix_compaction_test.go +++ b/tests/integration/compaction/mix_compaction_test.go @@ -52,6 +52,7 @@ func (s *CompactionSuite) TestMixCompaction() { indexType = integration.IndexFaissIvfFlat metricType = metric.L2 vecType = schemapb.DataType_FloatVector + // testType = schemapb.DataType_Geometry ) collectionName := "TestCompaction_" + funcutil.GenRandomStr() @@ -92,6 +93,7 @@ func (s *CompactionSuite) TestMixCompaction() { for i := 0; i < rowNum/batch; i++ { // insert fVecColumn := integration.NewFloatVectorFieldData(integration.FloatVecField, batch, dim) + // geoColumn := integration.NewGeometryFieldData(integration.GeometryField, batch) hashKeys := integration.GenerateHashKeys(batch) insertResult, err := c.Proxy.Insert(ctx, &milvuspb.InsertRequest{ DbName: dbName, diff --git a/tests/integration/import/import_test.go b/tests/integration/import/import_test.go index 2a75c49167..b54c39b84f 100644 --- a/tests/integration/import/import_test.go +++ b/tests/integration/import/import_test.go @@ -54,6 +54,8 @@ type BulkInsertSuite struct { vecType schemapb.DataType indexType indexparamcheck.IndexType metricType metric.MetricType + expr string + testType schemapb.DataType } func (s *BulkInsertSuite) SetupTest() { @@ -66,6 +68,8 @@ func (s *BulkInsertSuite) SetupTest() { s.vecType = schemapb.DataType_FloatVector s.indexType = "HNSW" s.metricType = metric.L2 + s.expr = "" + s.testType = schemapb.DataType_None } func (s *BulkInsertSuite) run() { @@ -84,12 +88,23 @@ func (s *BulkInsertSuite) run() { fieldSchema2 := &schemapb.FieldSchema{FieldID: 101, Name: "image_path", DataType: schemapb.DataType_VarChar, TypeParams: []*commonpb.KeyValuePair{{Key: common.MaxLengthKey, Value: "65535"}}} fieldSchema3 := &schemapb.FieldSchema{FieldID: 102, Name: "embeddings", DataType: s.vecType, TypeParams: []*commonpb.KeyValuePair{{Key: common.DimKey, Value: "128"}}} fieldSchema4 := &schemapb.FieldSchema{FieldID: 103, Name: "embeddings", DataType: s.vecType, TypeParams: []*commonpb.KeyValuePair{}} + + fields := []*schemapb.FieldSchema{fieldSchema1, fieldSchema2} if s.vecType != schemapb.DataType_SparseFloatVector { - schema = integration.ConstructSchema(collectionName, dim, false, fieldSchema1, fieldSchema2, fieldSchema3) + fields = append(fields, fieldSchema3) } else { - schema = integration.ConstructSchema(collectionName, dim, false, fieldSchema1, fieldSchema2, fieldSchema4) + fields = append(fields, fieldSchema4) } + // Append extra test field (e.g., Geometry) when specified + if s.testType != schemapb.DataType_None { + testFieldName := "testField" + schemapb.DataType_name[int32(s.testType)] + extraField := &schemapb.FieldSchema{FieldID: 104, Name: testFieldName, DataType: s.testType} + fields = append(fields, extraField) + } + + schema = integration.ConstructSchema(collectionName, dim, false, fields...) + marshaledSchema, err := proto.Marshal(schema) s.NoError(err) @@ -201,7 +216,7 @@ func (s *BulkInsertSuite) run() { s.WaitForLoad(ctx, collectionName) // search - expr := "" + expr := s.expr nq := 10 topk := 10 roundDecimal := -1 @@ -217,6 +232,12 @@ func (s *BulkInsertSuite) run() { // s.Equal(nq*topk, len(searchResult.GetResults().GetScores())) } +func (s *BulkInsertSuite) TestGeometryTypes() { + s.testType = schemapb.DataType_Geometry + s.expr = "st_equals(" + "testField" + schemapb.DataType_name[int32(s.testType)] + ",'POINT (-84.036 39.997)')" + s.run() +} + func (s *BulkInsertSuite) TestMultiFileTypes() { fileTypeArr := []importutilv2.FileType{importutilv2.JSON, importutilv2.Numpy, importutilv2.Parquet, importutilv2.CSV} diff --git a/tests/integration/util_insert.go b/tests/integration/util_insert.go index c415a70883..7eb51e7d47 100644 --- a/tests/integration/util_insert.go +++ b/tests/integration/util_insert.go @@ -135,6 +135,11 @@ func NewStringFieldData(fieldName string, numRows int) *schemapb.FieldData { return testutils.NewStringFieldData(fieldName, numRows) } +// note: unlike testutils's NewGeometryFieldData ,integration's NewGeometryFieldData generate wkt string bytes +func NewGeometryFieldData(fieldName string, numRows int) *schemapb.FieldData { + return testutils.NewGeometryFieldDataWktFormat(fieldName, numRows) +} + func NewFloatVectorFieldData(fieldName string, numRows, dim int) *schemapb.FieldData { return testutils.NewFloatVectorFieldData(fieldName, numRows, dim) } diff --git a/tests/integration/util_schema.go b/tests/integration/util_schema.go index e4a35f5a75..a0eced359a 100644 --- a/tests/integration/util_schema.go +++ b/tests/integration/util_schema.go @@ -34,6 +34,7 @@ const ( DoubleField = "doubleField" VarCharField = "varCharField" JSONField = "jsonField" + GeometryField = "geometryField" FloatVecField = "floatVecField" BinVecField = "binVecField" Float16VecField = "float16VecField" @@ -83,7 +84,7 @@ func ConstructSchema(collection string, dim int, autoID bool, fields ...*schemap } } -func ConstructSchemaOfVecDataType(collection string, dim int, autoID bool, dataType schemapb.DataType) *schemapb.CollectionSchema { +func ConstructSchemaOfVecDataType(collection string, dim int, autoID bool, dataType ...schemapb.DataType) *schemapb.CollectionSchema { pk := &schemapb.FieldSchema{ FieldID: 100, Name: Int64Field, @@ -96,33 +97,41 @@ func ConstructSchemaOfVecDataType(collection string, dim int, autoID bool, dataT } var name string var typeParams []*commonpb.KeyValuePair - switch dataType { - case schemapb.DataType_FloatVector: - name = FloatVecField - typeParams = []*commonpb.KeyValuePair{ - { - Key: common.DimKey, - Value: fmt.Sprintf("%d", dim), - }, + var fieldSchemaArray []*schemapb.FieldSchema + fieldSchemaArray = append(fieldSchemaArray, pk) + for i := 0; i < len(dataType); i++ { + switch dataType[i] { + case schemapb.DataType_FloatVector: + name = FloatVecField + typeParams = []*commonpb.KeyValuePair{ + { + Key: common.DimKey, + Value: fmt.Sprintf("%d", dim), + }, + } + case schemapb.DataType_SparseFloatVector: + name = SparseFloatVecField + typeParams = nil + case schemapb.DataType_Geometry: + name = GeometryField + typeParams = nil + default: + panic("unsupported data type") } - case schemapb.DataType_SparseFloatVector: - name = SparseFloatVecField - typeParams = nil - default: - panic("unsupported data type") - } - fVec := &schemapb.FieldSchema{ - FieldID: 101, - Name: name, - IsPrimaryKey: false, - Description: "", - DataType: dataType, - TypeParams: typeParams, - IndexParams: nil, + sche := &schemapb.FieldSchema{ + FieldID: 101 + int64(i), + Name: name, + IsPrimaryKey: false, + Description: "", + DataType: dataType[i], + TypeParams: typeParams, + IndexParams: nil, + } + fieldSchemaArray = append(fieldSchemaArray, sche) } return &schemapb.CollectionSchema{ Name: collection, AutoID: autoID, - Fields: []*schemapb.FieldSchema{pk, fVec}, + Fields: fieldSchemaArray, } } diff --git a/tests/python_client/geometry_comprehensive_test.py b/tests/python_client/geometry_comprehensive_test.py new file mode 100644 index 0000000000..b6b008c4c0 --- /dev/null +++ b/tests/python_client/geometry_comprehensive_test.py @@ -0,0 +1,327 @@ +import random +import numpy as np +import math +import time + +from pymilvus import MilvusClient, DataType + +COUNT = 10000 + +def generate_simple_point(): + """Generate simple random point with integer coordinates""" + x = random.randint(100, 120) + y = random.randint(30, 50) + return f"POINT({x} {y})" + +def generate_simple_line(): + """Generate simple random line with integer coordinates""" + x1, y1 = random.randint(100, 120), random.randint(30, 50) + x2, y2 = random.randint(100, 120), random.randint(30, 50) + return f"LINESTRING({x1} {y1}, {x2} {y2})" + +def generate_simple_polygon(): + """Generate simple random polygon with integer coordinates""" + # Generate center point + center_x = random.randint(100, 120) + center_y = random.randint(30, 50) + + # Generate polygon vertices (triangle or rectangle) + num_vertices = random.choice([3, 4]) + vertices = [] + + for i in range(num_vertices): + angle = (2 * math.pi * i) / num_vertices + radius = random.randint(1, 3) + x = center_x + int(radius * math.cos(angle)) + y = center_y + int(radius * math.sin(angle)) + vertices.append(f"{x} {y}") + + # Close polygon + vertices.append(vertices[0]) + return f"POLYGON(({', '.join(vertices)}))" + +def generate_clustered_data(): + """Generate clustered data with simple integer coordinates""" + # Define center areas with simple coordinates + centers = [ + (110, 40), # Center 1 + (115, 35), # Center 2 + (105, 45), # Center 3 + ] + + geometries = [] + + for i in range(COUNT): + # Choose a center + center = random.choice(centers) + center_x, center_y = center + + # Generate geometry objects around center + offset_x = random.randint(-5, 5) + offset_y = random.randint(-5, 5) + + geom_type = random.choice(['point', 'line', 'polygon']) + + if geom_type == 'point': + x = center_x + offset_x + y = center_y + offset_y + geom = f"POINT({x} {y})" + elif geom_type == 'line': + x1 = center_x + offset_x + y1 = center_y + offset_y + x2 = center_x + offset_x + random.randint(-3, 3) + y2 = center_y + offset_y + random.randint(-3, 3) + geom = f"LINESTRING({x1} {y1}, {x2} {y2})" + else: # polygon + # Generate small polygon around center + vertices = [] + for j in range(3): + angle = (2 * math.pi * j) / 3 + radius = random.randint(1, 3) + x = center_x + offset_x + int(radius * math.cos(angle)) + y = center_y + offset_y + int(radius * math.sin(angle)) + vertices.append(f"{x} {y}") + vertices.append(vertices[0]) # Close polygon + geom = f"POLYGON(({', '.join(vertices)}))" + + geometries.append(geom) + + return geometries + +def generate_test_data(num_records=10000): + """Generate test data""" + ids = list(range(1, num_records + 1)) + + # Use clustered data to generate geometry objects + geometries = generate_clustered_data() + + # Generate random vectors + vectors = [] + for i in range(num_records): + vector = [random.random() for _ in range(128)] + vectors.append(vector) + + return ids, geometries, vectors + +def main(): + fmt = "\n=== {:30} ===\n" + + # Connection configuration + client = MilvusClient( + uri="http://localhost:19530", + token="" + ) + collection_name = "comprehensive_geo_test" + dim = 128 # Vector dimension + + # Drop existing collection if exists + if client.has_collection(collection_name): + client.drop_collection(collection_name) + print(f"Dropped existing collection: {collection_name}") + + print(fmt.format("Creating Collection")) + try: + schema = client.create_schema(auto_id=False, description="comprehensive_geo_test") + schema.add_field("id", DataType.INT64, is_primary=True) + schema.add_field("geo", DataType.GEOMETRY) + schema.add_field("vector", DataType.FLOAT_VECTOR, dim=dim) + index_params = client.prepare_index_params() + index_params.add_index(field_name="vector", index_type="IVF_FLAT", metric_type="L2", nlist=128) + client.create_collection(collection_name, schema=schema, index_params=index_params) + print(f"Collection created: {collection_name}") + except Exception as e: + print(f"Error creating collection: {e}") + return + + # Generate test data + print(fmt.format("Generating Test Data")) + num_records = COUNT + ids, geometries, vectors = generate_test_data(num_records) + + # Show data preview + print(fmt.format("Data Preview")) + for i in range(5): + print(f"ID: {ids[i]}") + print(f"Geometry: {geometries[i]}") + print(f"Vector: [{', '.join([f'{x:.3f}' for x in vectors[i][:3]])}...]") + print("---") + + # Insert data + print(fmt.format("Inserting Data")) + + # Insert data in batches to avoid memory issues + batch_size = 1000 + total_inserted = 0 + time_start = time.time() + for i in range(0, num_records, batch_size): + end_idx = min(i + batch_size, num_records) + batch_data = [] + + for j in range(i, end_idx): + row = { + "id": ids[j], + "geo": geometries[j], + "vector": vectors[j] + } + batch_data.append(row) + + try: + insert_result = client.insert(collection_name, batch_data) + total_inserted += len(batch_data) + print(f"Inserted {total_inserted}/{num_records} records") + except Exception as e: + print(f"Error inserting data: {e}") + return + time_end = time.time() + print(f"Data Insertion Time: {(time_end - time_start) * 1000:.2f} ms") + print(fmt.format("Data Insertion Complete")) + + # # Flush data to persistent storage + # print("Flushing data...") + # try: + # client.flush(collection_name) + # print("Data flush complete") + # except Exception as e: + # print(f"Error flushing data: {e}") + # return + + # Load collection + try: + client.load_collection(collection_name) + print(fmt.format("Collection Loaded")) + except Exception as e: + print(f"Error loading collection: {e}") + return + + # Test non-spatial function queries + print(fmt.format("Testing Non-Spatial Queries")) + time_start = time.time() + try: + # Simple query test + print("\nSimple query test:") + query_results = client.query( + collection_name=collection_name, + filter="id <= 10", + output_fields=["id", "geo"], + limit=10 + ) + print(f"Found {len(query_results)} records") + for result in query_results[:3]: + print(f" ID: {result['id']}, geo: {result['geo']}") + except Exception as e: + print(f"Simple query test error: {e}") + time_end = time.time() + print(f"Simple query test Time: {(time_end - time_start) * 1000:.2f} ms") + # Test vector search + print(fmt.format("Testing Vector Search")) + try: + search_vector = vectors[0] + + search_results = client.search( + collection_name=collection_name, + data=[search_vector], + anns_field="vector", + search_params={"metric_type": "L2", "params": {"nprobe": 10}}, + limit=5, + output_fields=["id", "geo"] + ) + + print(f"Search results length: {len(search_results)}") + for i, hits in enumerate(search_results): + print(f"Query vector {i+1} search results:") + for j, hit in enumerate(hits): + print(f" Result {j+1} - ID: {hit['id']}, Geo: {hit['geo']}, distance: {hit['distance']:.4f}") + + except Exception as e: + print(f"Vector search test error: {e}") + + # Test all spatial functions + print(fmt.format("Testing Spatial Functions")) + + # Define test geometry objects with simple integer coordinates + test_geometries = { + "point": "POINT(110 40)", # Center point + "line": "LINESTRING(105 35, 115 45)", # Line across centers + "polygon": "POLYGON((105 35, 115 35, 115 45, 105 45, 105 35))", # Rectangle covering centers + "small_polygon": "POLYGON((108 38, 112 38, 112 42, 108 42, 108 38))", # Small rectangle + "crossing_line": "LINESTRING(100 30, 120 50)", # Line crossing the area + "overlapping_polygon": "POLYGON((110 38, 115 38, 115 42, 110 42, 110 38))" # Overlapping polygon + } + + # 空间函数列表 + spatial_functions = [ + ("st_equals", "ST_EQUALS"), + ("st_touches", "ST_TOUCHES"), + ("st_overlaps", "ST_OVERLAPS"), + ("st_crosses", "ST_CROSSES"), + ("st_contains", "ST_CONTAINS"), + ("st_intersects", "ST_INTERSECTS"), + ("st_within", "ST_WITHIN") + ] + + for func_name, func_alias in spatial_functions: + print(f"\nTesting {func_name} / {func_alias}:") + # Test different geometry objects + for geom_key, test_geom in test_geometries.items(): + try: + time_start = time.time() + expr = f"{func_name}(geo, '{test_geom}')" + results = client.query( + collection_name=collection_name, + filter=expr, + output_fields=["id","geo"], + limit=10 + ) + time_end = time.time() + print(f" {func_name} with {geom_key}: Found {len(results)} records, Time: {(time_end - time_start) * 1000:.2f} ms") + if results: + print(f" Sample IDs: {[r['id'] for r in results[:5]]}") + print(f" Sample geometries: {[r['geo'] for r in results[:5]]}") + except Exception as e: + print(f" {func_name} with {geom_key} test failed: {e}") + + # Test uppercase function name + try: + expr = f"{func_alias}(geo, '{test_geometries['point']}')" + results = client.query( + collection_name=collection_name, + filter=expr, + output_fields=["id","geo"], + limit=10 + ) + print(f" {func_alias}: Found {len(results)} records") + if results: + print(f" Sample IDs: {[r['id'] for r in results[:5]]}") + print(f" Sample geometries: {[r['geo'] for r in results[:5]]}") + except Exception as e: + print(f" {func_alias} test failed: {e}") + + # Test different geometry types + print(fmt.format("Testing Different Geometry Types")) + print(fmt.format("Using ST_INTERSECTS")) + for geom_type, test_geom in test_geometries.items(): + print(f"\nTesting {geom_type} geometry:") + try: + time_start = time.time() + expr = f"st_intersects(geo, '{test_geom}')" + results = client.query( + collection_name=collection_name, + filter=expr, + output_fields=["id","geo"], + limit=10 + ) + time_end = time.time() + print(f" Found {len(results)} records, Time: {(time_end - time_start) * 1000:.2f} ms") + if results: + print(f" Sample IDs: {[r['id'] for r in results[:5]]}") + print(f" Sample geometries: {[r['geo'] for r in results[:5]]}") + except Exception as e: + print(f" Test failed: {e}") + + print(fmt.format("Test Complete")) + print(f"Total records tested: {num_records}") + print(f"Total spatial functions tested: {len(spatial_functions)}") + print("All tests completed!") + +if __name__ == "__main__": + main() \ No newline at end of file