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.
This commit is contained in:
Gavin 2023-05-21 16:27:06 +02:00 committed by Christian Beikov
parent 87f0dfc9d6
commit b0e84c58fd
1 changed files with 18 additions and 6 deletions

View File

@ -628,6 +628,10 @@ public class OracleDialect extends Dialect {
case REAL: case REAL:
// Oracle's 'real' type is actually double precision // Oracle's 'real' type is actually double precision
return "float(24)"; 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 NUMERIC:
case DECIMAL: case DECIMAL:
@ -723,12 +727,20 @@ public class OracleDialect extends Dialect {
} }
break; break;
case NUMERIC: case NUMERIC:
if ( scale == -127 ) { if ( precision > 8 // precision of 0 means something funny
// For some reason, the Oracle JDBC driver reports FLOAT // For some reason, the Oracle JDBC driver reports
// as NUMERIC with scale -127 // FLOAT or DOUBLE as NUMERIC with scale -127
return precision <= getFloatPrecision() // (but note that expressions with unknown type
? jdbcTypeRegistry.getDescriptor( FLOAT ) // also get reported this way, so take care)
: jdbcTypeRegistry.getDescriptor( DOUBLE ); && 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: //intentional fall-through:
case DECIMAL: case DECIMAL: