From e5a81841e1dfcd0ba0df8cfa4c066219e3bc6032 Mon Sep 17 00:00:00 2001 From: Danylo Kravchenko Date: Fri, 2 Feb 2024 16:52:30 +0100 Subject: [PATCH] GIS #462: increase CHAR size; extend geo tests; change costs of enumerable operations --- .../enumerable/EnumerableAggregate.java | 8 ++++++ .../db/algebra/enumerable/EnumerableCalc.java | 7 +++++ .../algebra/type/AlgDataTypeSystemImpl.java | 2 +- .../polypheny/db/functions/GeoFunctions.java | 4 +-- .../db/type/entity/spatial/PolyGeometry.java | 16 +++++++----- .../java/org/polypheny/db/PolyphenyDb.java | 2 +- .../db/sql/fun/GeoFunctionsTest.java | 26 ++++++++++++++++++- .../polypheny/db/adapter/jdbc/JdbcRules.java | 13 ++++++++-- .../jdbc/JdbcToEnumerableConverter.java | 2 +- .../postgres/PostgresqlSqlDialect.java | 2 +- 10 files changed, 66 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableAggregate.java b/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableAggregate.java index 278d3a02a5..68119ae3ad 100644 --- a/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableAggregate.java +++ b/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableAggregate.java @@ -42,10 +42,13 @@ import org.polypheny.db.algebra.enumerable.impl.AggAddContextImpl; import org.polypheny.db.algebra.enumerable.impl.AggResultContextImpl; import org.polypheny.db.algebra.fun.AggFunction; +import org.polypheny.db.algebra.metadata.AlgMetadataQuery; import org.polypheny.db.algebra.type.AlgDataType; import org.polypheny.db.algebra.type.AlgDataTypeField; import org.polypheny.db.config.RuntimeConfig; import org.polypheny.db.plan.AlgOptCluster; +import org.polypheny.db.plan.AlgOptCost; +import org.polypheny.db.plan.AlgOptPlanner; import org.polypheny.db.plan.AlgTraitSet; import org.polypheny.db.prepare.JavaTypeFactoryImpl.SyntheticRecordType; import org.polypheny.db.rex.RexIndexRef; @@ -89,6 +92,11 @@ public EnumerableAggregate copy( AlgTraitSet traitSet, AlgNode input, boolean in } } + @Override + public AlgOptCost computeSelfCost( AlgOptPlanner planner, AlgMetadataQuery mq ) { + return planner.getCostFactory().makeInfiniteCost(); + } + @Override public Result implement( EnumerableAlgImplementor implementor, Prefer pref ) { diff --git a/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableCalc.java b/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableCalc.java index 1634864d8d..054c83634f 100644 --- a/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableCalc.java +++ b/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableCalc.java @@ -42,6 +42,8 @@ import org.polypheny.db.algebra.metadata.AlgMdDistribution; import org.polypheny.db.algebra.metadata.AlgMetadataQuery; import org.polypheny.db.plan.AlgOptCluster; +import org.polypheny.db.plan.AlgOptCost; +import org.polypheny.db.plan.AlgOptPlanner; import org.polypheny.db.plan.AlgOptPredicateList; import org.polypheny.db.plan.AlgTraitSet; import org.polypheny.db.rex.RexBuilder; @@ -92,6 +94,11 @@ public EnumerableCalc copy( AlgTraitSet traitSet, AlgNode child, RexProgram prog return new EnumerableCalc( getCluster(), traitSet, child, program ); } + @Override + public AlgOptCost computeSelfCost( AlgOptPlanner planner, AlgMetadataQuery mq ) { + return planner.getCostFactory().makeInfiniteCost(); + } + @Override public Result implement( EnumerableAlgImplementor implementor, Prefer pref ) { diff --git a/core/src/main/java/org/polypheny/db/algebra/type/AlgDataTypeSystemImpl.java b/core/src/main/java/org/polypheny/db/algebra/type/AlgDataTypeSystemImpl.java index a7ea8e5775..3ac351937e 100644 --- a/core/src/main/java/org/polypheny/db/algebra/type/AlgDataTypeSystemImpl.java +++ b/core/src/main/java/org/polypheny/db/algebra/type/AlgDataTypeSystemImpl.java @@ -142,7 +142,7 @@ public int getMaxPrecision( PolyType typeName ) { case JSON: case VARCHAR: case CHAR: - return 65536; + return 524288; case VARBINARY: case BINARY: return 65536; diff --git a/core/src/main/java/org/polypheny/db/functions/GeoFunctions.java b/core/src/main/java/org/polypheny/db/functions/GeoFunctions.java index ee6241587c..112c3dadfd 100644 --- a/core/src/main/java/org/polypheny/db/functions/GeoFunctions.java +++ b/core/src/main/java/org/polypheny/db/functions/GeoFunctions.java @@ -54,7 +54,7 @@ private GeoFunctions() { @SuppressWarnings("UnusedDeclaration") public static PolyGeometry stGeomFromText( PolyString wkt ) { try { - return PolyGeometry.of( wkt.value ); + return PolyGeometry.fromWKT( wkt.value ); } catch ( InvalidGeometryException e ) { throw toUnchecked( e ); } @@ -64,7 +64,7 @@ public static PolyGeometry stGeomFromText( PolyString wkt ) { @SuppressWarnings("UnusedDeclaration") public static PolyGeometry stGeomFromText( PolyString wkt, PolyNumber srid ) { try { - return PolyGeometry.of( wkt.value, srid.intValue() ); + return PolyGeometry.fromWKT( wkt.value, srid.intValue() ); } catch ( InvalidGeometryException e ) { throw toUnchecked( e ); } diff --git a/core/src/main/java/org/polypheny/db/type/entity/spatial/PolyGeometry.java b/core/src/main/java/org/polypheny/db/type/entity/spatial/PolyGeometry.java index c378dae83e..26ca0ef42b 100644 --- a/core/src/main/java/org/polypheny/db/type/entity/spatial/PolyGeometry.java +++ b/core/src/main/java/org/polypheny/db/type/entity/spatial/PolyGeometry.java @@ -165,14 +165,9 @@ protected PolyGeometry( PolyType type ) { } - public static PolyGeometry of( String wkt ) throws InvalidGeometryException { - return new PolyGeometry( wkt ); - } - - - public static PolyGeometry ofNullable( String wkt ) { + public static PolyGeometry of( String wkt ) { try { - return wkt == null ? null : of( wkt ); + return new PolyGeometry( wkt ); } catch ( InvalidGeometryException e ) { // hack to deal that InvalidGeometryException is not caught in code generation return null; @@ -180,6 +175,11 @@ public static PolyGeometry ofNullable( String wkt ) { } + public static PolyGeometry ofNullable( String wkt ) { + return wkt == null ? null : of( wkt ); + } + + public static PolyGeometry of( String wkt, int srid ) throws InvalidGeometryException { return new PolyGeometry( wkt, srid ); } @@ -200,6 +200,7 @@ public static PolyGeometry fromWKT( String wkt ) throws InvalidGeometryException } + @SuppressWarnings( "unused" ) public static PolyGeometry fromWKT( String wkt, int srid ) throws InvalidGeometryException { return new PolyGeometry( wkt, srid ); } @@ -215,6 +216,7 @@ public static PolyGeometry fromTWKB( String twkb, int srid ) throws InvalidGeome } + @SuppressWarnings( "unused" ) public static PolyGeometry fromNullableGeoJson( String geoJson ) { try { return geoJson == null ? null : fromGeoJson( geoJson ); diff --git a/dbms/src/main/java/org/polypheny/db/PolyphenyDb.java b/dbms/src/main/java/org/polypheny/db/PolyphenyDb.java index f0cb44c5c5..29535fbab3 100644 --- a/dbms/src/main/java/org/polypheny/db/PolyphenyDb.java +++ b/dbms/src/main/java/org/polypheny/db/PolyphenyDb.java @@ -127,7 +127,7 @@ public class PolyphenyDb { public boolean daemonMode = false; @Option(name = { "-defaultStore" }, description = "Type of default storeId") - public String defaultStoreName = "hsqldb"; + public String defaultStoreName = "postgresql"; @Option(name = { "-defaultSource" }, description = "Type of default source") public String defaultSourceName = "csv"; diff --git a/dbms/src/test/java/org/polypheny/db/sql/fun/GeoFunctionsTest.java b/dbms/src/test/java/org/polypheny/db/sql/fun/GeoFunctionsTest.java index 80049d3989..ad6b897ebf 100644 --- a/dbms/src/test/java/org/polypheny/db/sql/fun/GeoFunctionsTest.java +++ b/dbms/src/test/java/org/polypheny/db/sql/fun/GeoFunctionsTest.java @@ -48,7 +48,6 @@ private static void addTestData() throws SQLException { statement.executeUpdate( "CREATE TABLE TEST_GIS(ID INTEGER NOT NULL, WKT GEOMETRY, PRIMARY KEY (ID))" ); statement.executeUpdate( "INSERT INTO TEST_GIS VALUES (1, ST_GeomFromText('POINT (7.852923 47.998949)', 4326))" ); statement.executeUpdate( "INSERT INTO TEST_GIS VALUES (2, ST_GeomFromText('POINT (9.289382 48.741588)', 4326))" ); - // statement.executeUpdate( "INSERT INTO TEST_GIS VALUES (3, ST_GeomFromText('MULTIPOLYGON(((-95.58358199999999 31.75272,-95.583542 31.751756,-95.58359 31.751768,-95.58397599999999 31.751911999999997,-95.584453 31.752079,-95.584716 31.752173,-95.58653299999999 31.752824999999998,-95.58699899999999 31.753007,-95.587229 31.753089,-95.587459 31.753145,-95.587657 31.753207,-95.58771499999999 31.753207,-95.58811899999999 31.753204,-95.588354 31.753224,-95.58863699999999 31.753199,-95.588644 31.753594999999997,-95.58864899999999 31.75394,-95.587313 31.753967,-95.587316 31.755177999999997,-95.583674 31.754368999999997,-95.58358199999999 31.75272)))', 4326))" ); connection.commit(); } } @@ -180,6 +179,13 @@ public void commonPropertiesFunctions() throws SQLException { ImmutableList.of( new Object[]{ "SRID=0;POLYGON ((-1 -1, -1 2, 2 2, -1 -1))" } ) ); + // get the convex hull of the geometry from the database + TestHelper.checkResultSet( + statement.executeQuery( "SELECT ST_ConvexHull(WKT) from TEST_GIS" ), + ImmutableList.of( + new Object[]{ "SRID=4326;POINT (7.852923 47.998949)" }, + new Object[]{ "SRID=4326;POINT (9.289382 48.741588)" } + ) ); // get the centroid of the geometry TestHelper.checkResultSet( statement.executeQuery( "SELECT ST_Centroid(ST_GeomFromText('POLYGON ( (-1 -1, 2 2, -1 2, -1 -1 ) )'))" ), @@ -288,6 +294,24 @@ public void spatialRelationsFunctions() throws SQLException { ImmutableList.of( new Object[]{ true } ) ); + // check that area contains the point + TestHelper.checkResultSet( + statement.executeQuery( "SELECT count(*) from TEST_GIS where ST_Contains(ST_GeomFromText('POLYGON ((9.2 48.8, 10.289382 48.8, 10.289382 47.741588, 9.2 47.741588, 9.2 48.8))', 4326), WKT) and id = 2" ), + ImmutableList.of( + new Object[]{ 1 } + ) ); + // check that point is within area + TestHelper.checkResultSet( + statement.executeQuery( "SELECT count(*) from TEST_GIS where ST_Within(wkt, ST_GeomFromText('POLYGON ((9.2 48.8, 10.289382 48.8, 10.289382 47.741588, 9.2 47.741588, 9.2 48.8))', 4326))" ), + ImmutableList.of( + new Object[]{ 1 } + ) ); + // spatial join + TestHelper.checkResultSet( + statement.executeQuery( "SELECT count(*) from TEST_GIS g1, TEST_GIS g2 where ST_Contains(g1.wkt, g2.wkt)" ), + ImmutableList.of( + new Object[]{ 0 } + ) ); } } } diff --git a/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/JdbcRules.java b/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/JdbcRules.java index e32fd7b68c..6216b2871a 100644 --- a/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/JdbcRules.java +++ b/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/JdbcRules.java @@ -552,7 +552,7 @@ public JdbcProject copy( AlgTraitSet traitSet, AlgNode input, List proj @Override public AlgOptCost computeSelfCost( AlgOptPlanner planner, AlgMetadataQuery mq ) { - return super.computeSelfCost( planner, mq ).multiplyBy( JdbcConvention.COST_MULTIPLIER ); + return super.computeSelfCost( planner, mq ).multiplyBy( .1 ); } @@ -747,6 +747,11 @@ public Result implement( JdbcImplementor implementor ) { return implementor.implement( this ); } + @Override + public AlgOptCost computeSelfCost( AlgOptPlanner planner, AlgMetadataQuery mq ) { + return super.computeSelfCost( planner, mq ).multiplyBy( .1 ); + } + } @@ -842,6 +847,11 @@ public JdbcAggregate copy( } } + @Override + public AlgOptCost computeSelfCost( AlgOptPlanner planner, AlgMetadataQuery mq ) { + return super.computeSelfCost( planner, mq ).multiplyBy( .1 ); + } + @Override public Result implement( JdbcImplementor implementor ) { @@ -1154,7 +1164,6 @@ public JdbcTableModify( @Override public AlgOptCost computeSelfCost( AlgOptPlanner planner, AlgMetadataQuery mq ) { - double cost = super.computeSelfCost( planner, mq ).getCosts(); return super.computeSelfCost( planner, mq ).multiplyBy( .1 ); } diff --git a/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/JdbcToEnumerableConverter.java b/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/JdbcToEnumerableConverter.java index cbfd8ae03e..67f49831b1 100644 --- a/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/JdbcToEnumerableConverter.java +++ b/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/JdbcToEnumerableConverter.java @@ -430,7 +430,7 @@ private static Expression getOfPolyExpression( AlgDataType fieldType, Expression break; case GEOMETRY: if ( dialect.supportsPostGIS() ) { - // convert postgis geometry (net.postgres.PGgeometry) that is a wrapper of org.postgresql.util.PGobject has getValue() method to return string) into a string + // convert postgis geometry (net.postgres.PGgeometry) that is a wrapper of org.postgresql.util.PGobject (has getValue() method to return string) into a string poly = Expressions.call( PolyGeometry.class, fieldType.isNullable() ? "ofNullable" : "of", Expressions.convert_( Expressions.call( Expressions.convert_( source, net.postgis.jdbc.PGgeometry.class), "getValue" ), String.class ) ); } else if ( dialect.supportsGeoJson() ) { poly = Expressions.call( PolyGeometry.class, fieldType.isNullable() ? "fromNullableGeoJson": "fromGeoJson", Expressions.convert_( source, String.class ) ); diff --git a/plugins/postgres-adapter/src/main/java/org/polypheny/db/adapter/postgres/PostgresqlSqlDialect.java b/plugins/postgres-adapter/src/main/java/org/polypheny/db/adapter/postgres/PostgresqlSqlDialect.java index d3defee496..54d41bf3d0 100644 --- a/plugins/postgres-adapter/src/main/java/org/polypheny/db/adapter/postgres/PostgresqlSqlDialect.java +++ b/plugins/postgres-adapter/src/main/java/org/polypheny/db/adapter/postgres/PostgresqlSqlDialect.java @@ -104,7 +104,7 @@ public boolean supportsPostGIS() { } public List supportedGeoFunctions() { - return ImmutableList.of(OperatorName.ST_GEOMFROMTEXT, OperatorName.ST_TRANSFORM, + return ImmutableList.of(OperatorName.ST_GEOMFROMTEXT, OperatorName.ST_TRANSFORM, OperatorName.ST_EQUALS, OperatorName.ST_ISSIMPLE, OperatorName.ST_ISCLOSED, OperatorName.ST_ISEMPTY, OperatorName.ST_ISRING, OperatorName.ST_NUMPOINTS, OperatorName.ST_DIMENSION, OperatorName.ST_LENGTH, OperatorName.ST_AREA, OperatorName.ST_ENVELOPE, OperatorName.ST_BOUNDARY, OperatorName.ST_CONVEXHULL, OperatorName.ST_CENTROID,