github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/st_swapxy_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 TestSwapXY(t *testing.T) { 28 t.Run("point swap", func(t *testing.T) { 29 require := require.New(t) 30 f := NewSwapXY(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(types.Point{X: 2, Y: 1}, v) 34 }) 35 36 t.Run("linestring swap", func(t *testing.T) { 37 require := require.New(t) 38 f := NewSwapXY(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.LineStringType{})) 39 v, err := f.Eval(sql.NewEmptyContext(), nil) 40 require.NoError(err) 41 require.Equal(types.LineString{Points: []types.Point{{X: 1, Y: 0}, {X: 3, Y: 2}}}, v) 42 }) 43 44 t.Run("polygon swap", func(t *testing.T) { 45 require := require.New(t) 46 f := NewSwapXY(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.PointType{})) 47 v, err := f.Eval(sql.NewEmptyContext(), nil) 48 require.NoError(err) 49 require.Equal(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}}}, v) 50 }) 51 52 t.Run("multipoint swap", func(t *testing.T) { 53 require := require.New(t) 54 f := NewSwapXY(expression.NewLiteral(types.MultiPoint{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.MultiPointType{})) 55 v, err := f.Eval(sql.NewEmptyContext(), nil) 56 require.NoError(err) 57 require.Equal(types.MultiPoint{Points: []types.Point{{X: 1, Y: 0}, {X: 3, Y: 2}}}, v) 58 }) 59 60 t.Run("multilinestring swap", func(t *testing.T) { 61 require := require.New(t) 62 f := NewSwapXY(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{})) 63 v, err := f.Eval(sql.NewEmptyContext(), nil) 64 require.NoError(err) 65 require.Equal(types.MultiLineString{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}}}, v) 66 }) 67 68 t.Run("multipolygon swap", func(t *testing.T) { 69 require := require.New(t) 70 line := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 2}, {X: 3, Y: 4}, {X: 0, Y: 0}}} 71 poly := types.Polygon{Lines: []types.LineString{line}} 72 f := NewSwapXY(expression.NewLiteral(types.MultiPolygon{Polygons: []types.Polygon{poly}}, types.MultiPolygonType{})) 73 v, err := f.Eval(sql.NewEmptyContext(), nil) 74 require.NoError(err) 75 line2 := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 2, Y: 1}, {X: 4, Y: 3}, {X: 0, Y: 0}}} 76 poly2 := types.Polygon{Lines: []types.LineString{line2}} 77 require.Equal(types.MultiPolygon{Polygons: []types.Polygon{poly2}}, v) 78 }) 79 80 t.Run("geometry collection swap", func(t *testing.T) { 81 require := require.New(t) 82 point := types.Point{X: 1, Y: 2} 83 line := types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}} 84 poly := types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}}} 85 g := types.GeomColl{Geoms: []types.GeometryValue{ 86 point, 87 line, 88 poly, 89 }} 90 f := NewSwapXY(expression.NewLiteral(g, types.GeomCollType{})) 91 v, err := f.Eval(sql.NewEmptyContext(), nil) 92 require.NoError(err) 93 point2 := types.Point{X: 2, Y: 1} 94 line2 := types.LineString{Points: []types.Point{{X: 2, Y: 1}, {X: 4, Y: 3}}} 95 poly2 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 1}, {X: 0, Y: 0}}}}} 96 g2 := types.GeomColl{Geoms: []types.GeometryValue{ 97 point2, 98 line2, 99 poly2, 100 }} 101 require.Equal(g2, v) 102 }) 103 104 t.Run("swap wrong type", func(t *testing.T) { 105 require := require.New(t) 106 f := NewSwapXY(expression.NewLiteral(123, types.Int64)) 107 _, err := f.Eval(sql.NewEmptyContext(), nil) 108 require.Error(err) 109 }) 110 111 t.Run("null is null", func(t *testing.T) { 112 require := require.New(t) 113 f := NewSwapXY(expression.NewLiteral(nil, types.Null)) 114 v, err := f.Eval(sql.NewEmptyContext(), nil) 115 require.NoError(err) 116 require.Equal(nil, v) 117 }) 118 119 t.Run("geometry point swap", func(t *testing.T) { 120 require := require.New(t) 121 f := NewSwapXY(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.GeometryType{})) 122 v, err := f.Eval(sql.NewEmptyContext(), nil) 123 require.NoError(err) 124 require.Equal(types.Point{X: 2, Y: 1}, v) 125 }) 126 127 t.Run("geometry linestring swap", func(t *testing.T) { 128 require := require.New(t) 129 f := NewSwapXY(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.GeometryType{})) 130 v, err := f.Eval(sql.NewEmptyContext(), nil) 131 require.NoError(err) 132 require.Equal(types.LineString{Points: []types.Point{{X: 1, Y: 0}, {X: 3, Y: 2}}}, v) 133 }) 134 135 t.Run("geometry polygon swap", func(t *testing.T) { 136 require := require.New(t) 137 f := NewSwapXY(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{})) 138 v, err := f.Eval(sql.NewEmptyContext(), nil) 139 require.NoError(err) 140 require.Equal(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}}}, v) 141 }) 142 143 t.Run("geometry multipoint swap", func(t *testing.T) { 144 require := require.New(t) 145 f := NewSwapXY(expression.NewLiteral(types.MultiPoint{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.GeometryType{})) 146 v, err := f.Eval(sql.NewEmptyContext(), nil) 147 require.NoError(err) 148 require.Equal(types.MultiPoint{Points: []types.Point{{X: 1, Y: 0}, {X: 3, Y: 2}}}, v) 149 }) 150 151 t.Run("check return type", func(t *testing.T) { 152 require := require.New(t) 153 f := NewSwapXY(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{})) 154 155 v, err := f.Eval(sql.NewEmptyContext(), nil) 156 require.NoError(err) 157 158 typ := f.Type() 159 _, _, err = typ.Convert(v) 160 require.NoError(err) 161 }) 162 }