This is an automated email from the ASF dual-hosted git repository.
bchapuis pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new cd76712fcd [CALCITE-5281] Add ST_Explode for geometry parameter
cd76712fcd is described below
commit cd76712fcd762bd71d233229afa55792ebd72f88
Author: Bertil Chapuis <[email protected]>
AuthorDate: Fri Sep 30 00:23:49 2022 +0200
[CALCITE-5281] Add ST_Explode for geometry parameter
---
.../calcite/runtime/SpatialTypeFunctions.java | 9 ++++
.../calcite/sql/fun/SqlSpatialTypeFunctions.java | 51 ++++++++++++++++++++++
core/src/test/resources/sql/spatial.iq | 19 +++++++-
3 files changed, 78 insertions(+), 1 deletion(-)
diff --git
a/core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java
b/core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java
index 47a2d803bc..b8242f406e 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java
@@ -999,6 +999,15 @@ public class SpatialTypeFunctions {
return geom.getEnvelope();
}
+ /**
+ * Explodes the {@code geom} into multiple geometries.
+ */
+ private static void ST_Explode(final Geometry geom) {
+ // This is a dummy function. We cannot include table functions in this
+ // package, because they have too many dependencies. See the real
definition
+ // in SqlSpatialTypeFunctions.
+ }
+
// Geometry predicates ======================================================
/**
diff --git
a/core/src/main/java/org/apache/calcite/sql/fun/SqlSpatialTypeFunctions.java
b/core/src/main/java/org/apache/calcite/sql/fun/SqlSpatialTypeFunctions.java
index 2094afe166..7963948551 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlSpatialTypeFunctions.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlSpatialTypeFunctions.java
@@ -20,6 +20,7 @@ import org.apache.calcite.DataContext;
import org.apache.calcite.config.CalciteConnectionConfig;
import org.apache.calcite.linq4j.Enumerable;
import org.apache.calcite.linq4j.Linq4j;
+import org.apache.calcite.linq4j.function.Functions;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.runtime.SpatialTypeFunctions;
@@ -50,6 +51,15 @@ public class SqlSpatialTypeFunctions {
// Geometry table functions =================================================
+ /**
+ * Explodes the {@code geom} into multiple geometries.
+ *
+ * @see SpatialTypeFunctions ST_Explode */
+ @SuppressWarnings({"WeakerAccess", "unused"})
+ public static ScannableTable ST_Explode(Geometry geom) {
+ return new ExplodeTable(geom);
+ }
+
/** Calculates a regular grid of polygons based on {@code geom}.
*
* @see SpatialTypeFunctions ST_MakeGrid */
@@ -68,6 +78,47 @@ public class SqlSpatialTypeFunctions {
return new GridTable(geom, deltaX, deltaY, true);
}
+ /** Returns the geometries of a geometry. */
+ public static class ExplodeTable implements ScannableTable {
+
+ private final Geometry geometry;
+
+ public ExplodeTable(Geometry geometry) {
+ this.geometry = geometry;
+ }
+
+ @Override public Enumerable<@Nullable Object[]> scan(DataContext root) {
+ return Linq4j.asEnumerable(
+ Functions.generate(
+ geometry.getNumGeometries(),
+ i -> new Object[] { geometry.getGeometryN(i), i }));
+ }
+
+ @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) {
+ return typeFactory.builder()
+ .add("GEOM", SqlTypeName.GEOMETRY)
+ .add("INDEX", SqlTypeName.INTEGER)
+ .build();
+ }
+
+ @Override public Statistic getStatistic() {
+ return Statistics.UNKNOWN;
+ }
+
+ @Override public Schema.TableType getJdbcTableType() {
+ return Schema.TableType.TABLE;
+ }
+
+ @Override public boolean isRolledUp(String column) {
+ return false;
+ }
+
+ @Override public boolean rolledUpColumnValidInsideAgg(String column,
SqlCall call,
+ @Nullable SqlNode parent, @Nullable CalciteConnectionConfig config) {
+ return true;
+ }
+ }
+
/** Returns the points or rectangles in a grid that covers a given
* geometry. */
public static class GridTable implements ScannableTable {
diff --git a/core/src/test/resources/sql/spatial.iq
b/core/src/test/resources/sql/spatial.iq
index 4c2f643fbd..d926ab9a4a 100644
--- a/core/src/test/resources/sql/spatial.iq
+++ b/core/src/test/resources/sql/spatial.iq
@@ -753,7 +753,24 @@ POLYGON ((0 0, 0 1, 1.0000000001 1, 1.0000000001 0, 0 0))
!ok
# ST_Explode(query [, fieldName]) Explodes the geometry-collections in the
*fieldName* column of a query into multiple geometries
-# Not implemented
+
+SELECT t.geom, t.index FROM table(ST_Explode(ST_GeomFromText('MULTIPOINT((1
1), (2 2), (3 3), (4 4))'))) as t(geom, index);
+GEOM, INDEX
+POINT (1 1), 0
+POINT (2 2), 1
+POINT (3 3), 2
+POINT (4 4), 3
+!ok
+
+SELECT t1.id, t2.geom, t2.index
+FROM (SELECT 1 as id, 'MULTIPOINT((1 1), (2 2))' as points UNION ALL SELECT 2
as id, 'MULTIPOINT((3 3), (4 4))' as points) as t1,
+LATERAL table(ST_Explode(t1.points)) as t2(geom, index);
+ID, GEOM, INDEX
+1, POINT (1 1), 0
+1, POINT (2 2), 1
+2, POINT (3 3), 0
+2, POINT (4 4), 1
+!ok
# ST_Extent(geom) Returns the minimum bounding box of *geom* (which may be a
geometry-collection)