You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by am...@apache.org on 2021/05/27 12:04:07 UTC

[sis] 02/02: fix(sis-sqlstore): fix numeric value conversion for new PostgreSQL version

This is an automated email from the ASF dual-hosted git repository.

amanin pushed a commit to branch fix/postgis
in repository https://gitbox.apache.org/repos/asf/sis.git

commit ec007be92af99a1a88de5b429cbbecc3413f69bf
Author: Alexis Manin <al...@geomatys.com>
AuthorDate: Thu May 27 12:08:47 2021 +0200

    fix(sis-sqlstore): fix numeric value conversion for new PostgreSQL version
---
 .../sis/internal/sql/feature/ANSIMapping.java      | 27 +++++++++++++++++-----
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/ANSIMapping.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/ANSIMapping.java
index 536c5e1..f22a0a9 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/ANSIMapping.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/ANSIMapping.java
@@ -29,6 +29,8 @@ import java.time.OffsetDateTime;
 import java.time.OffsetTime;
 import java.time.ZoneOffset;
 import java.util.Optional;
+import java.util.function.BiFunction;
+import org.apache.sis.util.Numbers;
 
 /**
  * Default JDBC mapping type, used as a fallback when no other database-specific mapping can handle value binding.
@@ -69,14 +71,14 @@ class ANSIMapping implements DialectMapping {
             case Types.BIT:
             case Types.BOOLEAN:                 return forceCast(Boolean.class);
             case Types.TINYINT:                 if (!isByteUnsigned) return forceCast(Byte.class);  // else fallthrough.
-            case Types.SMALLINT:                return forceCast(Short.class);
-            case Types.INTEGER:                 return forceCast(Integer.class);
-            case Types.BIGINT:                  return forceCast(Long.class);
-            case Types.REAL:                    return forceCast(Float.class);
+            case Types.SMALLINT:                return forceNumberCast(Short.class);
+            case Types.INTEGER:                 return forceNumberCast(Integer.class);
+            case Types.BIGINT:                  return forceNumberCast(Long.class);
+            case Types.REAL:                    return forceNumberCast(Float.class);
             case Types.FLOAT:                   // Despite the name, this is implemented as DOUBLE in major databases.
-            case Types.DOUBLE:                  return forceCast(Double.class);
+            case Types.DOUBLE:                  return forceNumberCast(Double.class);
             case Types.NUMERIC:                 // Similar to DECIMAL except that it uses exactly the specified precision.
-            case Types.DECIMAL:                 return forceCast(BigDecimal.class);
+            case Types.DECIMAL:                 return forceNumberCast(BigDecimal.class);
             case Types.CHAR:
             case Types.VARCHAR:
             case Types.LONGVARCHAR:             return new ColumnAdapter.Simple<>(String.class, ResultSet::getString);
@@ -129,4 +131,17 @@ class ANSIMapping implements DialectMapping {
         final Object value = source.getObject(columnIndex);
         return value == null ? null : targetType.cast(value);
     }
+
+    private static <T extends Number> ColumnAdapter<T> forceNumberCast(final Class<T> targetType) {
+        return new ColumnAdapter.Simple<>(targetType, (r, i) -> forceNumberCast(targetType, r, i));
+    }
+
+    private static <T extends Number> T forceNumberCast(final Class<T> targetType, ResultSet source, final Integer columnIndex) throws SQLException {
+        final Object value = source.getObject(columnIndex);
+        if (value == null) return null;
+        else if (value instanceof Number) return Numbers.cast((Number) value, targetType);
+        else throw new SQLException(String.format(
+                    "A Number was expected for column %d values. However, a %s was received",
+                    columnIndex, value.getClass().getCanonicalName()));
+    }
 }