This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 9a1e96040c73dd72097fc4006c251dfd1f1c9597 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Thu Apr 10 17:24:12 2025 +0200 Workaround for limitations observed in DuckDB 1.2.1: - Ignore the catalog name when the database is DuckDB. - Do not add SRID argument in geometries because not supported. --- .../org/apache/sis/metadata/sql/privy/Dialect.java | 36 ++++++++++++++++++---- .../apache/sis/metadata/sql/privy/Reflection.java | 2 ++ .../apache/sis/metadata/sql/privy/Supports.java | 12 ++++++++ .../apache/sis/storage/sql/feature/Analyzer.java | 7 +++-- .../apache/sis/storage/sql/feature/Database.java | 6 ++-- .../sis/storage/sql/feature/SelectionClause.java | 10 +++--- 6 files changed, 59 insertions(+), 14 deletions(-) diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Dialect.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Dialect.java index 0cccbb1cd2..c5b4709a9f 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Dialect.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Dialect.java @@ -39,7 +39,9 @@ public enum Dialect { ANSI(null, Supports.ALTER_TABLE_WITH_ADD_CONSTRAINT | Supports.JAVA_TIME | Supports.READ_ONLY_UPDATE - | Supports.CONCURRENCY), + | Supports.CONCURRENCY + | Supports.CATALOG + | Supports.SRID), /** * The database uses Derby syntax. This is ANSI, with some constraints that PostgreSQL does not have @@ -50,7 +52,8 @@ public enum Dialect { */ DERBY("derby", Supports.ALTER_TABLE_WITH_ADD_CONSTRAINT | Supports.READ_ONLY_UPDATE - | Supports.CONCURRENCY), + | Supports.CONCURRENCY + | Supports.CATALOG), /** * The database uses HSQL syntax. This is ANSI, but does not allow {@code INSERT} statements inserting many lines. @@ -59,7 +62,8 @@ public enum Dialect { HSQL("hsqldb", Supports.ALTER_TABLE_WITH_ADD_CONSTRAINT | Supports.JAVA_TIME | Supports.READ_ONLY_UPDATE - | Supports.CONCURRENCY), + | Supports.CONCURRENCY + | Supports.CATALOG), /** * The database uses PostgreSQL syntax. This is ANSI, but provided an a separated @@ -69,7 +73,9 @@ public enum Dialect { | Supports.ALTER_TABLE_WITH_ADD_CONSTRAINT | Supports.JAVA_TIME | Supports.READ_ONLY_UPDATE - | Supports.CONCURRENCY), + | Supports.CONCURRENCY + | Supports.CATALOG + | Supports.SRID), /** * The database uses Oracle syntax. This is ANSI, but without {@code "AS"} keyword. @@ -77,14 +83,16 @@ public enum Dialect { ORACLE("oracle", Supports.ALTER_TABLE_WITH_ADD_CONSTRAINT | Supports.JAVA_TIME | Supports.READ_ONLY_UPDATE - | Supports.CONCURRENCY), + | Supports.CONCURRENCY + | Supports.CATALOG + | Supports.SRID), /** * The database uses SQLite syntax. This is ANSI, but with several limitations. * * @see <a href="https://www.sqlite.org/omitted.html">SQL Features That SQLite Does Not Implement</a> */ - SQLITE("sqlite", 0), + SQLITE("sqlite", Supports.SRID), /** * The database uses DuckDB syntax. This is subset of SQL. DuckDB is not designed for transactional @@ -193,6 +201,22 @@ public enum Dialect { return (flags & Supports.CONCURRENCY) != 0; } + /** + * Whether the JDBC driver supports catalog or correctly reports that there is no catalog. + * This flag should be {@code false} when the JDBC driver returns a non-null catalog name + * (for example, the database name) but doesn't accept the use of that catalog in SQL. + */ + public final boolean supportsCatalog() { + return (flags & Supports.CATALOG) != 0; + } + + /** + * Whether the spatial extension supports <abbr>SRID</abbr> in {@code ST_*} functions. + */ + public final boolean supportsSRID() { + return (flags & Supports.SRID) != 0; + } + /** * Converts the pattern to something that can be used for requesting metadata. * This is a workaround for a DuckDB bug and may be removed in a future version. diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Reflection.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Reflection.java index 1069b2682a..b2a87ca14a 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Reflection.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Reflection.java @@ -41,6 +41,8 @@ public final class Reflection { * The {@value} key for getting a catalog name. This column appears in all reflection * operations (listing schemas, tables, columns, constraints, <i>etc.</i>) used by SIS. * The value in that column may be null. + * + * @see Dialect#supportsCatalog() */ public static final String TABLE_CAT = "TABLE_CAT"; diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Supports.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Supports.java index b2556112e8..b4f2086e1b 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Supports.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/Supports.java @@ -66,6 +66,18 @@ final class Supports { */ static final int CONCURRENCY = 32; + /** + * Whether the JDBC driver supports catalog or correctly reports that there is no catalog. + * This flag should be {@code false} when the JDBC driver returns a non-null catalog name + * (for example, the database name) but doesn't accept the use of that catalog in SQL. + */ + static final int CATALOG = 64; + + /** + * Whether the spatial extension supports <abbr>SRID</abbr> in {@code ST_*} functions. + */ + static final int SRID = 128; + /** * Do not allow instantiation of this class. */ diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Analyzer.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Analyzer.java index 406b8c9239..e9d3e110bc 100644 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Analyzer.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Analyzer.java @@ -237,8 +237,11 @@ public final class Analyzer { if (ignoredTables.containsKey(table)) { continue; } - declared.add(new TableReference( - getUniqueString(reflect, Reflection.TABLE_CAT), + String catalog = null; + if (database.dialect.supportsCatalog()) { + catalog = getUniqueString(reflect, Reflection.TABLE_CAT); + } + declared.add(new TableReference(catalog, getUniqueString(reflect, Reflection.TABLE_SCHEM), table, getUniqueString(reflect, Reflection.REMARKS))); } diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java index ee585a3dfc..752c2da858 100644 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java @@ -399,8 +399,10 @@ public class Database<G> extends Syntax { if (found) { spatialSchema = convention; if (consistent) { - catalogOfSpatialTables = catalog; - schemaOfSpatialTables = schema; + if (dialect.supportsCatalog()) { + catalogOfSpatialTables = catalog; + } + schemaOfSpatialTables = schema; } break; } diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java index c94c5e4de6..46f6c94d59 100644 --- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java +++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java @@ -226,18 +226,19 @@ public final class SelectionClause extends SQLBuilder implements Consumer<Warnin } bounds = e; } + final Database<?> db = table.database; if (wrapper == null) { - wrapper = table.database.geomLibrary.toGeometry2D(bounds, WraparoundMethod.SPLIT); + wrapper = db.geomLibrary.toGeometry2D(bounds, WraparoundMethod.SPLIT); } final String wkt = wrapper.formatWKT(0.05 * span); // Arbitrary flateness factor. /* * Format a spatial function for building the geometry from the Well-Known Text. - * The CRS, if available, while be specified as a SRID if the spatial support has + * The CRS, if available, will be specified as a SRID if the spatial support has * been recognized (otherwise we cannot map the CRS to the database-dependent SRID). */ appendSpatialFunction("ST_GeomFromText"); append('(').appendValue(wkt); - if (table.database.getSpatialSchema().isPresent()) { + if (db.dialect.supportsSRID() && db.getSpatialSchema().isPresent()) { CoordinateReferenceSystem crs = wrapper.getCoordinateReferenceSystem(); if (REPLACE_UNSPECIFIED_CRS && columnCRS != null) { if (crs == null) { @@ -284,7 +285,8 @@ public final class SelectionClause extends SQLBuilder implements Consumer<Warnin * @param name name of the spatial function to append. */ final void appendSpatialFunction(final String name) { - appendIdentifier(table.database.catalogOfSpatialTables, table.database.schemaOfSpatialTables, name, false); + final Database<?> db = table.database; + appendIdentifier(db.catalogOfSpatialTables, db.schemaOfSpatialTables, name, false); } /**