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 d918d5e6fb4f6e8ff23b712056cff8b66fa080f5 Author: Martin Desruisseaux <[email protected]> AuthorDate: Sun Aug 10 14:18:29 2025 +0200 Rename the enumeration types in `EPSG_Prepare.sql` to the final names that they will have in the database. The previous version was using temporary names which were changed on-the-fly during the installation. Finer conversion to `VARCHAR` for databases that do not support enumerations. --- .../referencing/factory/sql/AuthorityCodes.java | 2 +- .../referencing/factory/sql/EPSGCodeFinder.java | 2 +- .../referencing/factory/sql/EPSGDataAccess.java | 6 ++-- .../sis/referencing/factory/sql/EPSGInstaller.java | 22 +++++++------ .../sis/referencing/factory/sql/EPSG_Prepare.sql | 20 ++++++------ .../sis/referencing/factory/sql/SQLTranslator.java | 11 +++++++ .../sis/referencing/factory/sql/TableInfo.java | 36 ++++++++++------------ .../sis/referencing/factory/sql/epsg/README.md | 11 ++++--- 8 files changed, 60 insertions(+), 50 deletions(-) diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/AuthorityCodes.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/AuthorityCodes.java index 5a7eac4e08..27b01d3b7d 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/AuthorityCodes.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/AuthorityCodes.java @@ -134,7 +134,7 @@ final class AuthorityCodes extends AbstractMap<String,String> implements Seriali final int columnNameStart = buffer.append("SELECT ").length(); final int columnNameEnd = buffer.append(table.codeColumn).length(); buffer.append(" FROM ").append(table.table); - final Class<?> tableType = table.where(type, buffer); + final Class<?> tableType = table.where(factory, type, buffer); final int conditionStart = buffer.length(); if (table.showColumn != null) { buffer.append(table.showColumn).append("<>0 AND "); diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java index 47975c6b37..cab3292126 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGCodeFinder.java @@ -418,7 +418,7 @@ crs: if (isInstance(CoordinateReferenceSystem.class, object)) { * It may be absent (typically, only datums or reference frames have that condition). */ buffer.append("SELECT ").append(table.codeColumn).append(" FROM ").append(table.table); - table.where(object, buffer); // Unconditionally append a "WHERE" clause. + table.where(dao, object, buffer); // Unconditionally append a "WHERE" clause. boolean isNext = false; for (final Condition filter : filters) { isNext |= filter.appendToWhere(buffer, isNext); diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java index 88c53ef737..49eca3b051 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java @@ -1596,7 +1596,7 @@ search: try (ResultSet result = executeMetadataQuery("Deprecation", */ final FactoryCall<CRSFactory, CoordinateReferenceSystem> constructor; /* - * The following switch statement should have a case for all "epsg_crs_kind" values enumerated + * The following switch statement should have a case for all "CRS Kind" values enumerated * in the "EPSG_Prepare.sql" file, except that the values in this Java code are in lower cases. */ switch (type.toLowerCase(Locale.US)) { @@ -1918,7 +1918,7 @@ search: try (ResultSet result = executeMetadataQuery("Deprecation", */ final FactoryCall<DatumFactory, ? extends Datum> constructor; /* - * The following switch statement should have a case for all "epsg_datum_kind" values enumerated + * The following switch statement should have a case for all "Datum Kind" values enumerated * in the "EPSG_Prepare.sql" file, except that the values in this Java code are in lower cases. */ switch (type.toLowerCase(Locale.US)) { @@ -2506,7 +2506,7 @@ search: try (ResultSet result = executeMetadataQuery("Deprecation", final Map<String,Object> properties = createProperties( "Coordinate System", epsg, name, null, null, null, remarks, deprecated); /* - * The following switch statement should have a case for all "epsg_cs_kind" values enumerated + * The following switch statement should have a case for all "CS Kind" values enumerated * in the "EPSG_Prepare.sql" file, except that the values in this Java code are in lower cases. */ final CSFactory csFactory = owner.csFactory; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java index 637aba0ca8..95615cb8dc 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java @@ -150,22 +150,24 @@ final class EPSGInstaller extends ScriptRunner { addReplacement(SQLTranslator.TABLE_PREFIX + "unitofmeasure", "Unit of Measure"); addReplacement(SQLTranslator.TABLE_PREFIX + "usage", "Usage"); addReplacement(SQLTranslator.TABLE_PREFIX + "versionhistory", "Version History"); - if (isEnumTypeSupported) { - addReplacement(SQLTranslator.TABLE_PREFIX + "datum_kind", "Datum Kind"); - addReplacement(SQLTranslator.TABLE_PREFIX + "crs_kind", "CRS Kind"); - addReplacement(SQLTranslator.TABLE_PREFIX + "cs_kind", "CS Kind"); - addReplacement(SQLTranslator.TABLE_PREFIX + "table_name", "Table Name"); - } prependNamespace(schema); } if (!isEnumTypeSupported) { - addReplacement(SQLTranslator.TABLE_PREFIX + "datum_kind", TableInfo.ENUM_REPLACEMENT); - addReplacement(SQLTranslator.TABLE_PREFIX + "crs_kind", TableInfo.ENUM_REPLACEMENT); - addReplacement(SQLTranslator.TABLE_PREFIX + "cs_kind", TableInfo.ENUM_REPLACEMENT); - addReplacement(SQLTranslator.TABLE_PREFIX + "table_name", TableInfo.ENUM_REPLACEMENT); + addReplacement("Datum Kind", "VARCHAR(16)"); // Original: VARCHAR(24) for column "datum_type". + addReplacement("CRS Kind", "VARCHAR(13)"); // Original: VARCHAR(24) for column "coord_ref_sys_kind". + addReplacement("CS Kind", "VARCHAR(15)"); // Original: VARCHAR(24) for column "coord_sys_type". + addReplacement("Supersession Type", "VARCHAR(12)"); // Original: VARCHAR(50) for column "supersession_type". + addReplacement("Table Name", ENUM_REPLACEMENT); // Original: VARCHAR(80) for columns "object_table_name". } } + /** + * The <abbr>SQL</abbr> type to use as a replacement for enumerated values in databases that do not + * support enumerations. The maximal length declared in this constant should be the greatest length + * declared in {@code VARCHAR(…)} substitutions done when {@link #isEnumTypeSupported} is false. + */ + static final String ENUM_REPLACEMENT = "VARCHAR(36)"; + /** * Prepends the given schema or catalog to all table names. */ diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSG_Prepare.sql b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSG_Prepare.sql index 7e0bdb267b..8afc412d0f 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSG_Prepare.sql +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSG_Prepare.sql @@ -10,11 +10,11 @@ -- If enumerated values are not supported by the database, Apache SIS will automatically replace their usage -- by the VARCHAR type. -- -CREATE TYPE epsg_datum_kind AS ENUM ('geodetic', 'vertical', 'temporal', 'engineering', 'dynamic geodetic', 'ensemble'); -CREATE TYPE epsg_crs_kind AS ENUM ('geocentric', 'geographic 2D', 'geographic 3D', 'projected', 'vertical', 'temporal', 'compound', 'engineering', 'derived'); -CREATE TYPE epsg_cs_kind AS ENUM ('ellipsoidal', 'spherical', 'Cartesian', 'vertical', 'gravity-related', 'time', 'linear', 'polar', 'cylindrical', 'affine', 'ordinal'); -CREATE TYPE epsg_supersession_type AS ENUM ('Supersession'); -CREATE TYPE epsg_table_name AS ENUM +CREATE TYPE "Datum Kind" AS ENUM ('geodetic', 'vertical', 'temporal', 'engineering', 'dynamic geodetic', 'ensemble'); +CREATE TYPE "CRS Kind" AS ENUM ('geocentric', 'geographic 2D', 'geographic 3D', 'projected', 'vertical', 'temporal', 'compound', 'engineering', 'derived'); +CREATE TYPE "CS Kind" AS ENUM ('ellipsoidal', 'spherical', 'Cartesian', 'vertical', 'gravity-related', 'time', 'linear', 'polar', 'cylindrical', 'affine', 'ordinal'); +CREATE TYPE "Supersession Type" AS ENUM ('Supersession'); +CREATE TYPE "Table Name" AS ENUM ('Alias', 'Area', -- Deprecated (removed in EPSG 10). 'Change', @@ -48,8 +48,8 @@ CREATE TYPE epsg_table_name AS ENUM -- -- Those casts allow to use enumerated values as if they were VARCHAR elements. -- -CREATE CAST (VARCHAR AS epsg_datum_kind) WITH INOUT AS ASSIGNMENT; -CREATE CAST (VARCHAR AS epsg_crs_kind) WITH INOUT AS ASSIGNMENT; -CREATE CAST (VARCHAR AS epsg_cs_kind) WITH INOUT AS ASSIGNMENT; -CREATE CAST (VARCHAR AS epsg_supersession_type) WITH INOUT AS ASSIGNMENT; -CREATE CAST (VARCHAR AS epsg_table_name) WITH INOUT AS ASSIGNMENT; +CREATE CAST (VARCHAR AS "Datum Kind") WITH INOUT AS ASSIGNMENT; +CREATE CAST (VARCHAR AS "CRS Kind") WITH INOUT AS ASSIGNMENT; +CREATE CAST (VARCHAR AS "CS Kind") WITH INOUT AS ASSIGNMENT; +CREATE CAST (VARCHAR AS "Supersession Type") WITH INOUT AS ASSIGNMENT; +CREATE CAST (VARCHAR AS "Table Name") WITH INOUT AS ASSIGNMENT; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/SQLTranslator.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/SQLTranslator.java index 95327f20ac..d84b6f3d96 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/SQLTranslator.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/SQLTranslator.java @@ -230,6 +230,8 @@ public class SQLTranslator implements UnaryOperator<String> { * Non-null if the {@value #ENUMERATION_COLUMN} column in {@code "Alias"} table uses enumeration instead * than character varying. In such case, this field contains the enumeration type. If {@code null}, then * then column type is {@code VARCHAR} and the cast can be omitted. + * + * @see #useEnumerations() */ private String tableNameEnum; @@ -570,6 +572,15 @@ check: for (;;) { return useBoolean; } + /** + * Returns {@code true} if the database uses enumeration values where applicable. + * This method use the {@value #ENUMERATION_COLUMN} column as a sentinel value for + * detecting whether enumerations are used for the whole <abbr>EPSG</abbr> database. + */ + final boolean useEnumerations() { + return tableNameEnum != null; + } + /** * Converts a mixed-case table name to the convention used in the database. * The names of the tables for the two conventions are listed in a table in the Javadoc of this class. diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/TableInfo.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/TableInfo.java index b2afeba4e5..55c0a8653b 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/TableInfo.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/TableInfo.java @@ -69,8 +69,8 @@ final class TableInfo { * <h4>Ambiguity</h4> * As of ISO 19111:2019, we have no standard way to identify the geocentric case from a {@link Class} argument * because the standard does not provide the {@code GeocentricCRS} interface. This implementation fallbacks on - * the SIS-specific geocentric CRS class, with a {@link #where(IdentifiedObject, StringBuilder)} method which - * will substitute implementation-neutral objects by the Apache SIS class. + * the SIS-specific geocentric CRS class, with a {@link #where(EPSGDataAccess, IdentifiedObject, StringBuilder)} + * method which will substitute implementation-neutral objects by the Apache SIS class. */ static final TableInfo[] EPSG = { CRS = new TableInfo(CoordinateReferenceSystem.class, @@ -187,17 +187,10 @@ final class TableInfo { final String nameColumn; /** - * Column type for the type (usually with the {@code "_TYPE"} suffix), or {@code null}. - * {@link EPSGDataAccess} and {@link AuthorityCodes} assume that values in this column - * are not longer than the maximal length specified in {@value #ENUM_REPLACEMENT}. + * Column name for the type (usually with the {@code "_TYPE"} suffix), or {@code null}. */ private final String typeColumn; - /** - * The SQL type to use as a replacement for enumerated values on databases that do not support enumerations. - */ - static final String ENUM_REPLACEMENT = "VARCHAR(80)"; - /** * Sub-interfaces of {@link #type} to handle, or {@code null} if none. */ @@ -257,7 +250,7 @@ final class TableInfo { /** * Returns the class of objects created from the given table. The given table name should be one of - * the values enumerated in the {@code epsg_table_name} types of the {@code EPSG_Prepare.sql} file. + * the values enumerated in the {@code "Table Name"} types of the {@code EPSG_Prepare.sql} file. * The name may be prefixed by {@code "epsg_"} and may contain abbreviations of the full name. * For example, {@code "epsg_coordoperation"} is considered as a match for {@code "Coordinate_Operation"}. * @@ -280,13 +273,14 @@ final class TableInfo { /** * Appends a {@code WHERE} clause together with a condition for searching the specified object. - * This method delegates to {@link #where(Class, StringBuilder)} with the type of the given object, - * except that some object properties may be inspected for resolving ambiguities. + * This method delegates to {@link #where(EPSGDataAccess, Class, StringBuilder)} with the type + * of the given object, except that some object properties may be inspected for resolving ambiguities. * - * @param object the object to search in the database. - * @param buffer where to append the {@code WHERE} clause. + * @param factory the factory which is writing a <abbr>SQL</abbr> statement. + * @param object the object to search in the database. + * @param buffer where to append the {@code WHERE} clause. */ - final void where(final IdentifiedObject object, final StringBuilder buffer) { + final void where(final EPSGDataAccess factory, final IdentifiedObject object, final StringBuilder buffer) { Class<?> userType = object.getClass(); if (object instanceof GeodeticCRS) { final CoordinateSystem cs = ((GeodeticCRS) object).getCoordinateSystem(); @@ -296,7 +290,7 @@ final class TableInfo { userType = DefaultGeocentricCRS.class; } } - where(userType, buffer); + where(factory, userType, buffer); } /** @@ -310,18 +304,20 @@ final class TableInfo { * * The caller shall add at least one condition after this method call. * + * @param factory the factory which is writing a <abbr>SQL</abbr> statement. * @param userType the type specified by the user. * @param buffer where to append the {@code WHERE} clause. * @return the subtype, or {@link #type} if no subtype was found. */ - final Class<?> where(final Class<?> userType, final StringBuilder buffer) { + final Class<?> where(final EPSGDataAccess factory, final Class<?> userType, final StringBuilder buffer) { buffer.append(" WHERE "); if (typeColumn != null) { for (int i=0; i<subTypes.length; i++) { final Class<?> candidate = subTypes[i]; if (candidate.isAssignableFrom(userType)) { - if (ENUM_REPLACEMENT != null) { - buffer.append("CAST(").append(typeColumn).append(" AS ").append(ENUM_REPLACEMENT).append(')'); + if (factory.translator.useEnumerations()) { + buffer.append("CAST(").append(typeColumn).append(" AS ") + .append(EPSGInstaller.ENUM_REPLACEMENT).append(')'); } else { buffer.append(typeColumn); } diff --git a/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/README.md b/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/README.md index 905941e658..5a5b1998d4 100644 --- a/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/README.md +++ b/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/README.md @@ -72,11 +72,12 @@ Open the `Tables.sql` file for edition: * Change all `FLOAT` types to `DOUBLE PRECISION` because Apache SIS reads all numbers as `double` type. This change avoids spurious digits in the conversions from `float` to `double`. * Change the type of `epsg_usage` column from `SERIAL` to `INTEGER NOT NULL`. -* Change the type of every `table_name` columns from `VARCHAR(80)` to `epsg_table_name`. -* Change the type of `coord_ref_sys_kind` column from `VARCHAR(24)` to `epsg_crs_kind`. -* Change the type of `coord_sys_type` column from `VARCHAR(24)` to `epsg_cs_kind`. -* Change the type of `datum_type` column from `VARCHAR(24)` to `epsg_datum_kind`. -* Change the type of `supersession_type` column from `VARCHAR(50)` to `epsg_supersession_type`. +* Change the type of every `table_name` columns from `VARCHAR(80)` to `"Table Name"`. +* Change the type of `coord_ref_sys_kind` column from `VARCHAR(24)` to `"CRS Kind"`. +* Change the type of `coord_sys_type` column from `VARCHAR(24)` to `"CS Kind"`. +* Change the type of `datum_type` column from `VARCHAR(24)` to `"Datum Kind"`. +* Change the type of `supersession_type` column from `VARCHAR(50)` to `"Supersession Type"`. +* If new enumeration values are added, check the maximal lengths of `VARCHAR` replacements in `EPSGInstaller`. * Suppress trailing spaces and save. Then open the `FKeys.sql` file for edition:
