github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/st_dimension_test.go (about) 1 // Copyright 2020-2021 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 "testing" 19 20 "github.com/stretchr/testify/require" 21 22 "github.com/dolthub/go-mysql-server/sql" 23 "github.com/dolthub/go-mysql-server/sql/expression" 24 "github.com/dolthub/go-mysql-server/sql/types" 25 ) 26 27 func TestDimension(t *testing.T) { 28 t.Run("point is dimension 0", func(t *testing.T) { 29 require := require.New(t) 30 f := NewDimension(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{})) 31 v, err := f.Eval(sql.NewEmptyContext(), nil) 32 require.NoError(err) 33 require.Equal(0, v) 34 }) 35 36 t.Run("point with srid 4326 is dimension 0", func(t *testing.T) { 37 require := require.New(t) 38 f := NewDimension(expression.NewLiteral(types.Point{SRID: 4326, X: 1, Y: 2}, types.PointType{})) 39 v, err := f.Eval(sql.NewEmptyContext(), nil) 40 require.NoError(err) 41 require.Equal(0, v) 42 }) 43 44 t.Run("point with srid 3857 is dimension 0", func(t *testing.T) { 45 require := require.New(t) 46 f := NewDimension(expression.NewLiteral(types.Point{SRID: 3857, X: 1, Y: 2}, types.PointType{})) 47 v, err := f.Eval(sql.NewEmptyContext(), nil) 48 require.NoError(err) 49 require.Equal(0, v) 50 }) 51 52 t.Run("linestring is dimension 1", func(t *testing.T) { 53 require := require.New(t) 54 f := NewDimension(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.LineStringType{})) 55 v, err := f.Eval(sql.NewEmptyContext(), nil) 56 require.NoError(err) 57 require.Equal(1, v) 58 }) 59 60 t.Run("polygon dimension 2", func(t *testing.T) { 61 require := require.New(t) 62 f := NewDimension(expression.NewLiteral(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 1}, {X: 0, Y: 0}}}}}, types.PolygonType{})) 63 v, err := f.Eval(sql.NewEmptyContext(), nil) 64 require.NoError(err) 65 require.Equal(2, v) 66 }) 67 68 t.Run("multipoint is dimension 0", func(t *testing.T) { 69 require := require.New(t) 70 f := NewDimension(expression.NewLiteral(types.MultiPoint{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.MultiPointType{})) 71 v, err := f.Eval(sql.NewEmptyContext(), nil) 72 require.NoError(err) 73 require.Equal(0, v) 74 }) 75 76 t.Run("multilinestring is dimension 1", func(t *testing.T) { 77 require := require.New(t) 78 f := NewDimension(expression.NewLiteral(types.MultiLineString{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 1}, {X: 0, Y: 0}}}}}, types.MultiLineStringType{})) 79 v, err := f.Eval(sql.NewEmptyContext(), nil) 80 require.NoError(err) 81 require.Equal(1, v) 82 }) 83 84 t.Run("geometry with inner point is dimension 0", func(t *testing.T) { 85 require := require.New(t) 86 f := NewDimension(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.GeometryType{})) 87 v, err := f.Eval(sql.NewEmptyContext(), nil) 88 require.NoError(err) 89 require.Equal(0, v) 90 }) 91 92 t.Run("geometry with inner linestring is dimension 1", func(t *testing.T) { 93 require := require.New(t) 94 f := NewDimension(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.GeometryType{})) 95 v, err := f.Eval(sql.NewEmptyContext(), nil) 96 require.NoError(err) 97 require.Equal(1, v) 98 }) 99 100 t.Run("geometry with inner polygon dimension 2", func(t *testing.T) { 101 require := require.New(t) 102 f := NewDimension(expression.NewLiteral(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 1}, {X: 0, Y: 0}}}}}, types.GeometryType{})) 103 v, err := f.Eval(sql.NewEmptyContext(), nil) 104 require.NoError(err) 105 require.Equal(2, v) 106 }) 107 108 t.Run("empty geometry collection has dimension null", func(t *testing.T) { 109 require := require.New(t) 110 f := NewDimension(expression.NewLiteral(types.GeomColl{}, types.GeometryType{})) 111 v, err := f.Eval(sql.NewEmptyContext(), nil) 112 require.NoError(err) 113 require.Equal(nil, v) 114 }) 115 116 t.Run("geometry collection of a point has dimension 0", func(t *testing.T) { 117 require := require.New(t) 118 f := NewDimension(expression.NewLiteral(types.GeomColl{Geoms: []types.GeometryValue{types.Point{}}}, types.GeometryType{})) 119 v, err := f.Eval(sql.NewEmptyContext(), nil) 120 require.NoError(err) 121 require.Equal(0, v) 122 }) 123 124 t.Run("geometry collection of a different types takes highest type", func(t *testing.T) { 125 require := require.New(t) 126 point := types.Point{} 127 line := types.LineStringType{}.Zero().(types.LineString) 128 poly := types.PolygonType{}.Zero().(types.Polygon) 129 f := NewDimension(expression.NewLiteral(types.GeomColl{Geoms: []types.GeometryValue{point, line, poly}}, types.GeometryType{})) 130 v, err := f.Eval(sql.NewEmptyContext(), nil) 131 require.NoError(err) 132 require.Equal(2, v) 133 }) 134 135 t.Run("geometry collection null is the largest dimension", func(t *testing.T) { 136 require := require.New(t) 137 point := types.Point{} 138 line := types.LineStringType{}.Zero().(types.LineString) 139 poly := types.PolygonType{}.Zero().(types.Polygon) 140 geom := types.GeomColl{} 141 f := NewDimension(expression.NewLiteral(types.GeomColl{Geoms: []types.GeometryValue{point, line, poly, geom}}, types.GeometryType{})) 142 v, err := f.Eval(sql.NewEmptyContext(), nil) 143 require.NoError(err) 144 require.Equal(nil, v) 145 }) 146 147 t.Run("null is null", func(t *testing.T) { 148 require := require.New(t) 149 f := NewDimension(expression.NewLiteral(123, types.Int64)) 150 _, err := f.Eval(sql.NewEmptyContext(), nil) 151 require.Error(err) 152 }) 153 154 t.Run("null is null", func(t *testing.T) { 155 require := require.New(t) 156 f := NewDimension(expression.NewLiteral(nil, types.Null)) 157 v, err := f.Eval(sql.NewEmptyContext(), nil) 158 require.NoError(err) 159 require.Equal(nil, v) 160 }) 161 162 t.Run("check return type", func(t *testing.T) { 163 require := require.New(t) 164 f := NewDimension(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{})) 165 166 v, err := f.Eval(sql.NewEmptyContext(), nil) 167 require.NoError(err) 168 169 typ := f.Type() 170 _, inRange, err := typ.Convert(v) 171 require.True(bool(inRange)) 172 require.NoError(err) 173 }) 174 }