Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions enginetest/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,55 @@ var SpatialQueryTests = []QueryTest{
{5.656854249492381},
},
},
{
Query: `SELECT ST_ASWKT(g) from geometry_table where g = point(1,2)`,
Expected: []sql.Row{
{"POINT(1 2)"},
},
},
{
Query: `SELECT ST_ASWKT(g) from geometry_table where g = st_srid(point(1,2),4326)`,
Expected: []sql.Row{
{"POINT(2 1)"},
},
},
{
Query: `SELECT ST_ASWKT(g) from geometry_table where g = unhex(hex(point(1,2)))`,
Expected: []sql.Row{
{"POINT(1 2)"},
},
},
{
Query: `SELECT unhex(hex(point(1,2))) < unhex(hex(point(3,4)))`,
Expected: []sql.Row{
{false},
},
},
{
Query: `SELECT ST_ASWKT(g) from geometry_table where g = st_geomfromtext('MultiPolygon(((0 0,1 2,3 4,0 0)))')`,
Expected: []sql.Row{
{"MULTIPOLYGON(((0 0,1 2,3 4,0 0)))"},
},
},
{
Query: `SELECT ST_ASWKT(g) from geometry_table ORDER BY g`,
Expected: []sql.Row{
{"POINT(1 2)"},
{"LINESTRING(1 2,3 4)"},
{"POLYGON((0 0,0 1,1 1,0 0))"},
{"MULTIPOINT(1 2,3 4)"},
{"MULTILINESTRING((1 2,3 4))"},
{"MULTIPOLYGON(((0 0,1 2,3 4,0 0)))"},
{"GEOMETRYCOLLECTION(GEOMETRYCOLLECTION())"},
{"POINT(2 1)"},
{"LINESTRING(2 1,4 3)"},
{"POLYGON((0 0,1 0,1 1,0 0))"},
{"MULTIPOINT(2 1,4 3)"},
{"MULTILINESTRING((2 1,4 3))"},
{"MULTIPOLYGON(((0 0,2 1,4 3,0 0)))"},
{"GEOMETRYCOLLECTION(GEOMETRYCOLLECTION())"},
},
},
}

