github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/wkt_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 TestAsWKT(t *testing.T) { 28 t.Run("convert point", func(t *testing.T) { 29 require := require.New(t) 30 f := NewAsWKT(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("POINT(1 2)", v) 34 }) 35 36 t.Run("convert point with negative floats", func(t *testing.T) { 37 require := require.New(t) 38 f := NewAsWKT(expression.NewLiteral(types.Point{X: -123.45, Y: 678.9}, types.PointType{})) 39 v, err := f.Eval(sql.NewEmptyContext(), nil) 40 require.NoError(err) 41 require.Equal("POINT(-123.45 678.9)", v) 42 }) 43 44 t.Run("convert linestring", func(t *testing.T) { 45 require := require.New(t) 46 f := NewAsWKT(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, types.LineStringType{})) 47 v, err := f.Eval(sql.NewEmptyContext(), nil) 48 require.NoError(err) 49 require.Equal("LINESTRING(1 2,3 4)", v) 50 }) 51 52 t.Run("convert polygon", func(t *testing.T) { 53 require := require.New(t) 54 f := NewAsWKT(expression.NewLiteral(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}}}, types.PolygonType{})) 55 v, err := f.Eval(sql.NewEmptyContext(), nil) 56 require.NoError(err) 57 require.Equal("POLYGON((0 0,1 1,1 0,0 0))", v) 58 }) 59 60 t.Run("convert multipoint", func(t *testing.T) { 61 require := require.New(t) 62 f := NewAsWKT(expression.NewLiteral(types.MultiPoint{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, types.LineStringType{})) 63 v, err := f.Eval(sql.NewEmptyContext(), nil) 64 require.NoError(err) 65 require.Equal("MULTIPOINT(1 2,3 4)", v) 66 }) 67 68 t.Run("convert multilinestring", func(t *testing.T) { 69 require := require.New(t) 70 f := NewAsWKT(expression.NewLiteral(types.MultiLineString{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}}}, types.MultiLineStringType{})) 71 v, err := f.Eval(sql.NewEmptyContext(), nil) 72 require.NoError(err) 73 require.Equal("MULTILINESTRING((0 0,1 1,1 0,0 0))", v) 74 }) 75 76 t.Run("convert multipolygon", func(t *testing.T) { 77 require := require.New(t) 78 line1 := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 0}, {X: 0, Y: 0}, {X: 0, Y: 0}}} 79 poly1 := types.Polygon{Lines: []types.LineString{line1}} 80 line2 := types.LineString{Points: []types.Point{{X: 1, Y: 1}, {X: 1, Y: 1}, {X: 1, Y: 1}, {X: 1, Y: 1}}} 81 poly2 := types.Polygon{Lines: []types.LineString{line2}} 82 f := NewAsWKT(expression.NewLiteral(types.MultiPolygon{Polygons: []types.Polygon{poly1, poly2}}, types.MultiPolygonType{})) 83 v, err := f.Eval(sql.NewEmptyContext(), nil) 84 require.NoError(err) 85 require.Equal("MULTIPOLYGON(((0 0,0 0,0 0,0 0)),((1 1,1 1,1 1,1 1)))", v) 86 }) 87 88 t.Run("convert empty geometry collections", func(t *testing.T) { 89 require := require.New(t) 90 f := NewAsWKT(expression.NewLiteral(types.GeomColl{}, types.GeomCollType{})) 91 v, err := f.Eval(sql.NewEmptyContext(), nil) 92 require.NoError(err) 93 require.Equal("GEOMETRYCOLLECTION()", v) 94 }) 95 96 t.Run("convert geometry collections", func(t *testing.T) { 97 require := require.New(t) 98 point := types.Point{X: 1, Y: 2} 99 line := types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}} 100 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}}}}} 101 mpoint := types.MultiPoint{Points: []types.Point{point, point}} 102 mline := types.MultiLineString{Lines: []types.LineString{line, line}} 103 mpoly := types.MultiPolygon{Polygons: []types.Polygon{poly, poly}} 104 gColl := types.GeomColl{} 105 g := types.GeomColl{Geoms: []types.GeometryValue{ 106 point, 107 line, 108 poly, 109 mpoint, 110 mline, 111 mpoly, 112 gColl, 113 }} 114 f := NewAsWKT(expression.NewLiteral(g, types.GeomCollType{})) 115 v, err := f.Eval(sql.NewEmptyContext(), nil) 116 require.NoError(err) 117 require.Equal("GEOMETRYCOLLECTION("+ 118 "POINT(1 2),"+ 119 "LINESTRING(1 2,3 4),"+ 120 "POLYGON((0 0,1 1,1 0,0 0)),"+ 121 "MULTIPOINT(1 2,1 2),"+ 122 "MULTILINESTRING((1 2,3 4),(1 2,3 4)),"+ 123 "MULTIPOLYGON(((0 0,1 1,1 0,0 0)),((0 0,1 1,1 0,0 0))),"+ 124 "GEOMETRYCOLLECTION()"+ 125 ")", v) 126 }) 127 128 t.Run("convert null", func(t *testing.T) { 129 require := require.New(t) 130 f := NewAsWKT(expression.NewLiteral(nil, types.Null)) 131 v, err := f.Eval(sql.NewEmptyContext(), nil) 132 require.NoError(err) 133 require.Equal(nil, v) 134 }) 135 136 t.Run("provide wrong type", func(t *testing.T) { 137 require := require.New(t) 138 f := NewAsWKT(expression.NewLiteral("notageometry", types.Blob)) 139 _, err := f.Eval(sql.NewEmptyContext(), nil) 140 require.Error(err) 141 }) 142 143 t.Run("check return type", func(t *testing.T) { 144 require := require.New(t) 145 f := NewAsWKT(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{})) 146 v, err := f.Eval(sql.NewEmptyContext(), nil) 147 require.NoError(err) 148 149 typ := f.Type() 150 _, _, err = typ.Convert(v) 151 require.NoError(err) 152 }) 153 } 154 155 func TestGeomFromText(t *testing.T) { 156 t.Run("create valid point with well formatted string", func(t *testing.T) { 157 require := require.New(t) 158 f, err := NewGeomFromText(expression.NewLiteral("POINT(1 2)", types.Blob)) 159 require.NoError(err) 160 161 v, err := f.Eval(sql.NewEmptyContext(), nil) 162 require.NoError(err) 163 require.Equal(types.Point{X: 1, Y: 2}, v) 164 }) 165 166 t.Run("create valid point with well formatted float", func(t *testing.T) { 167 require := require.New(t) 168 f, err := NewGeomFromText(expression.NewLiteral("POINT(123.456 789.0)", types.Blob)) 169 require.NoError(err) 170 171 v, err := f.Eval(sql.NewEmptyContext(), nil) 172 require.NoError(err) 173 require.Equal(types.Point{X: 123.456, Y: 789}, v) 174 }) 175 176 t.Run("create valid point with whitespace string", func(t *testing.T) { 177 require := require.New(t) 178 f, err := NewGeomFromText(expression.NewLiteral(" POINT ( 1 2 ) ", types.Blob)) 179 require.NoError(err) 180 181 v, err := f.Eval(sql.NewEmptyContext(), nil) 182 require.NoError(err) 183 require.Equal(types.Point{X: 1, Y: 2}, v) 184 }) 185 186 t.Run("null string returns null", func(t *testing.T) { 187 require := require.New(t) 188 f, err := NewGeomFromText(expression.NewLiteral(nil, types.Null)) 189 require.NoError(err) 190 191 v, err := f.Eval(sql.NewEmptyContext(), nil) 192 require.NoError(err) 193 require.Equal(nil, v) 194 }) 195 196 t.Run("create point with bad string", func(t *testing.T) { 197 require := require.New(t) 198 f, err := NewGeomFromText(expression.NewLiteral("badpoint(1 2)", types.Blob)) 199 require.NoError(err) 200 201 _, err = f.Eval(sql.NewEmptyContext(), nil) 202 require.Error(err) 203 }) 204 205 t.Run("create valid linestring with well formatted string", func(t *testing.T) { 206 require := require.New(t) 207 f, err := NewGeomFromText(expression.NewLiteral("LINESTRING(1 2, 3 4)", types.Blob)) 208 require.NoError(err) 209 210 v, err := f.Eval(sql.NewEmptyContext(), nil) 211 require.NoError(err) 212 require.Equal(types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, v) 213 }) 214 215 t.Run("create valid linestring with float", func(t *testing.T) { 216 require := require.New(t) 217 f, err := NewGeomFromText(expression.NewLiteral("LINESTRING(123.456 789.0, 987.654 321.0)", types.Blob)) 218 require.NoError(err) 219 220 v, err := f.Eval(sql.NewEmptyContext(), nil) 221 require.NoError(err) 222 require.Equal(types.LineString{Points: []types.Point{{X: 123.456, Y: 789}, {X: 987.654, Y: 321}}}, v) 223 }) 224 225 t.Run("create valid linestring with whitespace string", func(t *testing.T) { 226 require := require.New(t) 227 f, err := NewGeomFromText(expression.NewLiteral(" LINESTRING ( 1 2 , 3 4 ) ", types.Blob)) 228 require.NoError(err) 229 230 v, err := f.Eval(sql.NewEmptyContext(), nil) 231 require.NoError(err) 232 require.Equal(types.LineString{Points: []types.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}, v) 233 }) 234 235 t.Run("null string returns null", func(t *testing.T) { 236 require := require.New(t) 237 f, err := NewGeomFromText(expression.NewLiteral(nil, types.Null)) 238 require.NoError(err) 239 240 v, err := f.Eval(sql.NewEmptyContext(), nil) 241 require.NoError(err) 242 require.Equal(nil, v) 243 }) 244 245 t.Run("create linestring with bad string", func(t *testing.T) { 246 require := require.New(t) 247 f, err := NewGeomFromText(expression.NewLiteral("badlinestring(1 2)", types.Blob)) 248 require.NoError(err) 249 250 _, err = f.Eval(sql.NewEmptyContext(), nil) 251 require.Error(err) 252 }) 253 254 t.Run("create valid polygon with well formatted string", func(t *testing.T) { 255 require := require.New(t) 256 f, err := NewGeomFromText(expression.NewLiteral("POLYGON((0 0, 0 1, 1 0, 0 0))", types.Blob)) 257 require.NoError(err) 258 259 v, err := f.Eval(sql.NewEmptyContext(), nil) 260 require.NoError(err) 261 require.Equal(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}}}, v) 262 }) 263 264 t.Run("create valid polygon with multiple lines", func(t *testing.T) { 265 require := require.New(t) 266 f, err := NewGeomFromText(expression.NewLiteral("POLYGON((0 0, 0 1, 1 0, 0 0), (0 0, 1 0, 1 1, 0 1, 0 0))", types.Blob)) 267 require.NoError(err) 268 269 v, err := f.Eval(sql.NewEmptyContext(), nil) 270 require.NoError(err) 271 require.Equal(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}, {Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 1}, {X: 0, Y: 0}}}}}, v) 272 }) 273 274 t.Run("create valid linestring with whitespace string", func(t *testing.T) { 275 require := require.New(t) 276 f, err := NewGeomFromText(expression.NewLiteral(" POLYGON ( ( 0 0 , 0 1 , 1 0 , 0 0 ) ) ", types.Blob)) 277 require.NoError(err) 278 279 v, err := f.Eval(sql.NewEmptyContext(), nil) 280 require.NoError(err) 281 require.Equal(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 0}, {X: 0, Y: 0}}}}}, v) 282 }) 283 284 t.Run("null string returns null", func(t *testing.T) { 285 require := require.New(t) 286 f, err := NewGeomFromText(expression.NewLiteral(nil, types.Null)) 287 require.NoError(err) 288 289 v, err := f.Eval(sql.NewEmptyContext(), nil) 290 require.NoError(err) 291 require.Equal(nil, v) 292 }) 293 294 t.Run("null srid returns null", func(t *testing.T) { 295 require := require.New(t) 296 f, err := NewGeomFromText(expression.NewLiteral("POINT(1 2)", types.Blob), 297 expression.NewLiteral(nil, types.Null)) 298 require.NoError(err) 299 300 v, err := f.Eval(sql.NewEmptyContext(), nil) 301 require.NoError(err) 302 require.Equal(nil, v) 303 }) 304 305 t.Run("null axis options returns null", func(t *testing.T) { 306 require := require.New(t) 307 f, err := NewGeomFromText(expression.NewLiteral("POINT(1 2)", types.Blob), 308 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32), 309 expression.NewLiteral(nil, types.Null)) 310 require.NoError(err) 311 312 v, err := f.Eval(sql.NewEmptyContext(), nil) 313 require.NoError(err) 314 require.Equal(nil, v) 315 }) 316 317 t.Run("create polygon with non linear ring", func(t *testing.T) { 318 require := require.New(t) 319 f, err := NewGeomFromText(expression.NewLiteral("polygon((1 2, 3 4))", types.Blob)) 320 require.NoError(err) 321 322 _, err = f.Eval(sql.NewEmptyContext(), nil) 323 require.Error(err) 324 }) 325 326 t.Run("create polygon with bad string", func(t *testing.T) { 327 require := require.New(t) 328 f, err := NewGeomFromText(expression.NewLiteral("badlinestring(1 2)", types.Blob)) 329 require.NoError(err) 330 331 _, err = f.Eval(sql.NewEmptyContext(), nil) 332 require.Error(err) 333 }) 334 335 t.Run("create valid point with valid srid", func(t *testing.T) { 336 require := require.New(t) 337 f, err := NewGeomFromText(expression.NewLiteral("POINT(1 2)", types.Blob), 338 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32)) 339 require.NoError(err) 340 341 v, err := f.Eval(sql.NewEmptyContext(), nil) 342 require.NoError(err) 343 require.Equal(types.Point{SRID: types.GeoSpatialSRID, X: 2, Y: 1}, v) 344 }) 345 346 t.Run("create valid point with another valid srid", func(t *testing.T) { 347 require := require.New(t) 348 f, err := NewGeomFromText(expression.NewLiteral("POINT(1 2)", types.Blob), 349 expression.NewLiteral(3857, types.Uint32)) 350 require.NoError(err) 351 352 v, err := f.Eval(sql.NewEmptyContext(), nil) 353 require.NoError(err) 354 require.Equal(types.Point{SRID: 3857, X: 1, Y: 2}, v) 355 }) 356 357 t.Run("create valid point with invalid srid", func(t *testing.T) { 358 require := require.New(t) 359 f, err := NewGeomFromText(expression.NewLiteral("POINT(1 2)", types.Blob), 360 expression.NewLiteral(4320, types.Uint32)) 361 require.NoError(err) 362 363 _, err = f.Eval(sql.NewEmptyContext(), nil) 364 require.Error(err) 365 }) 366 367 t.Run("create valid point with srid and axis order long lat", func(t *testing.T) { 368 require := require.New(t) 369 f, err := NewGeomFromText(expression.NewLiteral("POINT(1 2)", types.Blob), 370 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32), 371 expression.NewLiteral("axis-order=long-lat", types.Blob)) 372 require.NoError(err) 373 374 v, err := f.Eval(sql.NewEmptyContext(), nil) 375 require.NoError(err) 376 require.Equal(types.Point{SRID: types.GeoSpatialSRID, X: 2, Y: 1}, v) 377 }) 378 379 t.Run("create valid linestring with valid srid", func(t *testing.T) { 380 require := require.New(t) 381 f, err := NewGeomFromText(expression.NewLiteral("LINESTRING(1 2, 3 4)", types.Blob), 382 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32)) 383 require.NoError(err) 384 385 v, err := f.Eval(sql.NewEmptyContext(), nil) 386 require.NoError(err) 387 require.Equal(types.LineString{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 2, Y: 1}, {SRID: types.GeoSpatialSRID, X: 4, Y: 3}}}, v) 388 }) 389 390 t.Run("create valid linestring with invalid srid", func(t *testing.T) { 391 require := require.New(t) 392 f, err := NewGeomFromText(expression.NewLiteral("LINESTRING(1 2, 3 4)", types.Blob), 393 expression.NewLiteral(1, types.Uint32)) 394 require.NoError(err) 395 396 _, err = f.Eval(sql.NewEmptyContext(), nil) 397 require.Error(err) 398 }) 399 400 t.Run("create valid linestring with srid and axis order long lat", func(t *testing.T) { 401 require := require.New(t) 402 f, err := NewGeomFromText(expression.NewLiteral("LINESTRING(1 2, 3 4)", types.Blob), 403 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32), 404 expression.NewLiteral("axis-order=long-lat", types.Blob)) 405 require.NoError(err) 406 407 v, err := f.Eval(sql.NewEmptyContext(), nil) 408 require.NoError(err) 409 require.Equal(types.LineString{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 2, Y: 1}, {SRID: types.GeoSpatialSRID, X: 4, Y: 3}}}, v) 410 }) 411 412 t.Run("create valid polygon with valid srid", func(t *testing.T) { 413 require := require.New(t) 414 f, err := NewGeomFromText(expression.NewLiteral("POLYGON((0 0, 0 1, 1 0, 0 0))", types.Blob), 415 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32)) 416 require.NoError(err) 417 418 v, err := f.Eval(sql.NewEmptyContext(), nil) 419 require.NoError(err) 420 require.Equal(types.Polygon{SRID: types.GeoSpatialSRID, Lines: []types.LineString{{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 0, Y: 0}, {SRID: types.GeoSpatialSRID, X: 1, Y: 0}, {SRID: types.GeoSpatialSRID, X: 0, Y: 1}, {SRID: types.GeoSpatialSRID, X: 0, Y: 0}}}}}, v) 421 }) 422 423 t.Run("create valid polygon with invalid srid", func(t *testing.T) { 424 require := require.New(t) 425 f, err := NewGeomFromText(expression.NewLiteral("POLYGON((0 0, 0 1, 1 0, 0 0))", types.Blob), 426 expression.NewLiteral(1234, types.Uint32)) 427 require.NoError(err) 428 429 _, err = f.Eval(sql.NewEmptyContext(), nil) 430 require.Error(err) 431 }) 432 433 t.Run("create valid polygon with srid", func(t *testing.T) { 434 require := require.New(t) 435 f, err := NewGeomFromText(expression.NewLiteral("POLYGON((0 0, 0 1, 1 0, 0 0))", types.Blob), 436 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32), 437 expression.NewLiteral("axis-order=long-lat", types.Blob)) 438 require.NoError(err) 439 440 v, err := f.Eval(sql.NewEmptyContext(), nil) 441 require.NoError(err) 442 require.Equal(types.Polygon{SRID: types.GeoSpatialSRID, Lines: []types.LineString{{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 0, Y: 0}, {SRID: types.GeoSpatialSRID, X: 1, Y: 0}, {SRID: types.GeoSpatialSRID, X: 0, Y: 1}, {SRID: types.GeoSpatialSRID, X: 0, Y: 0}}}}}, v) 443 }) 444 445 t.Run("create valid multipoint with valid srid", func(t *testing.T) { 446 require := require.New(t) 447 f, err := NewGeomFromText(expression.NewLiteral("MULTIPOINT(1 2, 3 4)", types.Blob), 448 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32)) 449 require.NoError(err) 450 451 v, err := f.Eval(sql.NewEmptyContext(), nil) 452 require.NoError(err) 453 require.Equal(types.MultiPoint{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 2, Y: 1}, {SRID: types.GeoSpatialSRID, X: 4, Y: 3}}}, v) 454 }) 455 456 t.Run("create valid multipoint with invalid srid", func(t *testing.T) { 457 require := require.New(t) 458 f, err := NewGeomFromText(expression.NewLiteral("MULTIPOINT(1 2, 3 4)", types.Blob), 459 expression.NewLiteral(1, types.Uint32)) 460 require.NoError(err) 461 462 _, err = f.Eval(sql.NewEmptyContext(), nil) 463 require.Error(err) 464 }) 465 466 t.Run("create valid multipoint with srid and axis order long lat", func(t *testing.T) { 467 require := require.New(t) 468 f, err := NewGeomFromText(expression.NewLiteral("MULTIPOINT(1 2, 3 4)", types.Blob), 469 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32), 470 expression.NewLiteral("axis-order=long-lat", types.Blob)) 471 require.NoError(err) 472 473 v, err := f.Eval(sql.NewEmptyContext(), nil) 474 require.NoError(err) 475 require.Equal(types.MultiPoint{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 2, Y: 1}, {SRID: types.GeoSpatialSRID, X: 4, Y: 3}}}, v) 476 }) 477 478 t.Run("create valid multilinestring with valid srid", func(t *testing.T) { 479 require := require.New(t) 480 f, err := NewGeomFromText(expression.NewLiteral("MULTILINESTRING((0 0, 0 1, 1 0, 0 0))", types.Blob), 481 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32)) 482 require.NoError(err) 483 484 v, err := f.Eval(sql.NewEmptyContext(), nil) 485 require.NoError(err) 486 require.Equal(types.MultiLineString{SRID: types.GeoSpatialSRID, Lines: []types.LineString{{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 0, Y: 0}, {SRID: types.GeoSpatialSRID, X: 1, Y: 0}, {SRID: types.GeoSpatialSRID, X: 0, Y: 1}, {SRID: types.GeoSpatialSRID, X: 0, Y: 0}}}}}, v) 487 }) 488 489 t.Run("create valid multilinestring with invalid srid", func(t *testing.T) { 490 require := require.New(t) 491 f, err := NewGeomFromText(expression.NewLiteral("MULTILINESTRING((0 0, 0 1, 1 0, 0 0))", types.Blob), 492 expression.NewLiteral(1234, types.Uint32)) 493 require.NoError(err) 494 495 _, err = f.Eval(sql.NewEmptyContext(), nil) 496 require.Error(err) 497 }) 498 499 t.Run("create valid multilinestring with srid", func(t *testing.T) { 500 require := require.New(t) 501 f, err := NewGeomFromText(expression.NewLiteral("MULTILINESTRING((0 0, 0 1, 1 0, 0 0))", types.Blob), 502 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32), 503 expression.NewLiteral("axis-order=long-lat", types.Blob)) 504 require.NoError(err) 505 506 v, err := f.Eval(sql.NewEmptyContext(), nil) 507 require.NoError(err) 508 require.Equal(types.MultiLineString{SRID: types.GeoSpatialSRID, Lines: []types.LineString{{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 0, Y: 0}, {SRID: types.GeoSpatialSRID, X: 1, Y: 0}, {SRID: types.GeoSpatialSRID, X: 0, Y: 1}, {SRID: types.GeoSpatialSRID, X: 0, Y: 0}}}}}, v) 509 }) 510 511 t.Run("create valid multipolygon with valid srid", func(t *testing.T) { 512 require := require.New(t) 513 f, err := NewGeomFromText(expression.NewLiteral("MULTIPOLYGON(((0 0,0 0,0 0,0 0)),((1 1,1 1,1 1,1 1)))", types.Blob), 514 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32)) 515 require.NoError(err) 516 517 v, err := f.Eval(sql.NewEmptyContext(), nil) 518 require.NoError(err) 519 line1 := types.LineString{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 0, Y: 0}, {SRID: types.GeoSpatialSRID, X: 0, Y: 0}, {SRID: types.GeoSpatialSRID, X: 0, Y: 0}, {SRID: types.GeoSpatialSRID, X: 0, Y: 0}}} 520 poly1 := types.Polygon{SRID: types.GeoSpatialSRID, Lines: []types.LineString{line1}} 521 line2 := types.LineString{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 1, Y: 1}, {SRID: types.GeoSpatialSRID, X: 1, Y: 1}, {SRID: types.GeoSpatialSRID, X: 1, Y: 1}, {SRID: types.GeoSpatialSRID, X: 1, Y: 1}}} 522 poly2 := types.Polygon{SRID: types.GeoSpatialSRID, Lines: []types.LineString{line2}} 523 require.Equal(types.MultiPolygon{SRID: types.GeoSpatialSRID, Polygons: []types.Polygon{poly1, poly2}}, v) 524 }) 525 526 t.Run("create valid multipolygon with invalid srid", func(t *testing.T) { 527 require := require.New(t) 528 f, err := NewGeomFromText(expression.NewLiteral("MULTIPOLYGON(((0 0,0 0,0 0,0 0)),((1 1,1 1,1 1,1 1)))", types.Blob), 529 expression.NewLiteral(1234, types.Uint32)) 530 require.NoError(err) 531 532 _, err = f.Eval(sql.NewEmptyContext(), nil) 533 require.Error(err) 534 }) 535 536 t.Run("create valid multipolygon with srid", func(t *testing.T) { 537 require := require.New(t) 538 f, err := NewGeomFromText(expression.NewLiteral("MULTIPOLYGON(((0 0,1 2,3 4,0 0)),((1 1,2 3,4 5,1 1)))", types.Blob), 539 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32), 540 expression.NewLiteral("axis-order=long-lat", types.Blob)) 541 require.NoError(err) 542 543 v, err := f.Eval(sql.NewEmptyContext(), nil) 544 require.NoError(err) 545 line1 := types.LineString{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 0, Y: 0}, {SRID: types.GeoSpatialSRID, X: 2, Y: 1}, {SRID: types.GeoSpatialSRID, X: 4, Y: 3}, {SRID: types.GeoSpatialSRID, X: 0, Y: 0}}} 546 poly1 := types.Polygon{SRID: types.GeoSpatialSRID, Lines: []types.LineString{line1}} 547 line2 := types.LineString{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 1, Y: 1}, {SRID: types.GeoSpatialSRID, X: 3, Y: 2}, {SRID: types.GeoSpatialSRID, X: 5, Y: 4}, {SRID: types.GeoSpatialSRID, X: 1, Y: 1}}} 548 poly2 := types.Polygon{SRID: types.GeoSpatialSRID, Lines: []types.LineString{line2}} 549 require.Equal(types.MultiPolygon{SRID: types.GeoSpatialSRID, Polygons: []types.Polygon{poly1, poly2}}, v) 550 }) 551 552 t.Run("create valid geometry collection with srid", func(t *testing.T) { 553 require := require.New(t) 554 f, err := NewGeomFromText( 555 expression.NewLiteral("GEOMETRYCOLLECTION("+ 556 "POINT(1 2),"+ 557 "LINESTRING(1 2,3 4),"+ 558 "POLYGON((0 0,1 1,1 0,0 0)),"+ 559 "MULTIPOINT(1 2,1 2),"+ 560 "MULTILINESTRING((1 2,3 4),(1 2,3 4)),"+ 561 "MULTIPOLYGON(((0 0,1 1,1 0,0 0)),((0 0,1 1,1 0,0 0))),"+ 562 "GEOMETRYCOLLECTION()"+ 563 ")", types.Blob), 564 expression.NewLiteral(types.GeoSpatialSRID, types.Uint32)) 565 566 point := types.Point{SRID: types.GeoSpatialSRID, X: 2, Y: 1} 567 line := types.LineString{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 2, Y: 1}, {SRID: types.GeoSpatialSRID, X: 4, Y: 3}}} 568 poly := types.Polygon{SRID: types.GeoSpatialSRID, Lines: []types.LineString{{SRID: types.GeoSpatialSRID, Points: []types.Point{{SRID: types.GeoSpatialSRID, X: 0, Y: 0}, {SRID: types.GeoSpatialSRID, X: 1, Y: 1}, {SRID: types.GeoSpatialSRID, X: 0, Y: 1}, {SRID: types.GeoSpatialSRID, X: 0, Y: 0}}}}} 569 mpoint := types.MultiPoint{SRID: types.GeoSpatialSRID, Points: []types.Point{point, point}} 570 mline := types.MultiLineString{SRID: types.GeoSpatialSRID, Lines: []types.LineString{line, line}} 571 mpoly := types.MultiPolygon{SRID: types.GeoSpatialSRID, Polygons: []types.Polygon{poly, poly}} 572 gColl := types.GeomColl{SRID: types.GeoSpatialSRID, Geoms: []types.GeometryValue{}} 573 g := types.GeomColl{SRID: types.GeoSpatialSRID, Geoms: []types.GeometryValue{ 574 point, 575 line, 576 poly, 577 mpoint, 578 mline, 579 mpoly, 580 gColl, 581 }} 582 v, err := f.Eval(sql.NewEmptyContext(), nil) 583 require.NoError(err) 584 require.Equal(g, v) 585 }) 586 587 t.Run("create valid geometry collection with another srid", func(t *testing.T) { 588 require := require.New(t) 589 f, err := NewGeomFromText( 590 expression.NewLiteral("GEOMETRYCOLLECTION("+ 591 "POINT(1 2),"+ 592 "LINESTRING(1 2,3 4),"+ 593 "POLYGON((0 0,1 1,1 0,0 0)),"+ 594 "MULTIPOINT(1 2,1 2),"+ 595 "MULTILINESTRING((1 2,3 4),(1 2,3 4)),"+ 596 "MULTIPOLYGON(((0 0,1 1,1 0,0 0)),((0 0,1 1,1 0,0 0))),"+ 597 "GEOMETRYCOLLECTION()"+ 598 ")", types.Blob), 599 expression.NewLiteral(3857, types.Uint32)) 600 601 point := types.Point{SRID: 3857, X: 1, Y: 2} 602 line := types.LineString{SRID: 3857, Points: []types.Point{{SRID: 3857, X: 1, Y: 2}, {SRID: 3857, X: 3, Y: 4}}} 603 poly := types.Polygon{SRID: 3857, Lines: []types.LineString{{SRID: 3857, Points: []types.Point{{SRID: 3857, X: 0, Y: 0}, {SRID: 3857, X: 1, Y: 1}, {SRID: 3857, X: 1, Y: 0}, {SRID: 3857, X: 0, Y: 0}}}}} 604 mpoint := types.MultiPoint{SRID: 3857, Points: []types.Point{point, point}} 605 mline := types.MultiLineString{SRID: 3857, Lines: []types.LineString{line, line}} 606 mpoly := types.MultiPolygon{SRID: 3857, Polygons: []types.Polygon{poly, poly}} 607 gColl := types.GeomColl{SRID: 3857, Geoms: []types.GeometryValue{}} 608 g := types.GeomColl{SRID: 3857, Geoms: []types.GeometryValue{ 609 point, 610 line, 611 poly, 612 mpoint, 613 mline, 614 mpoly, 615 gColl, 616 }} 617 v, err := f.Eval(sql.NewEmptyContext(), nil) 618 require.NoError(err) 619 require.Equal(g, v) 620 }) 621 622 t.Run("check return type", func(t *testing.T) { 623 require := require.New(t) 624 f, err := NewGeomFromText(expression.NewLiteral("POINT(1 2)", types.Blob)) 625 require.NoError(err) 626 typ := f.Type() 627 _, ok := typ.(types.GeometryType) 628 require.True(ok) 629 }) 630 }