From eded6e8ff98e533fc43d0823262429f43f2dd62a Mon Sep 17 00:00:00 2001 From: Gavin Date: Sun, 21 May 2023 16:27:06 +0200 Subject: [PATCH] HHH-16650 fix for native queries with "unknown" numeric types on Oracle Oracle reports FLOAT/DOUBLE PRECISION as NUMBER, which is wrong. The workaround was to look at the scale, which it reports as -127 for FLOAT. But certain other expression also get scale -127, and this could cause truncation of least-significant digits when we read them into a Java Double. --- .../org/hibernate/dialect/OracleDialect.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java index 670672799a..682337841d 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java @@ -647,6 +647,10 @@ public class OracleDialect extends Dialect { case REAL: // Oracle's 'real' type is actually double precision return "float(24)"; + case DOUBLE: + // Oracle's 'double precision' means float(126), and + // we never need 126 bits (38 decimal digits) + return "float(53)"; case NUMERIC: case DECIMAL: @@ -745,12 +749,20 @@ public class OracleDialect extends Dialect { } break; case NUMERIC: - if ( scale == -127 ) { - // For some reason, the Oracle JDBC driver reports FLOAT - // as NUMERIC with scale -127 - return precision <= getFloatPrecision() - ? jdbcTypeRegistry.getDescriptor( FLOAT ) - : jdbcTypeRegistry.getDescriptor( DOUBLE ); + if ( precision > 8 // precision of 0 means something funny + // For some reason, the Oracle JDBC driver reports + // FLOAT or DOUBLE as NUMERIC with scale -127 + // (but note that expressions with unknown type + // also get reported this way, so take care) + && scale == -127 ) { + if ( precision <= 24 ) { + // Can be represented as a Java float + return jdbcTypeRegistry.getDescriptor( FLOAT ); + } + else if ( precision <= 53 ) { + // Can be represented as a Java double + return jdbcTypeRegistry.getDescriptor( DOUBLE ); + } } //intentional fall-through: case DECIMAL: