github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/st_dimension_test.go (about)

     1  // Copyright 2020-2021 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package spatial
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/dolthub/go-mysql-server/sql"
    23  	"github.com/dolthub/go-mysql-server/sql/expression"
    24  	"github.com/dolthub/go-mysql-server/sql/types"
    25  )
    26  
    27  func TestDimension(t *testing.T) {
    28  	t.Run("point is dimension 0", func(t *testing.T) {
    29  		require := require.New(t)
    30  		f := NewDimension(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{}))
    31  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    32  		require.NoError(err)
    33  		require.Equal(0, v)
    34  	})
    35  
    36  	t.Run("point with srid 4326 is dimension 0", func(t *testing.T) {
    37  		require := require.New(t)
    38  		f := NewDimension(expression.NewLiteral(types.Point{SRID: 4326, X: 1, Y: 2}, types.PointType{}))
    39  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    40  		require.NoError(err)
    41  		require.Equal(0, v)
    42  	})
    43  
    44  	t.Run("point with srid 3857 is dimension 0", func(t *testing.T) {
    45  		require := require.New(t)
    46  		f := NewDimension(expression.NewLiteral(types.Point{SRID: 3857, X: 1, Y: 2}, types.PointType{}))
    47  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    48  		require.NoError(err)
    49  		require.Equal(0, v)
    50  	})
    51  
    52  	t.Run("linestring is dimension 1", func(t *testing.T) {
    53  		require := require.New(t)
    54  		f := NewDimension(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.LineStringType{}))
    55  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    56  		require.NoError(err)
    57  		require.Equal(1, v)
    58  	})
    59  
    60  	t.Run("polygon dimension 2", func(t *testing.T) {
    61  		require := require.New(t)
    62  		f := NewDimension(expression.NewLiteral(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 1}, {X: 0, Y: 0}}}}}, types.PolygonType{}))
    63  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    64  		require.NoError(err)
    65  		require.Equal(2, v)
    66  	})
    67  
    68  	t.Run("multipoint is dimension 0", func(t *testing.T) {
    69  		require := require.New(t)
    70  		f := NewDimension(expression.NewLiteral(types.MultiPoint{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.MultiPointType{}))
    71  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    72  		require.NoError(err)
    73  		require.Equal(0, v)
    74  	})
    75  
    76  	t.Run("multilinestring is dimension 1", func(t *testing.T) {
    77  		require := require.New(t)
    78  		f := NewDimension(expression.NewLiteral(types.MultiLineString{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 1}, {X: 0, Y: 0}}}}}, types.MultiLineStringType{}))
    79  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    80  		require.NoError(err)
    81  		require.Equal(1, v)
    82  	})
    83  
    84  	t.Run("geometry with inner point is dimension 0", func(t *testing.T) {
    85  		require := require.New(t)
    86  		f := NewDimension(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.GeometryType{}))
    87  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    88  		require.NoError(err)
    89  		require.Equal(0, v)
    90  	})
    91  
    92  	t.Run("geometry with inner linestring is dimension 1", func(t *testing.T) {
    93  		require := require.New(t)
    94  		f := NewDimension(expression.NewLiteral(types.LineString{Points: []types.Point{{X: 0, Y: 1}, {X: 2, Y: 3}}}, types.GeometryType{}))
    95  		v, err := f.Eval(sql.NewEmptyContext(), nil)
    96  		require.NoError(err)
    97  		require.Equal(1, v)
    98  	})
    99  
   100  	t.Run("geometry with inner polygon dimension 2", func(t *testing.T) {
   101  		require := require.New(t)
   102  		f := NewDimension(expression.NewLiteral(types.Polygon{Lines: []types.LineString{{Points: []types.Point{{X: 0, Y: 0}, {X: 1, Y: 1}, {X: 0, Y: 1}, {X: 0, Y: 0}}}}}, types.GeometryType{}))
   103  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   104  		require.NoError(err)
   105  		require.Equal(2, v)
   106  	})
   107  
   108  	t.Run("empty geometry collection has dimension null", func(t *testing.T) {
   109  		require := require.New(t)
   110  		f := NewDimension(expression.NewLiteral(types.GeomColl{}, types.GeometryType{}))
   111  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   112  		require.NoError(err)
   113  		require.Equal(nil, v)
   114  	})
   115  
   116  	t.Run("geometry collection of a point has dimension 0", func(t *testing.T) {
   117  		require := require.New(t)
   118  		f := NewDimension(expression.NewLiteral(types.GeomColl{Geoms: []types.GeometryValue{types.Point{}}}, types.GeometryType{}))
   119  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   120  		require.NoError(err)
   121  		require.Equal(0, v)
   122  	})
   123  
   124  	t.Run("geometry collection of a different types takes highest type", func(t *testing.T) {
   125  		require := require.New(t)
   126  		point := types.Point{}
   127  		line := types.LineStringType{}.Zero().(types.LineString)
   128  		poly := types.PolygonType{}.Zero().(types.Polygon)
   129  		f := NewDimension(expression.NewLiteral(types.GeomColl{Geoms: []types.GeometryValue{point, line, poly}}, types.GeometryType{}))
   130  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   131  		require.NoError(err)
   132  		require.Equal(2, v)
   133  	})
   134  
   135  	t.Run("geometry collection null is the largest dimension", func(t *testing.T) {
   136  		require := require.New(t)
   137  		point := types.Point{}
   138  		line := types.LineStringType{}.Zero().(types.LineString)
   139  		poly := types.PolygonType{}.Zero().(types.Polygon)
   140  		geom := types.GeomColl{}
   141  		f := NewDimension(expression.NewLiteral(types.GeomColl{Geoms: []types.GeometryValue{point, line, poly, geom}}, types.GeometryType{}))
   142  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   143  		require.NoError(err)
   144  		require.Equal(nil, v)
   145  	})
   146  
   147  	t.Run("null is null", func(t *testing.T) {
   148  		require := require.New(t)
   149  		f := NewDimension(expression.NewLiteral(123, types.Int64))
   150  		_, err := f.Eval(sql.NewEmptyContext(), nil)
   151  		require.Error(err)
   152  	})
   153  
   154  	t.Run("null is null", func(t *testing.T) {
   155  		require := require.New(t)
   156  		f := NewDimension(expression.NewLiteral(nil, types.Null))
   157  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   158  		require.NoError(err)
   159  		require.Equal(nil, v)
   160  	})
   161  
   162  	t.Run("check return type", func(t *testing.T) {
   163  		require := require.New(t)
   164  		f := NewDimension(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{}))
   165  
   166  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   167  		require.NoError(err)
   168  
   169  		typ := f.Type()
   170  		_, inRange, err := typ.Convert(v)
   171  		require.True(bool(inRange))
   172  		require.NoError(err)
   173  	})
   174  }