github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/st_distance_test.go (about) 1 // Copyright 2023 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package spatial 16 17 import ( 18 "math" 19 "testing" 20 21 "github.com/stretchr/testify/require" 22 23 "github.com/dolthub/go-mysql-server/sql" 24 "github.com/dolthub/go-mysql-server/sql/expression" 25 "github.com/dolthub/go-mysql-server/sql/types" 26 ) 27 28 func TestDistance(t *testing.T) { 29 t.Run("point distance from itself", func(t *testing.T) { 30 require := require.New(t) 31 p := types.Point{X: 0, Y: 0} 32 f, err := NewDistance(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(p, types.PointType{})) 33 require.NoError(err) 34 35 v, err := f.Eval(sql.NewEmptyContext(), nil) 36 require.NoError(err) 37 require.Equal(0.0, v) 38 }) 39 40 t.Run("simple point distance", func(t *testing.T) { 41 require := require.New(t) 42 p1 := types.Point{X: 100, Y: 200} 43 p2 := types.Point{X: 101, Y: 201} 44 f, err := NewDistance(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(p2, types.PointType{})) 45 require.NoError(err) 46 47 v, err := f.Eval(sql.NewEmptyContext(), nil) 48 require.NoError(err) 49 require.Equal(math.Sqrt(2), v) 50 }) 51 52 t.Run("geomcollection vs multipoint", func(t *testing.T) { 53 require := require.New(t) 54 p0 := types.Point{X: 0, Y: 0} 55 p1 := types.Point{X: 1, Y: 1} 56 p2 := types.Point{X: 2, Y: 2} 57 l := types.LineString{Points: []types.Point{p0, p1, p2}} 58 mp := types.MultiPoint{Points: []types.Point{p2, p1, p0}} 59 gc := types.GeomColl{Geoms: []types.GeometryValue{p0, l}} 60 f, err := NewDistance(expression.NewLiteral(gc, types.GeomCollType{}), expression.NewLiteral(mp, types.MultiPointType{})) 61 require.NoError(err) 62 63 v, err := f.Eval(sql.NewEmptyContext(), nil) 64 require.NoError(err) 65 require.Equal(0.0, v) 66 }) 67 68 t.Run("non-cartesian SRIDs error", func(t *testing.T) { 69 require := require.New(t) 70 p1 := types.Point{SRID: types.GeoSpatialSRID, X: 0, Y: 0} 71 p2 := types.Point{SRID: types.GeoSpatialSRID, X: 0, Y: 0} 72 f, err := NewDistance(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(p2, types.PointType{})) 73 require.NoError(err) 74 75 _, err = f.Eval(sql.NewEmptyContext(), nil) 76 require.Error(err) 77 }) 78 79 t.Run("different SRIDs error", func(t *testing.T) { 80 require := require.New(t) 81 p1 := types.Point{SRID: types.CartesianSRID, X: 0, Y: 0} 82 p2 := types.Point{SRID: types.GeoSpatialSRID, X: 0, Y: 0} 83 f, err := NewDistance(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(p2, types.PointType{})) 84 require.NoError(err) 85 86 _, err = f.Eval(sql.NewEmptyContext(), nil) 87 require.Error(err) 88 }) 89 90 t.Run("geospatial SRID unsupported", func(t *testing.T) { 91 require := require.New(t) 92 p1 := types.Point{SRID: types.GeoSpatialSRID, X: 0, Y: 0} 93 p2 := types.Point{SRID: types.GeoSpatialSRID, X: 0, Y: 0} 94 f, err := NewDistance(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(p2, types.PointType{})) 95 require.NoError(err) 96 97 _, err = f.Eval(sql.NewEmptyContext(), nil) 98 require.Error(err) 99 }) 100 101 t.Run("cartesian has no units", func(t *testing.T) { 102 require := require.New(t) 103 p1 := types.Point{SRID: types.CartesianSRID, X: 0, Y: 0} 104 p2 := types.Point{SRID: types.CartesianSRID, X: 0, Y: 0} 105 f, err := NewDistance(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(p2, types.PointType{}), expression.NewLiteral("meters", types.LongText)) 106 require.NoError(err) 107 108 _, err = f.Eval(sql.NewEmptyContext(), nil) 109 require.Error(err) 110 }) 111 }