mirror of
https://github.com/dolthub/dolt.git
synced 2026-03-09 11:19:01 -05:00
Merge pull request #4558 from dolthub/james/geomcoll
dolt support for `GeometryCollection`
This commit is contained in:
@@ -57,7 +57,7 @@ require (
|
||||
require (
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible
|
||||
github.com/cenkalti/backoff/v4 v4.1.3
|
||||
github.com/dolthub/go-mysql-server v0.12.1-0.20221014214651-c2bf09248ff9
|
||||
github.com/dolthub/go-mysql-server v0.12.1-0.20221017074119-86f7228536af
|
||||
github.com/google/flatbuffers v2.0.6+incompatible
|
||||
github.com/kch42/buzhash v0.0.0-20160816060738-9bdec3dec7c6
|
||||
github.com/mitchellh/go-ps v1.0.0
|
||||
|
||||
@@ -178,8 +178,8 @@ github.com/dolthub/flatbuffers v1.13.0-dh.1 h1:OWJdaPep22N52O/0xsUevxJ6Qfw1M2txC
|
||||
github.com/dolthub/flatbuffers v1.13.0-dh.1/go.mod h1:CorYGaDmXjHz1Z7i50PYXG1Ricn31GcA2wNOTFIQAKE=
|
||||
github.com/dolthub/fslock v0.0.3 h1:iLMpUIvJKMKm92+N1fmHVdxJP5NdyDK5bK7z7Ba2s2U=
|
||||
github.com/dolthub/fslock v0.0.3/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0=
|
||||
github.com/dolthub/go-mysql-server v0.12.1-0.20221014214651-c2bf09248ff9 h1:xGTHflXQ6gWZFvgXIyHHrBtmIEWoLEc70dSY6SGPl/g=
|
||||
github.com/dolthub/go-mysql-server v0.12.1-0.20221014214651-c2bf09248ff9/go.mod h1:9Q9FhWO82GrV4he13V2ZuDE0T/eDZbPVMOWLcZluOvg=
|
||||
github.com/dolthub/go-mysql-server v0.12.1-0.20221017074119-86f7228536af h1:Rck6hB+jn/X9SZRnIRqtz15Oi7VmVKYaaore4CIESdw=
|
||||
github.com/dolthub/go-mysql-server v0.12.1-0.20221017074119-86f7228536af/go.mod h1:9Q9FhWO82GrV4he13V2ZuDE0T/eDZbPVMOWLcZluOvg=
|
||||
github.com/dolthub/ishell v0.0.0-20220112232610-14e753f0f371 h1:oyPHJlzumKta1vnOQqUnfdz+pk3EmnHS3Nd0cCT0I2g=
|
||||
github.com/dolthub/ishell v0.0.0-20220112232610-14e753f0f371/go.mod h1:dhGBqcCEfK5kuFmeO5+WOx3hqc1k3M29c1oS/R7N4ms=
|
||||
github.com/dolthub/jsonpath v0.0.0-20210609232853-d49537a30474 h1:xTrR+l5l+1Lfq0NvhiEsctylXinUMFhhsqaEcl414p8=
|
||||
|
||||
@@ -160,7 +160,13 @@ func translateNomsField(ctx context.Context, ns tree.NodeStore, value types.Valu
|
||||
v := value.(types.Geometry).Inner
|
||||
translateGeometryField(v, idx, b)
|
||||
|
||||
case types.PointKind, types.LineStringKind, types.PolygonKind, types.MultiPointKind:
|
||||
case types.PointKind,
|
||||
types.LineStringKind,
|
||||
types.PolygonKind,
|
||||
types.MultiPointKind,
|
||||
types.MultiLineStringKind,
|
||||
types.MultiPolygonKind,
|
||||
types.GeometryCollectionKind:
|
||||
translateGeometryField(value, idx, b)
|
||||
|
||||
case types.JSONKind:
|
||||
@@ -288,6 +294,10 @@ func translateGeometryField(value types.Value, idx int, b *val.TupleBuilder) {
|
||||
p := types.ConvertTypesMultiPolygonToSQLMultiPolygon(value.(types.MultiPolygon))
|
||||
b.PutGeometry(idx, p.Serialize())
|
||||
|
||||
case types.GeometryCollectionKind:
|
||||
p := types.ConvertTypesGeomCollToSQLGeomColl(value.(types.GeomColl))
|
||||
b.PutGeometry(idx, p.Serialize())
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected NomsKind for geometry (%d)", nk))
|
||||
}
|
||||
|
||||
@@ -241,6 +241,7 @@ func nomsKindsFromQueryTypes(qt query.Type) []types.NomsKind {
|
||||
types.MultiPointKind,
|
||||
types.MultiLineStringKind,
|
||||
types.MultiPolygonKind,
|
||||
types.GeometryCollectionKind,
|
||||
}
|
||||
|
||||
case query.Type_JSON:
|
||||
|
||||
@@ -208,6 +208,8 @@ func bitTypeConverter(ctx context.Context, src *bitType, destTi TypeInfo) (tc Ty
|
||||
return wrapIsValid(dest.IsValid, src, dest)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -238,6 +238,8 @@ func blobStringTypeConverter(ctx context.Context, src *blobStringType, destTi Ty
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -215,6 +215,8 @@ func boolTypeConverter(ctx context.Context, src *boolType, destTi TypeInfo) (tc
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -219,6 +219,8 @@ func datetimeTypeConverter(ctx context.Context, src *datetimeType, destTi TypeIn
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -243,6 +243,8 @@ func decimalTypeConverter(ctx context.Context, src *decimalType, destTi TypeInfo
|
||||
}, true, nil
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -225,6 +225,8 @@ func enumTypeConverter(ctx context.Context, src *enumType, destTi TypeInfo) (tc
|
||||
}, true, nil
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -249,6 +249,8 @@ func floatTypeConverter(ctx context.Context, src *floatType, destTi TypeInfo) (t
|
||||
}, true, nil
|
||||
case *floatType:
|
||||
return wrapIsValid(dest.IsValid, src, dest)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -57,6 +57,8 @@ func (ti *geometryType) ConvertNomsValueToValue(v types.Value) (interface{}, err
|
||||
return types.ConvertTypesMultiLineStringToSQLMultiLineString(val), nil
|
||||
case types.MultiPolygon:
|
||||
return types.ConvertTypesMultiPolygonToSQLMultiPolygon(val), nil
|
||||
case types.GeomColl:
|
||||
return types.ConvertTypesGeomCollToSQLGeomColl(val), nil
|
||||
default:
|
||||
return nil, fmt.Errorf(`"%v" cannot convert NomsKind "%v" to a value`, ti.String(), v.Kind())
|
||||
}
|
||||
@@ -93,6 +95,10 @@ func (ti *geometryType) ReadFrom(nbf *types.NomsBinFormat, reader types.CodecRea
|
||||
if val, err = reader.ReadMultiPolygon(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case types.GeometryCollectionKind:
|
||||
if val, err = reader.ReadGeomColl(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case types.GeometryKind:
|
||||
// Note: GeometryKind is no longer written
|
||||
// included here for backward compatibility
|
||||
@@ -156,6 +162,8 @@ func (ti *geometryType) FormatValue(v types.Value) (*string, error) {
|
||||
return MultiLineStringType.FormatValue(val)
|
||||
case types.MultiPolygon:
|
||||
return MultiPolygonType.FormatValue(val)
|
||||
case types.GeomColl:
|
||||
return GeomCollType.FormatValue(val)
|
||||
case types.Geometry:
|
||||
switch inner := val.Inner.(type) {
|
||||
case types.Point:
|
||||
@@ -170,6 +178,8 @@ func (ti *geometryType) FormatValue(v types.Value) (*string, error) {
|
||||
return MultiLineStringType.FormatValue(inner)
|
||||
case types.MultiPolygon:
|
||||
return MultiPolygonType.FormatValue(val)
|
||||
case types.GeomColl:
|
||||
return GeomCollType.FormatValue(val)
|
||||
default:
|
||||
return nil, fmt.Errorf(`"%v" has unexpectedly encountered a value of type "%T" from embedded type`, ti.String(), v.Kind())
|
||||
}
|
||||
@@ -248,6 +258,8 @@ func geometryTypeConverter(ctx context.Context, src *geometryType, destTi TypeIn
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
231
go/libraries/doltcore/schema/typeinfo/geometry_collection.go
Normal file
231
go/libraries/doltcore/schema/typeinfo/geometry_collection.go
Normal file
@@ -0,0 +1,231 @@
|
||||
// Copyright 2020 Dolthub, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package typeinfo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
|
||||
// This is a dolt implementation of the MySQL type Point, thus most of the functionality
|
||||
// within is directly reliant on the go-mysql-server implementation.
|
||||
type geomcollType struct {
|
||||
sqlGeomCollType sql.GeomCollType
|
||||
}
|
||||
|
||||
var _ TypeInfo = (*geomcollType)(nil)
|
||||
|
||||
var GeomCollType = &geomcollType{sql.GeomCollType{}}
|
||||
|
||||
// ConvertNomsValueToValue implements TypeInfo interface.
|
||||
func (ti *geomcollType) ConvertNomsValueToValue(v types.Value) (interface{}, error) {
|
||||
// Check for null
|
||||
if _, ok := v.(types.Null); ok || v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
// Expect a types.GeomColl, return a sql.GeomColl
|
||||
if val, ok := v.(types.GeomColl); ok {
|
||||
return types.ConvertTypesGeomCollToSQLGeomColl(val), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf(`"%v" cannot convert NomsKind "%v" to a value`, ti.String(), v.Kind())
|
||||
}
|
||||
|
||||
// ReadFrom reads a go value from a noms types.CodecReader directly
|
||||
func (ti *geomcollType) ReadFrom(nbf *types.NomsBinFormat, reader types.CodecReader) (interface{}, error) {
|
||||
k := reader.ReadKind()
|
||||
switch k {
|
||||
case types.GeometryCollectionKind:
|
||||
p, err := reader.ReadGeomColl()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ti.ConvertNomsValueToValue(p)
|
||||
case types.NullKind:
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf(`"%v" cannot convert NomsKind "%v" to a value`, ti.String(), k)
|
||||
}
|
||||
|
||||
// ConvertValueToNomsValue implements TypeInfo interface.
|
||||
func (ti *geomcollType) ConvertValueToNomsValue(ctx context.Context, vrw types.ValueReadWriter, v interface{}) (types.Value, error) {
|
||||
// Check for null
|
||||
if v == nil {
|
||||
return types.NullValue, nil
|
||||
}
|
||||
|
||||
// Convert to sql.GeomColl
|
||||
geomColl, err := ti.sqlGeomCollType.Convert(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return types.ConvertSQLGeomCollToTypesGeomColl(geomColl.(sql.GeomColl)), nil
|
||||
}
|
||||
|
||||
// Equals implements TypeInfo interface.
|
||||
func (ti *geomcollType) Equals(other TypeInfo) bool {
|
||||
if other == nil {
|
||||
return false
|
||||
}
|
||||
if o, ok := other.(*geomcollType); ok {
|
||||
// if either ti or other has defined SRID, then check SRID value; otherwise,
|
||||
return (!ti.sqlGeomCollType.DefinedSRID && !o.sqlGeomCollType.DefinedSRID) || ti.sqlGeomCollType.SRID == o.sqlGeomCollType.SRID
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// FormatValue implements TypeInfo interface.
|
||||
func (ti *geomcollType) FormatValue(v types.Value) (*string, error) {
|
||||
if val, ok := v.(types.GeomColl); ok {
|
||||
resStr := string(types.SerializeGeomColl(val))
|
||||
return &resStr, nil
|
||||
}
|
||||
if _, ok := v.(types.Null); ok || v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf(`"%v" has unexpectedly encountered a value of type "%T" from embedded type`, ti.String(), v.Kind())
|
||||
}
|
||||
|
||||
// GetTypeIdentifier implements TypeInfo interface.
|
||||
func (ti *geomcollType) GetTypeIdentifier() Identifier {
|
||||
return GeometryCollectionTypeIdentifier
|
||||
}
|
||||
|
||||
// GetTypeParams implements TypeInfo interface.
|
||||
func (ti *geomcollType) GetTypeParams() map[string]string {
|
||||
return map[string]string{"SRID": strconv.FormatUint(uint64(ti.sqlGeomCollType.SRID), 10),
|
||||
"DefinedSRID": strconv.FormatBool(ti.sqlGeomCollType.DefinedSRID)}
|
||||
}
|
||||
|
||||
// IsValid implements TypeInfo interface.
|
||||
func (ti *geomcollType) IsValid(v types.Value) bool {
|
||||
if _, ok := v.(types.GeomColl); ok {
|
||||
return true
|
||||
}
|
||||
if _, ok := v.(types.Null); ok || v == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NomsKind implements TypeInfo interface.
|
||||
func (ti *geomcollType) NomsKind() types.NomsKind {
|
||||
return types.GeometryCollectionKind
|
||||
}
|
||||
|
||||
// Promote implements TypeInfo interface.
|
||||
func (ti *geomcollType) Promote() TypeInfo {
|
||||
return &geomcollType{ti.sqlGeomCollType.Promote().(sql.GeomCollType)}
|
||||
}
|
||||
|
||||
// String implements TypeInfo interface.
|
||||
func (ti *geomcollType) String() string {
|
||||
return "GeometryCollection"
|
||||
}
|
||||
|
||||
// ToSqlType implements TypeInfo interface.
|
||||
func (ti *geomcollType) ToSqlType() sql.Type {
|
||||
return ti.sqlGeomCollType
|
||||
}
|
||||
|
||||
// geomcollTypeConverter is an internal function for GetTypeConverter that handles the specific type as the source TypeInfo.
|
||||
func geomcollTypeConverter(ctx context.Context, src *geomcollType, destTi TypeInfo) (tc TypeConverter, needsConversion bool, err error) {
|
||||
switch dest := destTi.(type) {
|
||||
case *bitType:
|
||||
return func(ctx context.Context, vrw types.ValueReadWriter, v types.Value) (types.Value, error) {
|
||||
return types.Uint(0), nil
|
||||
}, true, nil
|
||||
case *blobStringType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *boolType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *datetimeType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *decimalType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *enumType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *intType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *jsonType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *linestringType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *multilinestringType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *multipointType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *multipolygonType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *pointType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *polygonType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *setType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *timeType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *uintType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *uuidType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *varBinaryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *varStringType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *yearType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
default:
|
||||
return nil, false, UnhandledTypeConversion.New(src.String(), destTi.String())
|
||||
}
|
||||
}
|
||||
|
||||
func CreateGeomCollTypeFromParams(params map[string]string) (TypeInfo, error) {
|
||||
var (
|
||||
err error
|
||||
sridVal uint64
|
||||
def bool
|
||||
)
|
||||
if s, ok := params["SRID"]; ok {
|
||||
sridVal, err = strconv.ParseUint(s, 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if d, ok := params["DefinedSRID"]; ok {
|
||||
def, err = strconv.ParseBool(d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &geomcollType{sqlGeomCollType: sql.GeomCollType{SRID: uint32(sridVal), DefinedSRID: def}}, nil
|
||||
}
|
||||
@@ -239,6 +239,8 @@ func inlineBlobTypeConverter(ctx context.Context, src *inlineBlobType, destTi Ty
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -277,6 +277,8 @@ func intTypeConverter(ctx context.Context, src *intType, destTi TypeInfo) (tc Ty
|
||||
}, true, nil
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -167,6 +167,8 @@ func jsonTypeConverter(ctx context.Context, src *jsonType, destTi TypeInfo) (tc
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -167,6 +167,8 @@ func linestringTypeConverter(ctx context.Context, src *linestringType, destTi Ty
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -167,6 +167,8 @@ func multilinestringTypeConverter(ctx context.Context, src *multilinestringType,
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -167,6 +167,8 @@ func multipointTypeConverter(ctx context.Context, src *multipointType, destTi Ty
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -167,6 +167,8 @@ func multipolygonTypeConverter(ctx context.Context, src *multipolygonType, destT
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -167,6 +167,8 @@ func pointTypeConverter(ctx context.Context, src *pointType, destTi TypeInfo) (t
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -167,6 +167,8 @@ func polygonTypeConverter(ctx context.Context, src *polygonType, destTi TypeInfo
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -208,6 +208,8 @@ func setTypeConverter(ctx context.Context, src *setType, destTi TypeInfo) (tc Ty
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -150,6 +150,8 @@ func timeTypeConverter(ctx context.Context, src *timeType, destTi TypeInfo) (tc
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -65,6 +65,8 @@ func GetTypeConverter(ctx context.Context, srcTi TypeInfo, destTi TypeInfo) (tc
|
||||
return enumTypeConverter(ctx, src, destTi)
|
||||
case *floatType:
|
||||
return floatTypeConverter(ctx, src, destTi)
|
||||
case *geomcollType:
|
||||
return geomcollTypeConverter(ctx, src, destTi)
|
||||
case *geometryType:
|
||||
return geometryTypeConverter(ctx, src, destTi)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -28,61 +28,63 @@ import (
|
||||
type Identifier string
|
||||
|
||||
const (
|
||||
UnknownTypeIdentifier Identifier = "unknown"
|
||||
BitTypeIdentifier Identifier = "bit"
|
||||
BlobStringTypeIdentifier Identifier = "blobstring"
|
||||
BoolTypeIdentifier Identifier = "bool"
|
||||
DatetimeTypeIdentifier Identifier = "datetime"
|
||||
DecimalTypeIdentifier Identifier = "decimal"
|
||||
EnumTypeIdentifier Identifier = "enum"
|
||||
FloatTypeIdentifier Identifier = "float"
|
||||
JSONTypeIdentifier Identifier = "json"
|
||||
InlineBlobTypeIdentifier Identifier = "inlineblob"
|
||||
IntTypeIdentifier Identifier = "int"
|
||||
SetTypeIdentifier Identifier = "set"
|
||||
TimeTypeIdentifier Identifier = "time"
|
||||
TupleTypeIdentifier Identifier = "tuple"
|
||||
UintTypeIdentifier Identifier = "uint"
|
||||
UuidTypeIdentifier Identifier = "uuid"
|
||||
VarBinaryTypeIdentifier Identifier = "varbinary"
|
||||
VarStringTypeIdentifier Identifier = "varstring"
|
||||
YearTypeIdentifier Identifier = "year"
|
||||
GeometryTypeIdentifier Identifier = "geometry"
|
||||
PointTypeIdentifier Identifier = "point"
|
||||
LineStringTypeIdentifier Identifier = "linestring"
|
||||
PolygonTypeIdentifier Identifier = "polygon"
|
||||
MultiPointTypeIdentifier Identifier = "multipoint"
|
||||
MultiLineStringTypeIdentifier Identifier = "multilinestring"
|
||||
MultiPolygonTypeIdentifier Identifier = "multipolygon"
|
||||
UnknownTypeIdentifier Identifier = "unknown"
|
||||
BitTypeIdentifier Identifier = "bit"
|
||||
BlobStringTypeIdentifier Identifier = "blobstring"
|
||||
BoolTypeIdentifier Identifier = "bool"
|
||||
DatetimeTypeIdentifier Identifier = "datetime"
|
||||
DecimalTypeIdentifier Identifier = "decimal"
|
||||
EnumTypeIdentifier Identifier = "enum"
|
||||
FloatTypeIdentifier Identifier = "float"
|
||||
JSONTypeIdentifier Identifier = "json"
|
||||
InlineBlobTypeIdentifier Identifier = "inlineblob"
|
||||
IntTypeIdentifier Identifier = "int"
|
||||
SetTypeIdentifier Identifier = "set"
|
||||
TimeTypeIdentifier Identifier = "time"
|
||||
TupleTypeIdentifier Identifier = "tuple"
|
||||
UintTypeIdentifier Identifier = "uint"
|
||||
UuidTypeIdentifier Identifier = "uuid"
|
||||
VarBinaryTypeIdentifier Identifier = "varbinary"
|
||||
VarStringTypeIdentifier Identifier = "varstring"
|
||||
YearTypeIdentifier Identifier = "year"
|
||||
GeometryTypeIdentifier Identifier = "geometry"
|
||||
PointTypeIdentifier Identifier = "point"
|
||||
LineStringTypeIdentifier Identifier = "linestring"
|
||||
PolygonTypeIdentifier Identifier = "polygon"
|
||||
MultiPointTypeIdentifier Identifier = "multipoint"
|
||||
MultiLineStringTypeIdentifier Identifier = "multilinestring"
|
||||
MultiPolygonTypeIdentifier Identifier = "multipolygon"
|
||||
GeometryCollectionTypeIdentifier Identifier = "geometrycollection"
|
||||
)
|
||||
|
||||
var Identifiers = map[Identifier]struct{}{
|
||||
UnknownTypeIdentifier: {},
|
||||
BitTypeIdentifier: {},
|
||||
BlobStringTypeIdentifier: {},
|
||||
BoolTypeIdentifier: {},
|
||||
DatetimeTypeIdentifier: {},
|
||||
DecimalTypeIdentifier: {},
|
||||
EnumTypeIdentifier: {},
|
||||
FloatTypeIdentifier: {},
|
||||
JSONTypeIdentifier: {},
|
||||
InlineBlobTypeIdentifier: {},
|
||||
IntTypeIdentifier: {},
|
||||
SetTypeIdentifier: {},
|
||||
TimeTypeIdentifier: {},
|
||||
TupleTypeIdentifier: {},
|
||||
UintTypeIdentifier: {},
|
||||
UuidTypeIdentifier: {},
|
||||
VarBinaryTypeIdentifier: {},
|
||||
VarStringTypeIdentifier: {},
|
||||
YearTypeIdentifier: {},
|
||||
GeometryTypeIdentifier: {},
|
||||
PointTypeIdentifier: {},
|
||||
LineStringTypeIdentifier: {},
|
||||
PolygonTypeIdentifier: {},
|
||||
MultiPointTypeIdentifier: {},
|
||||
MultiLineStringTypeIdentifier: {},
|
||||
MultiPolygonTypeIdentifier: {},
|
||||
UnknownTypeIdentifier: {},
|
||||
BitTypeIdentifier: {},
|
||||
BlobStringTypeIdentifier: {},
|
||||
BoolTypeIdentifier: {},
|
||||
DatetimeTypeIdentifier: {},
|
||||
DecimalTypeIdentifier: {},
|
||||
EnumTypeIdentifier: {},
|
||||
FloatTypeIdentifier: {},
|
||||
JSONTypeIdentifier: {},
|
||||
InlineBlobTypeIdentifier: {},
|
||||
IntTypeIdentifier: {},
|
||||
SetTypeIdentifier: {},
|
||||
TimeTypeIdentifier: {},
|
||||
TupleTypeIdentifier: {},
|
||||
UintTypeIdentifier: {},
|
||||
UuidTypeIdentifier: {},
|
||||
VarBinaryTypeIdentifier: {},
|
||||
VarStringTypeIdentifier: {},
|
||||
YearTypeIdentifier: {},
|
||||
GeometryTypeIdentifier: {},
|
||||
PointTypeIdentifier: {},
|
||||
LineStringTypeIdentifier: {},
|
||||
PolygonTypeIdentifier: {},
|
||||
MultiPointTypeIdentifier: {},
|
||||
MultiLineStringTypeIdentifier: {},
|
||||
MultiPolygonTypeIdentifier: {},
|
||||
GeometryCollectionTypeIdentifier: {},
|
||||
}
|
||||
|
||||
// TypeInfo is an interface used for encoding type information.
|
||||
@@ -183,6 +185,8 @@ func FromSqlType(sqlType sql.Type) (TypeInfo, error) {
|
||||
return &multilinestringType{}, nil
|
||||
case sql.MultiPolygonType{}.String():
|
||||
return &multipolygonType{}, nil
|
||||
case sql.GeomCollType{}.String():
|
||||
return &geomcollType{}, nil
|
||||
case sql.GeometryType{}.String():
|
||||
return &geometryType{sqlGeometryType: sqlType.(sql.GeometryType)}, nil
|
||||
default:
|
||||
@@ -296,6 +300,8 @@ func FromTypeParams(id Identifier, params map[string]string) (TypeInfo, error) {
|
||||
return CreateMultiLineStringTypeFromParams(params)
|
||||
case MultiPolygonTypeIdentifier:
|
||||
return CreateMultiPolygonTypeFromParams(params)
|
||||
case GeometryCollectionTypeIdentifier:
|
||||
return CreateGeomCollTypeFromParams(params)
|
||||
case SetTypeIdentifier:
|
||||
return CreateSetTypeFromParams(params)
|
||||
case TimeTypeIdentifier:
|
||||
|
||||
@@ -360,6 +360,7 @@ func generateTypeInfoArrays(t *testing.T) ([][]TypeInfo, [][]types.Value) {
|
||||
{MultiPointType},
|
||||
{MultiLineStringType},
|
||||
{MultiPolygonType},
|
||||
{GeomCollType},
|
||||
{GeometryType},
|
||||
generateSetTypes(t, 16),
|
||||
{TimeType},
|
||||
@@ -399,6 +400,7 @@ func generateTypeInfoArrays(t *testing.T) ([][]TypeInfo, [][]types.Value) {
|
||||
{types.MultiPoint{SRID: 0, Points: []types.Point{{SRID: 0, X: 1, Y: 2}, {SRID: 0, X: 3, Y: 4}}}}, // MultiPoint
|
||||
{types.MultiLineString{SRID: 0, Lines: []types.LineString{{SRID: 0, Points: []types.Point{{SRID: 0, X: 0, Y: 0}, {SRID: 0, X: 0, Y: 1}, {SRID: 0, X: 1, Y: 1}, {SRID: 0, X: 0, Y: 0}}}}}}, // MultiLineString
|
||||
{types.MultiPolygon{SRID: 0, Polygons: []types.Polygon{{SRID: 0, Lines: []types.LineString{{SRID: 0, Points: []types.Point{{SRID: 0, X: 0, Y: 0}, {SRID: 0, X: 0, Y: 1}, {SRID: 0, X: 1, Y: 1}, {SRID: 0, X: 0, Y: 0}}}}}}}}, // MultiPolygon
|
||||
{types.GeomColl{SRID: 0, Geometries: []types.Value{types.GeomColl{SRID: 0, Geometries: []types.Value{}}}}}, // Geometry Collection
|
||||
{types.Geometry{Inner: types.Point{SRID: 0, X: 1, Y: 2}}}, // Geometry holding a Point
|
||||
{types.Uint(1), types.Uint(5), types.Uint(64), types.Uint(42), types.Uint(192)}, //Set
|
||||
{types.Int(0), types.Int(1000000 /*"00:00:01"*/), types.Int(113000000 /*"00:01:53"*/), types.Int(247019000000 /*"68:36:59"*/), types.Int(458830485214 /*"127:27:10.485214"*/)}, //Time
|
||||
|
||||
@@ -277,6 +277,8 @@ func uintTypeConverter(ctx context.Context, src *uintType, destTi TypeInfo) (tc
|
||||
}, true, nil
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -155,6 +155,8 @@ func uuidTypeConverter(ctx context.Context, src *uuidType, destTi TypeInfo) (tc
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -267,6 +267,8 @@ func varBinaryTypeConverter(ctx context.Context, src *varBinaryType, destTi Type
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -290,6 +290,8 @@ func varStringTypeConverter(ctx context.Context, src *varStringType, destTi Type
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -166,6 +166,8 @@ func yearTypeConverter(ctx context.Context, src *yearType, destTi TypeInfo) (tc
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *floatType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geomcollType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *geometryType:
|
||||
return wrapConvertValueToNomsValue(dest.ConvertValueToNomsValue)
|
||||
case *inlineBlobType:
|
||||
|
||||
@@ -277,17 +277,19 @@ func deserializeGeometry(buf []byte) (v interface{}) {
|
||||
buf = buf[sql.EWKBHeaderSize:]
|
||||
switch typ {
|
||||
case sql.WKBPointID:
|
||||
v, _ = sql.DeserializePoint(buf, false, srid)
|
||||
v, _, _ = sql.DeserializePoint(buf, false, srid)
|
||||
case sql.WKBLineID:
|
||||
v, _ = sql.DeserializeLine(buf, false, srid)
|
||||
v, _, _ = sql.DeserializeLine(buf, false, srid)
|
||||
case sql.WKBPolyID:
|
||||
v, _ = sql.DeserializePoly(buf, false, srid)
|
||||
v, _, _ = sql.DeserializePoly(buf, false, srid)
|
||||
case sql.WKBMultiPointID:
|
||||
v, _ = sql.DeserializeMPoint(buf, false, srid)
|
||||
v, _, _ = sql.DeserializeMPoint(buf, false, srid)
|
||||
case sql.WKBMultiLineID:
|
||||
v, _ = sql.DeserializeMLine(buf, false, srid)
|
||||
v, _, _ = sql.DeserializeMLine(buf, false, srid)
|
||||
case sql.WKBMultiPolyID:
|
||||
v, _ = sql.DeserializeMPoly(buf, false, srid)
|
||||
v, _, _ = sql.DeserializeMPoly(buf, false, srid)
|
||||
case sql.WKBGeomCollID:
|
||||
v, _, _ = sql.DeserializeGeomColl(buf, false, srid)
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown geometry type %d", typ))
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ func testRoundTripProllyFields(t *testing.T, test prollyFieldTest) {
|
||||
|
||||
func mustParseGeometryType(t *testing.T, s string) (v interface{}) {
|
||||
// Determine type, and get data
|
||||
geomType, data, err := function.ParseWKTHeader(s)
|
||||
geomType, data, _, err := function.ParseWKTHeader(s)
|
||||
require.NoError(t, err)
|
||||
|
||||
srid, order := uint32(0), false
|
||||
|
||||
@@ -534,7 +534,14 @@ func interfaceValueAsSqlString(ti typeinfo.TypeInfo, value interface{}) (string,
|
||||
return "", fmt.Errorf("typeinfo.VarStringTypeIdentifier is not types.String")
|
||||
}
|
||||
return quoteAndEscapeString(string(s)), nil
|
||||
case typeinfo.GeometryTypeIdentifier, typeinfo.PointTypeIdentifier, typeinfo.LineStringTypeIdentifier, typeinfo.PolygonTypeIdentifier, typeinfo.MultiPointTypeIdentifier, typeinfo.MultiLineStringTypeIdentifier, typeinfo.MultiPolygonTypeIdentifier:
|
||||
case typeinfo.GeometryTypeIdentifier,
|
||||
typeinfo.PointTypeIdentifier,
|
||||
typeinfo.LineStringTypeIdentifier,
|
||||
typeinfo.PolygonTypeIdentifier,
|
||||
typeinfo.MultiPointTypeIdentifier,
|
||||
typeinfo.MultiLineStringTypeIdentifier,
|
||||
typeinfo.MultiPolygonTypeIdentifier,
|
||||
typeinfo.GeometryCollectionTypeIdentifier:
|
||||
return singleQuote + str + singleQuote, nil
|
||||
default:
|
||||
return str, nil
|
||||
|
||||
161
go/store/types/geometry_collection.go
Normal file
161
go/store/types/geometry_collection.go
Normal file
@@ -0,0 +1,161 @@
|
||||
// Copyright 2022 Dolthub, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
)
|
||||
|
||||
// GeomColl is a Noms Value wrapper around a string.
|
||||
type GeomColl struct {
|
||||
SRID uint32
|
||||
Geometries []Value
|
||||
}
|
||||
|
||||
// Value interface
|
||||
func (v GeomColl) Value(ctx context.Context) (Value, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (v GeomColl) Equals(other Value) bool {
|
||||
// Compare types
|
||||
v2, ok := other.(GeomColl)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
// Compare SRID
|
||||
if v.SRID != v2.SRID {
|
||||
return false
|
||||
}
|
||||
// Compare lengths of geometries
|
||||
if len(v.Geometries) != len(v2.Geometries) {
|
||||
return false
|
||||
}
|
||||
// Compare each geometry
|
||||
for i := 0; i < len(v.Geometries); i++ {
|
||||
if !v.Geometries[i].Equals(v2.Geometries[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (v GeomColl) Less(nbf *NomsBinFormat, other LesserValuable) (bool, error) {
|
||||
// Compare types
|
||||
v2, ok := other.(GeomColl)
|
||||
if !ok {
|
||||
return GeometryCollectionKind < other.Kind(), nil
|
||||
}
|
||||
// Compare SRID
|
||||
if v.SRID != v2.SRID {
|
||||
return v.SRID < v2.SRID, nil
|
||||
}
|
||||
// Get shorter length
|
||||
var n int
|
||||
len1 := len(v.Geometries)
|
||||
len2 := len(v2.Geometries)
|
||||
if len1 < len2 {
|
||||
n = len1
|
||||
} else {
|
||||
n = len2
|
||||
}
|
||||
// Compare each polygon until there is one that is less
|
||||
for i := 0; i < n; i++ {
|
||||
if !v.Geometries[i].Equals(v2.Geometries[i]) {
|
||||
return v.Geometries[i].Less(nbf, v2.Geometries[i])
|
||||
}
|
||||
}
|
||||
// Determine based off length
|
||||
return len1 < len2, nil
|
||||
}
|
||||
|
||||
func (v GeomColl) Hash(nbf *NomsBinFormat) (hash.Hash, error) {
|
||||
return getHash(v, nbf)
|
||||
}
|
||||
|
||||
func (v GeomColl) isPrimitive() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (v GeomColl) walkRefs(nbf *NomsBinFormat, cb RefCallback) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v GeomColl) typeOf() (*Type, error) {
|
||||
return PrimitiveTypeMap[GeometryCollectionKind], nil
|
||||
}
|
||||
|
||||
func (v GeomColl) Kind() NomsKind {
|
||||
return GeometryCollectionKind
|
||||
}
|
||||
|
||||
func (v GeomColl) valueReadWriter() ValueReadWriter {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v GeomColl) writeTo(w nomsWriter, nbf *NomsBinFormat) error {
|
||||
err := GeometryCollectionKind.writeTo(w, nbf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.writeString(string(SerializeGeomColl(v)))
|
||||
return nil
|
||||
}
|
||||
|
||||
func readGeomColl(nbf *NomsBinFormat, b *valueDecoder) (GeomColl, error) {
|
||||
buf := []byte(b.ReadString())
|
||||
srid, _, geomType, err := DeserializeEWKBHeader(buf)
|
||||
if err != nil {
|
||||
return GeomColl{}, err
|
||||
}
|
||||
if geomType != WKBGeomCollID {
|
||||
return GeomColl{}, errors.New("not a geometry collection")
|
||||
}
|
||||
buf = buf[EWKBHeaderSize:]
|
||||
return DeserializeTypesGeomColl(buf, false, srid), nil
|
||||
}
|
||||
|
||||
func (v GeomColl) readFrom(nbf *NomsBinFormat, b *binaryNomsReader) (Value, error) {
|
||||
buf := []byte(b.ReadString())
|
||||
srid, _, geomType, err := DeserializeEWKBHeader(buf)
|
||||
if err != nil {
|
||||
return GeomColl{}, err
|
||||
}
|
||||
if geomType != WKBGeomCollID {
|
||||
return GeomColl{}, errors.New("not a geometry collection")
|
||||
}
|
||||
buf = buf[EWKBHeaderSize:]
|
||||
return DeserializeTypesGeomColl(buf, false, srid), nil
|
||||
}
|
||||
|
||||
func (v GeomColl) skip(nbf *NomsBinFormat, b *binaryNomsReader) {
|
||||
b.skipString()
|
||||
}
|
||||
|
||||
func (v GeomColl) HumanReadableString() string {
|
||||
geoms := make([]string, len(v.Geometries))
|
||||
for i, l := range v.Geometries {
|
||||
geoms[i] = l.HumanReadableString()
|
||||
}
|
||||
s := fmt.Sprintf("SRID: %d GEOMETRIES(%s)", v.SRID, strings.Join(geoms, ","))
|
||||
return strconv.Quote(s)
|
||||
}
|
||||
@@ -106,6 +106,7 @@ func init() {
|
||||
KindToType[MultiPointKind] = MultiPoint{}
|
||||
KindToType[MultiLineStringKind] = MultiLineString{}
|
||||
KindToType[MultiPolygonKind] = MultiPolygon{}
|
||||
KindToType[GeometryCollectionKind] = GeomColl{}
|
||||
|
||||
SupportedKinds[BlobKind] = true
|
||||
SupportedKinds[BoolKind] = true
|
||||
@@ -137,6 +138,7 @@ func init() {
|
||||
SupportedKinds[MultiPointKind] = true
|
||||
SupportedKinds[MultiLineStringKind] = true
|
||||
SupportedKinds[MultiPolygonKind] = true
|
||||
SupportedKinds[GeometryCollectionKind] = true
|
||||
|
||||
if serial.MessageTypesKind != int(SerialMessageKind) {
|
||||
panic("internal error: serial.MessageTypesKind != SerialMessageKind")
|
||||
@@ -146,37 +148,38 @@ func init() {
|
||||
var KindToTypeSlice []Value
|
||||
|
||||
var KindToString = map[NomsKind]string{
|
||||
UnknownKind: "unknown",
|
||||
BlobKind: "Blob",
|
||||
BoolKind: "Bool",
|
||||
CycleKind: "Cycle",
|
||||
ListKind: "List",
|
||||
MapKind: "Map",
|
||||
FloatKind: "Float",
|
||||
RefKind: "Ref",
|
||||
SetKind: "Set",
|
||||
StructKind: "Struct",
|
||||
StringKind: "String",
|
||||
TypeKind: "Type",
|
||||
UnionKind: "Union",
|
||||
ValueKind: "Value",
|
||||
UUIDKind: "UUID",
|
||||
IntKind: "Int",
|
||||
UintKind: "Uint",
|
||||
NullKind: "Null",
|
||||
TupleKind: "Tuple",
|
||||
InlineBlobKind: "InlineBlob",
|
||||
TimestampKind: "Timestamp",
|
||||
DecimalKind: "Decimal",
|
||||
JSONKind: "JSON",
|
||||
GeometryKind: "Geometry",
|
||||
PointKind: "Point",
|
||||
LineStringKind: "LineString",
|
||||
PolygonKind: "Polygon",
|
||||
SerialMessageKind: "SerialMessage",
|
||||
MultiPointKind: "MultiPoint",
|
||||
MultiLineStringKind: "MultiLineString",
|
||||
MultiPolygonKind: "MultiPolygon",
|
||||
UnknownKind: "unknown",
|
||||
BlobKind: "Blob",
|
||||
BoolKind: "Bool",
|
||||
CycleKind: "Cycle",
|
||||
ListKind: "List",
|
||||
MapKind: "Map",
|
||||
FloatKind: "Float",
|
||||
RefKind: "Ref",
|
||||
SetKind: "Set",
|
||||
StructKind: "Struct",
|
||||
StringKind: "String",
|
||||
TypeKind: "Type",
|
||||
UnionKind: "Union",
|
||||
ValueKind: "Value",
|
||||
UUIDKind: "UUID",
|
||||
IntKind: "Int",
|
||||
UintKind: "Uint",
|
||||
NullKind: "Null",
|
||||
TupleKind: "Tuple",
|
||||
InlineBlobKind: "InlineBlob",
|
||||
TimestampKind: "Timestamp",
|
||||
DecimalKind: "Decimal",
|
||||
JSONKind: "JSON",
|
||||
GeometryKind: "Geometry",
|
||||
PointKind: "Point",
|
||||
LineStringKind: "LineString",
|
||||
PolygonKind: "Polygon",
|
||||
SerialMessageKind: "SerialMessage",
|
||||
MultiPointKind: "MultiPoint",
|
||||
MultiLineStringKind: "MultiLineString",
|
||||
MultiPolygonKind: "MultiPolygon",
|
||||
GeometryCollectionKind: "GeometryCollection",
|
||||
}
|
||||
|
||||
// String returns the name of the kind.
|
||||
|
||||
@@ -26,6 +26,14 @@ func ConvertTypesGeometryToSQLGeometry(g Geometry) interface{} {
|
||||
return ConvertTypesLineStringToSQLLineString(inner)
|
||||
case Polygon:
|
||||
return ConvertTypesPolygonToSQLPolygon(inner)
|
||||
case MultiPoint:
|
||||
return ConvertTypesMultiPointToSQLMultiPoint(inner)
|
||||
case MultiLineString:
|
||||
return ConvertTypesMultiLineStringToSQLMultiLineString(inner)
|
||||
case MultiPolygon:
|
||||
return ConvertTypesMultiPolygonToSQLMultiPolygon(inner)
|
||||
case GeomColl:
|
||||
return ConvertTypesGeomCollToSQLGeomColl(inner)
|
||||
default:
|
||||
panic("used an invalid type types.Geometry.Inner")
|
||||
}
|
||||
@@ -75,6 +83,29 @@ func ConvertTypesMultiPolygonToSQLMultiPolygon(p MultiPolygon) sql.MultiPolygon
|
||||
return sql.MultiPolygon{SRID: p.SRID, Polygons: polys}
|
||||
}
|
||||
|
||||
func ConvertTypesGeomCollToSQLGeomColl(g GeomColl) sql.GeomColl {
|
||||
geoms := make([]sql.GeometryValue, len(g.Geometries))
|
||||
for i, geom := range g.Geometries {
|
||||
switch geo := geom.(type) {
|
||||
case Point:
|
||||
geoms[i] = ConvertTypesPointToSQLPoint(geo)
|
||||
case LineString:
|
||||
geoms[i] = ConvertTypesLineStringToSQLLineString(geo)
|
||||
case Polygon:
|
||||
geoms[i] = ConvertTypesPolygonToSQLPolygon(geo)
|
||||
case MultiPoint:
|
||||
geoms[i] = ConvertTypesMultiPointToSQLMultiPoint(geo)
|
||||
case MultiLineString:
|
||||
geoms[i] = ConvertTypesMultiLineStringToSQLMultiLineString(geo)
|
||||
case MultiPolygon:
|
||||
geoms[i] = ConvertTypesMultiPolygonToSQLMultiPolygon(geo)
|
||||
case GeomColl:
|
||||
geoms[i] = ConvertTypesGeomCollToSQLGeomColl(geo)
|
||||
}
|
||||
}
|
||||
return sql.GeomColl{SRID: g.SRID, Geoms: geoms}
|
||||
}
|
||||
|
||||
func ConvertSQLGeometryToTypesGeometry(p interface{}) Value {
|
||||
switch inner := p.(type) {
|
||||
case sql.Point:
|
||||
@@ -89,6 +120,8 @@ func ConvertSQLGeometryToTypesGeometry(p interface{}) Value {
|
||||
return ConvertSQLMultiLineStringToTypesMultiLineString(inner)
|
||||
case sql.MultiPolygon:
|
||||
return ConvertSQLMultiPolygonToTypesMultiPolygon(inner)
|
||||
case sql.GeomColl:
|
||||
return ConvertSQLGeomCollToTypesGeomColl(inner)
|
||||
default:
|
||||
panic("used an invalid type sql.Geometry.Inner")
|
||||
}
|
||||
@@ -138,6 +171,29 @@ func ConvertSQLMultiPolygonToTypesMultiPolygon(p sql.MultiPolygon) MultiPolygon
|
||||
return MultiPolygon{SRID: p.SRID, Polygons: polys}
|
||||
}
|
||||
|
||||
func ConvertSQLGeomCollToTypesGeomColl(g sql.GeomColl) GeomColl {
|
||||
geoms := make([]Value, len(g.Geoms))
|
||||
for i, geom := range g.Geoms {
|
||||
switch geo := geom.(type) {
|
||||
case sql.Point:
|
||||
geoms[i] = ConvertSQLPointToTypesPoint(geo)
|
||||
case sql.LineString:
|
||||
geoms[i] = ConvertSQLLineStringToTypesLineString(geo)
|
||||
case sql.Polygon:
|
||||
geoms[i] = ConvertSQLPolygonToTypesPolygon(geo)
|
||||
case sql.MultiPoint:
|
||||
geoms[i] = ConvertSQLMultiPointToTypesMultiPoint(geo)
|
||||
case sql.MultiLineString:
|
||||
geoms[i] = ConvertSQLMultiLineStringToTypesMultiLineString(geo)
|
||||
case sql.MultiPolygon:
|
||||
geoms[i] = ConvertSQLMultiPolygonToTypesMultiPolygon(geo)
|
||||
case sql.GeomColl:
|
||||
geoms[i] = ConvertSQLGeomCollToTypesGeomColl(geo)
|
||||
}
|
||||
}
|
||||
return GeomColl{SRID: g.SRID, Geometries: geoms}
|
||||
}
|
||||
|
||||
// TODO: all methods here just defer to their SQL equivalents, and assume we always receive good data
|
||||
|
||||
func DeserializeEWKBHeader(buf []byte) (uint32, bool, uint32, error) {
|
||||
@@ -149,7 +205,7 @@ func DeserializeWKBHeader(buf []byte) (bool, uint32, error) {
|
||||
}
|
||||
|
||||
func DeserializePoint(buf []byte, isBig bool, srid uint32) sql.Point {
|
||||
p, err := sql.DeserializePoint(buf, isBig, srid)
|
||||
p, _, err := sql.DeserializePoint(buf, isBig, srid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -157,7 +213,7 @@ func DeserializePoint(buf []byte, isBig bool, srid uint32) sql.Point {
|
||||
}
|
||||
|
||||
func DeserializeLine(buf []byte, isBig bool, srid uint32) sql.LineString {
|
||||
l, err := sql.DeserializeLine(buf, isBig, srid)
|
||||
l, _, err := sql.DeserializeLine(buf, isBig, srid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -165,7 +221,7 @@ func DeserializeLine(buf []byte, isBig bool, srid uint32) sql.LineString {
|
||||
}
|
||||
|
||||
func DeserializePoly(buf []byte, isBig bool, srid uint32) sql.Polygon {
|
||||
p, err := sql.DeserializePoly(buf, isBig, srid)
|
||||
p, _, err := sql.DeserializePoly(buf, isBig, srid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -173,7 +229,7 @@ func DeserializePoly(buf []byte, isBig bool, srid uint32) sql.Polygon {
|
||||
}
|
||||
|
||||
func DeserializeMPoint(buf []byte, isBig bool, srid uint32) sql.MultiPoint {
|
||||
p, err := sql.DeserializeMPoint(buf, isBig, srid)
|
||||
p, _, err := sql.DeserializeMPoint(buf, isBig, srid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -181,7 +237,7 @@ func DeserializeMPoint(buf []byte, isBig bool, srid uint32) sql.MultiPoint {
|
||||
}
|
||||
|
||||
func DeserializeMLine(buf []byte, isBig bool, srid uint32) sql.MultiLineString {
|
||||
p, err := sql.DeserializeMLine(buf, isBig, srid)
|
||||
p, _, err := sql.DeserializeMLine(buf, isBig, srid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -189,13 +245,21 @@ func DeserializeMLine(buf []byte, isBig bool, srid uint32) sql.MultiLineString {
|
||||
}
|
||||
|
||||
func DeserializeMPoly(buf []byte, isBig bool, srid uint32) sql.MultiPolygon {
|
||||
p, err := sql.DeserializeMPoly(buf, isBig, srid)
|
||||
p, _, err := sql.DeserializeMPoly(buf, isBig, srid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func DeserializeGeomColl(buf []byte, isBig bool, srid uint32) sql.GeomColl {
|
||||
g, _, err := sql.DeserializeGeomColl(buf, isBig, srid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return g
|
||||
}
|
||||
|
||||
// TODO: noms needs results to be in types
|
||||
|
||||
func DeserializeTypesPoint(buf []byte, isBig bool, srid uint32) Point {
|
||||
@@ -221,3 +285,7 @@ func DeserializeTypesMLine(buf []byte, isBig bool, srid uint32) MultiLineString
|
||||
func DeserializeTypesMPoly(buf []byte, isBig bool, srid uint32) MultiPolygon {
|
||||
return ConvertSQLMultiPolygonToTypesMultiPolygon(DeserializeMPoly(buf, isBig, srid))
|
||||
}
|
||||
|
||||
func DeserializeTypesGeomColl(buf []byte, isBig bool, srid uint32) GeomColl {
|
||||
return ConvertSQLGeomCollToTypesGeomColl(DeserializeGeomColl(buf, isBig, srid))
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ type CodecReader interface {
|
||||
ReadMultiPoint() (MultiPoint, error)
|
||||
ReadMultiLineString() (MultiLineString, error)
|
||||
ReadMultiPolygon() (MultiPolygon, error)
|
||||
ReadGeomColl() (GeomColl, error)
|
||||
ReadBlob() (Blob, error)
|
||||
ReadJSON() (JSON, error)
|
||||
}
|
||||
@@ -115,6 +116,10 @@ func (r *valueDecoder) ReadMultiPolygon() (MultiPolygon, error) {
|
||||
return readMultiPolygon(nil, r)
|
||||
}
|
||||
|
||||
func (r *valueDecoder) ReadGeomColl() (GeomColl, error) {
|
||||
return readGeomColl(nil, r)
|
||||
}
|
||||
|
||||
func (r *valueDecoder) ReadJSON() (JSON, error) {
|
||||
return readJSON(r.vrw.Format(), r)
|
||||
}
|
||||
|
||||
@@ -34,14 +34,14 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
WKBUnknown = sql.WKBUnknown
|
||||
WKBPointID = sql.WKBPointID
|
||||
WKBLineID = sql.WKBLineID
|
||||
WKBPolyID = sql.WKBPolyID
|
||||
WKBMultiPointID = sql.WKBMultiPointID
|
||||
WKBMultiLineID = sql.WKBMultiLineID
|
||||
WKBMultiPolyID = sql.WKBMultiPolyID
|
||||
WKBGeomCollectionID = sql.WKBGeomCollectionID
|
||||
WKBUnknown = sql.WKBUnknown
|
||||
WKBPointID = sql.WKBPointID
|
||||
WKBLineID = sql.WKBLineID
|
||||
WKBPolyID = sql.WKBPolyID
|
||||
WKBMultiPointID = sql.WKBMultiPointID
|
||||
WKBMultiLineID = sql.WKBMultiLineID
|
||||
WKBMultiPolyID = sql.WKBMultiPolyID
|
||||
WKBGeomCollID = sql.WKBGeomCollID
|
||||
)
|
||||
|
||||
// TODO: all methods here just defer to their SQL equivalents, and assume we always receive good data
|
||||
@@ -73,3 +73,7 @@ func SerializeMultiLineString(p MultiLineString) []byte {
|
||||
func SerializeMultiPolygon(p MultiPolygon) []byte {
|
||||
return ConvertTypesMultiPolygonToSQLMultiPolygon(p).Serialize()
|
||||
}
|
||||
|
||||
func SerializeGeomColl(g GeomColl) []byte {
|
||||
return ConvertTypesGeomCollToSQLGeomColl(g).Serialize()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user