var QueryTests = []QueryTest{
Expand Down
26 changes: 10 additions & 16 deletions sql/geometry.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package sql

import (
"bytes"
"encoding/binary"
"math"
"reflect"
Expand Down Expand Up @@ -385,24 +386,17 @@ func (t GeometryType) Compare(a any, b any) (int, error) {
return res, nil
}

switch inner := a.(type) {
case Point:
return PointType{}.Compare(inner, b)
case LineString:
return LineStringType{}.Compare(inner, b)
case Polygon:
return PolygonType{}.Compare(inner, b)
case MultiPoint:
return MultiPointType{}.Compare(inner, b)
case MultiLineString:
return MultiLineStringType{}.Compare(inner, b)
case MultiPolygon:
return MultiPolygonType{}.Compare(inner, b)
case GeomColl:
return GeomCollType{}.Compare(inner, b)
default:
aa, ok := a.(GeometryValue)
if !ok {
return 0, ErrNotGeometry.New(a)
}

bb, ok := b.(GeometryValue)
if !ok {
return 0, ErrNotGeometry.New(b)
}

return bytes.Compare(aa.Serialize(), bb.Serialize()), nil
}

// Convert implements Type interface.
Expand Down
68 changes: 1 addition & 67 deletions sql/geometry_collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,73 +48,7 @@ var (

// Compare implements Type interface.
func (t GeomCollType) Compare(a interface{}, b interface{}) (int, error) {
// Compare nulls
if hasNulls, res := compareNulls(a, b); hasNulls {
return res, nil
}

// Expect to receive a GeomColl, throw error otherwise
_a, ok := a.(GeomColl)
if !ok {
return 0, ErrNotGeomColl.New(a)
}
_b, ok := b.(GeomColl)
if !ok {
return 0, ErrNotGeomColl.New(b)
}

// Get shorter length
var n int
lenA := len(_a.Geoms)
lenB := len(_b.Geoms)
if lenA < lenB {
n = lenA
} else {
n = lenB
}

// Compare each point until there's a difference
for i := 0; i < n; i++ {
ga := _a.Geoms[i]
gb := _b.Geoms[i]
var diff int
var err error
switch ga.(type) {
case Point:
diff, err = PointType{}.Compare(ga, gb)
case LineString:
diff, err = LineStringType{}.Compare(ga, gb)
case Polygon:
diff, err = PolygonType{}.Compare(ga, gb)
case MultiPoint:
diff, err = MultiPointType{}.Compare(ga, gb)
case MultiLineString:
diff, err = MultiLineStringType{}.Compare(ga, gb)
case MultiPolygon:
diff, err = MultiPolygonType{}.Compare(ga, gb)
case GeomColl:
diff, err = GeomCollType{}.Compare(ga, gb)
default:
panic("impossible")
}
if err != nil {
return 0, err
}
if diff != 0 {
return diff, nil
}
}

// Determine based off length
if lenA > lenB {
return 1, nil
}
if lenA < lenB {
return -1, nil
}

// GeomColls must be the same
return 0, nil
return GeometryType{}.Compare(a, b)
}

// Convert implements Type interface.
Expand Down
47 changes: 1 addition & 46 deletions sql/linestring.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,52 +49,7 @@ var (

// Compare implements Type interface.
func (t LineStringType) Compare(a interface{}, b interface{}) (int, error) {
// Compare nulls
if hasNulls, res := compareNulls(a, b); hasNulls {
return res, nil
}

// Expect to receive a LineString, throw error otherwise
_a, ok := a.(LineString)
if !ok {
return 0, ErrNotLineString.New(a)
}
_b, ok := b.(LineString)
if !ok {
return 0, ErrNotLineString.New(b)
}

// Get shorter length
var n int
lenA := len(_a.Points)
lenB := len(_b.Points)
if lenA < lenB {
n = lenA
} else {
n = lenB
}

// Compare each point until there's a difference
for i := 0; i < n; i++ {
diff, err := PointType{}.Compare(_a.Points[i], _b.Points[i])
if err != nil {
return 0, err
}
if diff != 0 {
return diff, nil
}
}

// Determine based off length
if lenA > lenB {
return 1, nil
}
if lenA < lenB {
return -1, nil
}

// Lines must be the same
return 0, nil
return GeometryType{}.Compare(a, b)
}

// Convert implements Type interface.
Expand Down
47 changes: 1 addition & 46 deletions sql/multilinestring.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,52 +49,7 @@ var _ GeometryValue = MultiLineString{}

// Compare implements Type interface.
func (t MultiLineStringType) Compare(a interface{}, b interface{}) (int, error) {
// Compare nulls
if hasNulls, res := compareNulls(a, b); hasNulls {
return res, nil
}

// Expect to receive a MultiLineString, throw error otherwise
_a, ok := a.(MultiLineString)
if !ok {
return 0, ErrNotMultiLineString.New(a)
}
_b, ok := b.(MultiLineString)
if !ok {
return 0, ErrNotMultiLineString.New(b)
}

// Get shorter length
var n int
lenA := len(_a.Lines)
lenB := len(_b.Lines)
if lenA < lenB {
n = lenA
} else {
n = lenB
}

// Compare each line until there's a difference
for i := 0; i < n; i++ {
diff, err := LineStringType{}.Compare(_a.Lines[i], _b.Lines[i])
if err != nil {
return 0, err
}
if diff != 0 {
return diff, nil
}
}

// Determine based off length
if lenA > lenB {
return 1, nil
}
if lenA < lenB {
return -1, nil
}

// MultiLineString must be the same
return 0, nil
return GeometryType{}.Compare(a, b)
}

// Convert implements Type interface.
Expand Down
47 changes: 1 addition & 46 deletions sql/multipoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,52 +49,7 @@ var (

// Compare implements Type interface.
func (t MultiPointType) Compare(a interface{}, b interface{}) (int, error) {
// Compare nulls
if hasNulls, res := compareNulls(a, b); hasNulls {
return res, nil
}

// Expect to receive a MultiPoint, throw error otherwise
_a, ok := a.(MultiPoint)
if !ok {
return 0, ErrNotMultiPoint.New(a)
}
_b, ok := b.(MultiPoint)
if !ok {
return 0, ErrNotMultiPoint.New(b)
}

// Get shorter length
var n int
lenA := len(_a.Points)
lenB := len(_b.Points)
if lenA < lenB {
n = lenA
} else {
n = lenB
}

// Compare each point until there's a difference
for i := 0; i < n; i++ {
diff, err := PointType{}.Compare(_a.Points[i], _b.Points[i])
if err != nil {
return 0, err
}
if diff != 0 {
return diff, nil
}
}

// Determine based off length
if lenA > lenB {
return 1, nil
}
if lenA < lenB {
return -1, nil
}

// MultiPoint must be the same
return 0, nil
return GeometryType{}.Compare(a, b)
}

// Convert implements Type interface.
Expand Down
48 changes: 1 addition & 47 deletions sql/multipolygon.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,54 +48,8 @@ var _ SpatialColumnType = MultiPolygonType{}
var _ GeometryValue = MultiPolygon{}

// Compare implements Type interface.
// TODO: it might be better to just serialize and the compare the []byte
func (t MultiPolygonType) Compare(a interface{}, b interface{}) (int, error) {
// Compare nulls
if hasNulls, res := compareNulls(a, b); hasNulls {
return res, nil
}

// Expect to receive a MultiPolygon, throw error otherwise
_a, ok := a.(MultiPolygon)
if !ok {
return 0, ErrNotMultiPolygon.New(a)
}
_b, ok := b.(MultiPolygon)
if !ok {
return 0, ErrNotMultiPolygon.New(b)
}

// Get shorter length
var n int
lenA := len(_a.Polygons)
lenB := len(_b.Polygons)
if lenA < lenB {
n = lenA
} else {
n = lenB
}

// Compare each polygon until there's a difference
for i := 0; i < n; i++ {
diff, err := PolygonType{}.Compare(_a.Polygons[i], _b.Polygons[i])
if err != nil {
return 0, err
}
if diff != 0 {
return diff, nil
}
}

// Determine based off length
if lenA > lenB {
return 1, nil
}
if lenA < lenB {
return -1, nil
}

// MultiPolygon must be the same
return 0, nil
return GeometryType{}.Compare(a, b)
}

// Convert implements Type interface.
Expand Down
Loading