mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-06 09:08:43 +08:00
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 <yinwei.li@zilliz.com> Signed-off-by: Cai Zhang <cai.zhang@zilliz.com> Co-authored-by: cai.zhang <cai.zhang@zilliz.com>
This commit is contained in:
parent
8821743c17
commit
cd931a0388
117
client/column/geometry.go
Normal file
117
client/column/geometry.go
Normal file
@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
82
client/column/geometry_test.go
Normal file
82
client/column/geometry_test.go
Normal file
@ -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))
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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=
|
||||
|
||||
@ -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,
|
||||
|
||||
38
go.mod
38
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
|
||||
|
||||
81
go.sum
81
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=
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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<std::string_view>(i) !=
|
||||
arr.get_data<std::string_view>(i)) {
|
||||
@ -340,6 +342,13 @@ class Array {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::GEOMETRY: {
|
||||
for (int j = 0; j < length_; ++j) {
|
||||
auto element = get_data<std::string>(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<std::string>(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<std::string>(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<std::string>(i);
|
||||
if (val != arr2.array(i).string_val()) {
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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<arrow::RecordBatchReader> data) {
|
||||
auto size = 0;
|
||||
std::vector<std::string> wkb_strs;
|
||||
std::vector<std::pair<const uint8_t*, int64_t>> null_bitmaps;
|
||||
for (auto batch : *data) {
|
||||
auto data = batch.ValueOrDie()->column(0);
|
||||
auto array = std::dynamic_pointer_cast<arrow::BinaryArray>(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<MmapChunkTarget>(file_path_);
|
||||
} else {
|
||||
target_ = std::make_shared<MemChunkTarget>(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<uint32_t>(target_->tell() + sizeof(uint32_t) * offset_num);
|
||||
std::vector<uint32_t> 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<Chunk>
|
||||
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<GeometryChunk>(row_nums_, data, size, nullable_);
|
||||
}
|
||||
|
||||
void
|
||||
ArrayChunkWriter::write(std::shared_ptr<arrow::RecordBatchReader> 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<JSONChunkWriter>(
|
||||
std::forward<Args>(args)..., nullable);
|
||||
case milvus::DataType::GEOMETRY: {
|
||||
return std::make_shared<GeometryChunkWriter>(
|
||||
std::forward<Args>(args)..., nullable);
|
||||
}
|
||||
case milvus::DataType::ARRAY:
|
||||
return std::make_shared<ArrayChunkWriter>(
|
||||
field_meta.get_element_type(),
|
||||
|
||||
@ -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<arrow::RecordBatchReader> data) override;
|
||||
|
||||
std::shared_ptr<Chunk>
|
||||
finish() override;
|
||||
};
|
||||
|
||||
class ArrayChunkWriter : public ChunkWriterBase {
|
||||
public:
|
||||
ArrayChunkWriter(const milvus::DataType element_type, bool nullable)
|
||||
|
||||
@ -213,6 +213,19 @@ FieldDataImpl<Type, is_type_entire_row>::FillFieldData(
|
||||
}
|
||||
return FillFieldData(values.data(), element_count);
|
||||
}
|
||||
case DataType::GEOMETRY: {
|
||||
auto geometry_array =
|
||||
std::dynamic_pointer_cast<arrow::BinaryArray>(array);
|
||||
std::vector<uint8_t> 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<arrow::BinaryArray>(array);
|
||||
@ -278,6 +291,7 @@ template class FieldDataImpl<float, true>;
|
||||
template class FieldDataImpl<double, true>;
|
||||
template class FieldDataImpl<std::string, true>;
|
||||
template class FieldDataImpl<Json, true>;
|
||||
template class FieldDataImpl<Geometry, true>;
|
||||
template class FieldDataImpl<Array, true>;
|
||||
|
||||
// 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<FieldData<Json>>(type, nullable, cap_rows);
|
||||
case DataType::GEOMETRY:
|
||||
return std::make_shared<FieldData<Geometry>>(
|
||||
type, nullable, cap_rows);
|
||||
default:
|
||||
PanicInfo(DataTypeInvalid,
|
||||
"InitScalarFieldData not support data type " +
|
||||
|
||||
@ -69,6 +69,17 @@ class FieldData<Json> : public FieldDataJsonImpl {
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class FieldData<Geometry> : public FieldDataGeometryImpl {
|
||||
public:
|
||||
static_assert(IsScalar<Geometry>);
|
||||
explicit FieldData(DataType data_type,
|
||||
bool nullable,
|
||||
int64_t buffered_num_rows = 0)
|
||||
: FieldDataGeometryImpl(data_type, nullable, buffered_num_rows) {
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class FieldData<Array> : public FieldDataArrayImpl {
|
||||
public:
|
||||
|
||||
@ -572,6 +572,75 @@ class FieldDataStringImpl : public FieldDataImpl<std::string, true> {
|
||||
}
|
||||
};
|
||||
|
||||
class FieldDataGeometryImpl : public FieldDataImpl<std::string, true> {
|
||||
public:
|
||||
explicit FieldDataGeometryImpl(DataType data_type,
|
||||
bool nullable,
|
||||
int64_t total_num_rows = 0)
|
||||
: FieldDataImpl<std::string, true>(
|
||||
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<arrow::Array> 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<arrow::BinaryArray>(array);
|
||||
FillFieldData(geometry_array);
|
||||
}
|
||||
void
|
||||
FillFieldData(const std::shared_ptr<arrow::BinaryArray>& 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<uint8_t>::op_copy(
|
||||
valid_data, 0, valid_data_.data(), length_, n);
|
||||
}
|
||||
}
|
||||
length_ += n;
|
||||
}
|
||||
};
|
||||
|
||||
class FieldDataJsonImpl : public FieldDataImpl<Json, true> {
|
||||
public:
|
||||
explicit FieldDataJsonImpl(DataType data_type,
|
||||
|
||||
142
internal/core/src/common/Geometry.h
Normal file
142
internal/core/src/common/Geometry.h
Normal file
@ -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 <memory>
|
||||
#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<unsigned char[]> wkb(new unsigned char[geometry_->WkbSize()]);
|
||||
geometry_->exportToWkb(wkbNDR, wkb.get());
|
||||
return std::string(reinterpret_cast<const char*>(wkb.get()),
|
||||
geometry_->WkbSize());
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<OGRGeometry, OGRGeometryDeleter> geometry_;
|
||||
};
|
||||
|
||||
} // namespace milvus
|
||||
@ -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<std::monostate,
|
||||
std::string>;
|
||||
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<DataType::JSON> {
|
||||
static constexpr const char* Name = "JSON";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TypeTraits<DataType::GEOMETRY> {
|
||||
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<DataType::ROW> {
|
||||
using NativeType = void;
|
||||
@ -630,6 +655,9 @@ struct fmt::formatter<milvus::DataType> : formatter<string_view> {
|
||||
case milvus::DataType::JSON:
|
||||
name = "JSON";
|
||||
break;
|
||||
case milvus::DataType::GEOMETRY:
|
||||
name = "GEOMETRY";
|
||||
break;
|
||||
case milvus::DataType::ROW:
|
||||
name = "ROW";
|
||||
break;
|
||||
|
||||
@ -60,9 +60,9 @@ constexpr bool IsVector = std::is_base_of_v<VectorTrait, T>;
|
||||
template <typename T>
|
||||
constexpr bool IsScalar =
|
||||
std::is_fundamental_v<T> || std::is_same_v<T, std::string> ||
|
||||
std::is_same_v<T, Json> || std::is_same_v<T, std::string_view> ||
|
||||
std::is_same_v<T, Array> || std::is_same_v<T, ArrayView> ||
|
||||
std::is_same_v<T, proto::plan::Array>;
|
||||
std::is_same_v<T, Json> || std::is_same_v<T, Geometry> ||
|
||||
std::is_same_v<T, std::string_view> || std::is_same_v<T, Array> ||
|
||||
std::is_same_v<T, ArrayView> || std::is_same_v<T, proto::plan::Array>;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool IsSparse = std::is_same_v<T, SparseFloatVector> ||
|
||||
@ -73,7 +73,7 @@ constexpr bool IsVariableType =
|
||||
std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view> ||
|
||||
std::is_same_v<T, Array> || std::is_same_v<T, ArrayView> ||
|
||||
std::is_same_v<T, proto::plan::Array> || std::is_same_v<T, Json> ||
|
||||
IsSparse<T>;
|
||||
std::is_same_v<T, Geometry> || IsSparse<T>;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool IsVariableTypeSupportInChunk =
|
||||
|
||||
@ -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<VectorPtr>& 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<PhyGISFunctionFilterExpr>(
|
||||
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());
|
||||
}
|
||||
|
||||
152
internal/core/src/exec/expression/GISFunctionFilterExpr.cpp
Normal file
152
internal/core/src/exec/expression/GISFunctionFilterExpr.cpp
Normal file
@ -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<ColumnVector>(
|
||||
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
|
||||
61
internal/core/src/exec/expression/GISFunctionFilterExpr.h
Normal file
61
internal/core/src/exec/expression/GISFunctionFilterExpr.h
Normal file
@ -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 <fmt/core.h>
|
||||
|
||||
#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<std::shared_ptr<Expr>>& input,
|
||||
const std::shared_ptr<const milvus::expr::GISFunctionFilterExpr>& 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<const milvus::expr::GISFunctionFilterExpr> expr_;
|
||||
};
|
||||
} //namespace exec
|
||||
} // namespace milvus
|
||||
@ -21,11 +21,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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,
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include <vector>
|
||||
|
||||
#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<const std::string*>(data->RawValue(i));
|
||||
ssize_t written_data_size =
|
||||
file.WriteInt<uint32_t>(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) {
|
||||
|
||||
@ -14,12 +14,17 @@
|
||||
#include <google/protobuf/text_format.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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::ValueExpr>(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<expr::GISFunctionFilterExpr>(
|
||||
columnInfo, expr_pb.op(), geometry);
|
||||
}
|
||||
|
||||
expr::TypedExprPtr
|
||||
ProtoParser::CreateAlwaysTrueExprs() {
|
||||
return std::make_shared<expr::AlwaysTrueExpr>();
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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<ChunkedVariableColumn<std::string>>(
|
||||
field_meta);
|
||||
std::shared_ptr<milvus::ArrowDataWrapper> 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<ChunkedArrayColumn>(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<ChunkedVariableColumn<std::string>>(
|
||||
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<ChunkedArrayColumn>(field_meta, chunks);
|
||||
@ -1576,6 +1600,15 @@ ChunkedSegmentSealedImpl::get_raw_data(FieldId field_id,
|
||||
break;
|
||||
}
|
||||
|
||||
case DataType::GEOMETRY: {
|
||||
bulk_subscript_ptr_impl<std::string>(column.get(),
|
||||
seg_offsets,
|
||||
count,
|
||||
ret->mutable_scalars()
|
||||
->mutable_geometry_data()
|
||||
->mutable_data());
|
||||
break;
|
||||
}
|
||||
case DataType::ARRAY: {
|
||||
bulk_subscript_array_impl(
|
||||
column.get(),
|
||||
|
||||
@ -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<std::string> 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<Array> data_raw{};
|
||||
|
||||
@ -437,6 +437,11 @@ struct InsertRecord {
|
||||
field_id, size_per_chunk, scalar_mmap_descriptor);
|
||||
break;
|
||||
}
|
||||
case DataType::GEOMETRY: {
|
||||
this->append_data<std::string>(
|
||||
field_id, size_per_chunk, scalar_mmap_descriptor);
|
||||
break;
|
||||
}
|
||||
case DataType::ARRAY: {
|
||||
this->append_data<Array>(
|
||||
field_id, size_per_chunk, scalar_mmap_descriptor);
|
||||
|
||||
@ -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<std::string>(vec_ptr,
|
||||
seg_offsets,
|
||||
count,
|
||||
result->mutable_scalars()
|
||||
->mutable_geometry_data()
|
||||
->mutable_data());
|
||||
break;
|
||||
}
|
||||
case DataType::ARRAY: {
|
||||
// element
|
||||
bulk_subscript_array_impl(*vec_ptr,
|
||||
|
||||
@ -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<std::string>>(
|
||||
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<SingleChunkArrayColumn>(
|
||||
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<SingleChunkVariableColumn<std::string>>(
|
||||
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<SingleChunkArrayColumn>(
|
||||
file, total_written, field_meta);
|
||||
@ -1444,6 +1470,15 @@ SegmentSealedImpl::get_raw_data(FieldId field_id,
|
||||
break;
|
||||
}
|
||||
|
||||
case DataType::GEOMETRY: {
|
||||
bulk_subscript_ptr_impl<std::string>(column.get(),
|
||||
seg_offsets,
|
||||
count,
|
||||
ret->mutable_scalars()
|
||||
->mutable_geometry_data()
|
||||
->mutable_data());
|
||||
break;
|
||||
}
|
||||
case DataType::ARRAY: {
|
||||
bulk_subscript_array_impl(
|
||||
column.get(),
|
||||
|
||||
@ -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<const std::string*>(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<const ScalarArray*>(data_raw);
|
||||
auto obj = scalar_array->mutable_array_data();
|
||||
@ -654,6 +680,13 @@ MergeDataArray(std::vector<MergeBase>& 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();
|
||||
|
||||
@ -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<const std::string*>(
|
||||
field_data->RawValue(offset));
|
||||
payload_writer->add_one_binary_payload(
|
||||
reinterpret_cast<const uint8_t*>(geo_ptr->data()),
|
||||
geo_ptr->size());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::VECTOR_SPARSE_FLOAT: {
|
||||
for (size_t offset = 0; offset < field_data->get_num_rows();
|
||||
++offset) {
|
||||
|
||||
@ -275,7 +275,8 @@ CreateArrowBuilder(DataType data_type) {
|
||||
return std::make_shared<arrow::StringBuilder>();
|
||||
}
|
||||
case DataType::ARRAY:
|
||||
case DataType::JSON: {
|
||||
case DataType::JSON:
|
||||
case DataType::GEOMETRY: {
|
||||
return std::make_shared<arrow::BinaryBuilder>();
|
||||
}
|
||||
// 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<FieldData<Json>>(
|
||||
type, nullable, total_num_rows);
|
||||
case DataType::GEOMETRY:
|
||||
return std::make_shared<FieldData<Geometry>>(
|
||||
type, nullable, total_num_rows);
|
||||
case DataType::ARRAY:
|
||||
return std::make_shared<FieldData<Array>>(
|
||||
type, nullable, total_num_rows);
|
||||
|
||||
@ -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<size_t>(nb_ - offset), kSizePerChunk);
|
||||
const size_t chunk_bitset_size = (rows + 7) / 8;
|
||||
const size_t buf_size =
|
||||
chunk_bitset_size + rows * dim_ * sizeof(float);
|
||||
|
||||
@ -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::shared_ptr<::arrow::RecordBatchReader>,
|
||||
std::unique_ptr<parquet::arrow::FileReader>> {
|
||||
auto buffer = std::make_shared<arrow::io::BufferReader>(
|
||||
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<std::string> 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<milvus::storage::PayloadReader>(field_data);
|
||||
event_data.payload_reader = payload_reader;
|
||||
auto ser_data = event_data.Serialize();
|
||||
auto buffer = std::make_shared<arrow::io::BufferReader>(
|
||||
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<parquet::arrow::FileReader> 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<GeometryChunk>(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<std::string> 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<milvus::storage::PayloadReader>(field_data);
|
||||
auto ser_data = event_data.Serialize();
|
||||
auto buffer = std::make_shared<arrow::io::BufferReader>(
|
||||
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<parquet::arrow::FileReader> 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<GeometryChunk>(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<std::string> 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<milvus::storage::PayloadReader>(field_data);
|
||||
auto ser_data = event_data.Serialize();
|
||||
auto buffer = std::make_shared<arrow::io::BufferReader>(
|
||||
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<parquet::arrow::FileReader> 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<GeometryChunk>(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<uint32_t>(wkb1.size())};
|
||||
size_t total_size = wkb1.size() + wkb2.size();
|
||||
std::vector<char> 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);
|
||||
}
|
||||
@ -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(),
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <sys/mman.h>
|
||||
|
||||
struct DeferRelease {
|
||||
using functype = std::function<void()>;
|
||||
@ -79,8 +80,13 @@ TEST(test_chunk_segment, TestSearchOnSealed) {
|
||||
auto data = dataset.get_col<float>(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<char*>(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<FixedWidthChunk>(
|
||||
|
||||
@ -17,6 +17,9 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
|
||||
#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<std::string> 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<milvus::storage::PayloadReader>(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<uint8_t[]> 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<std::string> 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<const std::string*>(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<std::string> 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<milvus::storage::PayloadReader>(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<uint8_t[]> 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<std::string> new_data(data.size());
|
||||
for (int i = 0; i < data.size(); ++i) {
|
||||
new_data[i] =
|
||||
*static_cast<const std::string*>(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<std::string> data = {
|
||||
"test1", "test2", "test3", "test4", "test5"};
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include <roaring/roaring.hh>
|
||||
|
||||
#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<Schema>();
|
||||
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<SegmentGrowingImpl*>(seg.get());
|
||||
|
||||
// Define GIS test cases using struct like JSON tests
|
||||
struct GISTestcase {
|
||||
std::string wkt_string;
|
||||
proto::plan::GISFunctionFilterExpr_GISOp op;
|
||||
};
|
||||
|
||||
std::vector<GISTestcase> 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::GISFunctionFilterExpr>(
|
||||
milvus::expr::ColumnInfo(geom_fid, DataType::GEOMETRY),
|
||||
testcase.op,
|
||||
geometry);
|
||||
|
||||
auto plan = std::make_shared<plan::FilterBitsNode>(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<Schema>();
|
||||
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<proto::plan::GISFunctionFilterExpr_GISOp, std::string>>
|
||||
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::GISFunctionFilterExpr>(
|
||||
expr::ColumnInfo(geo_fid, DataType::GEOMETRY), op, right_source);
|
||||
auto plan_node = std::make_shared<plan::FilterBitsNode>(
|
||||
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<Schema>();
|
||||
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<unsigned char> wkb(size);
|
||||
geometry->exportToWkb(wkbNDR, wkb.data());
|
||||
|
||||
geometry_field_data->mutable_scalars()
|
||||
->mutable_geometry_data()
|
||||
->add_data(
|
||||
std::string(reinterpret_cast<char*>(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<SegmentGrowingImpl*>(seg.get());
|
||||
|
||||
// Test specific GIS operations
|
||||
auto test_gis_operation = [&](const std::string& wkt,
|
||||
proto::plan::GISFunctionFilterExpr_GISOp op,
|
||||
std::function<bool(int)> 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::GISFunctionFilterExpr>(
|
||||
milvus::expr::ColumnInfo(geom_fid, DataType::GEOMETRY),
|
||||
op,
|
||||
geometry);
|
||||
|
||||
auto plan = std::make_shared<plan::FilterBitsNode>(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<Schema>();
|
||||
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<Schema>();
|
||||
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<std::pair<std::string, std::string>> 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;
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstdint>
|
||||
#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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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>(double_field);
|
||||
auto varchar_values = dataset.get_col<std::string>(varchar_field);
|
||||
auto json_values = dataset.get_col<std::string>(json_field);
|
||||
auto geometry_values = dataset.get_col<std::string>(geometry_field);
|
||||
auto int_array_values = dataset.get_col<ScalarArray>(int_array_field);
|
||||
auto long_array_values = dataset.get_col<ScalarArray>(long_array_field);
|
||||
auto bool_array_values = dataset.get_col<ScalarArray>(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>(double_field);
|
||||
auto varchar_values = dataset.get_col<std::string>(varchar_field);
|
||||
auto json_values = dataset.get_col<std::string>(json_field);
|
||||
auto geometry_values = dataset.get_col<std::string>(geometry_field);
|
||||
auto int_array_values = dataset.get_col<ScalarArray>(int_array_field);
|
||||
auto long_array_values = dataset.get_col<ScalarArray>(long_array_field);
|
||||
auto bool_array_values = dataset.get_col<ScalarArray>(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<Schema>();
|
||||
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<std::string, std::string> index_params = {
|
||||
{"index_type", "IVF_FLAT"},
|
||||
{"metric_type", metric_type},
|
||||
{"nlist", "128"}};
|
||||
std::map<std::string, std::string> type_params = {{"dim", "128"}};
|
||||
FieldIndexMeta fieldIndexMeta(
|
||||
vec, std::move(index_params), std::move(type_params));
|
||||
std::map<FieldId, FieldIndexMeta> filedMap = {{vec, fieldIndexMeta}};
|
||||
IndexMetaPtr metaPtr =
|
||||
std::make_shared<CollectionIndexMeta>(100000, std::move(filedMap));
|
||||
auto segment_sealed = CreateSealedSegment(schema, metaPtr);
|
||||
auto segment = dynamic_cast<SegmentSealedImpl*>(segment_sealed.get());
|
||||
|
||||
int64_t dataset_size = 1000;
|
||||
auto dataset = DataGen(schema, dataset_size);
|
||||
SealedLoadFieldData(dataset, *segment);
|
||||
|
||||
auto geometry_values = dataset.get_col<std::string>(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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include <cmath>
|
||||
#include <google/protobuf/text_format.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <ogr_geometry.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#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<std::string*>(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<double>(rand()) / RAND_MAX * 360.0 - 180.0);
|
||||
point.setY(static_cast<double>(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<double>(rand()) / RAND_MAX * 300.0 - 150.0;
|
||||
double startY = static_cast<double>(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<double>(rand()) / RAND_MAX - 0.5) * 20.0;
|
||||
double deltaY = (static_cast<double>(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<double>(rand()) / RAND_MAX * 300.0 - 150.0;
|
||||
double centerY = static_cast<double>(rand()) / RAND_MAX * 160.0 - 80.0;
|
||||
|
||||
// Generate radius
|
||||
double radius = 5.0 + static_cast<double>(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<std::string> 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<const char*>(wkb_data), size);
|
||||
OGRGeometryFactory::destroyGeometry(geo);
|
||||
delete[] wkb_data;
|
||||
}
|
||||
insert_cols(data, N, field_meta, random_valid);
|
||||
break;
|
||||
}
|
||||
case DataType::ARRAY: {
|
||||
vector<ScalarArray> 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<std::string> 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<Array> data_raw(src_data.size());
|
||||
|
||||
@ -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] = ""
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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:
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -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
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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{}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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}))
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
28
pkg/go.mod
28
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
|
||||
|
||||
77
pkg/go.sum
77
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=
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -41,7 +41,7 @@ const (
|
||||
// cost for test cases
|
||||
const (
|
||||
RowCount = "row_count"
|
||||
DefaultTimeout = 120
|
||||
DefaultTimeout = 600
|
||||
DefaultDim = 128
|
||||
DefaultShards = int32(2)
|
||||
DefaultNb = 3000
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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=
|
||||
|
||||
@ -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++ {
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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,
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user