You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by mm...@apache.org on 2017/09/05 14:36:52 UTC

[09/16] calcite git commit: [CALCITE-1968] OpenGIS Simple Feature Access SQL 1.2.1: add GEOMETRY data type and first 35 functions

http://git-wip-us.apache.org/repos/asf/calcite/blob/cc20ca13/core/src/test/resources/sql/spatial.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/spatial.iq b/core/src/test/resources/sql/spatial.iq
new file mode 100755
index 0000000..1a37b44
--- /dev/null
+++ b/core/src/test/resources/sql/spatial.iq
@@ -0,0 +1,1114 @@
+# spatial.iq - Geo-spatial functions
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use geo
+!set outputformat csv
+
+# Check that the data set is OK.
+select count(*) as c from GEO."countries";
+C
+245
+!ok
+
+#### Geometry conversion functions (2D)
+
+# ST_AsBinary(geom) Geometry to Well Known Binary
+# Not implemented
+
+# ST_AsGML(geom) Geometry to GML
+# Not implemented
+
+# ST_AsText(geom) Alias for `ST_AsWKT`
+SELECT ST_AsText(ST_GeomFromText('POINT(-71.064544 42.28787)'));
+EXPR$0
+POINT (-71.064544 42.28787)
+!ok
+
+# ST_AsWKT(geom) Converts *geom* → Well-Known Text
+
+SELECT ST_AsWKT(ST_GeomFromText('POINT(-71.064544 42.28787)'));
+EXPR$0
+POINT (-71.064544 42.28787)
+!ok
+
+# PostGIS can implicitly assign from CHAR to GEOMETRY; we can't
+!if (false) {
+# ST_AsWKT(geom) Geometry to Well Known Text
+SELECT ST_AsText('01030000000100000005000000000000000000
+000000000000000000000000000000000000000000000000
+F03F000000000000F03F000000000000F03F000000000000F03
+F000000000000000000000000000000000000000000000000');
+!ok
+!}
+
+SELECT ST_AsWKT(CAST(NULL AS GEOMETRY));
+EXPR$0
+null
+!ok
+
+# ST_Force2D(geom) 3D Geometry to 2D Geometry
+# Not implemented
+
+# ST_GeomFromGML(gml [, srid ]) GML to Geometry
+# Not implemented
+
+# ST_GeomFromText(wkt [, srid ]) Returns a specified geometry value from Well-Known Text representation
+
+SELECT ST_GeomFromText('LINESTRING(-71.160281 42.258729,-71.160837 42.259113,-71.161144 42.25932)');
+EXPR$0
+{"paths":[[[-71.160281,42.258729],[-71.160837,42.259113],[-71.161144,42.25932]]]}
+!ok
+
+SELECT ST_GeomFromText('LINESTRING(-71.160281 42.258729,-71.160837 42.259113,-71.161144 42.25932)',4269);
+EXPR$0
+{"paths":[[[-71.160281,42.258729],[-71.160837,42.259113],[-71.161144,42.25932]]],"spatialReference":{"wkid":4269}}
+!ok
+
+SELECT ST_GeomFromText('MULTILINESTRING((-71.160281 42.258729,-71.160837 42.259113,-71.161144 42.25932))');
+EXPR$0
+{"paths":[[[-71.160281,42.258729],[-71.160837,42.259113],[-71.161144,42.25932]]]}
+!ok
+
+SELECT ST_GeomFromText('POINT(-71.064544 42.28787)');
+EXPR$0
+{"x":-71.064544,"y":42.28787}
+!ok
+
+SELECT ST_GeomFromText('POLYGON((-71.1776585052917 42.3902909739571,-71.1776820268866 42.3903701743239,
+-71.1776063012595 42.3903825660754,-71.1775826583081 42.3903033653531,-71.1776585052917 42.3902909739571))');
+EXPR$0
+{"rings":[[[-71.1776585052917,42.3902909739571],[-71.1776820268866,42.3903701743239],[-71.1776063012595,42.3903825660754],[-71.1775826583081,42.3903033653531],[-71.1776585052917,42.3902909739571]]]}
+!ok
+
+SELECT ST_GeomFromText('MULTIPOLYGON(((-71.1031880899493 42.3152774590236,
+-71.1031627617667 42.3152960829043,-71.102923838298 42.3149156848307,
+-71.1023097974109 42.3151969047397,-71.1019285062273 42.3147384934248,
+-71.102505233663 42.3144722937587,-71.10277487471 42.3141658254797,
+-71.103113945163 42.3142739188902,-71.10324876416 42.31402489987,
+-71.1033002961013 42.3140393340215,-71.1033488797549 42.3139495090772,
+-71.103396240451 42.3138632439557,-71.1041521907712 42.3141153348029,
+-71.1041411411543 42.3141545014533,-71.1041287795912 42.3142114839058,
+-71.1041188134329 42.3142693656241,-71.1041112482575 42.3143272556118,
+-71.1041072845732 42.3143851580048,-71.1041057218871 42.3144430686681,
+-71.1041065602059 42.3145009876017,-71.1041097995362 42.3145589148055,
+-71.1041166403905 42.3146168544148,-71.1041258822717 42.3146748022936,
+-71.1041375307579 42.3147318674446,-71.1041492906949 42.3147711126569,
+-71.1041598612795 42.314808571739,-71.1042515013869 42.3151287620809,
+-71.1041173835118 42.3150739481917,-71.1040809891419 42.3151344119048,
+-71.1040438678912 42.3151191367447,-71.1040194562988 42.3151832057859,
+-71.1038734225584 42.3151140942995,-71.1038446938243 42.3151006300338,
+-71.1038315271889 42.315094347535,-71.1037393329282 42.315054824985,
+-71.1035447555574 42.3152608696313,-71.1033436658644 42.3151648370544,
+-71.1032580383161 42.3152269126061,-71.103223066939 42.3152517403219,
+-71.1031880899493 42.3152774590236)),
+((-71.1043632495873 42.315113108546,-71.1043583974082 42.3151211109857,
+-71.1043443253471 42.3150676015829,-71.1043850704575 42.3150793250568,-71.1043632495873 42.315113108546)))',4326);
+EXPR$0
+{"rings":[[[-71.1031880899493,42.3152774590236],[-71.1031627617667,42.3152960829043],[-71.102923838298,42.3149156848307],[-71.1023097974109,42.3151969047397],[-71.1019285062273,42.3147384934248],[-... (1697 characters)
+!ok
+
+# Disabled: Should not return null
+!if (false) {
+SELECT ST_GeomFromText('GEOMETRYCOLLECTION(
+  POLYGON((-7 4.2,-7.1 4.2,-7.1 4.3,-7 4.2))
+  POINT(5 5)
+  POINT(-2 3)
+  LINESTRING(5 5, 10 10)');
+EXPR$0
+!ok
+!}
+
+# PostGIS does CIRCULARSTRING; we don't currently
+!if (false) {
+SELECT ST_GeomFromText('CIRCULARSTRING(220268 150415,220227 150505,220227 150406)');
+!ok
+!}
+
+# In PostGIS prior to 2.0, ST_GeomFromText('GEOMETRYCOLLECTION(EMPTY)') was allowed
+# but ST_GeomFromText('GEOMETRYCOLLECTION EMPTY') is not preferred.
+SELECT ST_GeomFromText('GEOMETRYCOLLECTION EMPTY');
+EXPR$0
+null
+!ok
+
+# ST_GeomFromWKB(wkb [, srid ]) Well Known Binary to Geometry
+# Not implemented
+
+# ST_GoogleMapLink(geom [, layerType [, zoom ]]) Geometry to Google map link
+# Not implemented
+
+# ST_LineFromText(wkt [, srid ]) Well Known Text to LINESTRING
+SELECT ST_LineFromText('LINESTRING(1 2, 3 4)') AS aline,
+  ST_LineFromText('POINT(1 2)') AS null_return;
+ALINE, NULL_RETURN
+{"paths":[[[1,2],[3,4]]]}, {"x":1,"y":2}
+!ok
+
+# ST_LineFromWKB(wkb [, srid ]) Well Known Binary to LINESTRING
+# Not implemented
+
+# ST_MLineFromText(wkt [, srid ]) Well Known Text to MULTILINESTRING
+SELECT ST_MLineFromText('MULTILINESTRING((1 2, 3 4), (4 5, 6 7))');
+EXPR$0
+{"paths":[[[1,2],[3,4]],[[4,5],[6,7]]]}
+!ok
+
+# ST_MPointFromText(wkt [, srid ]) Well Known Text to MULTIPOINT
+SELECT ST_MPointFromText('MULTIPOINT(1 2, 3 4)');
+EXPR$0
+{"points":[[1,2],[3,4]]}
+!ok
+
+SELECT ST_MPointFromText('MULTIPOINT(-70.9590 42.1180, -70.9611 42.1223)', 4326);
+EXPR$0
+{"points":[[-70.959,42.118],[-70.9611,42.1223]],"spatialReference":{"wkid":4326}}
+!ok
+
+# ST_MPolyFromText(wkt [, srid ]) Well Known Text to MULTIPOLYGON
+SELECT ST_MPolyFromText('MULTIPOLYGON Z(((0 0 1,20 0 1,20 20 1,0 20 1,0 0 1),(5 5 3,5 7 3,7 7 3,7 5 3,5 5 3)))');
+EXPR$0
+{"hasZ":true,"rings":[[[0,0,1],[0,20,1],[20,20,1],[20,0,1],[0,0,1]],[[5,5,3],[7,5,3],[7,7,3],[5,7,3],[5,5,3]]]}
+!ok
+
+SELECt ST_MPolyFromText('MULTIPOLYGON(((-70.916 42.1002,-70.9468 42.0946,-70.9765 42.0872,-70.9754 42.0875,-70.9749 42.0879,-70.9752 42.0881,-70.9754 42.0891,-70.9758 42.0894,-70.9759 42.0897,-70.9759 42.0899,-70.9754 42.0902,-70.9756 42.0906,-70.9753 42.0907,-70.9753 42.0917,-70.9757 42.0924,-70.9755 42.0928,-70.9755 42.0942,-70.9751 42.0948,-70.9755 42.0953,-70.9751 42.0958,-70.9751 42.0962,-70.9759 42.0983,-70.9767 42.0987,-70.9768 42.0991,-70.9771 42.0997,-70.9771 42.1003,-70.9768 42.1005,-70.977 42.1011,-70.9766 42.1019,-70.9768 42.1026,-70.9769 42.1033,-70.9775 42.1042,-70.9773 42.1043,-70.9776 42.1043,-70.9778 42.1048,-70.9773 42.1058,-70.9774 42.1061,-70.9779 42.1065,-70.9782 42.1078,-70.9788 42.1085,-70.9798 42.1087,-70.9806 42.109,-70.9807 42.1093,-70.9806 42.1099,-70.9809 42.1109,-70.9808 42.1112,-70.9798 42.1116,-70.9792 42.1127,-70.979 42.1129,-70.9787 42.1134,-70.979 42.1139,-70.9791 42.1141,-70.9987 42.1116,-71.0022 42.1273,
+    -70.9408 42.1513,-70.9315 42.1165,-70.916 42.1002)))',4326);
+EXPR$0
+{"rings":[[[-70.916,42.1002],[-70.9468,42.0946],[-70.9765,42.0872],[-70.9754,42.0875],[-70.9749,42.0879],[-70.9752,42.0881],[-70.9754,42.0891],[-70.9758,42.0894],[-70.9759,42.0897],[-70.9759,42.089... (1123 characters)
+!ok
+
+# ST_OSMMapLink(geom [, marker ]) Geometry to OSM map link
+# Not implemented
+
+# ST_PointFromText(wkt [, srid ]) Well Known Text to POINT
+SELECT ST_PointFromText('POINT(-71.064544 42.28787)');
+EXPR$0
+{"x":-71.064544,"y":42.28787}
+!ok
+
+SELECT ST_PointFromText('POINT(-71.064544 42.28787)', 4326);
+EXPR$0
+{"x":-71.064544,"y":42.28787,"spatialReference":{"wkid":4326}}
+!ok
+
+# ST_PointFromWKB(wkb [, srid ]) Well Known Binary to POINT
+# Not implemented
+
+# ST_PolyFromText(wkt [, srid ]) Well Known Text to POLYGON
+SELECT ST_PolyFromText('POLYGON Z((0 0 1,20 0 1,20 20 1,0 20 1,0 0 1))');
+EXPR$0
+{"hasZ":true,"rings":[[[0,0,1],[0,20,1],[20,20,1],[20,0,1],[0,0,1]]]}
+!ok
+
+SELECT ST_PolyFromText(CAST(NULL AS VARCHAR));
+EXPR$0
+null
+!ok
+
+SELECT ST_PolyFromText('POLYGON((0 0))');
+EXPR$0
+{"rings":[[[0,0],[0,0]]]}
+!ok
+
+# ST_PolyFromWKB(wkb [, srid ]) Well Known Binary to POLYGON
+# Not implemented
+
+# ST_ToMultiLine(geom) Converts the coordinates of *geom* (which may be a geometry-collection) into a multi-line-string
+# Not implemented
+
+# ST_ToMultiPoint(geom)) Converts the coordinates of *geom* (which may be a geometry-collection) into a multi-point
+# Not implemented
+
+# ST_ToMultiSegments(geom) Converts *geom* (which may be a geometry-collection) into a set of distinct segments stored in a multi-line-string
+# Not implemented
+
+#### Geometry conversion functions (3D)
+
+# ST_Force3D(geom) 2D Geometry to 3D Geometry
+# Not implemented
+
+#### Geometry creation functions (2D)
+
+# ST_BoundingCircle(geom) Returns the minimum bounding circle of *geom*
+# Not implemented
+
+# ST_Expand(geom, distance) Expands *geom*'s envelope
+# Not implemented
+
+# ST_Expand(geom, deltaX, deltaY) Expands *geom*'s envelope
+# Not implemented
+
+# ST_MakeEllipse(point, width, height) Constructs an ellipse
+# Not implemented
+
+# ST_MakeEnvelope(xMin, yMin, xMax, yMax  [, srid ]) Creates a rectangular Polygon
+# Not implemented
+
+# ST_MakeGrid(geom, deltaX, deltaY) Calculates a regular grid of polygons based on *geom*
+# Not implemented
+
+# ST_MakeGridPoints(geom, deltaX, deltaY) Calculates a regular grid of points based on *geom*
+# Not implemented
+
+# ST_MakeLine(point1 [, point ]*) Creates a line-string from the given points (or multi-points)
+
+SELECT ST_MakeLine(ST_Point(1.0,1.0), ST_Point(-1.0,-1.0));
+EXPR$0
+{"paths":[[[1,1],[-1,-1]]]}
+!ok
+
+SELECT ST_MakeLine(ST_Point(1.0,1.0), ST_Point(-1.0,-1.0), ST_Point(-3.0,0.0));
+EXPR$0
+{"paths":[[[1,1],[-1,-1],[-3,0]]]}
+!ok
+
+# ST_MakePoint(x, y [, z ]) Constructs a point from two or three coordinates
+
+# Return point with unknown SRID
+SELECT ST_MakePoint(-71.1043443253471, 42.3150676015829);
+EXPR$0
+{"x":-71.1043443253471,"y":42.3150676015829}
+!ok
+
+# Return point marked as WGS 84 long lat
+SELECT ST_SetSRID(ST_MakePoint(-71.1043443253471, 42.3150676015829),4326);
+EXPR$0
+{"x":-71.1043443253471,"y":42.3150676015829}
+!ok
+
+# Return a 3D point (e.g. has altitude)
+SELECT ST_MakePoint(1.0, 2.0, 1.5);
+EXPR$0
+{"x":1,"y":2,"z":1.5}
+!ok
+
+# Get z of point
+SELECT ST_Z(ST_MakePoint(1.0, 2.0,1.5));
+EXPR$0
+1.5
+!ok
+
+select "name", ST_MakePoint("latitude", "longitude") AS p
+from GEO."countries" AS c
+ORDER BY "latitude" DESC LIMIT 3;
+name, P
+U.S.Minor Outlying Islands, null
+Svalbard and Jan Mayen, {"x":77.553604,"y":23.670272}
+Greenland, {"x":71.706936,"y":-42.604303}
+!ok
+
+# ST_MakePolygon(lineString [, hole ]*) Creates a polygon from *lineString* with the given holes (which are required to be closed line-strings)
+# Not implemented
+
+# ST_MinimumDiameter(geom) Returns the minimum diameter of *geom*
+# Not implemented
+
+# ST_MinimumRectangle(geom) Returns the minimum rectangle enclosing *geom*
+# Not implemented
+
+# ST_OctogonalEnvelope(geom) Returns the octogonal envelope of *geom*
+# Not implemented
+
+# ST_RingBuffer(geom, bufferSize, bufferCount [, endCapStyle [, doDifference]]) Returns a multi-polygon of buffers centered at *geom* and of increasing buffer size
+# Not implemented
+
+### Geometry creation functions (3D)
+
+# ST_Extrude(geom, height [, flag]) Extrudes a geometry
+# Not implemented
+
+# ST_GeometryShadow(geom, point, height) Computes the shadow footprint of *geom*
+# Not implemented
+
+# ST_GeometryShadow(geom, azimuth, altitude, height [, unify ]) Computes the shadow footprint of *geom*
+# Not implemented
+
+#### Geometry properties (2D)
+
+# ST_Boundary(geom [, srid ]) Returns the boundary of *geom*
+SELECT ST_AsText(ST_Boundary(ST_GeomFromText('LINESTRING(1 1,0 0, -1 1)')));
+EXPR$0
+MULTIPOINT ((1 1), (-1 1))
+!ok
+
+SELECT ST_AsText(ST_Boundary(ST_GeomFromText('POLYGON((1 1,0 0, -1 1, 1 1))')));
+EXPR$0
+MULTILINESTRING ((1 1, 0 0, -1 1, 1 1))
+!ok
+
+# Using a 3d polygon
+SELECT ST_AsText(ST_Boundary(ST_GeomFromText('POLYGON Z((1 1 1,0 0 1, -1 1 1, 1 1 1))')));
+
+EXPR$0
+MULTILINESTRING Z ((1 1 1, 0 0 1, -1 1 1, 1 1 1))
+!ok
+
+# Using a 3d multilinestring
+SELECT ST_AsText(ST_Boundary(ST_GeomFromText('MULTILINESTRING Z((1 1 1,0 0 0.5, -1 1 1),(1 1 0.5,0 0 0.5, -1 1 0.5, 1 1 0.5) )')));
+
+EXPR$0
+MULTIPOINT Z ((1 1 1), (-1 1 1))
+!ok
+
+# ST_Centroid(geom) Returns the centroid of *geom* (which may be a geometry-collection)
+# Not implemented
+
+# ST_CompactnessRatio(polygon) Returns the square root of *polygon*'s area divided by the area of the circle with circumference equal to its perimeter
+# Not implemented
+
+# ST_CoordDim(geom) Returns the dimension of the coordinates of *geom*
+# Not implemented
+
+# ST_Dimension(geom) Returns the dimension of *geom*
+# Not implemented
+
+# ST_Distance(geom1, geom2) Returns the distance between *geom1* and *geom2*
+
+SELECT ST_Distance(
+    ST_GeomFromText('POINT(10 10)'),
+    ST_GeomFromText('POINT(40 50)'));
+EXPR$0
+50.0
+!ok
+
+SELECT ST_Distance(
+    ST_GeomFromText('POINT(10 10)',4326),
+    ST_GeomFromText('POINT(40 50)', 4326));
+EXPR$0
+50.0
+!ok
+
+# Geometry example - units in planar degrees 4326 is WGS 84 long lat unit=degrees
+SELECT ST_Distance(
+    ST_GeomFromText('POINT(-72.1235 42.3521)',4326),
+    ST_GeomFromText('LINESTRING(-72.1260 42.45, -72.123 42.1546)', 4326));
+EXPR$0
+0.0015056772638282166
+!ok
+
+# Geometry example - units in meters (SRID: 26986 Massachusetts state plane meters) (most accurate for Massachusetts)
+SELECT ST_Distance(
+    ST_Transform(ST_GeomFromText('POINT(-72.1235 42.3521)',4326),26986),
+    ST_Transform(ST_GeomFromText('LINESTRING(-72.1260 42.45, -72.123 42.1546)', 4326),26986));
+EXPR$0
+0.0015056772638282166
+!ok
+
+# Geometry example - units in meters (SRID: 2163 US National Atlas Equal area) (least accurate)
+SELECT ST_Distance(
+    ST_Transform(ST_GeomFromText('POINT(-72.1235 42.3521)',4326),2163),
+    ST_Transform(ST_GeomFromText('LINESTRING(-72.1260 42.45, -72.123 42.1546)', 4326),2163));
+
+EXPR$0
+0.0015056772638282166
+!ok
+
+# Disabled: PostgreSQL does geography, Calcite does not
+!if (false) {
+# same as geometry example but note units in meters - use sphere for slightly faster less accurate
+SELECT ST_Distance(gg1, gg2) As spheroid_dist, ST_Distance(gg1, gg2, false) As sphere_dist
+FROM (SELECT
+    ST_GeogFromText('SRID=4326;POINT(-72.1235 42.3521)') As gg1,
+    ST_GeogFromText('SRID=4326;LINESTRING(-72.1260 42.45, -72.123 42.1546)') As gg2) As foo;
+
+  spheroid_dist   |   sphere_dist
+------------------+------------------
+ 123.802076746848 | 123.475736916397
+!ok
+!}
+
+# ST_EndPoint(lineString) Returns the last coordinate of *lineString*
+# Not implemented
+
+# ST_Envelope(geom [, srid ]) Returns the envelope of *geom* (which may be a geometry-collection) as a geometry
+
+SELECT ST_AsText(ST_Envelope(ST_GeomFromText('POINT(1 3)')));
+EXPR$0
+POLYGON ((1 3, 1 3, 1 3, 1 3, 1 3))
+!ok
+
+SELECT ST_AsText(ST_Envelope(ST_GeomFromText('LINESTRING(0 0, 1 3)')));
+EXPR$0
+POLYGON ((0 0, 1 0, 1 3, 0 3, 0 0))
+!ok
+
+SELECT ST_AsText(ST_Envelope(ST_GeomFromText('POLYGON((0 0, 0 1, 1.0000001 1, 1.0000001 0, 0 0))')));
+EXPR$0
+POLYGON ((0 0, 1.0000001 0, 1.0000001 1, 0 1, 0 0))
+!ok
+
+SELECT ST_AsText(ST_Envelope(ST_GeomFromText('POLYGON((0 0, 0 1, 1.0000000001 1, 1.0000000001 0, 0 0))')));
+EXPR$0
+POLYGON ((0 0, 1.0000000001 0, 1.0000000001 1, 0 1, 0 0))
+!ok
+
+# ST_Explode(query [, fieldName]) Explodes the geometry-collections in the *fieldName* column of a query into multiple geometries
+# Not implemented
+
+# ST_Extent(geom) Returns the minimum bounding box of *geom* (which may be a geometry-collection)
+# Not implemented
+
+# ST_ExteriorRing(polygon) Returns the exterior ring of *polygon* as a linear-ring
+# Not implemented
+
+# ST_GeometryN(geomCollection, n) Returns the *n*th geometry of *geomCollection*
+# Not implemented
+
+# ST_GeometryType(geom) Returns the type of *geom*
+
+SELECT ST_GeometryType(ST_Point(0.0, 0.0));
+EXPR$0
+POINT
+!ok
+
+# ST_GeometryTypeCode(geom) Returns the type code of *geom*
+
+SELECT id, ST_GeometryType(g), ST_GeometryTypeCode(g) FROM (VALUES
+ ('ls', ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)')),
+ ('p', ST_Point(0.0, 0.0)),
+ ('np', ST_Point(0.0, CAST(NULL AS DECIMAL))),
+ ('mp', ST_GeomFromText('MULTIPOLYGON(((1 1, 2 2, 5 3, 1 1)),
+                                       ((0 0, 2 2, 5 3, 0 0)))'))) AS t(id, g);
+ID, EXPR$1, EXPR$2
+ls, LINESTRING, 2
+mp, POLYGON, 3
+np, null, null
+p , POINT, 1
+!ok
+
+# ST_InteriorRingN(polygon, n) Returns the *n*th interior ring of *polygon*
+# Not implemented
+
+# ST_IsClosed(geom) Returns whether *geom* is a closed line-string or multi-line-string
+# Not implemented
+
+# ST_IsEmpty(geom) Returns whether *geom* is empty
+# Not implemented
+
+# ST_IsRectangle(geom) Returns whether *geom* is a rectangle
+# Not implemented
+
+# ST_IsRing(geom) Returns whether *geom* is a closed and simple line-string or multi-line-string
+# Not implemented
+
+# ST_IsSimple(geom) Returns whether *geom* is simple
+# Not implemented
+
+# ST_IsValid(geom) Returns whether *geom* is valid
+# Not implemented
+
+# ST_IsValidDetail(geom [, selfTouchValid ]) Returns a valid detail as an array of objects
+# Not implemented
+
+# ST_IsValidReason(geom [, selfTouchValid ]) Returns text stating whether *geom* is valid, and if not valid, a reason why
+# Not implemented
+
+# ST_NPoints(geom) Returns the number of points in *geom*
+# Not implemented
+
+# ST_NumGeometries(geom) Returns the number of geometries in *geom* (1 if it is not a geometry-collection)
+# Not implemented
+
+# ST_NumInteriorRing(geom) Alias for `ST_NumInteriorRings`
+# Not implemented
+
+# ST_NumInteriorRings(geom) Returns the number of interior rings of *geom*
+# Not implemented
+
+# ST_NumPoints(lineString) Returns the number of points in *lineString*
+# Not implemented
+
+# ST_PointN(geom, n) Returns the *n*th point of a *lineString*
+# Not implemented
+
+# ST_PointOnSurface(geom) Returns an interior or boundary point of *geom*
+# Not implemented
+
+# ST_SRID(geom) Returns SRID value of *geom* or 0 if it does not have one
+# Not implemented
+
+# ST_StartPoint(lineString) Returns the first coordinate of *lineString*
+# Not implemented
+
+# ST_X(geom) Returns the x-value of the first coordinate of *geom*
+# Not implemented
+
+# ST_XMax(geom) Returns the maximum x-value of *geom*
+# Not implemented
+
+# ST_XMin(geom) Returns the minimum x-value of *geom*
+# Not implemented
+
+# ST_Y(geom) Returns the y-value of the first coordinate of *geom*
+# Not implemented
+
+# ST_YMax(geom) Returns the maximum y-value of *geom*
+# Not implemented
+
+# ST_YMin(geom) Returns the minimum y-value of *geom*
+# Not implemented
+
+#### Geometry properties (3D)
+
+# ST_Is3D(s) Returns whether *geom* has at least one z-coordinate
+
+SELECT ST_Is3D(ST_GeomFromText('POINT Z(1 2 0)'));
+EXPR$0
+true
+!ok
+
+SELECT ST_Is3D(ST_GeomFromText('POINT (1 2)'));
+EXPR$0
+false
+!ok
+
+# ST_Z(geom) Returns the z-value of the first coordinate of *geom*
+
+SELECT ST_Z(ST_GeomFromText('POINT Z(1 2 3)'));
+EXPR$0
+3.0
+!ok
+
+SELECT ST_Z(ST_GeomFromText('POINT (1 2)'));
+EXPR$0
+null
+!ok
+
+# Not implemented
+
+# ST_ZMax(geom) Returns the maximum z-value of *geom*
+# Not implemented
+
+# ST_ZMin(geom) Returns the minimum z-value of *geom*
+# Not implemented
+
+### Geometry predicates
+
+# ST_Contains(geom1, geom2) Returns whether *geom1* contains *geom2*
+
+SELECT ST_Contains(ST_Point(0.0, 0.0), ST_Point(1.0, 2.0));
+EXPR$0
+false
+!ok
+
+SELECT ST_Contains(ST_Point(0.0, 0.0), ST_Point(0.0, 0.0));
+EXPR$0
+true
+!ok
+
+# ST_ContainsProperly(geom1, geom2) Returns whether *geom1* contains *geom2*
+
+-- Example demonstrating difference between contains and contains properly
+SELECT ST_GeometryType(geomA) As geomtype, ST_Contains(geomA,geomA) AS acontainsa, ST_ContainsProperly(geomA, geomA) AS acontainspropa,
+   ST_Contains(geomA, ST_Boundary(geomA)) As acontainsba, ST_ContainsProperly(geomA, ST_Boundary(geomA)) As acontainspropba
+FROM (VALUES ( ST_Buffer(ST_Point(1.0,1.0), 5/*,1*/) ),
+             ( ST_MakeLine(ST_Point(1.0,1.0), ST_Point(-1.0,-1.0) ) ),
+             ( ST_Point(1.0,1.0))) As foo(geomA);
+
+GEOMTYPE, ACONTAINSA, ACONTAINSPROPA, ACONTAINSBA, ACONTAINSPROPBA
+LINESTRING, true, true, false, false
+POINT, true, true, false, false
+POLYGON, true, true, false, false
+!ok
+
+# ST_Covers(geom1, geom2) Returns whether no point in *geom2* is outside *geom1*
+# Not implemented
+
+# ST_Crosses(geom1, geom2) Returns whether *geom1* crosses *geom2*
+
+SELECT ST_Crosses(ST_GeomFromText('LINESTRING(1 3, 5 3)'),
+                  ST_GeomFromText('LINESTRING(1 1, 5 2, 2 5)'));
+EXPR$0
+true
+!ok
+
+# ST_DWithin(geom1, geom2, distance) Returns whether *geom1* and *geom* are within *distance* of one another
+
+# Countries within 10 degrees of London
+select "name" from GEO."countries" AS c
+where ST_Distance(ST_MakePoint(51.5, -0.12), ST_MakePoint("latitude", "longitude")) < 10;
+name
+Andorra
+Belgium
+France
+Guernsey
+Ireland
+Isle of Man
+Jersey
+Luxembourg
+Netherlands
+Switzerland
+United Kingdom
+!ok
+
+# Countries within 10 degrees of London, formulated a different way
+select "name" from GEO."countries" AS c
+where ST_DWithin(ST_MakePoint(51.5, -0.12), ST_MakePoint("latitude", "longitude"), 10);
+name
+Andorra
+Belgium
+France
+Guernsey
+Ireland
+Isle of Man
+Jersey
+Luxembourg
+Netherlands
+Switzerland
+United Kingdom
+!ok
+
+# ST_Disjoint(geom1, geom2) Returns whether *geom1* and *geom2* are disjoint
+
+SELECT ST_Disjoint(ST_GeomFromText('LINESTRING(1 3, 5 3)'),
+                   ST_GeomFromText('LINESTRING(1 1, 5 2, 2 5)'));
+EXPR$0
+false
+!ok
+
+
+# ST_EnvelopesIntersect(geom1, geom2) Returns whether the envelope of *geom1* intersects the envelope of *geom2*
+
+SELECT ST_EnvelopesIntersect(ST_GeomFromText('LINESTRING(1 3, 5 3)'),
+                             ST_GeomFromText('LINESTRING(1 1, 5 2, 2 5)'));
+EXPR$0
+true
+!ok
+
+# ST_Equals(geom1, geom2) Returns whether *geom1* equals *geom2*
+
+SELECT ST_Equals(ST_GeomFromText('LINESTRING(1 3, 5 3)'),
+                 ST_GeomFromText('LINESTRING(1 1, 5 2, 2 5)'));
+EXPR$0
+false
+!ok
+
+# ST_Intersects(geom1, geom2) Returns whether *geom1* intersects *geom2*
+
+SELECT ST_Intersects(ST_GeomFromText('LINESTRING(1 3, 5 3)'),
+                     ST_GeomFromText('LINESTRING(1 1, 5 2, 2 5)'));
+EXPR$0
+true
+!ok
+
+# ST_OrderingEquals(geom1, geom2) Returns whether *geom1* equals *geom2* and their coordinates and component Geometries are listed in the same order
+# Not implemented
+
+# ST_Overlaps(geom1, geom2) Returns whether *geom1* overlaps *geom2*
+
+SELECT ST_Overlaps(ST_GeomFromText('LINESTRING(1 3, 5 3)'),
+                   ST_GeomFromText('LINESTRING(1 1, 5 2, 2 5)'));
+EXPR$0
+false
+!ok
+
+# ST_Relate(geom1, geom2) Returns the DE-9IM intersection matrix of *geom1* and *geom2*
+# Not implemented
+
+# ST_Relate(geom1, geom2, iMatrix) Returns whether *geom1* and *geom2* are related by the given intersection matrix *iMatrix*
+# Not implemented
+
+# ST_Touches(geom1, geom2) Returns whether *geom1* touches *geom2*
+
+SELECT ST_Touches(ST_GeomFromText('LINESTRING(1 3, 5 3)'),
+                  ST_GeomFromText('LINESTRING(1 1, 5 2, 2 5)'));
+EXPR$0
+false
+!ok
+
+# ST_Within(geom1, geom2) Returns whether *geom1* is within *geom2*
+
+SELECT ST_Within(ST_GeomFromText('LINESTRING(1 3, 5 3)'),
+                 ST_GeomFromText('LINESTRING(1 1, 5 2, 2 5)'));
+EXPR$0
+false
+!ok
+
+#### Geometry operators (2D)
+
+# ST_Buffer(geom, bufferSize [, quadSegs | style ]) Computes a buffer around *geom*
+
+SELECT ST_Buffer(
+ ST_GeomFromText('POINT(100 90)'),
+ 50);
+EXPR$0
+{"rings":[[[150,90],[149.89294616193018,86.72984353849284],[149.5722430686905,83.47369038899743],[149.0392640201615,80.24548389919359],[148.2962913144534,77.05904774487396],[147.34650647475527,73.9... (3574 characters)
+!ok
+
+SELECT ST_Buffer(
+ ST_GeomFromText('LINESTRING(10 10,30 10)'),
+ 5);
+EXPR$0
+{"rings":[[[10,5],[9.672984353849284,5.010705383806982],[9.347369038899743,5.042775693130948],[9.02454838991936,5.096073597983848],[8.705904774487397,5.1703708685546585],[8.39280267348419,5.2653493... (3532 characters)
+!ok
+
+SELECT ST_Buffer(
+  ST_GeomFromText('POLYGON((-71.1776585052917 42.3902909739571,-71.1776820268866 42.3903701743239,
+    -71.1776063012595 42.3903825660754,-71.1775826583081 42.3903033653531,-71.1776585052917 42.3902909739571))'),
+ 50);
+EXPR$0
+{"rings":[[[-21.17763234259735,42.39033677001625],[-21.284686180667173,39.12018030850909],[-21.60538927390683,35.864027159013666],[-22.138368322435824,32.635820669209835],[-22.881341028143936,29.44... (3872 characters)
+!ok
+
+# Negative buffer size makes the polgyon smaller
+SELECT ST_Buffer(
+  ST_GeomFromText('POLYGON((10 10,10 20,20 20,20 10))'),
+ -1);
+EXPR$0
+{"rings":[[[11,11],[11,19],[19,19],[19,11],[11,11]]]}
+!ok
+
+# ST_BUFFER(geom, bufferSize, style) variant - not implemented
+SELECT ST_Buffer(
+ ST_GeomFromText('POINT(100 90)'),
+ 50, 'quad_segs=8');
+at org.apache.calcite.runtime.GeoFunctions.todo
+!error GeoFunctions
+
+# ST_BUFFER(geom, bufferSize, quadSegs) variant - not implemented
+# When implemented, remove comment from ST_Contains test case
+SELECT ST_Buffer(
+ ST_GeomFromText('POINT(100 90)'),
+ 50, 2);
+at org.apache.calcite.runtime.GeoFunctions.todo
+!error GeoFunctions
+
+# ST_ConvexHull(geom) Computes the smallest convex polygon that contains all the points in the Geometry
+# Not implemented
+
+# ST_Difference(geom1, geom2) Computes the difference between two geometries
+# Not implemented
+
+# ST_Intersection(geom1, geom2) Computes the intersection of two geometries
+# Not implemented
+
+# ST_SymDifference(geom1, geom2) Computes the symmetric difference between two geometries
+# Not implemented
+
+# ST_Union(geom1, geom2) Computes the union of two or more geometries
+
+# NOTE: PostGIS altered the order: it returned MULTIPOINT(-2 3,1 2)
+SELECT ST_AsText(ST_Union(ST_GeomFromText('POINT(1 2)'),
+    ST_GeomFromText('POINT(-2 3)')));
+
+EXPR$0
+MULTIPOINT ((1 2), (-2 3))
+!ok
+
+# NOTE: PostGIS returned a point not a multipoint: POINT(1 2). ESRI bug?
+SELECT ST_AsText(ST_Union(ST_GeomFromText('POINT(1 2)'),
+    ST_GeomFromText('POINT(1 2)')));
+EXPR$0
+MULTIPOINT ((1 2))
+!ok
+
+# ST_Union(geomCollection) Computes the union of two or more geometries
+
+# Disabled: ST_GeomFromText cannot handle GEOMETRYCOLLECTION
+!if (false) {
+SELECT ST_AsText(st_union(ST_GeomFromText('GEOMETRYCOLLECTION(
+  POLYGON((-7 4.2,-7.1 4.2,-7.1 4.3,-7 4.2))
+  POINT(5 5)
+  POINT(-2 3)
+  LINESTRING(5 5, 10 10)')));
+EXPR$0
+null
+!ok
+!}
+
+# ST_UNION(ARRAY[GEOMETRY]) is a PostGIS extension
+# We don't support it
+!if (false) {
+
+SELECT ST_Union(ARRAY(SELECT the_geom FROM sometable));
+!ok
+
+SELECT ST_AsText(ST_Union(ARRAY[ST_GeomFromText('LINESTRING(1 2, 3 4)'),
+    ST_GeomFromText('LINESTRING(3 4, 4 5)')])) As wktunion;
+
+--wktunion---
+MULTILINESTRING((3 4,4 5),(1 2,3 4))
+!ok
+!}
+
+#### Affine transformation functions (3D and 2D)
+
+# ST_Rotate(geom, angle [, origin | x, y]) Rotates a *geom* counter-clockwise by *angle* (in radians) about *origin* (or the point (*x*, *y*))
+# Not implemented
+
+# ST_Scale(geom, xFactor, yFactor [, zFactor ]) Scales *geom* by multiplying the ordinates by the indicated scale factors
+# Not implemented
+
+# ST_Translate(geom, x, y, [, z]) Translates *geom*
+# Not implemented
+
+#### Geometry editing functions (2D)
+
+# ST_AddPoint(geom, point [, tolerance ]) Adds *point* to *geom* with a given *tolerance* (default 0)
+# Not implemented
+
+# ST_CollectionExtract(geom, dimension) Filters *geom*, returning a multi-geometry of those members with a given *dimension* (1 = point, 2 = line-string, 3 = polygon)
+# Not implemented
+
+# ST_Densify(geom, tolerance) Inserts extra vertices every *tolerance* along the line segments of *geom*
+# Not implemented
+
+# ST_FlipCoordinates(geom) Flips the X and Y coordinates of *geom*
+# Not implemented
+
+# ST_Holes(geom) Returns the holes in *geom* (which may be a geometry-collection)
+# Not implemented
+
+# ST_Normalize(geom) Converts *geom* to normal form
+# Not implemented
+
+# ST_RemoveDuplicatedCoordinates(geom) Removes duplicated coordinates from *geom*
+# Not implemented
+
+# ST_RemoveHoles(geom) Removes a *geom*'s holes
+# Not implemented
+
+# ST_RemovePoints(geom, poly) Removes all coordinates of *geom* located within *poly*; null if all coordinates are removed
+# Not implemented
+
+# ST_RemoveRepeatedPoints(geom, tolerance) Removes from *geom* all repeated points (or points within *tolerance* of another point)
+# Not implemented
+
+# ST_Reverse(geom) Reverses the vertex order of *geom*
+# Not implemented
+
+#### Geometry editing functions (3D)
+
+# ST_AddZ(geom, zToAdd) Adds *zToAdd* to the z-coordinate of *geom*
+# Not implemented
+
+# ST_Interpolate3DLine(geom) Returns *geom* with a interpolation of z values, or null if it is not a line-string or multi-line-string
+# Not implemented
+
+# ST_MultiplyZ(geom, zFactor) Returns *geom* with its z-values multiplied by *zFactor*
+# Not implemented
+
+# ST_Reverse3DLine(geom [, sortOrder ]) Potentially reverses *geom* according to the z-values of its first and last coordinates
+# Not implemented
+
+# ST_UpdateZ(geom, newZ [, updateCondition ]) Updates the z-values of *geom*
+# Not implemented
+
+# ST_ZUpdateLineExtremities(geom, startZ, endZ [, interpolate ]) Updates the start and end z-values of *geom*
+# Not implemented
+
+#### Geometry measurement functions (2D)
+
+# ST_Area(geom) Returns the area of *geom* (which may be a geometry collection)
+# Not implemented
+
+# ST_ClosestCoordinate(geom, point) Returns the coordinate(s) of *geom* closest to *point*
+# Not implemented
+
+# ST_ClosestPoint(geom1, geom2) Returns the point of *geom1* closest to *geom2*
+# Not implemented
+
+# ST_FurthestCoordinate(geom, point) Returns the coordinate(s) of *geom* that are furthest from *point*
+# Not implemented
+
+# ST_Length(lineString) Returns the length of *lineString*
+# Not implemented
+
+# ST_LocateAlong(geom, segmentLengthFraction, offsetDistance) Returns a multi-point containing points along the line segments of *geom* at *segmentLengthFraction* and *offsetDistance*
+# Not implemented
+
+# ST_LongestLine(geom1, geom2) Returns the 2-dimensional longest line-string between the points of *geom1* and *geom2*
+# Not implemented
+
+# ST_MaxDistance(geom1, geom2) Computes the maximum distance between *geom1* and *geom2*
+# Not implemented
+
+# ST_Perimeter(polygon) Returns the length of the perimeter of *polygon* (which may be a multi-polygon)
+# Not implemented
+
+# ST_ProjectPoint(point, lineString) Projects *point* onto a *lineString* (which may be a multi-line-string)
+# Not implemented
+
+#### Geometry measurement functions (3D)
+
+# ST_3DArea(geom) Return a polygon's 3D area
+# Not implemented
+
+# ST_3DLength(geom) Returns the 3D length of a line-string
+# Not implemented
+
+# ST_3DPerimeter(geom) Returns the 3D perimeter of a polygon or multi-polygon
+# Not implemented
+
+# ST_SunPosition(point [, timestamp ]) Computes the sun position at *point* and *timestamp* (now by default)
+# Not implemented
+
+#### Geometry processing functions (2D)
+
+# ST_LineIntersector(geom1, geom2) Splits *geom1* (a line-string) with *geom2*
+# Not implemented
+
+# ST_LineMerge(geom) Merges a collection of linear components to form a line-string of maximal length
+# Not implemented
+
+# ST_MakeValid(geom [, preserveGeomDim [, preserveDuplicateCoord [, preserveCoordDim]]]) Makes *geom* valid
+# Not implemented
+
+# ST_Polygonize(geom) Creates a multi-polygon from edges of *geom*
+# Not implemented
+
+# ST_PrecisionReducer(geom, n) Reduces *geom*'s precision to *n* decimal places
+# Not implemented
+
+# ST_RingSideBuffer(geom, bufferSize, bufferCount [, endCapStyle [, doDifference]]) Computes a ring buffer on one side
+# Not implemented
+
+# ST_SideBuffer(geom, bufferSize [, bufferStyle ]) Compute a single buffer on one side
+# Not implemented
+
+# ST_Simplify(geom, distance) Simplifies *geom* using the Douglas-Peuker algorithm with a *distance* tolerance
+# Not implemented
+
+# ST_SimplifyPreserveTopology(geom) Simplifies *geom*, preserving its topology
+# Not implemented
+
+# ST_Snap(geom1, geom2, tolerance) Snaps *geom1* and *geom2* together
+# Not implemented
+
+# ST_Split(geom1, geom2 [, tolerance]) Splits *geom1* by *geom2* using *tolerance* (default 1E-6) to determine where the point splits the line
+# Not implemented
+
+#### Geometry projection functions
+
+# ST_SetSRID(geom, srid) Returns a copy of *geom* with a new SRID
+
+SELECT ST_SetSRID(ST_MakePoint(-123.365556, 48.428611),4326) As wgs84long_lat;
+WGS84LONG_LAT
+{"x":-123.365556,"y":48.428611}
+!ok
+
+# Mark a point as WGS 84 long lat and then transform to web mercator (Spherical Mercator)
+SELECT ST_Transform(ST_SetSRID(ST_MakePoint(-123.365556, 48.428611),4326),3785) As sphere_merc;
+SPHERE_MERC
+{"x":-123.365556,"y":48.428611,"spatialReference":{"wkid":102113,"latestWkid":3785}}
+!ok
+
+# ST_Transform(geom, srid) Transforms *geom* from one coordinate reference system (CRS) to the CRS specified by *srid*
+
+SELECT ST_AsText(ST_Transform(ST_GeomFromText('POLYGON((743238 2967416,743238 2967450,
+  743265 2967450,743265.625 2967416,743238 2967416))',2249),4326)) As wgs_geom;
+
+WGS_GEOM
+MULTIPOLYGON (((743238 2967416, 743265.625 2967416, 743265 2967450, 743238 2967450, 743238 2967416)))
+!ok
+
+#### Trigonometry functions
+
+# ST_Azimuth(point1, point2) Return the azimuth of the segment from *point1* to *point2*
+# Not implemented
+
+#### Topography functions
+
+# ST_TriangleAspect(geom) Returns the aspect of a triangle
+# Not implemented
+
+# ST_TriangleContouring(query \[, z1, z2, z3 ]\[, varArgs]*) Splits triangles into smaller triangles according to classes
+# Not implemented
+
+# ST_TriangleDirection(geom) Computes the direction of steepest ascent of a triangle and returns it as a line-string
+# Not implemented
+
+# ST_TriangleSlope(geom) Computes the slope of a triangle as a percentage
+# Not implemented
+
+# ST_Voronoi(geom [, outDimension [, envelopePolygon ]]) Creates a Voronoi diagram
+# Not implemented
+
+#### Triangulation functions
+
+# ST_ConstrainedDelaunay(geom [, flag [, quality ]]) Computes a constrained Delaunay triangulation based on *geom*
+# Not implemented
+
+# ST_Delaunay(geom [, flag [, quality ]]) Computes a Delaunay triangulation based on points
+# Not implemented
+
+# ST_Tessellate(polygon) Tessellates *polygon* (may be multi-polygon) with adaptive triangles
+# Not implemented
+
+#### Geometry aggregate functions
+
+# ST_Accum(geom) Accumulates *geom* into a geometry-collection (or multi-point, multi-line-string or multi-polygon if possible)
+# Not implemented
+
+# ST_Collect(geom) Alias for `ST_Accum`
+# Not implemented
+
+# ST_Union(geom) Computes the union of geometries
+# Not implemented
+
+# Disabled - ST_Union agg function is not implemented
+!if (false) {
+SELECT ST_AsText(st_union(the_geom))
+FROM (VALUES ST_GeomFromText('POLYGON((-7 4.2,-7.1 4.2,-7.1 4.3,-7 4.2))'),
+  ST_GeomFromText('POINT(5 5)'),
+  ST_GeomFromText('POINT(-2 3)'),
+  ST_GeomFromText('LINESTRING(5 5, 10 10)')) as foo(the_geom);
+
+st_asewkt
+---------
+GEOMETRYCOLLECTION(POINT(-2 3 1),LINESTRING(5 5 5,10 10 10),POLYGON((-7 4.2 5,-7.1 4.2 5,-7.1 4.3 5,-7 4.2 5)))
+!ok
+!}
+
+# 3d example - sort of supports 3d (and with mixed dimensions!)
+# WRONG: Currently returns 4 rows, should return 1 row when ST_Union is aggregate function
+SELECT ST_AsText(st_union(the_geom))
+FROM (
+  SELECT ST_GeomFromText('POLYGON((-7 4.2,-7.1 4.2,-7.1 4.3,-7 4.2))') as the_geom
+  UNION ALL
+  SELECT ST_GeomFromText('POINT Z(5 5 5)') as the_geom
+  UNION ALL
+  SELECT ST_GeomFromText('POINT Z(-2 3 1)') as the_geom
+  UNION ALL
+  SELECT ST_GeomFromText('LINESTRING Z(5 5 5, 10 10 10)') as the_geom ) as foo;
+
+EXPR$0
+MULTILINESTRING Z ((5 5 5, 10 10 10))
+MULTIPOLYGON (((-7 4.2, -7.1 4.3, -7.1 4.2, -7 4.2)))
+POINT Z (-2 3 1)
+POINT Z (5 5 5)
+!ok
+
+# 3d example not mixing dimensions
+# WRONG: Currently returns 4 rows, should return 1 row when ST_Union is aggregate function
+SELECT ST_AsText(st_union(the_geom))
+FROM (
+  SELECT ST_GeomFromText('POLYGON Z((-7 4.2 2,-7.1 4.2 3,-7.1 4.3 2,-7 4.2 2))') as the_geom
+  UNION ALL
+  SELECT ST_GeomFromText('POINT Z(5 5 5)') as the_geom
+  UNION ALL
+  SELECT ST_GeomFromText('POINT Z(-2 3 1)') as the_geom
+  UNION ALL
+  SELECT ST_GeomFromText('LINESTRING Z(5 5 5, 10 10 10)') as the_geom ) as foo;
+
+EXPR$0
+MULTILINESTRING Z ((5 5 5, 10 10 10))
+MULTIPOLYGON Z (((-7 4.2 2, -7.1 4.3 2, -7.1 4.2 3, -7 4.2 2)))
+POINT Z (-2 3 1)
+POINT Z (5 5 5)
+!ok
+
+# End spatial.iq

http://git-wip-us.apache.org/repos/asf/calcite/blob/cc20ca13/file/src/test/resources/geo/countries.csv
----------------------------------------------------------------------
diff --git a/file/src/test/resources/geo/countries.csv b/file/src/test/resources/geo/countries.csv
new file mode 100644
index 0000000..9ae51a2
--- /dev/null
+++ b/file/src/test/resources/geo/countries.csv
@@ -0,0 +1,246 @@
+country:string,latitude:decimal,longitude:decimal,name:string
+AD,42.546245,1.601554,Andorra
+AE,23.424076,53.847818,United Arab Emirates
+AF,33.93911,67.709953,Afghanistan
+AG,17.060816,-61.796428,Antigua and Barbuda
+AI,18.220554,-63.068615,Anguilla
+AL,41.153332,20.168331,Albania
+AM,40.069099,45.038189,Armenia
+AN,12.226079,-69.060087,Netherlands Antilles
+AO,-11.202692,17.873887,Angola
+AQ,-75.250973,-0.071389,Antarctica
+AR,-38.416097,-63.616672,Argentina
+AS,-14.270972,-170.132217,American Samoa
+AT,47.516231,14.550072,Austria
+AU,-25.274398,133.775136,Australia
+AW,12.52111,-69.968338,Aruba
+AZ,40.143105,47.576927,Azerbaijan
+BA,43.915886,17.679076,Bosnia and Herzegovina
+BB,13.193887,-59.543198,Barbados
+BD,23.684994,90.356331,Bangladesh
+BE,50.503887,4.469936,Belgium
+BF,12.238333,-1.561593,Burkina Faso
+BG,42.733883,25.48583,Bulgaria
+BH,25.930414,50.637772,Bahrain
+BI,-3.373056,29.918886,Burundi
+BJ,9.30769,2.315834,Benin
+BM,32.321384,-64.75737,Bermuda
+BN,4.535277,114.727669,Brunei
+BO,-16.290154,-63.588653,Bolivia
+BR,-14.235004,-51.92528,Brazil
+BS,25.03428,-77.39628,Bahamas
+BT,27.514162,90.433601,Bhutan
+BV,-54.423199,3.413194,Bouvet Island
+BW,-22.328474,24.684866,Botswana
+BY,53.709807,27.953389,Belarus
+BZ,17.189877,-88.49765,Belize
+CA,56.130366,-106.346771,Canada
+CC,-12.164165,96.870956,Cocos [Keeling] Islands
+CD,-4.038333,21.758664,Congo [DRC]
+CF,6.611111,20.939444,Central African Republic
+CG,-0.228021,15.827659,Congo [Republic]
+CH,46.818188,8.227512,Switzerland
+CI,7.539989,-5.54708,Côte d'Ivoire
+CK,-21.236736,-159.777671,Cook Islands
+CL,-35.675147,-71.542969,Chile
+CM,7.369722,12.354722,Cameroon
+CN,35.86166,104.195397,China
+CO,4.570868,-74.297333,Colombia
+CR,9.748917,-83.753428,Costa Rica
+CU,21.521757,-77.781167,Cuba
+CV,16.002082,-24.013197,Cape Verde
+CX,-10.447525,105.690449,Christmas Island
+CY,35.126413,33.429859,Cyprus
+CZ,49.817492,15.472962,Czech Republic
+DE,51.165691,10.451526,Germany
+DJ,11.825138,42.590275,Djibouti
+DK,56.26392,9.501785,Denmark
+DM,15.414999,-61.370976,Dominica
+DO,18.735693,-70.162651,Dominican Republic
+DZ,28.033886,1.659626,Algeria
+EC,-1.831239,-78.183406,Ecuador
+EE,58.595272,25.013607,Estonia
+EG,26.820553,30.802498,Egypt
+EH,24.215527,-12.885834,Western Sahara
+ER,15.179384,39.782334,Eritrea
+ES,40.463667,-3.74922,Spain
+ET,9.145,40.489673,Ethiopia
+FI,61.92411,25.748151,Finland
+FJ,-16.578193,179.414413,Fiji
+FK,-51.796253,-59.523613,Falkland Islands [Islas Malvinas]
+FM,7.425554,150.550812,Micronesia
+FO,61.892635,-6.911806,Faroe Islands
+FR,46.227638,2.213749,France
+GA,-0.803689,11.609444,Gabon
+GB,55.378051,-3.435973,United Kingdom
+GD,12.262776,-61.604171,Grenada
+GE,42.315407,43.356892,Georgia
+GF,3.933889,-53.125782,French Guiana
+GG,49.465691,-2.585278,Guernsey
+GH,7.946527,-1.023194,Ghana
+GI,36.137741,-5.345374,Gibraltar
+GL,71.706936,-42.604303,Greenland
+GM,13.443182,-15.310139,Gambia
+GN,9.945587,-9.696645,Guinea
+GP,16.995971,-62.067641,Guadeloupe
+GQ,1.650801,10.267895,Equatorial Guinea
+GR,39.074208,21.824312,Greece
+GS,-54.429579,-36.587909,South Georgia and the South Sandwich Islands
+GT,15.783471,-90.230759,Guatemala
+GU,13.444304,144.793731,Guam
+GW,11.803749,-15.180413,Guinea-Bissau
+GY,4.860416,-58.93018,Guyana
+GZ,31.354676,34.308825,Gaza Strip
+HK,22.396428,114.109497,Hong Kong
+HM,-53.08181,73.504158,Heard Island and McDonald Islands
+HN,15.199999,-86.241905,Honduras
+HR,45.1,15.2,Croatia
+HT,18.971187,-72.285215,Haiti
+HU,47.162494,19.503304,Hungary
+ID,-0.789275,113.921327,Indonesia
+IE,53.41291,-8.24389,Ireland
+IL,31.046051,34.851612,Israel
+IM,54.236107,-4.548056,Isle of Man
+IN,20.593684,78.96288,India
+IO,-6.343194,71.876519,British Indian Ocean Territory
+IQ,33.223191,43.679291,Iraq
+IR,32.427908,53.688046,Iran
+IS,64.963051,-19.020835,Iceland
+IT,41.87194,12.56738,Italy
+JE,49.214439,-2.13125,Jersey
+JM,18.109581,-77.297508,Jamaica
+JO,30.585164,36.238414,Jordan
+JP,36.204824,138.252924,Japan
+KE,-0.023559,37.906193,Kenya
+KG,41.20438,74.766098,Kyrgyzstan
+KH,12.565679,104.990963,Cambodia
+KI,-3.370417,-168.734039,Kiribati
+KM,-11.875001,43.872219,Comoros
+KN,17.357822,-62.782998,Saint Kitts and Nevis
+KP,40.339852,127.510093,North Korea
+KR,35.907757,127.766922,South Korea
+KW,29.31166,47.481766,Kuwait
+KY,19.513469,-80.566956,Cayman Islands
+KZ,48.019573,66.923684,Kazakhstan
+LA,19.85627,102.495496,Laos
+LB,33.854721,35.862285,Lebanon
+LC,13.909444,-60.978893,Saint Lucia
+LI,47.166,9.555373,Liechtenstein
+LK,7.873054,80.771797,Sri Lanka
+LR,6.428055,-9.429499,Liberia
+LS,-29.609988,28.233608,Lesotho
+LT,55.169438,23.881275,Lithuania
+LU,49.815273,6.129583,Luxembourg
+LV,56.879635,24.603189,Latvia
+LY,26.3351,17.228331,Libya
+MA,31.791702,-7.09262,Morocco
+MC,43.750298,7.412841,Monaco
+MD,47.411631,28.369885,Moldova
+ME,42.708678,19.37439,Montenegro
+MG,-18.766947,46.869107,Madagascar
+MH,7.131474,171.184478,Marshall Islands
+MK,41.608635,21.745275,Macedonia [FYROM]
+ML,17.570692,-3.996166,Mali
+MM,21.913965,95.956223,Myanmar [Burma]
+MN,46.862496,103.846656,Mongolia
+MO,22.198745,113.543873,Macau
+MP,17.33083,145.38469,Northern Mariana Islands
+MQ,14.641528,-61.024174,Martinique
+MR,21.00789,-10.940835,Mauritania
+MS,16.742498,-62.187366,Montserrat
+MT,35.937496,14.375416,Malta
+MU,-20.348404,57.552152,Mauritius
+MV,3.202778,73.22068,Maldives
+MW,-13.254308,34.301525,Malawi
+MX,23.634501,-102.552784,Mexico
+MY,4.210484,101.975766,Malaysia
+MZ,-18.665695,35.529562,Mozambique
+NA,-22.95764,18.49041,Namibia
+NC,-20.904305,165.618042,New Caledonia
+NE,17.607789,8.081666,Niger
+NF,-29.040835,167.954712,Norfolk Island
+NG,9.081999,8.675277,Nigeria
+NI,12.865416,-85.207229,Nicaragua
+NL,52.132633,5.291266,Netherlands
+NO,60.472024,8.468946,Norway
+NP,28.394857,84.124008,Nepal
+NR,-0.522778,166.931503,Nauru
+NU,-19.054445,-169.867233,Niue
+NZ,-40.900557,174.885971,New Zealand
+OM,21.512583,55.923255,Oman
+PA,8.537981,-80.782127,Panama
+PE,-9.189967,-75.015152,Peru
+PF,-17.679742,-149.406843,French Polynesia
+PG,-6.314993,143.95555,Papua New Guinea
+PH,12.879721,121.774017,Philippines
+PK,30.375321,69.345116,Pakistan
+PL,51.919438,19.145136,Poland
+PM,46.941936,-56.27111,Saint Pierre and Miquelon
+PN,-24.703615,-127.439308,Pitcairn Islands
+PR,18.220833,-66.590149,Puerto Rico
+PS,31.952162,35.233154,Palestinian Territories
+PT,39.399872,-8.224454,Portugal
+PW,7.51498,134.58252,Palau
+PY,-23.442503,-58.443832,Paraguay
+QA,25.354826,51.183884,Qatar
+RE,-21.115141,55.536384,Réunion
+RO,45.943161,24.96676,Romania
+RS,44.016521,21.005859,Serbia
+RU,61.52401,105.318756,Russia
+RW,-1.940278,29.873888,Rwanda
+SA,23.885942,45.079162,Saudi Arabia
+SB,-9.64571,160.156194,Solomon Islands
+SC,-4.679574,55.491977,Seychelles
+SD,12.862807,30.217636,Sudan
+SE,60.128161,18.643501,Sweden
+SG,1.352083,103.819836,Singapore
+SH,-24.143474,-10.030696,Saint Helena
+SI,46.151241,14.995463,Slovenia
+SJ,77.553604,23.670272,Svalbard and Jan Mayen
+SK,48.669026,19.699024,Slovakia
+SL,8.460555,-11.779889,Sierra Leone
+SM,43.94236,12.457777,San Marino
+SN,14.497401,-14.452362,Senegal
+SO,5.152149,46.199616,Somalia
+SR,3.919305,-56.027783,Suriname
+ST,0.18636,6.613081,São Tomé and Príncipe
+SV,13.794185,-88.89653,El Salvador
+SY,34.802075,38.996815,Syria
+SZ,-26.522503,31.465866,Swaziland
+TC,21.694025,-71.797928,Turks and Caicos Islands
+TD,15.454166,18.732207,Chad
+TF,-49.280366,69.348557,French Southern Territories
+TG,8.619543,0.824782,Togo
+TH,15.870032,100.992541,Thailand
+TJ,38.861034,71.276093,Tajikistan
+TK,-8.967363,-171.855881,Tokelau
+TL,-8.874217,125.727539,Timor-Leste
+TM,38.969719,59.556278,Turkmenistan
+TN,33.886917,9.537499,Tunisia
+TO,-21.178986,-175.198242,Tonga
+TR,38.963745,35.243322,Turkey
+TT,10.691803,-61.222503,Trinidad and Tobago
+TV,-7.109535,177.64933,Tuvalu
+TW,23.69781,120.960515,Taiwan
+TZ,-6.369028,34.888822,Tanzania
+UA,48.379433,31.16558,Ukraine
+UG,1.373333,32.290275,Uganda
+UM,U.S.,Minor,Outlying Islands
+US,37.09024,-95.712891,United States
+UY,-32.522779,-55.765835,Uruguay
+UZ,41.377491,64.585262,Uzbekistan
+VA,41.902916,12.453389,Vatican City
+VC,12.984305,-61.287228,Saint Vincent and the Grenadines
+VE,6.42375,-66.58973,Venezuela
+VG,18.420695,-64.639968,British Virgin Islands
+VI,18.335765,-64.896335,U.S. Virgin Islands
+VN,14.058324,108.277199,Vietnam
+VU,-15.376706,166.959158,Vanuatu
+WF,-13.768752,-177.156097,Wallis and Futuna
+WS,-13.759029,-172.104629,Samoa
+XK,42.602636,20.902977,Kosovo
+YE,15.552727,48.516388,Yemen
+YT,-12.8275,45.166244,Mayotte
+ZA,-30.559482,22.937506,South Africa
+ZM,-13.133897,27.849332,Zambia
+ZW,-19.015438,29.154857,Zimbabwe

http://git-wip-us.apache.org/repos/asf/calcite/blob/cc20ca13/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a8f4df3..cb83c87 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,6 +62,7 @@ limitations under the License.
     <commons-logging.version>1.1.3</commons-logging.version>
     <elasticsearch-java-driver.version>2.3.2</elasticsearch-java-driver.version>
     <elasticsearch5-java-driver.version>5.5.2</elasticsearch5-java-driver.version>
+    <esri-geometry-api.version>2.0.0</esri-geometry-api.version>
     <findbugs.version>3.0.1</findbugs.version>
     <fmpp-maven-plugin.version>1.0</fmpp-maven-plugin.version>
     <foodmart-data-hsqldb.version>0.3</foodmart-data-hsqldb.version>
@@ -216,6 +217,11 @@ limitations under the License.
         <version>${cassandra-driver-core.version}</version>
       </dependency>
       <dependency>
+        <groupId>com.esri.geometry</groupId>
+        <artifactId>esri-geometry-api</artifactId>
+        <version>${esri-geometry-api.version}</version>
+      </dependency>
+      <dependency>
         <groupId>com.fasterxml.jackson.core</groupId>
         <artifactId>jackson-core</artifactId>
         <version>${jackson.version}</version>

http://git-wip-us.apache.org/repos/asf/calcite/blob/cc20ca13/site/_data/docs.yml
----------------------------------------------------------------------
diff --git a/site/_data/docs.yml b/site/_data/docs.yml
index 93e7154..ea38df9 100644
--- a/site/_data/docs.yml
+++ b/site/_data/docs.yml
@@ -24,6 +24,7 @@
 - title: Advanced
   docs:
   - adapter
+  - spatial
   - stream
   - lattice
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/cc20ca13/site/_docs/reference.md
----------------------------------------------------------------------
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index cbe48a6..209d39a 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -507,6 +507,7 @@ FRAC_SECOND,
 G,
 GENERAL,
 GENERATED,
+GEOMETRY,
 **GET**,
 **GLOBAL**,
 GO,
@@ -979,6 +980,7 @@ name will have been converted to upper case also.
 | TIMESTAMP [ WITHOUT TIME ZONE ] | Date and time | Example: TIMESTAMP '1969-07-20 20:17:40'
 | TIMESTAMP WITH TIME ZONE | Date and time with time zone | Example: TIMESTAMP '1969-07-20 20:17:40 America/Los Angeles'
 | INTERVAL timeUnit [ TO timeUnit ] | Date time interval | Examples: INTERVAL '1-5' YEAR TO MONTH, INTERVAL '45' DAY, INTERVAL '1 2:34:56.789' DAY TO SECOND
+| GEOMETRY | Geometry | Examples: ST_GeomFromText('POINT (30 10)')
 
 Where:
 
@@ -992,6 +994,8 @@ Note:
 * DATE, TIME and TIMESTAMP have no time zone. There is not even an implicit
   time zone, such as UTC (as in Java) or the local time zone. It is left to
   the user or application to supply a time zone.
+* GEOMETRY is allowed only in certain
+  [conformance levels]({{ site.apiRoot }}/org/apache/calcite/sql/validate/SqlConformance.html#allowGeometry--).
 
 ### Non-scalar types
 
@@ -1004,6 +1008,32 @@ Note:
 | ARRAY    | Ordered, contiguous collection that may contain duplicates
 | CURSOR   | Cursor over the result of executing a query
 
+### Spatial types
+
+Spatial data is represented as character strings encoded as
+[well-known text (WKT)](https://en.wikipedia.org/wiki/Well-known_text)
+or binary strings encoded as
+[well-known binary (WKB)](https://en.wikipedia.org/wiki/Well-known_binary).
+
+Where you would use a literal, apply the `ST_GeomFromText` function,
+for example `ST_GeomFromText('POINT (30 10)')`.
+
+| Data type   | Type code | Examples in WKT
+|:----------- |:--------- |:---------------------
+| GEOMETRY           |  0 | generalization of Point, Curve, Surface, GEOMETRYCOLLECTION
+| POINT              |  1 | <tt>ST_GeomFromText(&#8203;'POINT (30 10)')</tt> is a point in 2D space; <tt>ST_GeomFromText(&#8203;'POINT Z(30 10 2)')</tt> is point in 3D space
+| CURVE            | 13 | generalization of LINESTRING
+| LINESTRING         |  2 | <tt>ST_GeomFromText(&#8203;'LINESTRING (30 10, 10 30, 40 40)')</tt>
+| SURFACE            | 14 | generalization of Polygon, PolyhedralSurface
+| POLYGON            |  3 | <tt>ST_GeomFromText(&#8203;'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))')</tt> is a pentagon; <tt>ST_GeomFromText(&#8203;'POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))')</tt> is a pentagon with a quadrilateral hole
+| POLYHEDRALSURFACE  | 15 |
+| GEOMETRYCOLLECTION |  7 | a collection of zero or more GEOMETRY instances; a generalization of MULTIPOINT, MULTILINESTRING, MULTIPOLYGON
+| MULTIPOINT         |  4 | <tt>ST_GeomFromText(&#8203;'MULTIPOINT ((10 40), (40 30), (20 20), (30 10))')</tt> is equivalent to <tt>ST_GeomFromText(&#8203;'MULTIPOINT (10 40, 40 30, 20 20, 30 10)')</tt>
+| MULTICURVE         |  - | generalization of MULTILINESTRING
+| MULTILINESTRING    |  5 | <tt>ST_GeomFromText(&#8203;'MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))')</tt>
+| MULTISURFACE       |  - | generalization of MULTIPOLYGON
+| MULTIPOLYGON       |  6 | <tt>ST_GeomFromText(`&#8203;'MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5)))')</tt>
+
 ## Operators and functions
 
 ### Operator precedence
@@ -1536,7 +1566,317 @@ by a grouped window function.
 | TUMBLE_END(expression, interval [, time ]) | Returns the value of *expression* at the end of the window defined by a `TUMBLE` function call
 | TUMBLE_START(expression, interval [, time ]) | Returns the value of *expression* at the beginning of the window defined by a `TUMBLE` function call
 
-### User-defined functions
+### Spatial functions
+
+In the following:
+
+* *geom* is a GEOMETRY;
+* *geomCollection* is a GEOMETRYCOLLECTION;
+* *point* is a POINT;
+* *lineString* is a LINESTRING;
+* *iMatrix* is a [DE-9IM intersection matrix](https://en.wikipedia.org/wiki/DE-9IM);
+* *distance*, *tolerance*, *segmentLengthFraction*, *offsetDistance* are of type double;
+* *dimension*, *quadSegs*, *srid*, *zoom* are of type integer;
+* *layerType* is a character string;
+* *gml* is a character string containing [Geography Markup Language (GML)](https://en.wikipedia.org/wiki/Geography_Markup_Language);
+* *wkt* is a character string containing [well-known text (WKT)](https://en.wikipedia.org/wiki/Well-known_text);
+* *wkb* is a binary string containing [well-known binary (WKB)](https://en.wikipedia.org/wiki/Well-known_binary).
+
+In the "C" (for "compatibility") column, "o" indicates that the function
+implements the OpenGIS Simple Features Implementation Specification for SQL,
+[version 1.2.1](http://www.opengeospatial.org/standards/sfs);
+"p" indicates that the function is a
+[PostGIS](http://www.postgis.net/docs/reference.html) extension to OpenGIS.
+
+#### Geometry conversion functions (2D)
+
+| C | Operator syntax      | Description
+|:- |:-------------------- |:-----------
+| p | ST_AsText(geom) | Alias for `ST_AsWKT`
+| o | ST_AsWKT(geom) | Converts *geom* → WKT
+| o | ST_GeomFromText(wkt [, srid ]) | Returns a specified GEOMETRY value from WKT representation
+| o | ST_LineFromText(wkt [, srid ]) | Converts WKT → LINESTRING
+| o | ST_MLineFromText(wkt [, srid ]) | Converts WKT → MULTILINESTRING
+| o | ST_MPointFromText(wkt [, srid ]) | Converts WKT → MULTIPOINT
+| o | ST_MPolyFromText(wkt [, srid ]) Converts WKT → MULTIPOLYGON
+| o | ST_PointFromText(wkt [, srid ]) | Converts WKT → POINT
+| o | ST_PolyFromText(wkt [, srid ]) | Converts WKT → POLYGON
+
+Not implemented:
+
+* ST_AsBinary(geom) GEOMETRY → WKB
+* ST_AsGML(geom) GEOMETRY → GML
+* ST_Force2D(geom) 3D GEOMETRY → 2D GEOMETRY
+* ST_GeomFromGML(gml [, srid ]) GML → GEOMETRY
+* ST_GeomFromWKB(wkb [, srid ]) WKB → GEOMETRY
+* ST_GoogleMapLink(geom [, layerType [, zoom ]]) GEOMETRY → Google map link
+* ST_LineFromWKB(wkb [, srid ]) WKB → LINESTRING
+* ST_OSMMapLink(geom [, marker ]) GEOMETRY → OSM map link
+* ST_PointFromWKB(wkb [, srid ]) WKB → POINT
+* ST_PolyFromWKB(wkb [, srid ]) WKB → POLYGON
+* ST_ToMultiLine(geom) Converts the coordinates of *geom* (which may be a GEOMETRYCOLLECTION) into a MULTILINESTRING
+* ST_ToMultiPoint(geom)) Converts the coordinates of *geom* (which may be a GEOMETRYCOLLECTION) into a MULTIPOINT
+* ST_ToMultiSegments(geom) Converts *geom* (which may be a GEOMETRYCOLLECTION) into a set of distinct segments stored in a MULTILINESTRING
+
+#### Geometry conversion functions (3D)
+
+Not implemented:
+
+* ST_Force3D(geom) 2D GEOMETRY → 3D GEOMETRY
+
+#### Geometry creation functions (2D)
+
+| C | Operator syntax      | Description
+|:- |:-------------------- |:-----------
+| o | ST_MakeLine(point1 [, point ]*) | Creates a line-string from the given POINTs (or MULTIPOINTs)
+| p | ST_MakePoint(x, y [, z ]) | Alias for `ST_Point`
+| o | ST_Point(x, y [, z ]) | Constructs a point from two or three coordinates
+
+Not implemented:
+
+* ST_BoundingCircle(geom) Returns the minimum bounding circle of *geom*
+* ST_Expand(geom, distance) Expands *geom*'s envelope
+* ST_Expand(geom, deltaX, deltaY) Expands *geom*'s envelope
+* ST_MakeEllipse(point, width, height) Constructs an ellipse
+* ST_MakeEnvelope(xMin, yMin, xMax, yMax  [, srid ]) Creates a rectangular POLYGON
+* ST_MakeGrid(geom, deltaX, deltaY) Calculates a regular grid of POLYGONs based on *geom*
+* ST_MakeGridPoints(geom, deltaX, deltaY) Calculates a regular grid of points based on *geom*
+* ST_MakePolygon(lineString [, hole ]*) Creates a POLYGON from *lineString* with the given holes (which are required to be closed LINESTRINGs)
+* ST_MinimumDiameter(geom) Returns the minimum diameter of *geom*
+* ST_MinimumRectangle(geom) Returns the minimum rectangle enclosing *geom*
+* ST_OctogonalEnvelope(geom) Returns the octogonal envelope of *geom*
+* ST_RingBuffer(geom, distance, bufferCount [, endCapStyle [, doDifference]]) Returns a MULTIPOLYGON of buffers centered at *geom* and of increasing buffer size
+
+### Geometry creation functions (3D)
+
+Not implemented:
+
+* ST_Extrude(geom, height [, flag]) Extrudes a GEOMETRY
+* ST_GeometryShadow(geom, point, height) Computes the shadow footprint of *geom*
+* ST_GeometryShadow(geom, azimuth, altitude, height [, unify ]) Computes the shadow footprint of *geom*
+
+#### Geometry properties (2D)
+
+| C | Operator syntax      | Description
+|:- |:-------------------- |:-----------
+| o | ST_Boundary(geom [, srid ]) | Returns the boundary of *geom*
+| o | ST_Distance(geom1, geom2) | Returns the distance between *geom1* and *geom2*
+| o | ST_GeometryType(geom) | Returns the type of *geom*
+| o | ST_GeometryTypeCode(geom) | Returns the OGC SFS type code of *geom*
+| o | ST_Envelope(geom [, srid ]) | Returns the envelope of *geom* (which may be a GEOMETRYCOLLECTION) as a GEOMETRY
+
+Not implemented:
+
+* ST_Centroid(geom) Returns the centroid of *geom* (which may be a GEOMETRYCOLLECTION)
+* ST_CompactnessRatio(polygon) Returns the square root of *polygon*'s area divided by the area of the circle with circumference equal to its perimeter
+* ST_CoordDim(geom) Returns the dimension of the coordinates of *geom*
+* ST_Dimension(geom) Returns the dimension of *geom*
+* ST_EndPoint(lineString) Returns the last coordinate of *lineString*
+* ST_Envelope(geom [, srid ]) Returns the envelope of *geom* (which may be a GEOMETRYCOLLECTION) as a GEOMETRY
+* ST_Explode(query [, fieldName]) Explodes the GEOMETRYCOLLECTIONs in the *fieldName* column of a query into multiple geometries
+* ST_Extent(geom) Returns the minimum bounding box of *geom* (which may be a GEOMETRYCOLLECTION)
+* ST_ExteriorRing(polygon) Returns the exterior ring of *polygon* as a linear-ring
+* ST_GeometryN(geomCollection, n) Returns the *n*th GEOMETRY of *geomCollection*
+* ST_InteriorRingN(polygon, n) Returns the *n*th interior ring of *polygon*
+* ST_IsClosed(geom) Returns whether *geom* is a closed LINESTRING or MULTILINESTRING
+* ST_IsEmpty(geom) Returns whether *geom* is empty
+* ST_IsRectangle(geom) Returns whether *geom* is a rectangle
+* ST_IsRing(geom) Returns whether *geom* is a closed and simple line-string or MULTILINESTRING
+* ST_IsSimple(geom) Returns whether *geom* is simple
+* ST_IsValid(geom) Returns whether *geom* is valid
+* ST_IsValidDetail(geom [, selfTouchValid ]) Returns a valid detail as an array of objects
+* ST_IsValidReason(geom [, selfTouchValid ]) Returns text stating whether *geom* is valid, and if not valid, a reason why
+* ST_NPoints(geom) Returns the number of points in *geom*
+* ST_NumGeometries(geom) Returns the number of geometries in *geom* (1 if it is not a GEOMETRYCOLLECTION)
+* ST_NumInteriorRing(geom) Alias for `ST_NumInteriorRings`
+* ST_NumInteriorRings(geom) Returns the number of interior rings of *geom*
+* ST_NumPoints(lineString) Returns the number of points in *lineString*
+* ST_PointN(geom, n) Returns the *n*th point of a *lineString*
+* ST_PointOnSurface(geom) Returns an interior or boundary point of *geom*
+* ST_SRID(geom) Returns SRID value of *geom* or 0 if it does not have one
+* ST_StartPoint(lineString) Returns the first coordinate of *lineString*
+* ST_X(geom) Returns the x-value of the first coordinate of *geom*
+* ST_XMax(geom) Returns the maximum x-value of *geom*
+* ST_XMin(geom) Returns the minimum x-value of *geom*
+* ST_Y(geom) Returns the y-value of the first coordinate of *geom*
+* ST_YMax(geom) Returns the maximum y-value of *geom*
+* ST_YMin(geom) Returns the minimum y-value of *geom*
+
+#### Geometry properties (3D)
+
+| C | Operator syntax      | Description
+|:- |:-------------------- |:-----------
+| p | ST_Is3D(s) | Returns whether *geom* has at least one z-coordinate
+| o | ST_Z(geom) | Returns the z-value of the first coordinate of *geom*
+
+Not implemented:
+
+* ST_ZMax(geom) Returns the maximum z-value of *geom*
+* ST_ZMin(geom) Returns the minimum z-value of *geom*
+
+### Geometry predicates
+
+| C | Operator syntax      | Description
+|:- |:-------------------- |:-----------
+| o | ST_Contains(geom1, geom2) | Returns whether *geom1* contains *geom2*
+| p | ST_ContainsProperly(geom1, geom2) | Returns whether *geom1* contains *geom2* but does not intersect its boundary
+| o | ST_Crosses(geom1, geom2) | Returns whether *geom1* crosses *geom2*
+| o | ST_Disjoint(geom1, geom2) | Returns whether *geom1* and *geom2* are disjoint
+| p | ST_DWithin(geom1, geom2, distance) | Returns whether *geom1* and *geom* are within *distance* of one another
+| o | ST_EnvelopesIntersect(geom1, geom2) | Returns whether the envelope of *geom1* intersects the envelope of *geom2*
+| o | ST_Equals(geom1, geom2) | Returns whether *geom1* equals *geom2*
+| o | ST_Intersects(geom1, geom2) | Returns whether *geom1* intersects *geom2*
+| o | ST_Overlaps(geom1, geom2) | Returns whether *geom1* overlaps *geom2*
+| o | ST_Touches(geom1, geom2) | Returns whether *geom1* touches *geom2*
+| o | ST_Within(geom1, geom2) | Returns whether *geom1* is within *geom2*
+
+Not implemented:
+
+* ST_Covers(geom1, geom2) Returns whether no point in *geom2* is outside *geom1*
+* ST_OrderingEquals(geom1, geom2) Returns whether *geom1* equals *geom2* and their coordinates and component Geometries are listed in the same order
+* ST_Relate(geom1, geom2) Returns the DE-9IM intersection matrix of *geom1* and *geom2*
+* ST_Relate(geom1, geom2, iMatrix) Returns whether *geom1* and *geom2* are related by the given intersection matrix *iMatrix*
+
+#### Geometry operators (2D)
+
+The following functions combine 2D geometries.
+
+| C | Operator syntax      | Description
+|:- |:-------------------- |:-----------
+| o | ST_Buffer(geom, distance [, quadSegs \| style ]) | Computes a buffer around *geom*
+| o | ST_Union(geom1, geom2) | Computes the union of *geom1* and *geom2*
+| o | ST_Union(geomCollection) | Computes the union of the geometries in *geomCollection*
+
+See also: the `ST_Union` aggregate function.
+
+Not implemented:
+
+* ST_ConvexHull(geom) Computes the smallest convex polygon that contains all the points in *geom*
+* ST_Difference(geom1, geom2) Computes the difference between two geometries
+* ST_Intersection(geom1, geom2) Computes the intersection of two geometries
+* ST_SymDifference(geom1, geom2) Computes the symmetric difference between two geometries
+
+#### Affine transformation functions (3D and 2D)
+
+Not implemented:
+
+* ST_Rotate(geom, angle [, origin \| x, y]) Rotates a *geom* counter-clockwise by *angle* (in radians) about *origin* (or the point (*x*, *y*))
+* ST_Scale(geom, xFactor, yFactor [, zFactor ]) Scales *geom* by multiplying the ordinates by the indicated scale factors
+* ST_Translate(geom, x, y, [, z]) Translates *geom*
+
+#### Geometry editing functions (2D)
+
+The following functions modify 2D geometries.
+
+Not implemented:
+
+* ST_AddPoint(geom, point [, tolerance ]) Adds *point* to *geom* with a given *tolerance* (default 0)
+* ST_CollectionExtract(geom, dimension) Filters *geom*, returning a multi-geometry of those members with a given *dimension* (1 = point, 2 = line-string, 3 = polygon)
+* ST_Densify(geom, tolerance) Inserts extra vertices every *tolerance* along the line segments of *geom*
+* ST_FlipCoordinates(geom) Flips the X and Y coordinates of *geom*
+* ST_Holes(geom) Returns the holes in *geom* (which may be a GEOMETRYCOLLECTION)
+* ST_Normalize(geom) Converts *geom* to normal form
+* ST_RemoveDuplicatedCoordinates(geom) Removes duplicated coordinates from *geom*
+* ST_RemoveHoles(geom) Removes a *geom*'s holes
+* ST_RemovePoints(geom, poly) Removes all coordinates of *geom* located within *poly*; null if all coordinates are removed
+* ST_RemoveRepeatedPoints(geom, tolerance) Removes from *geom* all repeated points (or points within *tolerance* of another point)
+* ST_Reverse(geom) Reverses the vertex order of *geom*
+
+#### Geometry editing functions (3D)
+
+The following functions modify 3D geometries.
+
+Not implemented:
+
+* ST_AddZ(geom, zToAdd) Adds *zToAdd* to the z-coordinate of *geom*
+* ST_Interpolate3DLine(geom) Returns *geom* with a interpolation of z values, or null if it is not a line-string or MULTILINESTRING
+* ST_MultiplyZ(geom, zFactor) Returns *geom* with its z-values multiplied by *zFactor*
+* ST_Reverse3DLine(geom [, sortOrder ]) Potentially reverses *geom* according to the z-values of its first and last coordinates
+* ST_UpdateZ(geom, newZ [, updateCondition ]) Updates the z-values of *geom*
+* ST_ZUpdateLineExtremities(geom, startZ, endZ [, interpolate ]) Updates the start and end z-values of *geom*
+
+#### Geometry measurement functions (2D)
+
+Not implemented:
+
+* ST_Area(geom) Returns the area of *geom* (which may be a GEOMETRYCOLLECTION)
+* ST_ClosestCoordinate(geom, point) Returns the coordinate(s) of *geom* closest to *point*
+* ST_ClosestPoint(geom1, geom2) Returns the point of *geom1* closest to *geom2*
+* ST_FurthestCoordinate(geom, point) Returns the coordinate(s) of *geom* that are furthest from *point*
+* ST_Length(lineString) Returns the length of *lineString*
+* ST_LocateAlong(geom, segmentLengthFraction, offsetDistance) Returns a MULTIPOINT containing points along the line segments of *geom* at *segmentLengthFraction* and *offsetDistance*
+* ST_LongestLine(geom1, geom2) Returns the 2-dimensional longest line-string between the points of *geom1* and *geom2*
+* ST_MaxDistance(geom1, geom2) Computes the maximum distance between *geom1* and *geom2*
+* ST_Perimeter(polygon) Returns the length of the perimeter of *polygon* (which may be a MULTIPOLYGON)
+* ST_ProjectPoint(point, lineString) Projects *point* onto a *lineString* (which may be a MULTILINESTRING)
+
+#### Geometry measurement functions (3D)
+
+Not implemented:
+
+* ST_3DArea(geom) Return a polygon's 3D area
+* ST_3DLength(geom) Returns the 3D length of a line-string
+* ST_3DPerimeter(geom) Returns the 3D perimeter of a polygon or MULTIPOLYGON
+* ST_SunPosition(point [, timestamp ]) Computes the sun position at *point* and *timestamp* (now by default)
+
+#### Geometry processing functions (2D)
+
+The following functions process geometries.
+
+Not implemented:
+
+* ST_LineIntersector(geom1, geom2) Splits *geom1* (a line-string) with *geom2*
+* ST_LineMerge(geom) Merges a collection of linear components to form a line-string of maximal length
+* ST_MakeValid(geom [, preserveGeomDim [, preserveDuplicateCoord [, preserveCoordDim]]]) Makes *geom* valid
+* ST_Polygonize(geom) Creates a MULTIPOLYGON from edges of *geom*
+* ST_PrecisionReducer(geom, n) Reduces *geom*'s precision to *n* decimal places
+* ST_RingSideBuffer(geom, distance, bufferCount [, endCapStyle [, doDifference]]) Computes a ring buffer on one side
+* ST_SideBuffer(geom, distance [, bufferStyle ]) Compute a single buffer on one side
+* ST_Simplify(geom, distance) Simplifies *geom* using the [Douglas-Peuker algorithm](https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm) with a *distance* tolerance
+* ST_SimplifyPreserveTopology(geom) Simplifies *geom*, preserving its topology
+* ST_Snap(geom1, geom2, tolerance) Snaps *geom1* and *geom2* together
+* ST_Split(geom1, geom2 [, tolerance]) Splits *geom1* by *geom2* using *tolerance* (default 1E-6) to determine where the point splits the line
+
+#### Geometry projection functions
+
+| C | Operator syntax      | Description
+|:- |:-------------------- |:-----------
+| o | ST_SetSRID(geom, srid) | Returns a copy of *geom* with a new SRID
+| o | ST_Transform(geom, srid) | Transforms *geom* from one coordinate reference system (CRS) to the CRS specified by *srid*
+
+#### Trigonometry functions
+
+Not implemented:
+
+* ST_Azimuth(point1, point2) Return the azimuth of the segment from *point1* to *point2*
+
+#### Topography functions
+
+Not implemented:
+
+* ST_TriangleAspect(geom) Returns the aspect of a triangle
+* ST_TriangleContouring(query \[, z1, z2, z3 ]\[, varArgs]*) Splits triangles into smaller triangles according to classes
+* ST_TriangleDirection(geom) Computes the direction of steepest ascent of a triangle and returns it as a line-string
+* ST_TriangleSlope(geom) Computes the slope of a triangle as a percentage
+* ST_Voronoi(geom [, outDimension [, envelopePolygon ]]) Creates a Voronoi diagram
+
+#### Triangulation functions
+
+Not implemented:
+
+* ST_ConstrainedDelaunay(geom [, flag [, quality ]]) Computes a constrained Delaunay triangulation based on *geom*
+* ST_Delaunay(geom [, flag [, quality ]]) Computes a Delaunay triangulation based on points
+* ST_Tessellate(polygon) Tessellates *polygon* (may be MULTIPOLYGON) with adaptive triangles
+
+#### Geometry aggregate functions
+
+Not implemented:
+
+* ST_Accum(geom) Accumulates *geom* into a GEOMETRYCOLLECTION (or MULTIPOINT, MULTILINESTRING or MULTIPOLYGON if possible)
+* ST_Collect(geom) Alias for `ST_Accum`
+* ST_Union(geom) Computes the union of geometries
+
+## User-defined functions
 
 Calcite is extensible. You can define each kind of function using user code.
 For each kind of function there are often several ways to define a function,

http://git-wip-us.apache.org/repos/asf/calcite/blob/cc20ca13/site/_docs/spatial.md
----------------------------------------------------------------------
diff --git a/site/_docs/spatial.md b/site/_docs/spatial.md
new file mode 100644
index 0000000..3b98464
--- /dev/null
+++ b/site/_docs/spatial.md
@@ -0,0 +1,63 @@
+---
+layout: docs
+title: Spatial
+permalink: /docs/spatial.html
+---
+<!--
+{% comment %}
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+-->
+
+Calcite is [aiming](https://issues.apache.org/jira/browse/CALCITE-1968) to implement
+OpenGIS Simple Features Implementation Specification for SQL,
+[version 1.2.1](http://www.opengeospatial.org/standards/sfs),
+a standard implemented by spatial databases such as
+[PostGIS](http://postgis.net/)
+and [H2GIS](http://www.h2gis.org/).
+
+We also aim to add optimizer support for
+[spatial indexes](https://issues.apache.org/jira/browse/CALCITE-1861)
+and other forms of query optimization.
+
+* TOC
+{:toc}
+
+## Introduction
+
+A spatial database is a database that is optimized for storing and query data
+that represents objects defined in a geometric space.
+
+Calcite's support for spatial data includes:
+
+* A [GEOMETRY](reference.html#data-types) data type and
+  [sub-types](reference.html#spatial-types) including `POINT`, `LINESTRING`
+  and `POLYGON`
+* [Spatial functions](reference.html#spatial-functions) (prefixed `ST_`;
+  we have implemented about 35 of the 150 in the OpenGIS specification)
+
+and will at some point also include query rewrites to use spatial indexes.
+
+## Acknowledgements
+
+Calcite's OpenGIS implementation uses the
+[Esri geometry API](https://github.com/Esri/geometry-api-java). Thanks for the
+help we received from their community.
+
+While developing this feature, we made extensive use of the
+PostGIS documentation and tests,
+and the H2GIS documentation, and consulted both as reference implementations
+when the specification wasn't clear. Thank you to these awesome projects.

http://git-wip-us.apache.org/repos/asf/calcite/blob/cc20ca13/src/main/config/checkstyle/suppressions.xml
----------------------------------------------------------------------
diff --git a/src/main/config/checkstyle/suppressions.xml b/src/main/config/checkstyle/suppressions.xml
index e8e839e..2f55a52 100644
--- a/src/main/config/checkstyle/suppressions.xml
+++ b/src/main/config/checkstyle/suppressions.xml
@@ -38,6 +38,9 @@ limitations under the License.
   <!-- Don't complain about field names such as cust_id -->
   <suppress checks=".*Name" files="JdbcExample.java"/>
 
+  <!-- Don't complain about method names in a class full of UDFs -->
+  <suppress checks="MethodName" files="GeoFunctions.java"/>
+
   <!-- Suppress JavadocPackage in the test packages -->
   <suppress checks="JavadocPackage" files="src[/\\]test[/\\]java[/\\]"/>