github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/st_within_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  func TestPointWithinPoint(t *testing.T) {
    28  	t.Run("point within point", func(t *testing.T) {
    29  		require := require.New(t)
    30  		p := types.Point{X: 1, Y: 2}
    31  		f := NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(p, types.PointType{}))
    32  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    33  		require.NoError(err)
    34  		require.Equal(true, v)
    35  	})
    36  
    37  	t.Run("point not within point", func(t *testing.T) {
    38  		require := require.New(t)
    39  		p1 := types.Point{X: 1, Y: 2}
    40  		p2 := types.Point{X: 123, Y: 456}
    41  		f := NewWithin(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(p2, types.PointType{}))
    42  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    43  		require.NoError(err)
    44  		require.Equal(false, v)
    45  	})
    46  }
    47  
    48  func TestPointWithinLineString(t *testing.T) {
    49  	t.Run("point within linestring", func(t *testing.T) {
    50  		require := require.New(t)
    51  		p := types.Point{X: 1, Y: 1}
    52  		l := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 2, Y: 2}}}
    53  		f := NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(l, types.LineStringType{}))
    54  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    55  		require.NoError(err)
    56  		require.Equal(true, v)
    57  	})
    58  
    59  	t.Run("point within closed linestring of length 0", func(t *testing.T) {
    60  		require := require.New(t)
    61  		p := types.Point{X: 123, Y: 456}
    62  		l := types.LineString{Points: []types.Point{p, p}}
    63  
    64  		f := NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(l, types.PointType{}))
    65  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    66  		require.NoError(err)
    67  		require.Equal(true, v)
    68  
    69  		l = types.LineString{Points: []types.Point{p, p, p, p, p}}
    70  		f = NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(l, types.PointType{}))
    71  		v, err = f.Eval(sql.NewEmptyContext(), nil)
    72  		require.NoError(err)
    73  		require.Equal(true, v)
    74  	})
    75  
    76  	t.Run("point not within linestring", func(t *testing.T) {
    77  		require := require.New(t)
    78  		p := types.Point{X: 100, Y: 200}
    79  		l := types.LineString{Points: []types.Point{{X: 0, Y: 0}, {X: 2, Y: 2}}}
    80  		f := NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(l, types.PointType{}))
    81  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    82  		require.NoError(err)
    83  		require.Equal(false, v)
    84  	})
    85  
    86  	t.Run("terminal points are not within linestring", func(t *testing.T) {
    87  		require := require.New(t)
    88  		f := NewWithin(expression.NewLiteral(simpleLineString.Points[0], types.PointType{}), expression.NewLiteral(simpleLineString, types.PointType{}))
    89  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    90  		require.NoError(err)
    91  		require.Equal(false, v)
    92  
    93  		f = NewWithin(expression.NewLiteral(simpleLineString.Points[2], types.PointType{}), expression.NewLiteral(simpleLineString, types.PointType{}))
    94  		v, err = f.Eval(sql.NewEmptyContext(), nil)
    95  		require.NoError(err)
    96  		require.Equal(false, v)
    97  	})
    98  
    99  	t.Run("overlapping terminal points are not within linestring", func(t *testing.T) {
   100  		require := require.New(t)
   101  
   102  		// it looks like two triangles:
   103  		//  /\  |  /\
   104  		// /__s_|_e__\
   105  		s := types.Point{X: -1, Y: 0}
   106  		p1 := types.Point{X: -2, Y: 1}
   107  		p2 := types.Point{X: -3, Y: 0}
   108  		p3 := types.Point{X: 3, Y: 0}
   109  		p4 := types.Point{X: 2, Y: 1}
   110  		e := types.Point{X: 1, Y: 0}
   111  
   112  		l := types.LineString{Points: []types.Point{s, p1, p2, p3, p4, e}}
   113  
   114  		f := NewWithin(expression.NewLiteral(s, types.PointType{}), expression.NewLiteral(l, types.PointType{}))
   115  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   116  		require.NoError(err)
   117  		require.Equal(false, v)
   118  
   119  		f = NewWithin(expression.NewLiteral(e, types.PointType{}), expression.NewLiteral(l, types.PointType{}))
   120  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   121  		require.NoError(err)
   122  		require.Equal(false, v)
   123  	})
   124  }
   125  
   126  func TestPointWithinPolygon(t *testing.T) {
   127  	t.Run("point within polygon", func(t *testing.T) {
   128  		require := require.New(t)
   129  		f := NewWithin(expression.NewLiteral(types.Point{}, types.PointType{}), expression.NewLiteral(square, types.PolygonType{}))
   130  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   131  		require.NoError(err)
   132  		require.Equal(true, v)
   133  	})
   134  
   135  	t.Run("point within polygon intersects vertex", func(t *testing.T) {
   136  		require := require.New(t)
   137  		p := types.Point{X: 0, Y: 0}
   138  		a := types.Point{X: -1, Y: 0}
   139  		b := types.Point{X: 0, Y: 1}
   140  		c := types.Point{X: 1, Y: 0}
   141  		d := types.Point{X: 0, Y: -1}
   142  		poly := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, b, c, d, a}}}}
   143  		f := NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(poly, types.PolygonType{}))
   144  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   145  		require.NoError(err)
   146  		require.Equal(true, v)
   147  	})
   148  
   149  	t.Run("point within polygon (square) with hole", func(t *testing.T) {
   150  		require := require.New(t)
   151  		// passes through segments c2d2, a1b1, and a2b2; overlaps segment d2a2
   152  		p1 := types.Point{X: -3, Y: 2}
   153  		f := NewWithin(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(squareWithHole, types.PolygonType{}))
   154  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   155  		require.NoError(err)
   156  		require.Equal(true, v)
   157  
   158  		// passes through segments c2d2, a1b1, and a2b2
   159  		p2 := types.Point{X: -3, Y: 0}
   160  		f = NewWithin(expression.NewLiteral(p2, types.PointType{}), expression.NewLiteral(squareWithHole, types.PolygonType{}))
   161  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   162  		require.NoError(err)
   163  		require.Equal(true, v)
   164  
   165  		// passes through segments c2d2, a1b1, and a2b2; overlaps segment b2c2
   166  		p3 := types.Point{X: -3, Y: -2}
   167  		f = NewWithin(expression.NewLiteral(p3, 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  
   173  	t.Run("point within polygon (diamond) with hole", func(t *testing.T) {
   174  		require := require.New(t)
   175  
   176  		p1 := types.Point{X: -3, Y: 0}
   177  		f := NewWithin(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(diamondWithHole, types.PolygonType{}))
   178  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   179  		require.NoError(err)
   180  		require.Equal(true, v)
   181  
   182  		// passes through vertex a2 and segment a1b1
   183  		p2 := types.Point{X: -1, Y: 2}
   184  		f = NewWithin(expression.NewLiteral(p2, types.PointType{}), expression.NewLiteral(diamondWithHole, types.PolygonType{}))
   185  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   186  		require.NoError(err)
   187  		require.Equal(true, v)
   188  
   189  		p3 := types.Point{X: -1, Y: -2}
   190  		f = NewWithin(expression.NewLiteral(p3, types.PointType{}), expression.NewLiteral(diamondWithHole, types.PolygonType{}))
   191  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   192  		require.NoError(err)
   193  		require.Equal(true, v)
   194  	})
   195  
   196  	t.Run("point on polygon boundary not within", func(t *testing.T) {
   197  		require := require.New(t)
   198  
   199  		f := NewWithin(expression.NewLiteral(diamond.Lines[0].Points[0], types.PointType{}), expression.NewLiteral(diamond, types.PolygonType{}))
   200  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   201  		require.NoError(err)
   202  		require.Equal(false, v)
   203  
   204  		f = NewWithin(expression.NewLiteral(diamond.Lines[0].Points[1], types.PointType{}), expression.NewLiteral(diamond, types.PolygonType{}))
   205  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   206  		require.NoError(err)
   207  		require.Equal(false, v)
   208  
   209  		f = NewWithin(expression.NewLiteral(diamond.Lines[0].Points[2], types.PointType{}), expression.NewLiteral(diamond, types.PolygonType{}))
   210  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   211  		require.NoError(err)
   212  		require.Equal(false, v)
   213  
   214  		f = NewWithin(expression.NewLiteral(diamond.Lines[0].Points[3], types.PointType{}), expression.NewLiteral(diamond, types.PolygonType{}))
   215  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   216  		require.NoError(err)
   217  		require.Equal(false, v)
   218  	})
   219  
   220  	t.Run("point not within polygon intersects vertex", func(t *testing.T) {
   221  		require := require.New(t)
   222  
   223  		// passes through vertex b
   224  		p1 := types.Point{X: -1, Y: 4}
   225  		f := NewWithin(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(diamond, types.PolygonType{}))
   226  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   227  		require.NoError(err)
   228  		require.Equal(false, v)
   229  
   230  		// passes through vertex a and c
   231  		p2 := types.Point{X: -5, Y: 0}
   232  		f = NewWithin(expression.NewLiteral(p2, types.PointType{}), expression.NewLiteral(diamond, types.PolygonType{}))
   233  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   234  		require.NoError(err)
   235  		require.Equal(false, v)
   236  
   237  		// passes through vertex d
   238  		p3 := types.Point{X: -1, Y: -4}
   239  		f = NewWithin(expression.NewLiteral(p3, types.PointType{}), expression.NewLiteral(diamond, types.PolygonType{}))
   240  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   241  		require.NoError(err)
   242  		require.Equal(false, v)
   243  	})
   244  
   245  	t.Run("point not within polygon (square) with hole", func(t *testing.T) {
   246  		require := require.New(t)
   247  
   248  		// passes through segments a1b1 and a2b2
   249  		p1 := types.Point{X: 0, Y: 0}
   250  		f := NewWithin(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(squareWithHole, types.PolygonType{}))
   251  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   252  		require.NoError(err)
   253  		require.Equal(false, v)
   254  
   255  		// passes through segments c1d1, c2d2, a1b1, and a2b2; overlaps segment d2a2
   256  		p2 := types.Point{X: -5, Y: 2}
   257  		f = NewWithin(expression.NewLiteral(p2, types.PointType{}), expression.NewLiteral(squareWithHole, types.PolygonType{}))
   258  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   259  		require.NoError(err)
   260  		require.Equal(false, v)
   261  
   262  		// passes through segments c1d1, c2d2, a1b1, and a2b2; overlaps segment b2c2
   263  		p3 := types.Point{X: -5, Y: -2}
   264  		f = NewWithin(expression.NewLiteral(p3, types.PointType{}), expression.NewLiteral(squareWithHole, types.PolygonType{}))
   265  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   266  		require.NoError(err)
   267  		require.Equal(false, v)
   268  	})
   269  
   270  	t.Run("point not within polygon (diamond) with hole", func(t *testing.T) {
   271  		require := require.New(t)
   272  
   273  		// passes through vertexes d2, b2, and b1
   274  		p1 := types.Point{X: -3, Y: 0}
   275  		f := NewWithin(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(diamondWithHole, types.PolygonType{}))
   276  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   277  		require.NoError(err)
   278  		require.Equal(true, v)
   279  
   280  		// passes through vertex a2 and segment a1b1
   281  		p2 := types.Point{X: -1, Y: 2}
   282  		f = NewWithin(expression.NewLiteral(p2, types.PointType{}), expression.NewLiteral(diamondWithHole, types.PolygonType{}))
   283  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   284  		require.NoError(err)
   285  		require.Equal(true, v)
   286  
   287  		// passes through vertex c2 and segment b1c1
   288  		p3 := types.Point{X: -1, Y: -2}
   289  		f = NewWithin(expression.NewLiteral(p3, types.PointType{}), expression.NewLiteral(diamondWithHole, types.PolygonType{}))
   290  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   291  		require.NoError(err)
   292  		require.Equal(true, v)
   293  	})
   294  
   295  	t.Run("point not within polygon (square) with hole in hole", func(t *testing.T) {
   296  		require := require.New(t)
   297  
   298  		a3 := types.Point{X: 1, Y: 1}
   299  		b3 := types.Point{X: 1, Y: -1}
   300  		c3 := types.Point{X: -1, Y: -1}
   301  		d3 := types.Point{X: -1, Y: 1}
   302  
   303  		l3 := types.LineString{Points: []types.Point{a3, b3, c3, d3, a3}}
   304  		poly := types.Polygon{Lines: []types.LineString{squareWithHole.Lines[0], squareWithHole.Lines[1], l3}}
   305  
   306  		// passes through segments a1b1 and a2b2
   307  		p1 := types.Point{X: 0, Y: 0}
   308  		f := NewWithin(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(poly, types.PolygonType{}))
   309  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   310  		require.NoError(err)
   311  		require.Equal(false, v)
   312  
   313  		// passes through segments c1d1, c2d2, a1b1, and a2b2; overlaps segment d2a2
   314  		p2 := types.Point{X: -5, Y: 2}
   315  		f = NewWithin(expression.NewLiteral(p2, types.PointType{}), expression.NewLiteral(poly, types.PolygonType{}))
   316  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   317  		require.NoError(err)
   318  		require.Equal(false, v)
   319  
   320  		// passes through segments c1d1, c2d2, a1b1, and a2b2; overlaps segment b2c2
   321  		p3 := types.Point{X: -5, Y: -2}
   322  		f = NewWithin(expression.NewLiteral(p3, types.PointType{}), expression.NewLiteral(poly, types.PolygonType{}))
   323  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   324  		require.NoError(err)
   325  		require.Equal(false, v)
   326  	})
   327  
   328  	t.Run("point within non-simple polygon", func(t *testing.T) {
   329  		require := require.New(t)
   330  		// looks like a bowtie
   331  		a := types.Point{X: -2, Y: 2}
   332  		b := types.Point{X: 2, Y: 2}
   333  		c := types.Point{X: 2, Y: -2}
   334  		d := types.Point{X: -2, Y: -2}
   335  		l := types.LineString{Points: []types.Point{a, c, b, d, a}}
   336  		p := types.Polygon{Lines: []types.LineString{l}}
   337  
   338  		o := types.Point{}
   339  		w := types.Point{X: -1, Y: 0}
   340  		x := types.Point{X: 0, Y: 1}
   341  		y := types.Point{X: 1, Y: 0}
   342  		z := types.Point{X: 0, Y: -1}
   343  
   344  		f := NewWithin(expression.NewLiteral(o, types.PointType{}), expression.NewLiteral(p, types.PolygonType{}))
   345  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   346  		require.NoError(err)
   347  		require.Equal(false, v)
   348  
   349  		f = NewWithin(expression.NewLiteral(w, types.PointType{}), expression.NewLiteral(p, types.PolygonType{}))
   350  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   351  		require.NoError(err)
   352  		require.Equal(true, v)
   353  
   354  		f = NewWithin(expression.NewLiteral(x, types.PointType{}), expression.NewLiteral(p, types.PolygonType{}))
   355  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   356  		require.NoError(err)
   357  		require.Equal(false, v)
   358  
   359  		f = NewWithin(expression.NewLiteral(y, types.PointType{}), expression.NewLiteral(p, types.PolygonType{}))
   360  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   361  		require.NoError(err)
   362  		require.Equal(true, v)
   363  
   364  		f = NewWithin(expression.NewLiteral(z, types.PointType{}), expression.NewLiteral(p, types.PolygonType{}))
   365  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   366  		require.NoError(err)
   367  		require.Equal(false, v)
   368  	})
   369  }
   370  
   371  func TestPointWithinMultiPoint(t *testing.T) {
   372  	t.Run("points within multipoint", func(t *testing.T) {
   373  		require := require.New(t)
   374  
   375  		f := NewWithin(expression.NewLiteral(simpleMultiPoint.Points[0], types.PointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{}))
   376  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   377  		require.NoError(err)
   378  		require.Equal(true, v)
   379  
   380  		f = NewWithin(expression.NewLiteral(simpleMultiPoint.Points[0], types.PointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{}))
   381  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   382  		require.NoError(err)
   383  		require.Equal(true, v)
   384  
   385  		f = NewWithin(expression.NewLiteral(simpleMultiPoint.Points[0], types.PointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{}))
   386  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   387  		require.NoError(err)
   388  		require.Equal(true, v)
   389  	})
   390  
   391  	t.Run("point not within multipoint", func(t *testing.T) {
   392  		require := require.New(t)
   393  
   394  		f := NewWithin(expression.NewLiteral(types.Point{}, types.PointType{}), expression.NewLiteral(simpleMultiPoint, types.MultiPointType{}))
   395  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   396  		require.NoError(err)
   397  		require.Equal(false, v)
   398  	})
   399  }
   400  
   401  func TestPointWithinMultiLineString(t *testing.T) {
   402  	t.Run("points within multilinestring", func(t *testing.T) {
   403  		require := require.New(t)
   404  		p1 := types.Point{X: -1, Y: -1}
   405  		p2 := types.Point{X: 1, Y: 1}
   406  		p3 := types.Point{X: 123, Y: 456}
   407  		l1 := types.LineString{Points: []types.Point{p1, p2}}
   408  		l2 := types.LineString{Points: []types.Point{p3, p3}}
   409  		ml := types.MultiLineString{Lines: []types.LineString{l1, l2}}
   410  
   411  		f := NewWithin(expression.NewLiteral(p3, types.PointType{}), expression.NewLiteral(ml, types.MultiPointType{}))
   412  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   413  		require.NoError(err)
   414  		require.Equal(true, v)
   415  
   416  		p := types.Point{X: 0, Y: 0}
   417  		f = NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(ml, types.MultiPointType{}))
   418  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   419  		require.NoError(err)
   420  		require.Equal(true, v)
   421  	})
   422  
   423  	t.Run("points not within multilinestring", func(t *testing.T) {
   424  		require := require.New(t)
   425  		p1 := types.Point{X: -1, Y: -1}
   426  		p2 := types.Point{X: 1, Y: 1}
   427  		p3 := types.Point{X: 123, Y: 456}
   428  		l1 := types.LineString{Points: []types.Point{p1, p2}}
   429  		l2 := types.LineString{Points: []types.Point{p3, p3}}
   430  		ml := types.MultiLineString{Lines: []types.LineString{l1, l2}}
   431  
   432  		f := NewWithin(expression.NewLiteral(p1, types.PointType{}), expression.NewLiteral(ml, types.MultiLineStringType{}))
   433  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   434  		require.NoError(err)
   435  		require.Equal(false, v)
   436  
   437  		p := types.Point{X: 100, Y: 1000}
   438  		f = NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(ml, types.MultiLineStringType{}))
   439  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   440  		require.NoError(err)
   441  		require.Equal(false, v)
   442  	})
   443  }
   444  
   445  func TestPointWithinMultiPolygon(t *testing.T) {
   446  	t.Run("point within multipolygon", func(t *testing.T) {
   447  		require := require.New(t)
   448  		f := NewWithin(expression.NewLiteral(types.Point{}, types.PointType{}), expression.NewLiteral(simpleMultiPolygon, types.MultiLineStringType{}))
   449  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   450  		require.NoError(err)
   451  		require.Equal(true, v)
   452  	})
   453  
   454  	t.Run("points not within multipolygon", func(t *testing.T) {
   455  		// TODO: fix this one
   456  		require := require.New(t)
   457  		p := types.Point{X: 100, Y: 100}
   458  
   459  		a1 := types.Point{X: 4, Y: 4}
   460  		b1 := types.Point{X: 4, Y: -4}
   461  		c1 := types.Point{X: -4, Y: -4}
   462  		d1 := types.Point{X: -4, Y: 4}
   463  
   464  		a2 := types.Point{X: 2, Y: 2}
   465  		b2 := types.Point{X: 2, Y: -2}
   466  		c2 := types.Point{X: -2, Y: -2}
   467  		d2 := types.Point{X: -2, Y: 2}
   468  
   469  		l1 := types.LineString{Points: []types.Point{a1, b1, c1, d1, a1}}
   470  		l2 := types.LineString{Points: []types.Point{a2, b2, c2, d2, a2}}
   471  		mp := types.MultiPolygon{Polygons: []types.Polygon{{Lines: []types.LineString{l1}}, {Lines: []types.LineString{l2}}}}
   472  
   473  		f := NewWithin(expression.NewLiteral(p, types.PointType{}), 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 TestPointWithinGeometryCollection(t *testing.T) {
   481  	t.Run("point within empty geometrycollection returns null", func(t *testing.T) {
   482  		require := require.New(t)
   483  		p := types.Point{X: 0, Y: 0}
   484  		gc := types.GeomColl{}
   485  
   486  		f := NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(gc, types.GeomCollType{}))
   487  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   488  		require.NoError(err)
   489  		require.Equal(nil, v)
   490  	})
   491  
   492  	t.Run("point within geometrycollection", func(t *testing.T) {
   493  		require := require.New(t)
   494  		p := types.Point{X: 0, Y: 0}
   495  		gc := types.GeomColl{Geoms: []types.GeometryValue{p}}
   496  
   497  		f := NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(gc, types.GeomCollType{}))
   498  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   499  		require.NoError(err)
   500  		require.Equal(true, v)
   501  	})
   502  
   503  	t.Run("point not within geometrycollection", func(t *testing.T) {
   504  		require := require.New(t)
   505  		p := types.Point{X: 0, Y: 0}
   506  		a := types.Point{X: 1, Y: 0}
   507  		gc := types.GeomColl{Geoms: []types.GeometryValue{a}}
   508  
   509  		f := NewWithin(expression.NewLiteral(p, types.PointType{}), expression.NewLiteral(gc, types.GeomCollType{}))
   510  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   511  		require.NoError(err)
   512  		require.Equal(false, v)
   513  	})
   514  }
   515  
   516  func TestWithin(t *testing.T) {
   517  	t.Skip("these are all the cases that haven't been implemented yet")
   518  
   519  	// LineString vs Point
   520  	t.Run("linestring never within point", func(t *testing.T) {
   521  		require := require.New(t)
   522  		f := NewWithin(expression.NewLiteral(emptyLineString, types.LineStringType{}), expression.NewLiteral(types.Point{}, types.PointType{}))
   523  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   524  		require.NoError(err)
   525  		require.Equal(false, v)
   526  	})
   527  
   528  	// LineString vs LineString
   529  	t.Run("linestring within linestring", func(t *testing.T) {
   530  		require := require.New(t)
   531  		a := types.Point{X: 0, Y: 0}
   532  		b := types.Point{X: 1, Y: 1}
   533  		c := types.Point{X: -5, Y: -5}
   534  		d := types.Point{X: 5, Y: 5}
   535  		l1 := types.LineString{Points: []types.Point{a, b}}
   536  		l2 := types.LineString{Points: []types.Point{c, d}}
   537  		f := NewWithin(expression.NewLiteral(l1, types.LineStringType{}), expression.NewLiteral(l2, types.LineStringType{}))
   538  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   539  		require.NoError(err)
   540  		require.Equal(true, v)
   541  	})
   542  
   543  	t.Run("linestring within itself", func(t *testing.T) {
   544  		require := require.New(t)
   545  		f := NewWithin(expression.NewLiteral(simpleLineString, types.LineStringType{}), expression.NewLiteral(simpleLineString, types.LineStringType{}))
   546  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   547  		require.NoError(err)
   548  		require.Equal(true, v)
   549  	})
   550  
   551  	t.Run("many line segments within larger line segment", func(t *testing.T) {
   552  		require := require.New(t)
   553  		p := types.Point{X: 0, Y: 0}
   554  		q := types.Point{X: 4, Y: 4}
   555  		l := types.LineString{Points: []types.Point{p, q}}
   556  
   557  		f := NewWithin(expression.NewLiteral(simpleLineString, types.LineStringType{}), expression.NewLiteral(l, types.LineStringType{}))
   558  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   559  		require.NoError(err)
   560  		require.Equal(true, v)
   561  	})
   562  
   563  	t.Run("larger line segment within many small line segments", func(t *testing.T) {
   564  		require := require.New(t)
   565  
   566  		a := types.Point{X: 0, Y: 0}
   567  		b := types.Point{X: 1, Y: 1}
   568  		c := types.Point{X: 2, Y: 2}
   569  		d := types.Point{X: 3, Y: 3}
   570  		e := types.Point{X: 4, Y: 4}
   571  		l1 := types.LineString{Points: []types.Point{b, d}}
   572  		l2 := types.LineString{Points: []types.Point{a, b, c, d, e}}
   573  
   574  		f := NewWithin(expression.NewLiteral(l1, types.LineStringType{}), expression.NewLiteral(l2, types.LineStringType{}))
   575  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   576  		require.NoError(err)
   577  		require.Equal(true, v)
   578  	})
   579  
   580  	t.Run("alternating line segments", func(t *testing.T) {
   581  		require := require.New(t)
   582  
   583  		a := types.Point{X: 0, Y: 0}
   584  		b := types.Point{X: 1, Y: 1}
   585  		c := types.Point{X: 2, Y: 2}
   586  		d := types.Point{X: 3, Y: 3}
   587  		e := types.Point{X: 4, Y: 4}
   588  		l1 := types.LineString{Points: []types.Point{b, d}}
   589  		l2 := types.LineString{Points: []types.Point{a, c, e}}
   590  
   591  		f := NewWithin(expression.NewLiteral(l1, types.LineStringType{}), expression.NewLiteral(l2, types.LineStringType{}))
   592  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   593  		require.NoError(err)
   594  		require.Equal(true, v)
   595  	})
   596  
   597  	t.Run("linestring not within perpendicular linestring", func(t *testing.T) {
   598  		require := require.New(t)
   599  		a := types.Point{X: 0, Y: 0}
   600  		b := types.Point{X: 1, Y: 1}
   601  		c := types.Point{X: 1, Y: 0}
   602  		d := types.Point{X: 0, Y: 1}
   603  		l1 := types.LineString{Points: []types.Point{a, b}}
   604  		l2 := types.LineString{Points: []types.Point{c, d}}
   605  		f := NewWithin(expression.NewLiteral(l1, types.LineStringType{}), expression.NewLiteral(l2, types.LineStringType{}))
   606  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   607  		require.NoError(err)
   608  		require.Equal(false, v)
   609  		f = NewWithin(expression.NewLiteral(l2, types.LineStringType{}), expression.NewLiteral(l1, types.LineStringType{}))
   610  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   611  		require.NoError(err)
   612  		require.Equal(false, v)
   613  	})
   614  
   615  	t.Run("axis-aligned perpendicular linestring not within", func(t *testing.T) {
   616  		require := require.New(t)
   617  		a := types.Point{X: 0, Y: 0}
   618  		b := types.Point{X: 0, Y: 1}
   619  		c := types.Point{X: 1, Y: 0}
   620  		l1 := types.LineString{Points: []types.Point{a, b}}
   621  		l2 := types.LineString{Points: []types.Point{a, c}}
   622  		f := NewWithin(expression.NewLiteral(l1, types.LineStringType{}), expression.NewLiteral(l2, types.LineStringType{}))
   623  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   624  		require.NoError(err)
   625  		require.Equal(false, v)
   626  		f = NewWithin(expression.NewLiteral(l2, types.LineStringType{}), expression.NewLiteral(l1, types.LineStringType{}))
   627  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   628  		require.NoError(err)
   629  		require.Equal(false, v)
   630  	})
   631  
   632  	t.Run("terminal line points not in line", func(t *testing.T) {
   633  		require := require.New(t)
   634  		a := types.Point{X: 0, Y: 0}
   635  		b := types.Point{X: 1, Y: 1}
   636  		l := types.LineString{Points: []types.Point{a, b}}
   637  		la := types.LineString{Points: []types.Point{a, a}}
   638  		lb := types.LineString{Points: []types.Point{b, b}}
   639  		f := NewWithin(expression.NewLiteral(la, types.LineStringType{}), expression.NewLiteral(l, types.LineStringType{}))
   640  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   641  		require.NoError(err)
   642  		require.Equal(false, v)
   643  		f = NewWithin(expression.NewLiteral(lb, types.LineStringType{}), expression.NewLiteral(l, types.LineStringType{}))
   644  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   645  		require.NoError(err)
   646  		require.Equal(false, v)
   647  	})
   648  
   649  	// LineString vs Polygon
   650  	t.Run("linestring within polygon", func(t *testing.T) {
   651  		require := require.New(t)
   652  		i := types.Point{X: -1, Y: -1}
   653  		j := types.Point{X: 1, Y: 1}
   654  		l := types.LineString{Points: []types.Point{i, j}}
   655  
   656  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(square, types.LineStringType{}))
   657  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   658  		require.NoError(err)
   659  		require.Equal(true, v)
   660  	})
   661  
   662  	t.Run("linestring touching boundary is within polygon", func(t *testing.T) {
   663  		require := require.New(t)
   664  		a := types.Point{X: -1, Y: -1}
   665  		b := types.Point{X: 1, Y: 1}
   666  		c := types.Point{X: 4, Y: 4}
   667  		d := types.Point{X: -4, Y: 4}
   668  		l := types.LineString{Points: []types.Point{a, b, c, d}}
   669  
   670  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(square, types.LineStringType{}))
   671  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   672  		require.NoError(err)
   673  		require.Equal(true, v)
   674  	})
   675  
   676  	t.Run("linestring is not within polygon", func(t *testing.T) {
   677  		require := require.New(t)
   678  		a := types.Point{X: -100, Y: 100}
   679  		b := types.Point{X: 100, Y: 100}
   680  		c := types.Point{X: 4, Y: 4}
   681  		d := types.Point{X: -4, Y: 4}
   682  		l := types.LineString{Points: []types.Point{a, b, c, d}}
   683  
   684  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(square, types.LineStringType{}))
   685  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   686  		require.NoError(err)
   687  		require.Equal(false, v)
   688  	})
   689  
   690  	t.Run("linestring crosses through polygon", func(t *testing.T) {
   691  		require := require.New(t)
   692  		i := types.Point{X: -100, Y: -100}
   693  		j := types.Point{X: 100, Y: 100}
   694  		l := types.LineString{Points: []types.Point{i, j}}
   695  
   696  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(square, types.LineStringType{}))
   697  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   698  		require.NoError(err)
   699  		require.Equal(false, v)
   700  	})
   701  
   702  	t.Run("linestring boundary is not within polygon", func(t *testing.T) {
   703  		require := require.New(t)
   704  		f := NewWithin(expression.NewLiteral(square.Lines[0], types.LineStringType{}), expression.NewLiteral(square, types.LineStringType{}))
   705  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   706  		require.NoError(err)
   707  		require.Equal(false, v)
   708  	})
   709  
   710  	t.Run("linestring in hole is not within polygon", func(t *testing.T) {
   711  		require := require.New(t)
   712  		i := types.Point{X: -1, Y: -1}
   713  		j := types.Point{X: 1, Y: 1}
   714  		l := types.LineString{Points: []types.Point{i, j}}
   715  
   716  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(squareWithHole, types.LineStringType{}))
   717  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   718  		require.NoError(err)
   719  		require.Equal(false, v)
   720  	})
   721  
   722  	t.Run("linestring crosses exterior not within polygon", func(t *testing.T) {
   723  		require := require.New(t)
   724  		a := types.Point{X: 4, Y: 0}
   725  		b := types.Point{X: -4, Y: 0}
   726  		c := types.Point{X: -2, Y: 4}
   727  		d := types.Point{X: 0, Y: 2}
   728  		e := types.Point{X: 2, Y: 4}
   729  		l1 := types.LineString{Points: []types.Point{a, b, c, d, e, a}}
   730  		p := types.Polygon{Lines: []types.LineString{l1}}
   731  
   732  		i := types.Point{X: -2, Y: 3}
   733  		j := types.Point{X: 2, Y: 3}
   734  		l := types.LineString{Points: []types.Point{i, j}}
   735  
   736  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(p, types.LineStringType{}))
   737  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   738  		require.NoError(err)
   739  		require.Equal(false, v)
   740  	})
   741  
   742  	t.Run("linestring within non-simple polygon", func(t *testing.T) {
   743  		require := require.New(t)
   744  		// looks like a bowtie
   745  		a := types.Point{X: -2, Y: 2}
   746  		b := types.Point{X: 2, Y: 2}
   747  		c := types.Point{X: 2, Y: -2}
   748  		d := types.Point{X: -2, Y: -2}
   749  		l := types.LineString{Points: []types.Point{a, b, c, d, a}}
   750  		p := types.Polygon{Lines: []types.LineString{l}}
   751  
   752  		w := types.Point{X: -1, Y: 0}
   753  		x := types.Point{X: 0, Y: 1}
   754  		y := types.Point{X: 1, Y: 0}
   755  		z := types.Point{X: 0, Y: -1}
   756  
   757  		wx := types.LineString{Points: []types.Point{w, x}}
   758  		yz := types.LineString{Points: []types.Point{y, z}}
   759  		wy := types.LineString{Points: []types.Point{w, y}}
   760  		xz := types.LineString{Points: []types.Point{x, z}}
   761  
   762  		f := NewWithin(expression.NewLiteral(wx, types.LineStringType{}), expression.NewLiteral(p, types.PolygonType{}))
   763  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   764  		require.NoError(err)
   765  		require.Equal(false, v)
   766  
   767  		f = NewWithin(expression.NewLiteral(yz, types.LineStringType{}), expression.NewLiteral(p, types.PolygonType{}))
   768  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   769  		require.NoError(err)
   770  		require.Equal(false, v)
   771  
   772  		f = NewWithin(expression.NewLiteral(wy, types.LineStringType{}), expression.NewLiteral(p, types.PolygonType{}))
   773  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   774  		require.NoError(err)
   775  		require.Equal(false, v)
   776  
   777  		// Oddly, the LineString that is completely out of the Polygon is the one that is true
   778  		f = NewWithin(expression.NewLiteral(xz, types.LineStringType{}), expression.NewLiteral(p, types.PolygonType{}))
   779  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   780  		require.NoError(err)
   781  		require.Equal(true, v)
   782  	})
   783  
   784  	// LineString vs MultiPoint
   785  	t.Run("linestring never within multipoint", func(t *testing.T) {
   786  		require := require.New(t)
   787  		a := types.Point{X: 4, Y: 4}
   788  		b := types.Point{X: 4, Y: -4}
   789  		c := types.Point{X: -4, Y: -4}
   790  		d := types.Point{X: -4, Y: 4}
   791  		l := types.LineString{Points: []types.Point{a, b, c, d}}
   792  		mp := types.MultiPoint{Points: []types.Point{a, b, c, d}}
   793  
   794  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(mp, types.MultiPointType{}))
   795  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   796  		require.NoError(err)
   797  		require.Equal(false, v)
   798  	})
   799  
   800  	// LineString vs MultiLineString
   801  	t.Run("linestring within multilinestring", func(t *testing.T) {
   802  		require := require.New(t)
   803  		a := types.Point{X: 0, Y: 0}
   804  		b := types.Point{X: 1, Y: 1}
   805  		c := types.Point{X: 2, Y: 2}
   806  		l := types.LineString{Points: []types.Point{a, b, c}}
   807  		ml := types.MultiLineString{Lines: []types.LineString{l}}
   808  
   809  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(ml, types.MultiLineStringType{}))
   810  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   811  		require.NoError(err)
   812  		require.Equal(true, v)
   813  	})
   814  
   815  	// TODO: need to do that weird even odd thing...
   816  	t.Run("linestring within split multilinestring", func(t *testing.T) {
   817  		require := require.New(t)
   818  		a := types.Point{X: 0, Y: 0}
   819  		b := types.Point{X: 1, Y: 1}
   820  		c := types.Point{X: 2, Y: 2}
   821  		l1 := types.LineString{Points: []types.Point{a, b}}
   822  		l2 := types.LineString{Points: []types.Point{b, c}}
   823  		ml := types.MultiLineString{Lines: []types.LineString{l1, l2}}
   824  		l := types.LineString{Points: []types.Point{a, c}}
   825  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(ml, types.MultiLineStringType{}))
   826  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   827  		require.NoError(err)
   828  		require.Equal(true, v)
   829  	})
   830  
   831  	t.Run("terminal line points not with in multilinestring", func(t *testing.T) {
   832  		require := require.New(t)
   833  		a := types.Point{X: 0, Y: 0}
   834  		b := types.Point{X: 1, Y: 1}
   835  		c := types.Point{X: 2, Y: 2}
   836  		ab := types.LineString{Points: []types.Point{a, b}}
   837  		bc := types.LineString{Points: []types.Point{b, c}}
   838  		ml := types.MultiLineString{Lines: []types.LineString{ab, bc}}
   839  
   840  		aa := types.LineString{Points: []types.Point{a, a}}
   841  		bb := types.LineString{Points: []types.Point{b, b}}
   842  		cc := types.LineString{Points: []types.Point{c, c}}
   843  		f := NewWithin(expression.NewLiteral(aa, types.LineStringType{}), expression.NewLiteral(ml, types.MultiLineStringType{}))
   844  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   845  		require.NoError(err)
   846  		require.Equal(false, v)
   847  		f = NewWithin(expression.NewLiteral(bb, types.LineStringType{}), expression.NewLiteral(ml, types.MultiLineStringType{}))
   848  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   849  		require.NoError(err)
   850  		require.Equal(true, v)
   851  		f = NewWithin(expression.NewLiteral(cc, types.LineStringType{}), expression.NewLiteral(ml, types.MultiLineStringType{}))
   852  		v, err = f.Eval(sql.NewEmptyContext(), nil)
   853  		require.NoError(err)
   854  		require.Equal(false, v)
   855  	})
   856  
   857  	// LineString vs MultiPolygon
   858  	t.Run("linestring within two separate touching polygons", func(t *testing.T) {
   859  		require := require.New(t)
   860  		a := types.Point{X: -2, Y: 1}
   861  		b := types.Point{X: 0, Y: 1}
   862  		c := types.Point{X: 0, Y: -1}
   863  		d := types.Point{X: -2, Y: -1}
   864  		e := types.Point{X: 2, Y: 1}
   865  		f := types.Point{X: 2, Y: -1}
   866  		// these are two rectangles that share a side on the y axis
   867  		p1 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, b, c, d, a}}}}
   868  		p2 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{b, e, f, c, b}}}}
   869  		mp := types.MultiPolygon{Polygons: []types.Polygon{p1, p2}}
   870  
   871  		l := types.LineString{Points: []types.Point{{X: -1, Y: 0}, {X: 1, Y: 0}}}
   872  		ff := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(mp, types.MultiLineStringType{}))
   873  		v, err := ff.Eval(sql.NewEmptyContext(), nil)
   874  		require.NoError(err)
   875  		require.Equal(true, v)
   876  
   877  		l = types.LineString{Points: []types.Point{{X: -3, Y: 0}, {X: 3, Y: 0}}}
   878  		ff = NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(mp, types.MultiLineStringType{}))
   879  		v, err = ff.Eval(sql.NewEmptyContext(), nil)
   880  		require.NoError(err)
   881  		require.Equal(false, v)
   882  	})
   883  
   884  	t.Run("linestring within two separate not touching polygons", func(t *testing.T) {
   885  		require := require.New(t)
   886  		// triangle
   887  		a := types.Point{X: -3, Y: 0}
   888  		b := types.Point{X: -2, Y: 2}
   889  		c := types.Point{X: -1, Y: 0}
   890  		p1 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, b, c, a}}}}
   891  
   892  		// triangle
   893  		d := types.Point{X: 1, Y: 0}
   894  		e := types.Point{X: 2, Y: 2}
   895  		f := types.Point{X: 3, Y: 0}
   896  		p2 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{d, e, f, d}}}}
   897  
   898  		mp := types.MultiPolygon{Polygons: []types.Polygon{p1, p2}}
   899  
   900  		l := types.LineString{Points: []types.Point{{X: -2, Y: 1}, {X: 2, Y: 1}}}
   901  		ff := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(mp, types.MultiLineStringType{}))
   902  		v, err := ff.Eval(sql.NewEmptyContext(), nil)
   903  		require.NoError(err)
   904  		require.Equal(false, v)
   905  	})
   906  
   907  	// LineString vs GeometryCollection
   908  	t.Run("linestring within empty geometrycollection returns null", func(t *testing.T) {
   909  		require := require.New(t)
   910  		l := types.LineString{Points: []types.Point{{}, {}}}
   911  		gc := types.GeomColl{}
   912  
   913  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(gc, types.GeomCollType{}))
   914  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   915  		require.NoError(err)
   916  		require.Equal(nil, v)
   917  	})
   918  
   919  	t.Run("linestring within geometrycollection", func(t *testing.T) {
   920  		require := require.New(t)
   921  		l := types.LineString{Points: []types.Point{{}, {}}}
   922  		gc := types.GeomColl{Geoms: []types.GeometryValue{l}}
   923  
   924  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(gc, types.GeomCollType{}))
   925  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   926  		require.NoError(err)
   927  		require.Equal(true, v)
   928  	})
   929  
   930  	t.Run("linestring not within geometrycollection", func(t *testing.T) {
   931  		require := require.New(t)
   932  		l := types.LineString{Points: []types.Point{{}, {}}}
   933  		l1 := types.LineString{Points: []types.Point{{X: 1, Y: 1}, {}}}
   934  		gc := types.GeomColl{Geoms: []types.GeometryValue{l1}}
   935  
   936  		f := NewWithin(expression.NewLiteral(l, types.LineStringType{}), expression.NewLiteral(gc, types.GeomCollType{}))
   937  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   938  		require.NoError(err)
   939  		require.Equal(false, v)
   940  	})
   941  
   942  	// LineString vs GeometryCollection
   943  
   944  	// Polygon vs Point
   945  	t.Run("polygon never within point", func(t *testing.T) {
   946  		require := require.New(t)
   947  		p := types.Point{X: 0, Y: 0}
   948  		l := types.LineString{Points: []types.Point{p, p, p, p}}
   949  		poly := types.Polygon{Lines: []types.LineString{l}}
   950  
   951  		f := NewWithin(expression.NewLiteral(poly, types.PolygonType{}), expression.NewLiteral(p, types.PointType{}))
   952  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   953  		require.NoError(err)
   954  		require.Equal(false, v)
   955  	})
   956  
   957  	// Polygon vs LineString
   958  	t.Run("polygon never within linestring", func(t *testing.T) {
   959  		require := require.New(t)
   960  		p := types.Point{X: 0, Y: 0}
   961  		l := types.LineString{Points: []types.Point{p, p, p, p}}
   962  		poly := types.Polygon{Lines: []types.LineString{l}}
   963  
   964  		f := NewWithin(expression.NewLiteral(poly, types.PolygonType{}), expression.NewLiteral(l, types.LineStringType{}))
   965  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   966  		require.NoError(err)
   967  		require.Equal(false, v)
   968  	})
   969  
   970  	// Polygon vs Polygon
   971  	t.Run("empty polygon within polygon", func(t *testing.T) {
   972  		require := require.New(t)
   973  
   974  		f := NewWithin(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(square, types.PolygonType{}))
   975  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   976  		require.NoError(err)
   977  		require.Equal(true, v)
   978  	})
   979  
   980  	t.Run("polygon within polygon touching border", func(t *testing.T) {
   981  		require := require.New(t)
   982  		// triangle inside polygon
   983  		a := types.Point{X: -1, Y: 1}
   984  		b := types.Point{X: 1, Y: 1}
   985  		c := types.Point{X: 1, Y: -1}
   986  		d := types.Point{X: -1, Y: -1}
   987  		l := types.LineString{Points: []types.Point{a, b, c, d, a}}
   988  		p1 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, b, {}, a}}}}
   989  		p2 := types.Polygon{Lines: []types.LineString{l}}
   990  
   991  		f := NewWithin(expression.NewLiteral(p1, types.PolygonType{}), expression.NewLiteral(p2, types.PolygonType{}))
   992  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   993  		require.NoError(err)
   994  		require.Equal(true, v)
   995  	})
   996  
   997  	t.Run("empty polygon on vertex not within polygon", func(t *testing.T) {
   998  		require := require.New(t)
   999  
  1000  		a := types.Point{X: -1, Y: 1}
  1001  		b := types.Point{X: 1, Y: 1}
  1002  		c := types.Point{X: 1, Y: -1}
  1003  		d := types.Point{X: -1, Y: -1}
  1004  		p1 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, a, a, a}}}}
  1005  		l := types.LineString{Points: []types.Point{a, b, c, d, a}}
  1006  		p2 := types.Polygon{Lines: []types.LineString{l}}
  1007  
  1008  		f := NewWithin(expression.NewLiteral(p1, types.PolygonType{}), expression.NewLiteral(p2, types.PolygonType{}))
  1009  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1010  		require.NoError(err)
  1011  		require.Equal(false, v)
  1012  	})
  1013  
  1014  	t.Run("empty polygon not within itself", func(t *testing.T) {
  1015  		require := require.New(t)
  1016  		p := types.Polygon{Lines: []types.LineString{{Points: []types.Point{{}, {}, {}, {}}}}}
  1017  
  1018  		f := NewWithin(expression.NewLiteral(p, types.PolygonType{}), expression.NewLiteral(p, types.PolygonType{}))
  1019  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1020  		require.NoError(err)
  1021  		require.Equal(false, v)
  1022  	})
  1023  
  1024  	t.Run("polygon not within overlapping polygon", func(t *testing.T) {
  1025  		require := require.New(t)
  1026  		// right triangles
  1027  		a := types.Point{X: -1, Y: 1}
  1028  		b := types.Point{X: 1, Y: 0}
  1029  		c := types.Point{X: -1, Y: 0}
  1030  		d := types.Point{X: 1, Y: 1}
  1031  		p1 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, b, c, a}}}}
  1032  		p2 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{b, c, d, b}}}}
  1033  
  1034  		f := NewWithin(expression.NewLiteral(p1, types.LineStringType{}), expression.NewLiteral(p2, types.MultiLineStringType{}))
  1035  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1036  		require.NoError(err)
  1037  		require.Equal(false, v)
  1038  
  1039  		f = NewWithin(expression.NewLiteral(p2, types.LineStringType{}), expression.NewLiteral(p1, types.MultiLineStringType{}))
  1040  		v, err = f.Eval(sql.NewEmptyContext(), nil)
  1041  		require.NoError(err)
  1042  		require.Equal(false, v)
  1043  	})
  1044  
  1045  	// Polygon vs MultiPoint
  1046  	t.Run("polygon never within point", func(t *testing.T) {
  1047  		require := require.New(t)
  1048  		p := types.Point{X: 0, Y: 0}
  1049  		l := types.LineString{Points: []types.Point{p, p, p, p}}
  1050  		poly := types.Polygon{Lines: []types.LineString{l}}
  1051  
  1052  		f := NewWithin(expression.NewLiteral(poly, types.PolygonType{}), expression.NewLiteral(p, types.PointType{}))
  1053  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1054  		require.NoError(err)
  1055  		require.Equal(false, v)
  1056  	})
  1057  
  1058  	// Polygon vs MultiLineString
  1059  	t.Run("polygon never within multilinestring", func(t *testing.T) {
  1060  		require := require.New(t)
  1061  		p := types.Point{X: 0, Y: 0}
  1062  		l := types.LineString{Points: []types.Point{p, p, p, p}}
  1063  		ml := types.MultiLineString{Lines: []types.LineString{l}}
  1064  		poly := types.Polygon{Lines: []types.LineString{l}}
  1065  
  1066  		f := NewWithin(expression.NewLiteral(poly, types.PolygonType{}), expression.NewLiteral(ml, types.PointType{}))
  1067  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1068  		require.NoError(err)
  1069  		require.Equal(false, v)
  1070  	})
  1071  
  1072  	// Polygon vs MultiPolygon
  1073  	t.Run("polygon not within split touching multipolygon", func(t *testing.T) {
  1074  		require := require.New(t)
  1075  		a1 := types.Point{X: -1, Y: 1}
  1076  		b1 := types.Point{X: 1, Y: 1}
  1077  		c1 := types.Point{X: 1, Y: -1}
  1078  		d1 := types.Point{X: -1, Y: -1}
  1079  		l1 := types.LineString{Points: []types.Point{a1, b1, c1, d1, a1}}
  1080  		p1 := types.Polygon{Lines: []types.LineString{l1}}
  1081  
  1082  		a2 := types.Point{X: -2, Y: 2}
  1083  		b2 := types.Point{X: 2, Y: 2}
  1084  		c2 := types.Point{X: 2, Y: -2}
  1085  		d2 := types.Point{X: -2, Y: -2}
  1086  		e2 := types.Point{X: 0, Y: 2}
  1087  		f2 := types.Point{X: 0, Y: -2}
  1088  		l2 := types.LineString{Points: []types.Point{a2, e2, f2, d2, a1}}
  1089  		p2 := types.Polygon{Lines: []types.LineString{l2}}
  1090  		l3 := types.LineString{Points: []types.Point{e2, b2, c2, f2, e2}}
  1091  		p3 := types.Polygon{Lines: []types.LineString{l3}}
  1092  		mp := types.MultiPolygon{Polygons: []types.Polygon{p2, p3}}
  1093  
  1094  		f := NewWithin(expression.NewLiteral(p1, types.PolygonType{}), expression.NewLiteral(mp, types.PointType{}))
  1095  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1096  		require.NoError(err)
  1097  		require.Equal(false, v)
  1098  	})
  1099  
  1100  	// Polygon vs GeometryCollection
  1101  	t.Run("polygon within empty geometry collection returns null", func(t *testing.T) {
  1102  		require := require.New(t)
  1103  
  1104  		g := types.GeomColl{}
  1105  
  1106  		f := NewWithin(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(g, types.GeomCollType{}))
  1107  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1108  		require.NoError(err)
  1109  		require.Equal(nil, v)
  1110  	})
  1111  
  1112  	t.Run("empty polygon within geometry collection", func(t *testing.T) {
  1113  		require := require.New(t)
  1114  		g := types.GeomColl{Geoms: []types.GeometryValue{square}}
  1115  		f := NewWithin(expression.NewLiteral(emptyPolygon, types.PolygonType{}), expression.NewLiteral(g, types.GeomCollType{}))
  1116  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1117  		require.NoError(err)
  1118  		require.Equal(true, v)
  1119  	})
  1120  
  1121  	// MultiPoint vs Point
  1122  	t.Run("multipoint within point", func(t *testing.T) {
  1123  		require := require.New(t)
  1124  		p1 := types.Point{}
  1125  		mp := types.MultiPoint{Points: []types.Point{p1, p1, p1}}
  1126  
  1127  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(p1, types.PointType{}))
  1128  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1129  		require.NoError(err)
  1130  		require.Equal(true, v)
  1131  	})
  1132  
  1133  	t.Run("multipoint not within point", func(t *testing.T) {
  1134  		require := require.New(t)
  1135  		p1 := types.Point{}
  1136  		p2 := types.Point{X: 1, Y: 2}
  1137  		mp := types.MultiPoint{Points: []types.Point{p1, p2}}
  1138  
  1139  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(p1, types.PointType{}))
  1140  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1141  		require.NoError(err)
  1142  		require.Equal(false, v)
  1143  	})
  1144  
  1145  	// MultiPoint vs LineString
  1146  	t.Run("multipoint terminal points within empty linestring", func(t *testing.T) {
  1147  		require := require.New(t)
  1148  		p := types.Point{}
  1149  		mp := types.MultiPoint{Points: []types.Point{p, p}}
  1150  		l := types.LineString{Points: []types.Point{p, p}}
  1151  
  1152  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(l, types.LineStringType{}))
  1153  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1154  		require.NoError(err)
  1155  		require.Equal(true, v)
  1156  	})
  1157  
  1158  	t.Run("multipoint within linestring", func(t *testing.T) {
  1159  		require := require.New(t)
  1160  		a := types.Point{}
  1161  		b := types.Point{X: 2, Y: 2}
  1162  		p := types.Point{X: 1, Y: 1}
  1163  		mp := types.MultiPoint{Points: []types.Point{p}}
  1164  		ab := types.LineString{Points: []types.Point{a, b}}
  1165  
  1166  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(ab, types.LineStringType{}))
  1167  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1168  		require.NoError(err)
  1169  		require.Equal(true, v)
  1170  	})
  1171  
  1172  	t.Run("multipoint some within linestring", func(t *testing.T) {
  1173  		require := require.New(t)
  1174  		a := types.Point{}
  1175  		b := types.Point{X: 2, Y: 2}
  1176  		p := types.Point{X: 1, Y: 1}
  1177  		mp := types.MultiPoint{Points: []types.Point{a, p, b}}
  1178  		ab := types.LineString{Points: []types.Point{a, b}}
  1179  
  1180  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(ab, types.LineStringType{}))
  1181  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1182  		require.NoError(err)
  1183  		require.Equal(false, v)
  1184  	})
  1185  
  1186  	t.Run("multipoint terminal points not within linestring", func(t *testing.T) {
  1187  		require := require.New(t)
  1188  		a := types.Point{X: 1, Y: 1}
  1189  		b := types.Point{X: 2, Y: 2}
  1190  		mp := types.MultiPoint{Points: []types.Point{a, b}}
  1191  		ab := types.LineString{Points: []types.Point{a, b}}
  1192  
  1193  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(ab, types.LineStringType{}))
  1194  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1195  		require.NoError(err)
  1196  		require.Equal(false, v)
  1197  	})
  1198  
  1199  	// MultiPoint vs Polygon
  1200  	t.Run("multipoint within polygon", func(t *testing.T) {
  1201  		require := require.New(t)
  1202  		mp := types.MultiPoint{Points: []types.Point{{}}}
  1203  		a := types.Point{X: -1, Y: 1}
  1204  		b := types.Point{X: 1, Y: 1}
  1205  		c := types.Point{X: 1, Y: -1}
  1206  		d := types.Point{X: -1, Y: -1}
  1207  		poly := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, b, c, d, a}}}}
  1208  
  1209  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(poly, types.PolygonType{}))
  1210  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1211  		require.NoError(err)
  1212  		require.Equal(true, v)
  1213  	})
  1214  
  1215  	t.Run("multipoint origin and vertexes within polygon with", func(t *testing.T) {
  1216  		require := require.New(t)
  1217  
  1218  		a := types.Point{X: -1, Y: 1}
  1219  		b := types.Point{X: 1, Y: 1}
  1220  		c := types.Point{X: 1, Y: -1}
  1221  		d := types.Point{X: -1, Y: -1}
  1222  		mp := types.MultiPoint{Points: []types.Point{a, b, c, d, {}}}
  1223  		poly := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, b, c, d, a}}}}
  1224  
  1225  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(poly, types.PolygonType{}))
  1226  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1227  		require.NoError(err)
  1228  		require.Equal(true, v)
  1229  	})
  1230  
  1231  	t.Run("multipoint vertexes not within polygon", func(t *testing.T) {
  1232  		require := require.New(t)
  1233  
  1234  		a := types.Point{X: -1, Y: 1}
  1235  		b := types.Point{X: 1, Y: 1}
  1236  		c := types.Point{X: 1, Y: -1}
  1237  		d := types.Point{X: -1, Y: -1}
  1238  		mp := types.MultiPoint{Points: []types.Point{a, b, c, d}}
  1239  		poly := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, b, c, d, a}}}}
  1240  
  1241  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(poly, types.PolygonType{}))
  1242  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1243  		require.NoError(err)
  1244  		require.Equal(false, v)
  1245  	})
  1246  
  1247  	t.Run("multipoint points on interior, boundary, and exterior not within polygon", func(t *testing.T) {
  1248  		require := require.New(t)
  1249  
  1250  		a := types.Point{X: -1, Y: 1}
  1251  		b := types.Point{X: 1, Y: 1}
  1252  		c := types.Point{X: 1, Y: -1}
  1253  		d := types.Point{X: -1, Y: -1}
  1254  		mp := types.MultiPoint{Points: []types.Point{a, {}, types.Point{X: 100, Y: 100}}}
  1255  		poly := types.Polygon{Lines: []types.LineString{{Points: []types.Point{a, b, c, d, a}}}}
  1256  
  1257  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(poly, types.PolygonType{}))
  1258  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1259  		require.NoError(err)
  1260  		require.Equal(false, v)
  1261  	})
  1262  
  1263  	t.Run("multipoint terminal points not within empty polygon", func(t *testing.T) {
  1264  		require := require.New(t)
  1265  		mp := types.MultiPoint{Points: []types.Point{{}}}
  1266  		poly := types.Polygon{Lines: []types.LineString{{}, {}, {}, {}}}
  1267  
  1268  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(poly, types.PolygonType{}))
  1269  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1270  		require.NoError(err)
  1271  		require.Equal(false, v)
  1272  	})
  1273  
  1274  	// MultiPoint vs MultiPoint
  1275  
  1276  	// MultiPoint vs MultiLineString
  1277  
  1278  	// MultiPoint vs MultiPolygon
  1279  
  1280  	// MultiPoint vs GeometryCollection
  1281  	t.Run("multipoint within empty geometrycollection returns null", func(t *testing.T) {
  1282  		require := require.New(t)
  1283  		mp := types.MultiPoint{Points: []types.Point{{}, {}}}
  1284  		gc := types.GeomColl{}
  1285  
  1286  		f := NewWithin(expression.NewLiteral(mp, types.MultiPointType{}), expression.NewLiteral(gc, types.GeomCollType{}))
  1287  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1288  		require.NoError(err)
  1289  		require.Equal(nil, v)
  1290  	})
  1291  
  1292  	// MultiLineString vs Point
  1293  	t.Run("multilinestring never within point", func(t *testing.T) {
  1294  		require := require.New(t)
  1295  		p := types.Point{X: 0, Y: 0}
  1296  		l := types.LineString{Points: []types.Point{p, p}}
  1297  		ml := types.MultiLineString{Lines: []types.LineString{l}}
  1298  
  1299  		f := NewWithin(expression.NewLiteral(ml, types.LineStringType{}), expression.NewLiteral(p, types.PointType{}))
  1300  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1301  		require.NoError(err)
  1302  		require.Equal(false, v)
  1303  	})
  1304  
  1305  	// MultiLineString vs LineString
  1306  
  1307  	// MultiLineString vs Polygon
  1308  
  1309  	// MultiLineString vs MultiPoint
  1310  
  1311  	// MultiLineString vs MultiLineString
  1312  
  1313  	// MultiLineString vs MultiPolygon
  1314  
  1315  	// MultiLineString vs GeometryCollection
  1316  	t.Run("multilinestring within empty geometrycollection returns null", func(t *testing.T) {
  1317  		require := require.New(t)
  1318  		l := types.LineString{Points: []types.Point{{}, {}}}
  1319  		ml := types.MultiLineString{Lines: []types.LineString{l, l}}
  1320  		gc := types.GeomColl{}
  1321  
  1322  		f := NewWithin(expression.NewLiteral(ml, types.MultiLineStringType{}), expression.NewLiteral(gc, types.GeomCollType{}))
  1323  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1324  		require.NoError(err)
  1325  		require.Equal(nil, v)
  1326  	})
  1327  
  1328  	// MultiPolygon vs Point
  1329  	t.Run("multipolygon never within point", func(t *testing.T) {
  1330  		require := require.New(t)
  1331  		p := types.Point{X: 0, Y: 0}
  1332  		l := types.LineString{Points: []types.Point{p, p}}
  1333  		poly := types.Polygon{Lines: []types.LineString{l}}
  1334  		mpoly := types.MultiPolygon{Polygons: []types.Polygon{poly}}
  1335  
  1336  		f := NewWithin(expression.NewLiteral(mpoly, types.MultiPolygonType{}), expression.NewLiteral(p, types.PointType{}))
  1337  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1338  		require.NoError(err)
  1339  		require.Equal(false, v)
  1340  	})
  1341  
  1342  	// MultiPolygon vs LineString
  1343  	t.Run("multipolygon never within linestring", func(t *testing.T) {
  1344  		require := require.New(t)
  1345  		p := types.Point{X: 0, Y: 0}
  1346  		l := types.LineString{Points: []types.Point{p, p}}
  1347  		poly := types.Polygon{Lines: []types.LineString{l}}
  1348  		mpoly := types.MultiPolygon{Polygons: []types.Polygon{poly}}
  1349  
  1350  		f := NewWithin(expression.NewLiteral(mpoly, types.MultiPolygonType{}), expression.NewLiteral(l, types.LineStringType{}))
  1351  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1352  		require.NoError(err)
  1353  		require.Equal(false, v)
  1354  	})
  1355  
  1356  	// MultiPolygon vs Polygon
  1357  
  1358  	// MultiPolygon vs MultiPoint
  1359  
  1360  	// MultiPolygon vs MultiLineString
  1361  
  1362  	// MultiPolygon vs MultiPolygon
  1363  
  1364  	// MultiPolygon vs GeometryCollection
  1365  	t.Run("multipolygon within empty geometrycollection returns null", func(t *testing.T) {
  1366  		require := require.New(t)
  1367  		l := types.LineString{Points: []types.Point{{}, {}, {}, {}}}
  1368  		p := types.Polygon{Lines: []types.LineString{l}}
  1369  		mp := types.MultiPolygon{Polygons: []types.Polygon{p, p}}
  1370  		gc := types.GeomColl{}
  1371  
  1372  		f := NewWithin(expression.NewLiteral(mp, types.MultiPolygonType{}), expression.NewLiteral(gc, types.GeomCollType{}))
  1373  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1374  		require.NoError(err)
  1375  		require.Equal(nil, v)
  1376  	})
  1377  
  1378  	// GeometryCollection vs Point
  1379  	t.Run("geometrycollection within point", func(t *testing.T) {
  1380  		require := require.New(t)
  1381  		p := types.Point{}
  1382  		gc := types.GeomColl{Geoms: []types.GeometryValue{p}}
  1383  		f := NewWithin(expression.NewLiteral(gc, types.GeomCollType{}), expression.NewLiteral(p, types.PointType{}))
  1384  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1385  		require.NoError(err)
  1386  		require.Equal(true, v)
  1387  	})
  1388  
  1389  	// GeometryCollection vs LineString
  1390  	t.Run("geometrycollection within linestring", func(t *testing.T) {
  1391  		require := require.New(t)
  1392  		a := types.Point{X: 0, Y: 0}
  1393  		b := types.Point{X: 1, Y: 1}
  1394  		c := types.Point{X: -5, Y: -5}
  1395  		d := types.Point{X: 5, Y: 5}
  1396  		ab := types.LineString{Points: []types.Point{a, b}}
  1397  		cd := types.LineString{Points: []types.Point{c, d}}
  1398  		gc := types.GeomColl{Geoms: []types.GeometryValue{cd}}
  1399  		f := NewWithin(expression.NewLiteral(ab, types.GeomCollType{}), expression.NewLiteral(gc, types.LineStringType{}))
  1400  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1401  		require.NoError(err)
  1402  		require.Equal(true, v)
  1403  	})
  1404  
  1405  	// GeometryCollection vs Polygon
  1406  	t.Run("geometrycollection within polygon", func(t *testing.T) {
  1407  		require := require.New(t)
  1408  
  1409  		p1 := types.Polygon{Lines: []types.LineString{{Points: []types.Point{{}, {}, {}, {}}}}}
  1410  		gc := types.GeomColl{Geoms: []types.GeometryValue{p1}}
  1411  
  1412  		a := types.Point{X: -1, Y: 1}
  1413  		b := types.Point{X: 1, Y: 1}
  1414  		c := types.Point{X: 1, Y: -1}
  1415  		d := types.Point{X: -1, Y: -1}
  1416  		l := types.LineString{Points: []types.Point{a, b, c, d, a}}
  1417  		p2 := types.Polygon{Lines: []types.LineString{l}}
  1418  
  1419  		f := NewWithin(expression.NewLiteral(gc, types.GeomCollType{}), expression.NewLiteral(p2, types.PolygonType{}))
  1420  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1421  		require.NoError(err)
  1422  		require.Equal(true, v)
  1423  	})
  1424  
  1425  	// GeometryCollection vs MultiPoint
  1426  
  1427  	// GeometryCollection vs MultiLineString
  1428  
  1429  	// GeometryCollection vs MultiPolygon
  1430  
  1431  	// GeometryCollection vs GeometryCollection
  1432  	t.Run("empty geometry collection within empty geometrycollection returns null", func(t *testing.T) {
  1433  		require := require.New(t)
  1434  		gc := types.GeomColl{}
  1435  
  1436  		f := NewWithin(expression.NewLiteral(gc, types.GeomCollType{}), expression.NewLiteral(gc, types.GeomCollType{}))
  1437  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1438  		require.NoError(err)
  1439  		require.Equal(nil, v)
  1440  	})
  1441  
  1442  	t.Run("geometry collection within empty geometrycollection returns null", func(t *testing.T) {
  1443  		require := require.New(t)
  1444  		gc1 := types.GeomColl{Geoms: []types.GeometryValue{types.Point{}}}
  1445  		gc2 := types.GeomColl{}
  1446  
  1447  		f := NewWithin(expression.NewLiteral(gc1, types.GeomCollType{}), expression.NewLiteral(gc2, types.GeomCollType{}))
  1448  		v, err := f.Eval(sql.NewEmptyContext(), nil)
  1449  		require.NoError(err)
  1450  		require.Equal(nil, v)
  1451  	})
  1452  }