github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/st_srid_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 TestSRID(t *testing.T) {
    28  	t.Run("select unspecified SRID is 0", func(t *testing.T) {
    29  		require := require.New(t)
    30  		f, err := NewSRID(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{}))
    31  		require.NoError(err)
    32  
    33  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    34  		require.NoError(err)
    35  		require.Equal(uint32(0), v)
    36  	})
    37  
    38  	t.Run("select specified SRID is 0", func(t *testing.T) {
    39  		require := require.New(t)
    40  		f, err := NewSRID(expression.NewLiteral(types.Point{SRID: 0, X: 1, Y: 2}, types.PointType{}))
    41  		require.NoError(err)
    42  
    43  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    44  		require.NoError(err)
    45  		require.Equal(uint32(0), v)
    46  	})
    47  
    48  	t.Run("select specified SRID is 4326", func(t *testing.T) {
    49  		require := require.New(t)
    50  		f, err := NewSRID(expression.NewLiteral(types.Point{SRID: 4326, X: 1, Y: 2}, types.PointType{}))
    51  		require.NoError(err)
    52  
    53  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    54  		require.NoError(err)
    55  		require.Equal(uint32(4326), v)
    56  	})
    57  
    58  	t.Run("change SRID to 0", func(t *testing.T) {
    59  		require := require.New(t)
    60  		f, err := NewSRID(expression.NewLiteral(types.Point{SRID: 4326, X: 1, Y: 2}, types.PointType{}),
    61  			expression.NewLiteral(0, types.Int32))
    62  		require.NoError(err)
    63  
    64  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    65  		require.NoError(err)
    66  		require.Equal(types.Point{SRID: 0, X: 1, Y: 2}, v)
    67  	})
    68  
    69  	t.Run("change SRID to 4326", func(t *testing.T) {
    70  		require := require.New(t)
    71  		f, err := NewSRID(expression.NewLiteral(types.Point{SRID: 0, X: 123.4, Y: 56.789}, types.PointType{}),
    72  			expression.NewLiteral(4326, types.Int32))
    73  		require.NoError(err)
    74  
    75  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    76  		require.NoError(err)
    77  		require.Equal(types.Point{SRID: 4326, X: 123.4, Y: 56.789}, v)
    78  	})
    79  
    80  	t.Run("change SRID to invalid 1234", func(t *testing.T) {
    81  		require := require.New(t)
    82  		f, err := NewSRID(expression.NewLiteral(types.Point{SRID: 0, X: 123.4, Y: 56.789}, types.PointType{}),
    83  			expression.NewLiteral(1234, types.Int32))
    84  		require.NoError(err)
    85  
    86  		_, err = f.Eval(sql.NewEmptyContext(), nil)
    87  		require.Error(err)
    88  	})
    89  
    90  	t.Run("invalid number of arguments, 0", func(t *testing.T) {
    91  		require := require.New(t)
    92  		_, err := NewSRID()
    93  		require.Error(err)
    94  	})
    95  
    96  	t.Run("change SRID of linestring to 4326", func(t *testing.T) {
    97  		require := require.New(t)
    98  		f, err := NewSRID(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, types.LineStringType{}),
    99  			expression.NewLiteral(4326, types.Int32))
   100  		require.NoError(err)
   101  
   102  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   103  		require.NoError(err)
   104  		require.Equal(types.LineString{SRID: 4326, Points: []types.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}, v)
   105  	})
   106  
   107  	t.Run("change SRID of polygon to 4326", func(t *testing.T) {
   108  		require := require.New(t)
   109  		f, err := NewSRID(expression.NewLiteral(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 0, Y: 0}}}}}, types.PolygonType{}),
   110  			expression.NewLiteral(4326, types.Int32))
   111  		require.NoError(err)
   112  
   113  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   114  		require.NoError(err)
   115  		require.Equal(types.Polygon{SRID: 4326, Lines: []types.LineString{{SRID: 4326, Points: []types.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 0, Y: 1}, {SRID: 4326, X: 1, Y: 1}, {SRID: 4326, X: 0, Y: 0}}}}}, v)
   116  	})
   117  
   118  	t.Run("select srid of geometry with inner point", func(t *testing.T) {
   119  		require := require.New(t)
   120  
   121  		f, err := NewSRID(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.GeometryType{}))
   122  		require.NoError(err)
   123  
   124  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   125  		require.NoError(err)
   126  		require.Equal(uint32(0), v)
   127  	})
   128  
   129  	t.Run("select srid of geometry with inner linestring", func(t *testing.T) {
   130  		require := require.New(t)
   131  
   132  		f, err := NewSRID(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, types.GeometryType{}))
   133  		require.NoError(err)
   134  
   135  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   136  		require.NoError(err)
   137  		require.Equal(uint32(0), v)
   138  	})
   139  
   140  	t.Run("select srid of geometry with inner polygon", func(t *testing.T) {
   141  		require := require.New(t)
   142  
   143  		f, err := NewSRID(expression.NewLiteral(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 0, Y: 0}}}}}, types.GeometryType{}))
   144  		require.NoError(err)
   145  
   146  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   147  		require.NoError(err)
   148  		require.Equal(uint32(0), v)
   149  	})
   150  
   151  	t.Run("select srid of geometry with inner multipoint", func(t *testing.T) {
   152  		require := require.New(t)
   153  
   154  		f, err := NewSRID(expression.NewLiteral(types.MultiPoint{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, types.GeometryType{}))
   155  		require.NoError(err)
   156  
   157  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   158  		require.NoError(err)
   159  		require.Equal(uint32(0), v)
   160  	})
   161  
   162  	t.Run("select srid of geometry with inner multilinestring", func(t *testing.T) {
   163  		require := require.New(t)
   164  
   165  		f, err := NewSRID(expression.NewLiteral(types.MultiLineString{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 0, Y: 0}}}}}, types.GeometryType{}))
   166  		require.NoError(err)
   167  
   168  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   169  		require.NoError(err)
   170  		require.Equal(uint32(0), v)
   171  	})
   172  
   173  	t.Run("select srid of geometry with inner multipolygon", func(t *testing.T) {
   174  		require := require.New(t)
   175  		line := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 0}}}
   176  		poly := types.Polygon{Lines: []types.LineString{line}}
   177  		f, err := NewSRID(expression.NewLiteral(types.MultiPolygon{Polygons: []types.Polygon{poly}}, types.GeometryType{}))
   178  		require.NoError(err)
   179  
   180  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   181  		require.NoError(err)
   182  		require.Equal(uint32(0), v)
   183  	})
   184  
   185  	t.Run("change srid of geometry with inner point to 4326", func(t *testing.T) {
   186  		require := require.New(t)
   187  
   188  		f, err := NewSRID(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.GeometryType{}),
   189  			expression.NewLiteral(4326, types.Int32))
   190  		require.NoError(err)
   191  
   192  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   193  		require.NoError(err)
   194  		require.Equal(types.Point{SRID: 4326, X: 1, Y: 2}, v)
   195  	})
   196  
   197  	t.Run("change srid of geometry with inner linestring to 4326", func(t *testing.T) {
   198  		require := require.New(t)
   199  
   200  		f, err := NewSRID(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, types.GeometryType{}),
   201  			expression.NewLiteral(4326, types.Int32))
   202  		require.NoError(err)
   203  
   204  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   205  		require.NoError(err)
   206  		require.Equal(types.LineString{SRID: 4326, Points: []types.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}, v)
   207  	})
   208  
   209  	t.Run("change srid of geometry with inner polygon to 4326", func(t *testing.T) {
   210  		require := require.New(t)
   211  
   212  		f, err := NewSRID(expression.NewLiteral(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 0, Y: 0}}}}}, types.GeometryType{}),
   213  			expression.NewLiteral(4326, types.Int32))
   214  		require.NoError(err)
   215  
   216  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   217  		require.NoError(err)
   218  		require.Equal(types.Polygon{SRID: 4326, Lines: []types.LineString{{SRID: 4326, Points: []types.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 0, Y: 1}, {SRID: 4326, X: 1, Y: 1}, {SRID: 4326, X: 0, Y: 0}}}}}, v)
   219  	})
   220  
   221  	t.Run("change srid of geometry with inner multipoint to 4326", func(t *testing.T) {
   222  		require := require.New(t)
   223  
   224  		f, err := NewSRID(expression.NewLiteral(types.MultiPoint{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, types.GeometryType{}),
   225  			expression.NewLiteral(4326, types.Int32))
   226  		require.NoError(err)
   227  
   228  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   229  		require.NoError(err)
   230  		require.Equal(types.MultiPoint{SRID: 4326, Points: []types.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}, v)
   231  	})
   232  
   233  	t.Run("change srid of geometry with inner multilinestring", func(t *testing.T) {
   234  		require := require.New(t)
   235  
   236  		f, err := NewSRID(expression.NewLiteral(types.MultiLineString{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 0, Y: 0}}}}}, types.GeometryType{}),
   237  			expression.NewLiteral(4326, types.Int32))
   238  		require.NoError(err)
   239  
   240  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   241  		require.NoError(err)
   242  		require.Equal(types.MultiLineString{SRID: 4326, Lines: []types.LineString{{SRID: 4326, Points: []types.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 0, Y: 1}, {SRID: 4326, X: 1, Y: 1}, {SRID: 4326, X: 0, Y: 0}}}}}, v)
   243  	})
   244  
   245  	t.Run("change srid of geometry with inner multipolygon", func(t *testing.T) {
   246  		require := require.New(t)
   247  		line := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 0}}}
   248  		poly := types.Polygon{Lines: []types.LineString{line}}
   249  		f, err := NewSRID(expression.NewLiteral(types.MultiPolygon{SRID: 0, Polygons: []types.Polygon{poly}}, types.GeometryType{}),
   250  			expression.NewLiteral(4326, types.Int32))
   251  		require.NoError(err)
   252  
   253  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   254  		require.NoError(err)
   255  		line2 := types.LineString{SRID: 4326, Points: []types.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 1, Y: 0}, {SRID: 4326, X: 1, Y: 1}, {SRID: 4326, X: 0, Y: 0}}}
   256  		poly2 := types.Polygon{SRID: 4326, Lines: []types.LineString{line2}}
   257  		require.Equal(types.MultiPolygon{SRID: 4326, Polygons: []types.Polygon{poly2}}, v)
   258  	})
   259  
   260  	t.Run("change srid of geometry with inner geometry collection", func(t *testing.T) {
   261  		require := require.New(t)
   262  		point := types.Point{X: 1, Y: 2}
   263  		line := types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}
   264  		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}}}}}
   265  		g := types.GeomColl{Geoms: []types.GeometryValue{
   266  			point,
   267  			line,
   268  			poly,
   269  		}}
   270  		f, err := NewSRID(expression.NewLiteral(g, types.GeometryType{}),
   271  			expression.NewLiteral(4326, types.Int32))
   272  		require.NoError(err)
   273  
   274  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   275  		require.NoError(err)
   276  		point2 := types.Point{SRID: 4326, X: 1, Y: 2}
   277  		line2 := types.LineString{SRID: 4326, Points: []types.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}
   278  		poly2 := types.Polygon{SRID: 4326, Lines: []types.LineString{{SRID: 4326, Points: []types.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 1, Y: 1}, {SRID: 4326, X: 1, Y: 0}, {SRID: 4326, X: 0, Y: 0}}}}}
   279  		g2 := types.GeomColl{SRID: 4326, Geoms: []types.GeometryValue{
   280  			point2,
   281  			line2,
   282  			poly2,
   283  		}}
   284  		require.Equal(g2, v)
   285  	})
   286  
   287  	t.Run("return type with one argument", func(t *testing.T) {
   288  		require := require.New(t)
   289  		f, err := NewSRID(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{}))
   290  		require.NoError(err)
   291  
   292  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   293  		require.NoError(err)
   294  
   295  		typ := f.Type()
   296  		_, _, err = typ.Convert(v)
   297  		require.NoError(err)
   298  	})
   299  
   300  	t.Run("return type with two arguments", func(t *testing.T) {
   301  		require := require.New(t)
   302  		f, err := NewSRID(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, types.LineStringType{}),
   303  			expression.NewLiteral(4326, types.Int32))
   304  		require.NoError(err)
   305  
   306  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   307  		require.NoError(err)
   308  
   309  		typ := f.Type()
   310  		_, _, err = typ.Convert(v)
   311  		require.NoError(err)
   312  	})
   313  }