github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/st_intersects_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 "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 var ( 28 triangle = types.Polygon{Lines: []types.LineString{ 29 {Points: []types.Point{{X: -1, Y: 0}, {X: 0, Y: 2}, {X: 1, Y: 0}, {X: -1, Y: 0}}}, 30 }} 31 square = types.Polygon{Lines: []types.LineString{ 32 {Points: []types.Point{{X: -4, Y: 4}, {X: 4, Y: 4}, {X: 4, Y: -4}, {X: -4, Y: -4}, {X: -4, Y: 4}}}, 33 }} 34 squareWithHole = types.Polygon{Lines: []types.LineString{ 35 {Points: []types.Point{{X: -4, Y: 4}, {X: 4, Y: 4}, {X: 4, Y: -4}, {X: -4, Y: -4}, {X: -4, Y: 4}}}, 36 {Points: []types.Point{{X: -2, Y: 2}, {X: 2, Y: 2}, {X: 2, Y: -2}, {X: -2, Y: -2}, {X: -2, Y: 2}}}, 37 }} 38 diamond = types.Polygon{Lines: []types.LineString{ 39 {Points: []types.Point{{X: 0, Y: 4}, {X: 4, Y: 0}, {X: 0, Y: -4}, {X: -4, Y: 0}, {X: 0, Y: 4}}}, 40 }} 41 diamondWithHole = types.Polygon{Lines: []types.LineString{ 42 {Points: []types.Point{{X: 0, Y: 4}, {X: 4, Y: 0}, {X: 0, Y: -4}, {X: -4, Y: 0}, {X: 0, Y: 4}}}, 43 {Points: []types.Point{{X: 0, Y: 2}, {X: 2, Y: 0}, {X: 0, Y: -2}, {X: -2, Y: 0}, {X: 0, Y: 2}}}, 44 }} 45 46 emptyLineString = types.LineString{Points: []types.Point{{}, {}}} 47 emptyPolygon = types.Polygon{Lines: []types.LineString{ 48 {Points: []types.Point{{}, {}, {}, {}}}, 49 }} 50 emptyMultiPoint = types.MultiPoint{Points: []types.Point{{}}} 51 emptyMultiLineString = types.MultiLineString{Lines: []types.LineString{emptyLineString}} 52 emptyMultiPolygon = types.MultiPolygon{Polygons: []types.Polygon{emptyPolygon}} 53 54 simpleLineString = types.LineString{Points: []types.Point{{X: 1, Y: 1}, {X: 2, Y: 2}, {X: 3, Y: 3}}} 55 simpleMultiPoint = types.MultiPoint{Points: []types.Point{{X: 1, Y: 1}, {X: 2, Y: 2}, {X: 3, Y: 3}}} 56 simpleMultiLineString = types.MultiLineString{Lines: []types.LineString{simpleLineString}} 57 simpleMultiPolygon = types.MultiPolygon{Polygons: []types.Polygon{square}} 58 simpleGeomColl = types.GeomColl{Geoms: []types.GeometryValue{types.Point{}}} 59 ) 60 61 func TestPointIntersectsPoint(t *testing.T) { 62 t.Run("point intersects point", func(t *testing.T) { 63 require := require.New(t) 64 p := types.Point{X: 1, Y: 2} 65 f := NewIntersects(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(p, types.PointType{})) 66 v, err := f.Eval(sql.NewEmptyContext(), nil) 67 require.NoError(err) 68 require.Equal(true, v) 69 }) 70 71 t.Run("point not intersects point", func(t *testing.T) { 72 require := require.New(t) 73 p1 := types.Point{X: 1, Y: 2} 74 p2 := types.Point{X: 123, Y: 456} 75 f := NewIntersects(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(p2, types.PointType{})) 76 v, err := f.Eval(sql.NewEmptyContext(), nil) 77 require.NoError(err) 78 require.Equal(false, v) 79 }) 80 } 81 82 func TestPointIntersectsLineString(t *testing.T) { 83 t.Run("points intersects linestring", func(t *testing.T) { 84 require := require.New(t) 85 86 f := NewIntersects(expression.NewLiteral(simpleLineString.Points[0], types.PointType{}), expression.NewLiteral(simpleLineString, types.LineStringType{})) 87 v, err := f.Eval(sql.NewEmptyContext(), nil) 88 require.NoError(err) 89 require.Equal(true, v) 90 91 f = NewIntersects(expression.NewLiteral(simpleLineString.Points[1], types.PointType{}), expression.NewLiteral(simpleLineString, types.LineStringType{})) 92 v, err = f.Eval(sql.NewEmptyContext(), nil) 93 require.NoError(err) 94 require.Equal(true, v) 95 96 f = NewIntersects(expression.NewLiteral(simpleLineString.Points[2], types.PointType{}), expression.NewLiteral(simpleLineString, types.LineStringType{})) 97 v, err = f.Eval(sql.NewEmptyContext(), nil) 98 require.NoError(err) 99 require.Equal(true, v) 100 }) 101 102 t.Run("point intersects empty linestring", func(t *testing.T) { 103 require := require.New(t) 104 f := NewIntersects(expression.NewLiteral(types.Point{}, types.PointType{}), expression.NewLiteral(emptyLineString, types.LineStringType{})) 105 v, err := f.Eval(sql.NewEmptyContext(), nil) 106 require.NoError(err) 107 require.Equal(true, v) 108 }) 109 110 t.Run("point not intersects linestring", func(t *testing.T) { 111 require := require.New(t) 112 p := types.Point{X: 100, Y: 200} 113 l := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 2, Y: 2}}} 114 f := NewIntersects(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(l, types.LineStringType{})) 115 v, err := f.Eval(sql.NewEmptyContext(), nil) 116 require.NoError(err) 117 require.Equal(false, v) 118 }) 119 } 120 121 func TestPointIntersectsPolygon(t *testing.T) { 122 t.Run("point intersects polygon", func(t *testing.T) { 123 require := require.New(t) 124 125 // vertexes intersect 126 f := NewIntersects(expression.NewLiteral(triangle.Lines[0].Points[0], types.PointType{}), expression.NewLiteral(triangle, types.PolygonType{})) 127 v, err := f.Eval(sql.NewEmptyContext(), nil) 128 require.NoError(err) 129 require.Equal(true, v) 130 131 f = NewIntersects(expression.NewLiteral(triangle.Lines[0].Points[1], types.PointType{}), expression.NewLiteral(triangle, types.PolygonType{})) 132 v, err = f.Eval(sql.NewEmptyContext(), nil) 133 require.NoError(err) 134 require.Equal(true, v) 135 136 f = NewIntersects(expression.NewLiteral(triangle.Lines[0].Points[2], types.PointType{}), expression.NewLiteral(triangle, types.PolygonType{})) 137 v, err = f.Eval(sql.NewEmptyContext(), nil) 138 require.NoError(err) 139 require.Equal(true, v) 140 141 // border intersect 142 f = NewIntersects(expression.NewLiteral(types.Point{}, types.PointType{}), expression.NewLiteral(triangle, types.PolygonType{})) 143 v, err = f.Eval(sql.NewEmptyContext(), nil) 144 require.NoError(err) 145 require.Equal(true, v) 146 147 // interior intersect 148 q := types.Point{X: 0, Y: 1} 149 f = NewIntersects(expression.NewLiteral(q, types.PointType{}), expression.NewLiteral(triangle, types.PolygonType{})) 150 v, err = f.Eval(sql.NewEmptyContext(), nil) 151 require.NoError(err) 152 require.Equal(true, v) 153 }) 154 155 t.Run("point intersects empty polygon", func(t *testing.T) { 156 require := require.New(t) 157 f := NewIntersects(expression.NewLiteral(types.Point{}, types.PointType{}), expression.NewLiteral(emptyPolygon, types.PolygonType{})) 158 v, err := f.Eval(sql.NewEmptyContext(), nil) 159 require.NoError(err) 160 require.Equal(true, v) 161 }) 162 163 t.Run("point intersects polygon with hole", func(t *testing.T) { 164 require := require.New(t) 165 166 p1 := types.Point{X: -3, Y: 2} 167 f := NewIntersects(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 168 v, err := f.Eval(sql.NewEmptyContext(), nil) 169 require.NoError(err) 170 require.Equal(true, v) 171 172 p2 := types.Point{X: -3, Y: 0} 173 f = NewIntersects(expression.NewLiteral(p2, types.PointType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 174 v, err = f.Eval(sql.NewEmptyContext(), nil) 175 require.NoError(err) 176 require.Equal(true, v) 177 178 p3 := types.Point{X: -3, Y: -2} 179 f = NewIntersects(expression.NewLiteral(p3, types.PointType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 180 v, err = f.Eval(sql.NewEmptyContext(), nil) 181 require.NoError(err) 182 require.Equal(true, v) 183 184 f = NewIntersects(expression.NewLiteral(types.Point{}, types.PointType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 185 v, err = f.Eval(sql.NewEmptyContext(), nil) 186 require.NoError(err) 187 require.Equal(false, v) 188 }) 189 } 190 191 func TestPointIntersectsMultiPoint(t *testing.T) { 192 t.Run("points intersects multipoint", func(t *testing.T) { 193 require := require.New(t) 194 195 f := NewIntersects(expression.NewLiteral(simpleMultiPoint.Points[0], types.PointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 196 v, err := f.Eval(sql.NewEmptyContext(), nil) 197 require.NoError(err) 198 require.Equal(true, v) 199 200 f = NewIntersects(expression.NewLiteral(simpleMultiPoint.Points[1], types.PointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 201 v, err = f.Eval(sql.NewEmptyContext(), nil) 202 require.NoError(err) 203 require.Equal(true, v) 204 205 f = NewIntersects(expression.NewLiteral(simpleMultiPoint.Points[2], types.PointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 206 v, err = f.Eval(sql.NewEmptyContext(), nil) 207 require.NoError(err) 208 require.Equal(true, v) 209 }) 210 211 t.Run("point not intersects multipoint", func(t *testing.T) { 212 require := require.New(t) 213 214 p := types.Point{X: 0, Y: 0} 215 f := NewIntersects(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 216 v, err := f.Eval(sql.NewEmptyContext(), nil) 217 require.NoError(err) 218 require.Equal(false, v) 219 }) 220 } 221 222 func TestPointIntersectsMultiLineString(t *testing.T) { 223 p1 := types.Point{X: -1, Y: -1} 224 p2 := types.Point{X: 1, Y: 1} 225 p3 := types.Point{X: 123, Y: 456} 226 l1 := types.LineString{Points: []types.Point{p1, p2}} 227 l2 := types.LineString{Points: []types.Point{p3, p3}} 228 ml := types.MultiLineString{Lines: []types.LineString{l1, l2}} 229 t.Run("points intersects multilinestring", func(t *testing.T) { 230 require := require.New(t) 231 232 f := NewIntersects(expression.NewLiteral(p3, types.PointType{}), expression.NewLiteral(ml, types.MultiLineStringType{})) 233 v, err := f.Eval(sql.NewEmptyContext(), nil) 234 require.NoError(err) 235 require.Equal(true, v) 236 237 p := types.Point{X: 0, Y: 0} 238 f = NewIntersects(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(ml, types.MultiLineStringType{})) 239 v, err = f.Eval(sql.NewEmptyContext(), nil) 240 require.NoError(err) 241 require.Equal(true, v) 242 }) 243 244 t.Run("points not intersects multilinestring", func(t *testing.T) { 245 require := require.New(t) 246 247 p4 := types.Point{X: -100, Y: -123123} 248 f := NewIntersects(expression.NewLiteral(p4, types.PointType{}), expression.NewLiteral(ml, types.MultiLineStringType{})) 249 v, err := f.Eval(sql.NewEmptyContext(), nil) 250 require.NoError(err) 251 require.Equal(false, v) 252 253 p5 := types.Point{X: 100, Y: 1001} 254 f = NewIntersects(expression.NewLiteral(p5, types.PointType{}), expression.NewLiteral(ml, types.MultiLineStringType{})) 255 v, err = f.Eval(sql.NewEmptyContext(), nil) 256 require.NoError(err) 257 require.Equal(false, v) 258 }) 259 } 260 261 func TestPointIntersectsMultiPolygon(t *testing.T) { 262 mp := types.MultiPolygon{Polygons: []types.Polygon{square}} 263 t.Run("point intersects multipolygon", func(t *testing.T) { 264 require := require.New(t) 265 266 f := NewIntersects(expression.NewLiteral(types.Point{}, types.PointType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 267 v, err := f.Eval(sql.NewEmptyContext(), nil) 268 require.NoError(err) 269 require.Equal(true, v) 270 }) 271 272 t.Run("points not intersects multipolygon", func(t *testing.T) { 273 require := require.New(t) 274 p := types.Point{X: 100, Y: 100} 275 f := NewIntersects(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 276 v, err := f.Eval(sql.NewEmptyContext(), nil) 277 require.NoError(err) 278 require.Equal(false, v) 279 }) 280 } 281 282 func TestPointIntersectsGeometryCollection(t *testing.T) { 283 p := types.Point{} 284 285 t.Run("point intersects empty geometrycollection returns null", func(t *testing.T) { 286 require := require.New(t) 287 gc := types.GeomColl{} 288 289 f := NewIntersects(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(gc, types.GeomCollType{})) 290 v, err := f.Eval(sql.NewEmptyContext(), nil) 291 require.NoError(err) 292 require.Equal(nil, v) 293 }) 294 295 t.Run("point intersects geometrycollection", func(t *testing.T) { 296 require := require.New(t) 297 gc := types.GeomColl{Geoms: []types.GeometryValue{p}} 298 299 f := NewIntersects(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(gc, types.GeomCollType{})) 300 v, err := f.Eval(sql.NewEmptyContext(), nil) 301 require.NoError(err) 302 require.Equal(true, v) 303 }) 304 305 t.Run("point not intersects geometrycollection", func(t *testing.T) { 306 require := require.New(t) 307 a := types.Point{X: 1, Y: 0} 308 gc := types.GeomColl{Geoms: []types.GeometryValue{a}} 309 310 f := NewIntersects(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(gc, types.GeomCollType{})) 311 v, err := f.Eval(sql.NewEmptyContext(), nil) 312 require.NoError(err) 313 require.Equal(false, v) 314 }) 315 } 316 317 func TestLineStringIntersectsLineString(t *testing.T) { 318 t.Run("linestring intersects linestring", func(t *testing.T) { 319 require := require.New(t) 320 a := types.Point{X: 0, Y: 0} 321 b := types.Point{X: 1, Y: 1} 322 c := types.Point{X: 0, Y: 1} 323 d := types.Point{X: 1, Y: 0} 324 ab := types.LineString{Points: []types.Point{a, b}} 325 cd := types.LineString{Points: []types.Point{c, d}} 326 327 f := NewIntersects(expression.NewLiteral(ab, types.LineStringType{}), expression.NewLiteral(cd, types.LineStringType{})) 328 v, err := f.Eval(sql.NewEmptyContext(), nil) 329 require.NoError(err) 330 require.Equal(true, v) 331 }) 332 333 t.Run("empty linestring intersects empty linestring", func(t *testing.T) { 334 require := require.New(t) 335 f := NewIntersects(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(emptyLineString, types.LineStringType{})) 336 v, err := f.Eval(sql.NewEmptyContext(), nil) 337 require.NoError(err) 338 require.Equal(true, v) 339 }) 340 341 t.Run("linestring not intersects linestring", func(t *testing.T) { 342 require := require.New(t) 343 l1 := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 2, Y: 2}}} 344 l2 := types.LineString{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}} 345 f := NewIntersects(expression.NewLiteral(l1, types.LineStringType{}), expression.NewLiteral(l2, types.LineStringType{})) 346 v, err := f.Eval(sql.NewEmptyContext(), nil) 347 require.NoError(err) 348 require.Equal(false, v) 349 }) 350 } 351 352 func TestLineStringIntersectsPolygon(t *testing.T) { 353 t.Run("linestring intersects polygon", func(t *testing.T) { 354 require := require.New(t) 355 356 // border intersect 357 f := NewIntersects(expression.NewLiteral(squareWithHole.Lines[0], types.LineStringType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 358 v, err := f.Eval(sql.NewEmptyContext(), nil) 359 require.NoError(err) 360 require.Equal(true, v) 361 362 f = NewIntersects(expression.NewLiteral(squareWithHole.Lines[1], types.LineStringType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 363 v, err = f.Eval(sql.NewEmptyContext(), nil) 364 require.NoError(err) 365 require.Equal(true, v) 366 367 // interior intersect 368 l1 := types.LineString{Points: []types.Point{{X: -3, Y: 3}, {X: 3, Y: 3}}} 369 f = NewIntersects(expression.NewLiteral(l1, types.LineStringType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 370 v, err = f.Eval(sql.NewEmptyContext(), nil) 371 require.NoError(err) 372 require.Equal(true, v) 373 374 l2 := types.LineString{Points: []types.Point{{X: -3, Y: -3}, {X: 3, Y: 3}}} 375 f = NewIntersects(expression.NewLiteral(l2, types.LineStringType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 376 v, err = f.Eval(sql.NewEmptyContext(), nil) 377 require.NoError(err) 378 require.Equal(true, v) 379 380 l3 := types.LineString{Points: []types.Point{{X: -5}, {X: 5}}} 381 f = NewIntersects(expression.NewLiteral(l3, types.LineStringType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 382 v, err = f.Eval(sql.NewEmptyContext(), nil) 383 require.NoError(err) 384 require.Equal(true, v) 385 }) 386 387 t.Run("linestring does not intersect polygon", func(t *testing.T) { 388 require := require.New(t) 389 390 // in hole 391 f := NewIntersects(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 392 v, err := f.Eval(sql.NewEmptyContext(), nil) 393 require.NoError(err) 394 require.Equal(false, v) 395 396 // completely outside 397 a := types.Point{X: 100, Y: 100} 398 b := types.Point{X: 200, Y: 200} 399 l := types.LineString{Points: []types.Point{a, b}} 400 f = NewIntersects(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 401 v, err = f.Eval(sql.NewEmptyContext(), nil) 402 require.NoError(err) 403 require.Equal(false, v) 404 }) 405 406 t.Run("empty linestring intersects empty polygon", func(t *testing.T) { 407 require := require.New(t) 408 f := NewIntersects(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(emptyPolygon, types.PolygonType{})) 409 v, err := f.Eval(sql.NewEmptyContext(), nil) 410 require.NoError(err) 411 require.Equal(true, v) 412 }) 413 } 414 415 func TestLineStringIntersectsMultiPoint(t *testing.T) { 416 t.Run("linestring intersects multipoint", func(t *testing.T) { 417 require := require.New(t) 418 f := NewIntersects(expression.NewLiteral(simpleLineString, types.LineStringType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 419 v, err := f.Eval(sql.NewEmptyContext(), nil) 420 require.NoError(err) 421 require.Equal(true, v) 422 }) 423 424 t.Run("linestring not intersects multipoint", func(t *testing.T) { 425 require := require.New(t) 426 427 f := NewIntersects(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 428 v, err := f.Eval(sql.NewEmptyContext(), nil) 429 require.NoError(err) 430 require.Equal(false, v) 431 }) 432 } 433 434 func TestLineStringIntersectsMultiLineString(t *testing.T) { 435 t.Run("linestring intersects multilinestring", func(t *testing.T) { 436 require := require.New(t) 437 438 f := NewIntersects(expression.NewLiteral(simpleLineString, types.LineStringType{}), expression.NewLiteral(simpleMultiLineString, types.MultiLineStringType{})) 439 v, err := f.Eval(sql.NewEmptyContext(), nil) 440 require.NoError(err) 441 require.Equal(true, v) 442 443 a := types.Point{X: 1.5, Y: 10} 444 b := types.Point{X: 1.5, Y: -10} 445 ab := types.LineString{Points: []types.Point{a, b}} 446 f = NewIntersects(expression.NewLiteral(ab, types.LineStringType{}), expression.NewLiteral(simpleMultiLineString, types.MultiLineStringType{})) 447 v, err = f.Eval(sql.NewEmptyContext(), nil) 448 require.NoError(err) 449 require.Equal(true, v) 450 }) 451 452 t.Run("linestring not intersects multilinestring", func(t *testing.T) { 453 require := require.New(t) 454 f := NewIntersects(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(simpleMultiLineString, types.MultiLineStringType{})) 455 v, err := f.Eval(sql.NewEmptyContext(), nil) 456 require.NoError(err) 457 require.Equal(false, v) 458 }) 459 } 460 461 func TestLineStringIntersectsMultiPolygon(t *testing.T) { 462 mp := types.MultiPolygon{Polygons: []types.Polygon{squareWithHole}} 463 t.Run("linestring intersects multipolygon", func(t *testing.T) { 464 require := require.New(t) 465 f := NewIntersects(expression.NewLiteral(squareWithHole.Lines[0], types.LineStringType{}), expression.NewLiteral(mp, types.MultiLineStringType{})) 466 v, err := f.Eval(sql.NewEmptyContext(), nil) 467 require.NoError(err) 468 require.Equal(true, v) 469 }) 470 471 t.Run("linestring not intersects multipolygon", func(t *testing.T) { 472 require := require.New(t) 473 f := NewIntersects(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(mp, types.MultiLineStringType{})) 474 v, err := f.Eval(sql.NewEmptyContext(), nil) 475 require.NoError(err) 476 require.Equal(false, v) 477 }) 478 } 479 480 func TestLineStringIntersectsGeometryCollection(t *testing.T) { 481 t.Run("linestring intersects empty geometrycollection returns null", func(t *testing.T) { 482 require := require.New(t) 483 gc := types.GeomColl{} 484 f := NewIntersects(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(gc, types.GeomCollType{})) 485 v, err := f.Eval(sql.NewEmptyContext(), nil) 486 require.NoError(err) 487 require.Equal(nil, v) 488 }) 489 490 t.Run("linestring intersects geometrycollection", func(t *testing.T) { 491 require := require.New(t) 492 gc := types.GeomColl{Geoms: []types.GeometryValue{emptyLineString}} 493 f := NewIntersects(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(gc, types.GeomCollType{})) 494 v, err := f.Eval(sql.NewEmptyContext(), nil) 495 require.NoError(err) 496 require.Equal(true, v) 497 }) 498 499 t.Run("linestring not intersects geometrycollection", func(t *testing.T) { 500 require := require.New(t) 501 gc := types.GeomColl{Geoms: []types.GeometryValue{simpleLineString}} 502 f := NewIntersects(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(gc, types.GeomCollType{})) 503 v, err := f.Eval(sql.NewEmptyContext(), nil) 504 require.NoError(err) 505 require.Equal(false, v) 506 }) 507 } 508 509 func TestPolygonIntersectsPolygon(t *testing.T) { 510 t.Run("polygon intersects polygon", func(t *testing.T) { 511 require := require.New(t) 512 513 smallSquare := types.Polygon{Lines: []types.LineString{squareWithHole.Lines[1]}} 514 515 f := NewIntersects(expression.NewLiteral(smallSquare, types.PolygonType{}), expression.NewLiteral(square, types.PolygonType{})) 516 v, err := f.Eval(sql.NewEmptyContext(), nil) 517 require.NoError(err) 518 require.Equal(true, v) 519 520 f = NewIntersects(expression.NewLiteral(square, types.PolygonType{}), expression.NewLiteral(smallSquare, types.PolygonType{})) 521 v, err = f.Eval(sql.NewEmptyContext(), nil) 522 require.NoError(err) 523 require.Equal(true, v) 524 }) 525 526 t.Run("polygon does not intersect polygon", func(t *testing.T) { 527 require := require.New(t) 528 529 // in hole 530 f := NewIntersects(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(squareWithHole, types.PolygonType{})) 531 v, err := f.Eval(sql.NewEmptyContext(), nil) 532 require.NoError(err) 533 require.Equal(false, v) 534 535 // completely outside 536 a := types.Point{X: 100, Y: 100} 537 b := types.Point{X: 100, Y: 200} 538 c := types.Point{X: 200, Y: 200} 539 d := types.Point{X: 200, Y: 100} 540 l := types.LineString{Points: []types.Point{a, b, c, d, a}} 541 p := types.Polygon{Lines: []types.LineString{l}} 542 f = NewIntersects(expression.NewLiteral(p, types.PolygonType{}), expression.NewLiteral(square, types.PolygonType{})) 543 v, err = f.Eval(sql.NewEmptyContext(), nil) 544 require.NoError(err) 545 require.Equal(false, v) 546 }) 547 548 t.Run("empty polygon intersects empty polygon", func(t *testing.T) { 549 require := require.New(t) 550 f := NewIntersects(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(emptyPolygon, types.PolygonType{})) 551 v, err := f.Eval(sql.NewEmptyContext(), nil) 552 require.NoError(err) 553 require.Equal(true, v) 554 }) 555 } 556 557 func TestPolygonIntersectsMultiPoint(t *testing.T) { 558 t.Run("polygon intersects multipoint", func(t *testing.T) { 559 require := require.New(t) 560 f := NewIntersects(expression.NewLiteral(square, types.PolygonType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 561 v, err := f.Eval(sql.NewEmptyContext(), nil) 562 require.NoError(err) 563 require.Equal(true, v) 564 }) 565 566 t.Run("polygon not intersects multipoint", func(t *testing.T) { 567 require := require.New(t) 568 569 f := NewIntersects(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 570 v, err := f.Eval(sql.NewEmptyContext(), nil) 571 require.NoError(err) 572 require.Equal(false, v) 573 574 mp := types.MultiPoint{Points: []types.Point{{}}} 575 f = NewIntersects(expression.NewLiteral(squareWithHole, types.PolygonType{}), expression.NewLiteral(mp, types.MultiPointType{})) 576 v, err = f.Eval(sql.NewEmptyContext(), nil) 577 require.NoError(err) 578 require.Equal(false, v) 579 }) 580 } 581 582 func TestPolygonIntersectsMultiLineString(t *testing.T) { 583 t.Run("polygon intersects multilinestring", func(t *testing.T) { 584 require := require.New(t) 585 586 f := NewIntersects(expression.NewLiteral(square, types.PolygonType{}), expression.NewLiteral(simpleMultiLineString, types.MultiLineStringType{})) 587 v, err := f.Eval(sql.NewEmptyContext(), nil) 588 require.NoError(err) 589 require.Equal(true, v) 590 }) 591 592 t.Run("polygon not intersects multilinestring", func(t *testing.T) { 593 require := require.New(t) 594 f := NewIntersects(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(simpleMultiLineString, types.MultiLineStringType{})) 595 v, err := f.Eval(sql.NewEmptyContext(), nil) 596 require.NoError(err) 597 require.Equal(false, v) 598 599 ml := types.MultiLineString{Lines: []types.LineString{emptyLineString}} 600 f = NewIntersects(expression.NewLiteral(squareWithHole, types.PolygonType{}), expression.NewLiteral(ml, types.MultiLineStringType{})) 601 v, err = f.Eval(sql.NewEmptyContext(), nil) 602 require.NoError(err) 603 require.Equal(false, v) 604 }) 605 } 606 607 func TestPolygonIntersectsMultiPolygon(t *testing.T) { 608 mp := types.MultiPolygon{Polygons: []types.Polygon{squareWithHole}} 609 t.Run("polygon intersects multipolygon", func(t *testing.T) { 610 require := require.New(t) 611 f := NewIntersects(expression.NewLiteral(squareWithHole, types.PolygonType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 612 v, err := f.Eval(sql.NewEmptyContext(), nil) 613 require.NoError(err) 614 require.Equal(true, v) 615 }) 616 617 t.Run("polygon not intersects multipolygon", func(t *testing.T) { 618 require := require.New(t) 619 f := NewIntersects(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 620 v, err := f.Eval(sql.NewEmptyContext(), nil) 621 require.NoError(err) 622 require.Equal(false, v) 623 }) 624 } 625 626 func TestPolygonIntersectsGeometryCollection(t *testing.T) { 627 t.Run("polygon intersects empty geometrycollection returns null", func(t *testing.T) { 628 require := require.New(t) 629 gc := types.GeomColl{} 630 f := NewIntersects(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(gc, types.GeomCollType{})) 631 v, err := f.Eval(sql.NewEmptyContext(), nil) 632 require.NoError(err) 633 require.Equal(nil, v) 634 }) 635 636 t.Run("polygon intersects geometrycollection", func(t *testing.T) { 637 require := require.New(t) 638 gc := types.GeomColl{Geoms: []types.GeometryValue{emptyPolygon}} 639 f := NewIntersects(expression.NewLiteral(square, types.PolygonType{}), expression.NewLiteral(gc, types.GeomCollType{})) 640 v, err := f.Eval(sql.NewEmptyContext(), nil) 641 require.NoError(err) 642 require.Equal(true, v) 643 }) 644 645 t.Run("polygon not intersects geometrycollection", func(t *testing.T) { 646 require := require.New(t) 647 gc := types.GeomColl{Geoms: []types.GeometryValue{squareWithHole}} 648 f := NewIntersects(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(gc, types.GeomCollType{})) 649 v, err := f.Eval(sql.NewEmptyContext(), nil) 650 require.NoError(err) 651 require.Equal(false, v) 652 }) 653 } 654 655 func TestMultiPointIntersectsMultiPoint(t *testing.T) { 656 t.Run("multipoint intersects multipoint", func(t *testing.T) { 657 require := require.New(t) 658 f := NewIntersects(expression.NewLiteral(simpleMultiPoint, types.MultiPointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 659 v, err := f.Eval(sql.NewEmptyContext(), nil) 660 require.NoError(err) 661 require.Equal(true, v) 662 }) 663 664 t.Run("multipoint not intersects multipoint", func(t *testing.T) { 665 require := require.New(t) 666 667 f := NewIntersects(expression.NewLiteral(emptyMultiPoint, types.MultiPointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{})) 668 v, err := f.Eval(sql.NewEmptyContext(), nil) 669 require.NoError(err) 670 require.Equal(false, v) 671 }) 672 } 673 674 func TestMultiPointIntersectsMultiLineString(t *testing.T) { 675 t.Run("multipoint intersects multilinestring", func(t *testing.T) { 676 require := require.New(t) 677 678 f := NewIntersects(expression.NewLiteral(simpleMultiPoint, types.MultiPointType{}), expression.NewLiteral(simpleMultiLineString, types.MultiLineStringType{})) 679 v, err := f.Eval(sql.NewEmptyContext(), nil) 680 require.NoError(err) 681 require.Equal(true, v) 682 }) 683 684 t.Run("c not intersects multilinestring", func(t *testing.T) { 685 require := require.New(t) 686 f := NewIntersects(expression.NewLiteral(emptyMultiPoint, types.MultiPointType{}), expression.NewLiteral(simpleMultiLineString, types.MultiLineStringType{})) 687 v, err := f.Eval(sql.NewEmptyContext(), nil) 688 require.NoError(err) 689 require.Equal(false, v) 690 }) 691 } 692 693 func TestMultiPointIntersectsMultiPolygon(t *testing.T) { 694 mp := types.MultiPolygon{Polygons: []types.Polygon{squareWithHole}} 695 t.Run("multipoint intersects multipolygon", func(t *testing.T) { 696 require := require.New(t) 697 f := NewIntersects(expression.NewLiteral(simpleMultiPoint, types.MultiPointType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 698 v, err := f.Eval(sql.NewEmptyContext(), nil) 699 require.NoError(err) 700 require.Equal(true, v) 701 }) 702 703 t.Run("multipoint not intersects multipolygon", func(t *testing.T) { 704 require := require.New(t) 705 f := NewIntersects(expression.NewLiteral(emptyMultiPoint, types.MultiPointType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 706 v, err := f.Eval(sql.NewEmptyContext(), nil) 707 require.NoError(err) 708 require.Equal(false, v) 709 }) 710 } 711 712 func TestMultiPointIntersectsGeometryCollection(t *testing.T) { 713 t.Run("multipoint intersects empty geometrycollection returns null", func(t *testing.T) { 714 require := require.New(t) 715 gc := types.GeomColl{} 716 f := NewIntersects(expression.NewLiteral(emptyMultiPoint, types.MultiPointType{}), expression.NewLiteral(gc, types.GeomCollType{})) 717 v, err := f.Eval(sql.NewEmptyContext(), nil) 718 require.NoError(err) 719 require.Equal(nil, v) 720 }) 721 722 t.Run("multipoint intersects geometrycollection", func(t *testing.T) { 723 require := require.New(t) 724 gc := types.GeomColl{Geoms: []types.GeometryValue{emptyMultiPoint}} 725 f := NewIntersects(expression.NewLiteral(emptyMultiPoint, types.MultiPointType{}), expression.NewLiteral(gc, types.GeomCollType{})) 726 v, err := f.Eval(sql.NewEmptyContext(), nil) 727 require.NoError(err) 728 require.Equal(true, v) 729 }) 730 731 t.Run("multipoint not intersects geometrycollection", func(t *testing.T) { 732 require := require.New(t) 733 gc := types.GeomColl{Geoms: []types.GeometryValue{simpleMultiPoint}} 734 f := NewIntersects(expression.NewLiteral(emptyMultiPoint, types.MultiPointType{}), expression.NewLiteral(gc, types.GeomCollType{})) 735 v, err := f.Eval(sql.NewEmptyContext(), nil) 736 require.NoError(err) 737 require.Equal(false, v) 738 }) 739 } 740 741 func TestMultiLineStringIntersectsMultiLineString(t *testing.T) { 742 t.Run("multilinestring intersects multilinestring", func(t *testing.T) { 743 require := require.New(t) 744 745 f := NewIntersects(expression.NewLiteral(simpleLineString, types.MultiLineStringType{}), expression.NewLiteral(simpleMultiLineString, types.MultiLineStringType{})) 746 v, err := f.Eval(sql.NewEmptyContext(), nil) 747 require.NoError(err) 748 require.Equal(true, v) 749 }) 750 751 t.Run("multilinestring not intersects multilinestring", func(t *testing.T) { 752 require := require.New(t) 753 f := NewIntersects(expression.NewLiteral(emptyMultiPoint, types.MultiLineStringType{}), expression.NewLiteral(simpleMultiLineString, types.MultiLineStringType{})) 754 v, err := f.Eval(sql.NewEmptyContext(), nil) 755 require.NoError(err) 756 require.Equal(false, v) 757 }) 758 } 759 760 func TestMultiLineStringIntersectsMultiPolygon(t *testing.T) { 761 mp := types.MultiPolygon{Polygons: []types.Polygon{squareWithHole}} 762 t.Run("multilinestring intersects multipolygon", func(t *testing.T) { 763 require := require.New(t) 764 f := NewIntersects(expression.NewLiteral(simpleMultiPoint, types.MultiLineStringType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 765 v, err := f.Eval(sql.NewEmptyContext(), nil) 766 require.NoError(err) 767 require.Equal(true, v) 768 }) 769 770 t.Run("multilinestring not intersects multipolygon", func(t *testing.T) { 771 require := require.New(t) 772 f := NewIntersects(expression.NewLiteral(emptyMultiPoint, types.MultiLineStringType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 773 v, err := f.Eval(sql.NewEmptyContext(), nil) 774 require.NoError(err) 775 require.Equal(false, v) 776 }) 777 } 778 779 func TestMultiLineStringIntersectsGeometryCollection(t *testing.T) { 780 t.Run("multilinestring intersects empty geometrycollection returns null", func(t *testing.T) { 781 require := require.New(t) 782 gc := types.GeomColl{} 783 f := NewIntersects(expression.NewLiteral(emptyMultiLineString, types.MultiLineStringType{}), expression.NewLiteral(gc, types.GeomCollType{})) 784 v, err := f.Eval(sql.NewEmptyContext(), nil) 785 require.NoError(err) 786 require.Equal(nil, v) 787 }) 788 789 t.Run("multilinestring intersects geometrycollection", func(t *testing.T) { 790 require := require.New(t) 791 gc := types.GeomColl{Geoms: []types.GeometryValue{emptyMultiLineString}} 792 f := NewIntersects(expression.NewLiteral(emptyMultiLineString, types.MultiLineStringType{}), expression.NewLiteral(gc, types.GeomCollType{})) 793 v, err := f.Eval(sql.NewEmptyContext(), nil) 794 require.NoError(err) 795 require.Equal(true, v) 796 }) 797 798 t.Run("multilinestring not intersects geometrycollection", func(t *testing.T) { 799 require := require.New(t) 800 gc := types.GeomColl{Geoms: []types.GeometryValue{simpleLineString}} 801 f := NewIntersects(expression.NewLiteral(emptyMultiLineString, types.MultiLineStringType{}), expression.NewLiteral(gc, types.GeomCollType{})) 802 v, err := f.Eval(sql.NewEmptyContext(), nil) 803 require.NoError(err) 804 require.Equal(false, v) 805 }) 806 } 807 808 func TestMultiPolygonIntersectsMultiPolygon(t *testing.T) { 809 mp := types.MultiPolygon{Polygons: []types.Polygon{squareWithHole}} 810 t.Run("multipolygon intersects multipolygon", func(t *testing.T) { 811 require := require.New(t) 812 f := NewIntersects(expression.NewLiteral(mp, types.MultiPolygonType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 813 v, err := f.Eval(sql.NewEmptyContext(), nil) 814 require.NoError(err) 815 require.Equal(true, v) 816 }) 817 818 t.Run("multipolygon not intersects multipolygon", func(t *testing.T) { 819 require := require.New(t) 820 f := NewIntersects(expression.NewLiteral(emptyMultiPolygon, types.MultiPolygonType{}), expression.NewLiteral(mp, types.MultiPolygonType{})) 821 v, err := f.Eval(sql.NewEmptyContext(), nil) 822 require.NoError(err) 823 require.Equal(false, v) 824 }) 825 } 826 827 func TestMultiPolygonIntersectsGeometryCollection(t *testing.T) { 828 t.Run("multipolygon intersects empty geometrycollection returns null", func(t *testing.T) { 829 require := require.New(t) 830 gc := types.GeomColl{} 831 f := NewIntersects(expression.NewLiteral(emptyMultiPolygon, types.MultiPolygonType{}), expression.NewLiteral(gc, types.GeomCollType{})) 832 v, err := f.Eval(sql.NewEmptyContext(), nil) 833 require.NoError(err) 834 require.Equal(nil, v) 835 }) 836 837 t.Run("multipolygon intersects geometrycollection", func(t *testing.T) { 838 require := require.New(t) 839 gc := types.GeomColl{Geoms: []types.GeometryValue{emptyMultiPolygon}} 840 f := NewIntersects(expression.NewLiteral(emptyMultiPolygon, types.MultiPolygonType{}), expression.NewLiteral(gc, types.GeomCollType{})) 841 v, err := f.Eval(sql.NewEmptyContext(), nil) 842 require.NoError(err) 843 require.Equal(true, v) 844 }) 845 846 t.Run("multipolygon not intersects geometrycollection", func(t *testing.T) { 847 require := require.New(t) 848 mp := types.MultiPolygon{Polygons: []types.Polygon{squareWithHole}} 849 gc := types.GeomColl{Geoms: []types.GeometryValue{mp}} 850 f := NewIntersects(expression.NewLiteral(emptyMultiPolygon, types.MultiPolygonType{}), expression.NewLiteral(gc, types.GeomCollType{})) 851 v, err := f.Eval(sql.NewEmptyContext(), nil) 852 require.NoError(err) 853 require.Equal(false, v) 854 }) 855 } 856 857 func TestGeometryCollectionIntersectsGeometryCollection(t *testing.T) { 858 t.Run("empty geometrycollection intersects empty geometrycollection returns null", func(t *testing.T) { 859 require := require.New(t) 860 gc := types.GeomColl{} 861 f := NewIntersects(expression.NewLiteral(gc, types.GeomCollType{}), expression.NewLiteral(gc, types.GeomCollType{})) 862 v, err := f.Eval(sql.NewEmptyContext(), nil) 863 require.NoError(err) 864 require.Equal(nil, v) 865 }) 866 867 t.Run("geometrycollection intersects geometrycollection", func(t *testing.T) { 868 require := require.New(t) 869 870 gc1 := types.GeomColl{Geoms: []types.GeometryValue{types.Point{}}} 871 f := NewIntersects(expression.NewLiteral(gc1, types.GeomCollType{}), expression.NewLiteral(gc1, types.GeomCollType{})) 872 v, err := f.Eval(sql.NewEmptyContext(), nil) 873 require.NoError(err) 874 require.Equal(true, v) 875 876 gc2 := types.GeomColl{Geoms: []types.GeometryValue{square}} 877 f = NewIntersects(expression.NewLiteral(gc1, types.GeomCollType{}), expression.NewLiteral(gc2, types.GeomCollType{})) 878 v, err = f.Eval(sql.NewEmptyContext(), nil) 879 require.NoError(err) 880 require.Equal(true, v) 881 882 f = NewIntersects(expression.NewLiteral(gc2, types.GeomCollType{}), expression.NewLiteral(gc1, types.GeomCollType{})) 883 v, err = f.Eval(sql.NewEmptyContext(), nil) 884 require.NoError(err) 885 require.Equal(true, v) 886 }) 887 888 t.Run("geometrycollection not intersects geometrycollection", func(t *testing.T) { 889 require := require.New(t) 890 gc1 := types.GeomColl{Geoms: []types.GeometryValue{squareWithHole}} 891 gc2 := types.GeomColl{Geoms: []types.GeometryValue{emptyLineString}} 892 f := NewIntersects(expression.NewLiteral(gc1, types.GeomCollType{}), expression.NewLiteral(gc2, types.GeomCollType{})) 893 v, err := f.Eval(sql.NewEmptyContext(), nil) 894 require.NoError(err) 895 require.Equal(false, v) 896 897 f = NewIntersects(expression.NewLiteral(gc1, types.GeomCollType{}), expression.NewLiteral(gc2, types.GeomCollType{})) 898 v, err = f.Eval(sql.NewEmptyContext(), nil) 899 require.NoError(err) 900 require.Equal(false, v) 901 }) 902 }