Skip to content

Commit

Permalink
Merge pull request #1332 from dolthub/james/geomcoll
Browse files Browse the repository at this point in the history
add support for `GeometryCollection` pt. 1
  • Loading branch information
jycor authored Oct 18, 2022
2 parents 1282422 + c2fafa6 commit 3e6ea0f
Show file tree
Hide file tree
Showing 26 changed files with 1,612 additions and 209 deletions.
12 changes: 12 additions & 0 deletions enginetest/queries/insert_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,8 @@ var SpatialInsertQueries = []WriteQueryTest{
{10, sql.MultiLineString{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}}}},
{11, sql.MultiPolygon{Polygons: []sql.Polygon{{Lines: []sql.LineString{{Points: []sql.Point{{X: 0, Y: 0}, {X: 1, Y: 2}, {X: 3, Y: 4}, {X: 0, Y: 0}}}}}}}},
{12, sql.MultiPolygon{SRID: 4326, Polygons: []sql.Polygon{{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}, {SRID: 4326, X: 0, Y: 0}}}}}}}},
{13, sql.GeomColl{Geoms: []sql.GeometryValue{sql.GeomColl{Geoms: []sql.GeometryValue{}}}}},
{14, sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{}}}}},
{100, sql.Point{X: 123.456, Y: 7.89}},
},
},
Expand All @@ -728,6 +730,8 @@ var SpatialInsertQueries = []WriteQueryTest{
{10, sql.MultiLineString{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}}}},
{11, sql.MultiPolygon{Polygons: []sql.Polygon{{Lines: []sql.LineString{{Points: []sql.Point{{X: 0, Y: 0}, {X: 1, Y: 2}, {X: 3, Y: 4}, {X: 0, Y: 0}}}}}}}},
{12, sql.MultiPolygon{SRID: 4326, Polygons: []sql.Polygon{{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}, {SRID: 4326, X: 0, Y: 0}}}}}}}},
{13, sql.GeomColl{Geoms: []sql.GeometryValue{sql.GeomColl{Geoms: []sql.GeometryValue{}}}}},
{14, sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{}}}}},
{100, sql.Point{X: 123.456, Y: 7.89}},
},
},
Expand All @@ -748,6 +752,8 @@ var SpatialInsertQueries = []WriteQueryTest{
{10, sql.MultiLineString{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}}}},
{11, sql.MultiPolygon{Polygons: []sql.Polygon{{Lines: []sql.LineString{{Points: []sql.Point{{X: 0, Y: 0}, {X: 1, Y: 2}, {X: 3, Y: 4}, {X: 0, Y: 0}}}}}}}},
{12, sql.MultiPolygon{SRID: 4326, Polygons: []sql.Polygon{{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}, {SRID: 4326, X: 0, Y: 0}}}}}}}},
{13, sql.GeomColl{Geoms: []sql.GeometryValue{sql.GeomColl{Geoms: []sql.GeometryValue{}}}}},
{14, sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{}}}}},
{100, sql.LineString{Points: []sql.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}},
},
},
Expand All @@ -768,6 +774,8 @@ var SpatialInsertQueries = []WriteQueryTest{
{10, sql.MultiLineString{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}}}},
{11, sql.MultiPolygon{Polygons: []sql.Polygon{{Lines: []sql.LineString{{Points: []sql.Point{{X: 0, Y: 0}, {X: 1, Y: 2}, {X: 3, Y: 4}, {X: 0, Y: 0}}}}}}}},
{12, sql.MultiPolygon{SRID: 4326, Polygons: []sql.Polygon{{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}, {SRID: 4326, X: 0, Y: 0}}}}}}}},
{13, sql.GeomColl{Geoms: []sql.GeometryValue{sql.GeomColl{Geoms: []sql.GeometryValue{}}}}},
{14, sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{}}}}},
{100, sql.LineString{Points: []sql.Point{{X: 1, Y: 2}, {X: 3, Y: 4}}}},
},
},
Expand All @@ -788,6 +796,8 @@ var SpatialInsertQueries = []WriteQueryTest{
{10, sql.MultiLineString{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}}}},
{11, sql.MultiPolygon{Polygons: []sql.Polygon{{Lines: []sql.LineString{{Points: []sql.Point{{X: 0, Y: 0}, {X: 1, Y: 2}, {X: 3, Y: 4}, {X: 0, Y: 0}}}}}}}},
{12, sql.MultiPolygon{SRID: 4326, Polygons: []sql.Polygon{{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}, {SRID: 4326, X: 0, Y: 0}}}}}}}},
{13, sql.GeomColl{Geoms: []sql.GeometryValue{sql.GeomColl{Geoms: []sql.GeometryValue{}}}}},
{14, sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{}}}}},
{100, sql.Polygon{Lines: []sql.LineString{{Points: []sql.Point{{X: 1, Y: 1}, {X: 1, Y: -1}, {X: -1, Y: -1}, {X: -1, Y: 1}, {X: 1, Y: 1}}}}}},
},
},
Expand All @@ -808,6 +818,8 @@ var SpatialInsertQueries = []WriteQueryTest{
{10, sql.MultiLineString{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}}}}}},
{11, sql.MultiPolygon{Polygons: []sql.Polygon{{Lines: []sql.LineString{{Points: []sql.Point{{X: 0, Y: 0}, {X: 1, Y: 2}, {X: 3, Y: 4}, {X: 0, Y: 0}}}}}}}},
{12, sql.MultiPolygon{SRID: 4326, Polygons: []sql.Polygon{{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 1, Y: 2}, {SRID: 4326, X: 3, Y: 4}, {SRID: 4326, X: 0, Y: 0}}}}}}}},
{13, sql.GeomColl{Geoms: []sql.GeometryValue{sql.GeomColl{Geoms: []sql.GeometryValue{}}}}},
{14, sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{}}}}},
{100, sql.Polygon{Lines: []sql.LineString{{Points: []sql.Point{{X: 1, Y: 1}, {X: 1, Y: -1}, {X: -1, Y: -1}, {X: -1, Y: 1}, {X: 1, Y: 1}}}}}},
},
},
Expand Down
26 changes: 26 additions & 0 deletions enginetest/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ var SpatialQueryTests = []QueryTest{
{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 1.1, Y: 2.2}, {SRID: 4326, X: 3.3, Y: 4.4}, {SRID: 4326, X: 0, Y: 0}}}}},
{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 1.1, Y: 1.1}, {SRID: 4326, X: 1.1, Y: 2.2}, {SRID: 4326, X: 3.3, Y: 4.4}, {SRID: 4326, X: 1.1, Y: 1.1}}}}},
}}},
{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{}}}}},
},
},
{
Expand Down Expand Up @@ -312,6 +313,7 @@ var SpatialQueryTests = []QueryTest{
{sql.JSONDocument{Val: map[string]interface{}{"type": "MultiPoint", "coordinates": [][2]float64{{1.23, 2.345}, {3.56789, 4.56}}}}},
{sql.JSONDocument{Val: map[string]interface{}{"type": "MultiLineString", "coordinates": [][][2]float64{{{1.1, 2.2}, {3.3, 4.4}}, {{5.5, 6.6}, {7.7, 8.8}}}}}},
{sql.JSONDocument{Val: map[string]interface{}{"type": "MultiPolygon", "coordinates": [][][][2]float64{{{{0, 0}, {1.1, 2.2}, {3.3, 4.4}, {0, 0}}}, {{{1.1, 1.1}, {1.1, 2.2}, {3.3, 4.4}, {1.1, 1.1}}}}}}},
{sql.JSONDocument{Val: map[string]interface{}{"type": "GeometryCollection", "geometries": []interface{}{map[string]interface{}{"type": "GeometryCollection", "geometries": []interface{}{}}}}}},
},
},
{
Expand Down Expand Up @@ -357,6 +359,12 @@ var SpatialQueryTests = []QueryTest{
{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 1, Y: 1}, {SRID: 4326, X: 2, Y: 3}, {SRID: 4326, X: 4, Y: 5}, {SRID: 4326, X: 1, Y: 1}}}}}}}},
},
},
{
Query: `SELECT ST_GEOMFROMGEOJSON(ST_ASGEOJSON(g)) from geom_coll_table`,
Expected: []sql.Row{
{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{}}}}},
},
},
{
Query: `SELECT ST_DIMENSION(p) from point_table`,
Expected: []sql.Row{
Expand Down Expand Up @@ -398,6 +406,12 @@ var SpatialQueryTests = []QueryTest{
{2},
},
},
{
Query: `SELECT ST_DIMENSION(g) from geom_coll_table`,
Expected: []sql.Row{
{nil},
},
},
{
Query: `SELECT ST_SWAPXY(p) from point_table`,
Expected: []sql.Row{
Expand Down Expand Up @@ -433,6 +447,8 @@ var SpatialQueryTests = []QueryTest{
{"MULTILINESTRING((2 1,4 3))"},
{"MULTIPOLYGON(((0 0,1 2,3 4,0 0)))"},
{"MULTIPOLYGON(((0 0,2 1,4 3,0 0)))"},
{"GEOMETRYCOLLECTION(GEOMETRYCOLLECTION())"},
{"GEOMETRYCOLLECTION(GEOMETRYCOLLECTION())"},
},
},
{
Expand Down Expand Up @@ -474,6 +490,8 @@ var SpatialQueryTests = []QueryTest{
{"0105000000010000000102000000020000000000000000000040000000000000F03F00000000000010400000000000000840"},
{"0106000000010000000103000000010000000400000000000000000000000000000000000000000000000000F03F00000000000000400000000000000840000000000000104000000000000000000000000000000000"},
{"01060000000100000001030000000100000004000000000000000000000000000000000000000000000000000040000000000000F03F0000000000001040000000000000084000000000000000000000000000000000"},
{"010700000001000000010700000000000000"},
{"010700000001000000010700000000000000"},
},
},
{
Expand All @@ -491,6 +509,8 @@ var SpatialQueryTests = []QueryTest{
{uint64(4326)},
{uint64(0)},
{uint64(4326)},
{uint64(0)},
{uint64(4326)},
},
},
{
Expand All @@ -508,6 +528,8 @@ var SpatialQueryTests = []QueryTest{
{sql.MultiLineString{SRID: 0, Lines: []sql.LineString{{SRID: 0, Points: []sql.Point{{SRID: 0, X: 1, Y: 2}, {SRID: 0, X: 3, Y: 4}}}}}},
{sql.MultiPolygon{SRID: 0, Polygons: []sql.Polygon{{SRID: 0, Lines: []sql.LineString{{SRID: 0, Points: []sql.Point{{SRID: 0, X: 0, Y: 0}, {SRID: 0, X: 1, Y: 2}, {SRID: 0, X: 3, Y: 4}, {SRID: 0, X: 0, Y: 0}}}}}}}},
{sql.MultiPolygon{SRID: 0, Polygons: []sql.Polygon{{SRID: 0, Lines: []sql.LineString{{SRID: 0, Points: []sql.Point{{SRID: 0, X: 0, Y: 0}, {SRID: 0, X: 1, Y: 2}, {SRID: 0, X: 3, Y: 4}, {SRID: 0, X: 0, Y: 0}}}}}}}},
{sql.GeomColl{Geoms: []sql.GeometryValue{sql.GeomColl{Geoms: []sql.GeometryValue{}}}}},
{sql.GeomColl{Geoms: []sql.GeometryValue{sql.GeomColl{Geoms: []sql.GeometryValue{}}}}},
},
},
{
Expand All @@ -525,6 +547,8 @@ var SpatialQueryTests = []QueryTest{
{1},
{2},
{2},
{nil},
{nil},
},
},
{
Expand All @@ -542,6 +566,8 @@ var SpatialQueryTests = []QueryTest{
{sql.MultiLineString{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 2, Y: 1}, {SRID: 4326, X: 4, Y: 3}}}}}},
{sql.MultiPolygon{SRID: 0, Polygons: []sql.Polygon{{SRID: 0, Lines: []sql.LineString{{SRID: 0, Points: []sql.Point{{SRID: 0, X: 0, Y: 0}, {SRID: 0, X: 2, Y: 1}, {SRID: 0, X: 4, Y: 3}, {SRID: 0, X: 0, Y: 0}}}}}}}},
{sql.MultiPolygon{SRID: 4326, Polygons: []sql.Polygon{{SRID: 4326, Lines: []sql.LineString{{SRID: 4326, Points: []sql.Point{{SRID: 4326, X: 0, Y: 0}, {SRID: 4326, X: 2, Y: 1}, {SRID: 4326, X: 4, Y: 3}, {SRID: 4326, X: 0, Y: 0}}}}}}}},
{sql.GeomColl{Geoms: []sql.GeometryValue{sql.GeomColl{Geoms: []sql.GeometryValue{}}}}},
{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{sql.GeomColl{SRID: 4326, Geoms: []sql.GeometryValue{}}}}},
},
},
{
Expand Down
16 changes: 14 additions & 2 deletions enginetest/scriptgen/setup/scripts/spatial
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ insert into stringtogeojson_table values
(6, '{"type": "MultiPoint", "coordinates": [[1,2],[3,4]]}'),
(7, '{"type": "MultiPoint", "coordinates": [[1.23,2.345],[3.56789,4.56]]}'),
(8, '{"type": "MultiLineString", "coordinates": [[[1.1,2.2],[3.3,4.4]],[[5.5,6.6],[7.7,8.8]]]}'),
(9, '{"type": "MultiPolygon", "coordinates": [[[[0.0, 0.0],[1.1,2.2],[3.3,4.4],[0.0,0.0]]],[[[1.1,1.1],[1.1,2.2],[3.3,4.4],[1.1,1.1]]]]}')
(9, '{"type": "MultiPolygon", "coordinates": [[[[0.0, 0.0],[1.1,2.2],[3.3,4.4],[0.0,0.0]]],[[[1.1,1.1],[1.1,2.2],[3.3,4.4],[1.1,1.1]]]]}'),
(10, '{"type": "GeometryCollection", "geometries": [{"type": "GeometryCollection", "geometries":[]}]}')
----

exec
Expand All @@ -33,7 +34,9 @@ insert into geometry_table values
(9, ST_GeomFromText('MULTILINESTRING((1 2,3 4))')),
(10, ST_SRID(ST_GeomFromText('MULTILINESTRING((1 2,3 4))'), 4326)),
(11, ST_GeomFromText('MultiPolygon(((0 0,1 2,3 4,0 0)))')),
(12, ST_SRID(ST_GeomFromText('MultiPolygon(((0 0,1 2,3 4,0 0)))'), 4326))
(12, ST_SRID(ST_GeomFromText('MultiPolygon(((0 0,1 2,3 4,0 0)))'), 4326)),
(13, ST_GeomFromText('GeometryCollection(GeometryCollection())')),
(14, ST_SRID(ST_GeomFromText('GeometryCollection(GeometryCollection())'), 4326))
----

exec
Expand Down Expand Up @@ -92,4 +95,13 @@ exec
insert into mpoly_table values
(0, ST_GeomFromText('MultiPolygon(((0 0,1 2,3 4,0 0)))')),
(1, ST_GeomFromText('MultiPolygon(((0 0,1 2,3 4,0 0)),((1 1,2 3,4 5,1 1)))'))
----

exec
create table geom_coll_table (i bigint primary key, g geometrycollection NOT NULL);
----

exec
insert into geom_coll_table values
(0, ST_GeomFromText('GeometryCollection(GeometryCollection())'))
----
6 changes: 4 additions & 2 deletions enginetest/scriptgen/setup/setup_data.sg.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 31 additions & 7 deletions sql/expression/function/dimension.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,34 @@ func (p *Dimension) WithChildren(children ...sql.Expression) (sql.Expression, er
return NewDimension(children[0]), nil
}

func FindDimension(g sql.GeometryValue) interface{} {
switch v := g.(type) {
case sql.Point, sql.MultiPoint:
return 0
case sql.LineString, sql.MultiLineString:
return 1
case sql.Polygon, sql.MultiPolygon:
return 2
case sql.GeomColl:
if len(v.Geoms) == 0 {
return nil
}
maxDim := 0
for _, geom := range v.Geoms {
dim := FindDimension(geom)
if dim == nil {
return nil
}
if dim.(int) > maxDim {
maxDim = dim.(int)
}
}
return maxDim
default:
return nil
}
}

// Eval implements the sql.Expression interface.
func (p *Dimension) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
// Evaluate child
Expand All @@ -79,13 +107,9 @@ func (p *Dimension) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
}

