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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 5112580cf8 `SQLStore` needs to understand more than one CRS definition 
column. The current use case is to accept the Geopackage extension storing a 
WKT 2 definition in a separated column in addition to WKT 1. Future versions 
may accept more columns for CRS-JSON or others.
5112580cf8 is described below

commit 5112580cf81741e759fafdcdd0d253f47075eacf
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Tue Aug 13 19:17:56 2024 +0200

    `SQLStore` needs to understand more than one CRS definition column.
    The current use case is to accept the Geopackage extension storing
    a WKT 2 definition in a separated column in addition to WKT 1.
    Future versions may accept more columns for CRS-JSON or others.
---
 .../main/org/apache/sis/storage/sql/SQLStore.java  |   8 +-
 .../sis/storage/sql/feature/CRSEncoding.java       |  40 +++++++
 .../apache/sis/storage/sql/feature/Database.java   |  60 ++++++++---
 .../sis/storage/sql/feature/InfoStatements.java    | 116 +++++++++++++--------
 .../sis/storage/sql/feature/SpatialSchema.java     |  26 +++--
 .../org/apache/sis/storage/sql/package-info.java   |   2 +-
 6 files changed, 183 insertions(+), 69 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/SQLStore.java
 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/SQLStore.java
index f96ad09b8a..2dec07e23d 100644
--- 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/SQLStore.java
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/SQLStore.java
@@ -141,10 +141,15 @@ public class SQLStore extends DataStore implements 
Aggregate {
         source      = connector.getStorageAs(DataSource.class);
         geomLibrary = connector.getOption(OptionKey.GEOMETRY_LIBRARY);
         customizer  = connector.getOption(SchemaModifier.OPTION);
+
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         final GenericName[] tableNames = new GenericName[resources.length];
-        final ResourceDefinition[] queries = new 
ResourceDefinition[resources.length];
         int tableCount = 0;
+
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
+        final ResourceDefinition[] queries = new 
ResourceDefinition[resources.length];
         int queryCount = 0;
+
         for (int i=0; i<resources.length; i++) {
             final ResourceDefinition resource = resources[i];
             ArgumentChecks.ensureNonNullElement("resources", i, resource);
@@ -246,6 +251,7 @@ public class SQLStore extends DataStore implements 
Aggregate {
             final MetadataBuilder builder = new MetadataBuilder();
             
builder.addSpatialRepresentation(SpatialRepresentationType.TEXT_TABLE);
             try (Connection c = source.getConnection()) {
+                @SuppressWarnings("LocalVariableHidesMemberVariable")
                 final Database<?> model = model(c);
                 if (model.hasGeometry()) {
                     
builder.addSpatialRepresentation(SpatialRepresentationType.VECTOR);
diff --git 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/CRSEncoding.java
 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/CRSEncoding.java
new file mode 100644
index 0000000000..8b8e91df0b
--- /dev/null
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/CRSEncoding.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+package org.apache.sis.storage.sql.feature;
+
+
+/**
+ * The encoding of Coordinate Reference Systems in a particular column, in 
preference order.
+ *
+ * <p><b>Note:</b> the distinction between version 1 and 2 of <abbr>WKT</abbr> 
formats should not have been needed,
+ * because a decent parser should be able to differentiate those two versions 
automatically based on the fact that
+ * they use different keywords. Unfortunately, the Geopackage format decided 
to use a separated column for WKT 2.
+ * From Apache <abbr>SIS</abbr> perspective, this is more complication than 
help.</p>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ */
+enum CRSEncoding {
+    /**
+     * Well-Known Text 2 as defined by ISO 19162.
+     */
+    WKT2,
+
+    /**
+     * Well-KNown Text 1 as defined by OGC 01-009.
+     */
+    WKT1;
+}
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 379a96a11a..eac795c2ce 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
@@ -19,6 +19,7 @@ package org.apache.sis.storage.sql.feature;
 import java.util.Set;
 import java.util.Map;
 import java.util.List;
+import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
@@ -44,6 +45,7 @@ import org.apache.sis.metadata.sql.privy.Syntax;
 import org.apache.sis.metadata.sql.privy.Dialect;
 import org.apache.sis.metadata.sql.privy.Reflection;
 import org.apache.sis.metadata.sql.privy.SQLBuilder;
+import org.apache.sis.metadata.sql.privy.SQLUtilities;
 import org.apache.sis.storage.FeatureSet;
 import org.apache.sis.storage.FeatureNaming;
 import org.apache.sis.storage.DataStoreException;
@@ -52,8 +54,6 @@ import org.apache.sis.storage.base.MetadataBuilder;
 import org.apache.sis.geometry.wrapper.Geometries;
 import org.apache.sis.geometry.wrapper.GeometryType;
 import org.apache.sis.system.Modules;
-import org.apache.sis.util.Debug;
-import org.apache.sis.util.privy.UnmodifiableArrayList;
 import org.apache.sis.storage.sql.SQLStore;
 import org.apache.sis.storage.sql.ResourceDefinition;
 import org.apache.sis.storage.sql.postgis.Postgres;
@@ -61,6 +61,8 @@ import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.util.collection.FrequencySortedSet;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.Cache;
+import org.apache.sis.util.privy.UnmodifiableArrayList;
+import org.apache.sis.util.Debug;
 
 
 /**
@@ -151,6 +153,12 @@ public class Database<G> extends Syntax  {
      */
     private SpatialSchema spatialSchema;
 
+    /**
+     * The encoding of Coordinate Reference Systems in the spatial database, 
in preference order.
+     * This field is initialized by {@link #analyze analyze(…)} and shall not 
be modified after that point.
+     */
+    final EnumSet<CRSEncoding> crsEncodings;
+
     /**
      * {@code true} if this database contains at least one geometry column.
      * This field is initialized by {@link #analyze analyze(…)} and shall not 
be modified after that point.
@@ -273,6 +281,7 @@ public class Database<G> extends Syntax  {
         supportsCatalogs   = metadata.supportsCatalogsInDataManipulation();
         supportsSchemas    = metadata.supportsSchemasInDataManipulation();
         supportsJavaTime   = dialect.supportsJavaTime;
+        crsEncodings       = EnumSet.noneOf(CRSEncoding.class);
     }
 
     /**
@@ -346,32 +355,55 @@ public class Database<G> extends Syntax  {
          * the default case specified by the SQL standard. However, some 
databases use lower
          * cases instead.
          */
+        String crsTable = null;
         final var ignoredTables = new HashMap<String,Boolean>(8);
         for (SpatialSchema schema : getPossibleSpatialSchemas(ignoredTables)) {
-            String tableCRS  = schema.crsTable;;
-            String tableGeom = schema.geometryColumns;
+            String geomTable;
+            crsTable  = schema.crsTable;
+            geomTable = schema.geometryColumns;
             if (metadata.storesLowerCaseIdentifiers()) {
-                tableCRS  = tableCRS .toLowerCase(Locale.US).intern();
-                tableGeom = tableGeom.toLowerCase(Locale.US).intern();
+                crsTable  = crsTable .toLowerCase(Locale.US).intern();
+                geomTable = geomTable.toLowerCase(Locale.US).intern();
             } else if (metadata.storesUpperCaseIdentifiers()) {
-                tableCRS  = tableCRS .toUpperCase(Locale.US).intern();
-                tableGeom = tableGeom.toUpperCase(Locale.US).intern();
+                crsTable  = crsTable .toUpperCase(Locale.US).intern();
+                geomTable = geomTable.toUpperCase(Locale.US).intern();
             }
-            ignoredTables.put(tableCRS,  Boolean.TRUE);
-            ignoredTables.put(tableGeom, Boolean.TRUE);
+            ignoredTables.put(crsTable,  Boolean.TRUE);
+            ignoredTables.put(geomTable, Boolean.TRUE);
             if (hasTable(metadata, tableTypes, ignoredTables)) {
                 spatialSchema = schema;
                 break;
             }
-            ignoredTables.remove(tableCRS);
-            ignoredTables.remove(tableGeom);
+            ignoredTables.remove(crsTable);
+            ignoredTables.remove(geomTable);
+        }
+        /*
+         * Get the columns for CRS definitions. At least one column should 
exist for CRS encoded in WKT1 format.
+         * Some schemas have additional columns for optional encodings, for 
example a separated column for WKT2.
+         * The preference order will be defined by the `CRSEncoding` 
enumeration order.
+         */
+        final Analyzer analyzer = new Analyzer(this, connection, metadata, 
customizer);
+        if (spatialSchema != null) {
+            final String schema = SQLUtilities.escape(schemaOfSpatialTables, 
analyzer.escape);
+            final String table  = SQLUtilities.escape(crsTable, 
analyzer.escape);
+            for (Map.Entry<CRSEncoding, String> entry : 
spatialSchema.crsDefinitionColumn.entrySet()) {
+                String column = entry.getValue();
+                if (metadata.storesLowerCaseIdentifiers()) {
+                    column = column.toLowerCase(Locale.US);
+                }
+                column = SQLUtilities.escape(column, analyzer.escape);
+                try (ResultSet reflect = 
metadata.getColumns(catalogOfSpatialTables, schema, table, column)) {
+                    if (reflect.next()) {
+                        crsEncodings.add(entry.getKey());
+                    }
+                }
+            }
         }
         /*
          * Collect the names of all tables specified by user, ignoring the 
tables
          * used for database internal working (for example by PostGIS).
          */
-        final Analyzer analyzer = new Analyzer(this, connection, metadata, 
customizer);
-        final Set<TableReference> declared = new LinkedHashSet<>();
+        final var declared = new LinkedHashSet<TableReference>();
         for (final GenericName tableName : tableNames) {
             final String[] names = TableReference.splitName(tableName);
             try (ResultSet reflect = metadata.getTables(names[2], names[1], 
names[0], tableTypes)) {
diff --git 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/InfoStatements.java
 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/InfoStatements.java
index 26b61023db..ac6e66e91d 100644
--- 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/InfoStatements.java
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/InfoStatements.java
@@ -289,6 +289,37 @@ public class InfoStatements implements Localized, 
AutoCloseable {
         return database.cacheOfCRS.getOrCreate(srid, () -> parseCRS(srid));
     }
 
+    /**
+     * Creates a prepared statement for getting an authority code from SRID, 
or the converse.
+     * In both cases, the definition in all supported CRS encoding is provided 
in the last columns.
+     *
+     * @param  byAuthorityCode  {@code false} for (authority, code) from SRID, 
or {@code true} for the converse.
+     * @return the prepared statement.
+     * @throws SQLException if an error occurred while creating the prepared 
statement.
+     */
+    private PreparedStatement prepareSearchCRS(final boolean byAuthorityCode) 
throws SQLException {
+        final SpatialSchema schema = database.getSpatialSchema().orElseThrow();
+        final SQLBuilder sql = new SQLBuilder(database);
+        sql.append(SQLBuilder.SELECT);
+        if (byAuthorityCode) {
+            sql.append(schema.crsIdentifierColumn);
+        } else {
+            sql.append(schema.crsAuthorityNameColumn).append(", ")
+               .append(schema.crsAuthorityCodeColumn);
+        }
+        for (CRSEncoding encoding : database.crsEncodings) {
+            sql.append(", ").append(schema.crsDefinitionColumn.get(encoding));
+        }
+        appendFrom(sql, schema.crsTable);
+        if (byAuthorityCode) {
+            sql.append(schema.crsAuthorityNameColumn).append("=? AND ")
+               .append(schema.crsAuthorityCodeColumn).append("=?");
+        } else {
+            sql.append(schema.crsIdentifierColumn).append("=?");
+        }
+        return connection.prepareStatement(sql.toString());
+    }
+
     /**
      * Invoked when the requested CRS is not in the cache. This method gets 
the entry from the
      * {@link SpatialSchema#refSysTable} then gets the CRS from its authority 
code if possible,
@@ -300,14 +331,7 @@ public class InfoStatements implements Localized, 
AutoCloseable {
      */
     private CoordinateReferenceSystem parseCRS(final int srid) throws 
Exception {
         if (wktFromSrid == null) {
-            final SpatialSchema schema = 
database.getSpatialSchema().orElseThrow();
-            final SQLBuilder sql = new SQLBuilder(database);
-            sql.append(SQLBuilder.SELECT).append(schema.crsAuthorityNameColumn)
-                            .append(", ").append(schema.crsAuthorityCodeColumn)
-                            .append(", ").append(schema.crsDefinitionColumn);
-            appendFrom(sql, schema.crsTable);
-            sql.append(schema.crsIdentifierColumn).append("=?");
-            wktFromSrid = connection.prepareStatement(sql.toString());
+            wktFromSrid = prepareSearchCRS(false);
         }
         wktFromSrid.setInt(1, srid);
         CoordinateReferenceSystem crs = null;
@@ -332,34 +356,30 @@ public class InfoStatements implements Localized, 
AutoCloseable {
                 }
                 /*
                  * Parse the WKT unconditionally, even if we already got the 
CRS from authority code.
-                 * It the latter case, the CRS from WKT will be used only for 
a consistency check and
+                 * In the latter case, the CRS from WKT will be used only for 
a consistency check and
                  * the main CRS will be the one from authority.
                  */
-                CoordinateReferenceSystem fromWKT = null;
-                final String wkt = result.getString(3);
-                if (wkt != null && !wkt.isEmpty()) {
-                    final Object parsed;
-                    try {
-                        parsed = wktReader().parseObject(wkt);
-                    } catch (ParseException e) {
-                        if (authorityError != null) {
-                            e.addSuppressed(authorityError);
-                        }
-                        throw e;
-                    }
-                    if (parsed instanceof CoordinateReferenceSystem) {
-                        fromWKT = (CoordinateReferenceSystem) parsed;
+                final CoordinateReferenceSystem fromDefinition;
+                try {
+                    final Object parsed = parseDefinition(result, 3);
+                    if (parsed == null || parsed instanceof 
CoordinateReferenceSystem) {
+                        fromDefinition = (CoordinateReferenceSystem) parsed;
                     } else {
                         throw 
invalidSRID(Resources.Keys.UnexpectedTypeForSRID_2,
                                 ReferencingUtilities.getInterface(parsed), 
srid, authorityError);
                     }
+                } catch (ParseException e) {
+                    if (authorityError != null) {
+                        e.addSuppressed(authorityError);
+                    }
+                    throw e;
                 }
                 /*
                  * If one of the CRS is null, take the non-null one. If both 
CRSs are defined (which is the usual case),
                  * verify that they are consistent. Inconsistency will be 
logged as warning if the rest of the operation
                  * succeed.
                  */
-                final DefinitionVerifier v = 
DefinitionVerifier.compare(fromWKT, fromAuthority, getLocale());
+                final DefinitionVerifier v = 
DefinitionVerifier.compare(fromDefinition, fromAuthority, getLocale());
                 if (v.recommendation != null) {
                     if (crs == null) {
                         crs = v.recommendation;
@@ -368,7 +388,7 @@ public class InfoStatements implements Localized, 
AutoCloseable {
                         throw invalidSRID(Resources.Keys.DuplicatedSRID_2, 
schema.crsTable, srid, authorityError);
                     }
                     warning = v.warning(false);
-                    if (warning == null && fromWKT != null) {
+                    if (warning == null && fromDefinition != null) {
                         /*
                          * Following warnings may have occurred during WKT 
parsing and are considered minor.
                          * They will be reported only if there are no more 
important warnings to report.
@@ -470,24 +490,16 @@ public class InfoStatements implements Localized, 
AutoCloseable {
                  * Get the WKT and verifies if the CRS is approximately equal.
                  */
                 if (sridFromCRS == null) {
-                    final SpatialSchema schema = 
database.getSpatialSchema().orElseThrow();
-                    final SQLBuilder sql = new SQLBuilder(database);
-                    
sql.append(SQLBuilder.SELECT).append(schema.crsDefinitionColumn)
-                                    .append(", 
").append(schema.crsIdentifierColumn);
-                    appendFrom(sql, schema.crsTable);
-                    sql.append(schema.crsAuthorityNameColumn).append("=? AND ")
-                       .append(schema.crsAuthorityCodeColumn).append("=?");
-                    sridFromCRS = connection.prepareStatement(sql.toString());
+                    sridFromCRS = prepareSearchCRS(true);
                 }
                 sridFromCRS.setString(1, authority);
                 sridFromCRS.setInt(2, codeValue);
                 try (ResultSet result = sridFromCRS.executeQuery()) {
                     while (result.next()) {
-                        final String wkt = result.getString(1);
-                        if (wkt != null && !wkt.isEmpty()) try {
-                            final Object parsed = wktReader().parseObject(wkt);
+                        try {
+                            final Object parsed = parseDefinition(result, 2);
                             if (Utilities.equalsApproximately(parsed, crs)) {
-                                final int srid = result.getInt(2);
+                                final int srid = result.getInt(1);
                                 synchronized (database.cacheOfSRID) {
                                     database.cacheOfSRID.put(crs, srid);
                                 }
@@ -518,15 +530,31 @@ public class InfoStatements implements Localized, 
AutoCloseable {
     }
 
     /**
-     * Returns the object to use for parsing Well Known Text (CRS).
-     * The parser is created when first needed.
+     * Parses the CRS defined in the first non-blank column starting at the 
given index.
+     * The expected encoding are given by {@link Database#crsEncodings} in 
that order.
+     *
+     * @param  result  the row containing the CRS definition to parse.
+     * @param  column  column of the preferred CRS definition. Next columns 
may be used if needed.
+     * @return the result of parsing the CRS definition, or {@code nnull} if 
none.
      */
-    private WKTFormat wktReader() {
-        if (wktReader == null) {
-            wktReader = new WKTFormat();
-            wktReader.setConvention(Convention.WKT1_COMMON_UNITS);
+    private Object parseDefinition(final ResultSet result, int column) throws 
SQLException, ParseException {
+        for (CRSEncoding encoding : database.crsEncodings) {
+            final String wkt = result.getString(column++);
+            if (wkt == null || wkt.isBlank()) {
+                continue;
+            }
+            switch (encoding) {
+                default: {
+                    if (wktReader == null) {
+                        wktReader = new WKTFormat();
+                        wktReader.setConvention(Convention.WKT1_COMMON_UNITS);
+                    }
+                    return wktReader.parseObject(wkt);
+                }
+                // JSON encoding may be added in a future version.
+            }
         }
-        return wktReader;
+        return null;
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java
 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java
index e171d80793..e405545841 100644
--- 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.storage.sql.feature;
 
+import java.util.Map;
+
 
 /**
  * Information about table names and column names used for the spatial schema.
@@ -38,9 +40,12 @@ public enum SpatialSchema {
      * except for table names, for the case (Geopackage uses lower case) and 
for the addition of a
      * {@code geometry_type_name} column.
      */
-    GEOPACKAGE("gpkg_spatial_ref_sys", "srs_id", "organization", 
"organization_coordsys_id", "definition",
-               "gpkg_geometry_columns", "table_catalog", "table_schema", 
"table_name", "column_name",
-               "geometry_type_name", GeometryTypeEncoding.TEXTUAL),
+    GEOPACKAGE("gpkg_spatial_ref_sys", "srs_id", "organization", 
"organization_coordsys_id",
+               Map.of(CRSEncoding.WKT1, "definition",
+                      CRSEncoding.WKT2, "definition_12_063"),
+
+               "gpkg_geometry_columns", "table_catalog", "table_schema", 
"table_name",
+               "column_name", "geometry_type_name", 
GeometryTypeEncoding.TEXTUAL),
 
     /**
      * Table and column names as specified by ISO-13249 SQL/MM. This is the 
same thing as {@link #SIMPLE_FEATURE}
@@ -59,7 +64,8 @@ public enum SpatialSchema {
      * In Geopackage, this table is named {@code "gpkg_spatial_ref_sys"} but 
otherwise has identical content
      * except for the case (Geopackage uses lower case).
      */
-    SQL_MM("ST_SPATIAL_REFERENCE_SYSTEMS", "SRS_ID", "ORGANIZATION", 
"ORGANIZATION_COORDSYS_ID", "DEFINITION",
+    SQL_MM("ST_SPATIAL_REFERENCE_SYSTEMS", "SRS_ID", "ORGANIZATION", 
"ORGANIZATION_COORDSYS_ID",
+           Map.of(CRSEncoding.WKT1, "DEFINITION"),
            "ST_GEOMETRY_COLUMNS", "TABLE_CATALOG", "TABLE_SCHEMA", 
"TABLE_NAME", "COLUMN_NAME", null, null),
 
     /**
@@ -76,7 +82,7 @@ public enum SpatialSchema {
      *   SRTEXT CHARACTER VARYING(2048))
      * }
      */
-    SIMPLE_FEATURE("SPATIAL_REF_SYS", "SRID", "AUTH_NAME", "AUTH_SRID", 
"SRTEXT",
+    SIMPLE_FEATURE("SPATIAL_REF_SYS", "SRID", "AUTH_NAME", "AUTH_SRID", 
Map.of(CRSEncoding.WKT1, "SRTEXT"),
                    "GEOMETRY_COLUMNS", "F_TABLE_CATALOG", "F_TABLE_SCHEMA", 
"F_TABLE_NAME", "F_GEOMETRY_COLUMN",
                    "GEOMETRY_TYPE", GeometryTypeEncoding.NUMERIC);
 
@@ -108,8 +114,9 @@ public enum SpatialSchema {
     /**
      * Name of the column for CRS definitions in Well-Known Text 
(<abbr>WKT</abbr>) format.
      * Example: {@code "SRTEXT"}, {@code "DEFINITION"}.
+     * Entries are in no particular order.
      */
-    final String crsDefinitionColumn;
+    final Map<CRSEncoding, String> crsDefinitionColumn;
 
     /**
      * Name of the table enumerating the geometry columns.
@@ -168,9 +175,10 @@ public enum SpatialSchema {
      * @param typeEncoding            how geometry types are encoded in the 
{@link #geomTypeColumn}.
      */
     private SpatialSchema(String crsTable, String crsIdentifierColumn, String 
crsAuthorityNameColumn,
-                          String crsAuthorityCodeColumn, String 
crsDefinitionColumn, String geometryColumns,
-                          String geomCatalogColumn, String geomSchemaColumn, 
String geomTableColumn,
-                          String geomColNameColumn, String geomTypeColumn, 
GeometryTypeEncoding typeEncoding)
+                          String crsAuthorityCodeColumn, 
Map<CRSEncoding,String> crsDefinitionColumn,
+                          String geometryColumns, String geomCatalogColumn, 
String geomSchemaColumn,
+                          String geomTableColumn, String geomColNameColumn, 
String geomTypeColumn,
+                          GeometryTypeEncoding typeEncoding)
     {
         this.crsTable               = crsTable;
         this.crsIdentifierColumn    = crsIdentifierColumn;
diff --git 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/package-info.java
 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/package-info.java
index d075f6c912..49ced53cff 100644
--- 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/package-info.java
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/package-info.java
@@ -56,7 +56,7 @@
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.3
+ * @version 1.5
  * @since   1.0
  */
 package org.apache.sis.storage.sql;

Reply via email to