// Expect one of the geometry types
switch val.(type) {
case sql.Point, sql.MultiPoint:
return 0, nil
case sql.LineString, sql.MultiLineString:
return 1, nil
case sql.Polygon, sql.MultiPolygon:
return 2, nil
switch v := val.(type) {
case sql.GeometryValue:
return FindDimension(v), nil
default:
return nil, sql.ErrInvalidGISData.New("ST_DIMENSION")
}
Expand Down
39 changes: 39 additions & 0 deletions sql/expression/function/dimension_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,45 @@ func TestDimension(t *testing.T) {
require.Equal(2, v)
})

t.Run("empty geometry collection has dimension null", func(t *testing.T) {
require := require.New(t)
f := NewDimension(expression.NewLiteral(sql.GeomColl{}, sql.GeometryType{}))
v, err := f.Eval(sql.NewEmptyContext(), nil)
require.NoError(err)
require.Equal(nil, v)
})

t.Run("geometry collection of a point has dimension 0", func(t *testing.T) {
require := require.New(t)
f := NewDimension(expression.NewLiteral(sql.GeomColl{Geoms: []sql.GeometryValue{sql.Point{}}}, sql.GeometryType{}))
v, err := f.Eval(sql.NewEmptyContext(), nil)
require.NoError(err)
require.Equal(0, v)
})

t.Run("geometry collection of a different types takes highest type", func(t *testing.T) {
require := require.New(t)
point := sql.Point{}
line := sql.LineStringType{}.Zero().(sql.LineString)
poly := sql.PolygonType{}.Zero().(sql.Polygon)
f := NewDimension(expression.NewLiteral(sql.GeomColl{Geoms: []sql.GeometryValue{point, line, poly}}, sql.GeometryType{}))
v, err := f.Eval(sql.NewEmptyContext(), nil)
require.NoError(err)
require.Equal(2, v)
})

t.Run("geometry collection null is the largest dimension", func(t *testing.T) {
require := require.New(t)
point := sql.Point{}
line := sql.LineStringType{}.Zero().(sql.LineString)
poly := sql.PolygonType{}.Zero().(sql.Polygon)
geom := sql.GeomColl{}
f := NewDimension(expression.NewLiteral(sql.GeomColl{Geoms: []sql.GeometryValue{point, line, poly, geom}}, sql.GeometryType{}))
v, err := f.Eval(sql.NewEmptyContext(), nil)
require.NoError(err)
require.Equal(nil, v)
})

t.Run("null is null", func(t *testing.T) {
require := require.New(t)
f := NewDimension(expression.NewLiteral(123, sql.Int64))
Expand Down
Loading

0 comments on commit 3e6ea0f

Please sign in to comment.