|
105 | 105 | import org.hibernate.type.descriptor.jdbc.NullJdbcType;
|
106 | 106 | import org.hibernate.type.descriptor.jdbc.ObjectNullAsNullTypeJdbcType;
|
107 | 107 | import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
| 108 | +import org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl; |
108 | 109 | import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
109 | 110 | import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
|
110 | 111 | import org.hibernate.type.spi.TypeConfiguration;
|
111 | 112 |
|
112 | 113 | import jakarta.persistence.TemporalType;
|
113 | 114 |
|
| 115 | +import static java.util.regex.Pattern.CASE_INSENSITIVE; |
114 | 116 | import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
|
115 | 117 | import static org.hibernate.query.sqm.TemporalUnit.DAY;
|
116 | 118 | import static org.hibernate.query.sqm.TemporalUnit.HOUR;
|
|
124 | 126 | import static org.hibernate.type.SqlTypes.BOOLEAN;
|
125 | 127 | import static org.hibernate.type.SqlTypes.DATE;
|
126 | 128 | import static org.hibernate.type.SqlTypes.DECIMAL;
|
| 129 | +import static org.hibernate.type.SqlTypes.DOUBLE; |
| 130 | +import static org.hibernate.type.SqlTypes.FLOAT; |
127 | 131 | import static org.hibernate.type.SqlTypes.GEOMETRY;
|
128 | 132 | import static org.hibernate.type.SqlTypes.INTEGER;
|
129 | 133 | import static org.hibernate.type.SqlTypes.JSON;
|
|
133 | 137 | import static org.hibernate.type.SqlTypes.SMALLINT;
|
134 | 138 | import static org.hibernate.type.SqlTypes.SQLXML;
|
135 | 139 | import static org.hibernate.type.SqlTypes.STRUCT;
|
| 140 | +import static org.hibernate.type.SqlTypes.TABLE; |
136 | 141 | import static org.hibernate.type.SqlTypes.TIME;
|
137 | 142 | import static org.hibernate.type.SqlTypes.TIMESTAMP;
|
138 | 143 | import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
|
|
150 | 155 | */
|
151 | 156 | public class OracleLegacyDialect extends Dialect {
|
152 | 157 |
|
153 |
| - private static final Pattern DISTINCT_KEYWORD_PATTERN = Pattern.compile( "\\bdistinct\\b" ); |
154 |
| - private static final Pattern GROUP_BY_KEYWORD_PATTERN = Pattern.compile( "\\bgroup\\sby\\b" ); |
155 |
| - private static final Pattern ORDER_BY_KEYWORD_PATTERN = Pattern.compile( "\\border\\sby\\b" ); |
156 |
| - private static final Pattern UNION_KEYWORD_PATTERN = Pattern.compile( "\\bunion\\b" ); |
157 |
| - private static final Pattern SQL_STATEMENT_TYPE_PATTERN = Pattern.compile("^(?:/\\*.*?\\*/)?\\s*(select|insert|update|delete)\\s+.*?", Pattern.CASE_INSENSITIVE); |
| 158 | + private static final Pattern DISTINCT_KEYWORD_PATTERN = Pattern.compile( "\\bdistinct\\b", CASE_INSENSITIVE ); |
| 159 | + private static final Pattern GROUP_BY_KEYWORD_PATTERN = Pattern.compile( "\\bgroup\\s+by\\b", CASE_INSENSITIVE ); |
| 160 | + private static final Pattern ORDER_BY_KEYWORD_PATTERN = Pattern.compile( "\\border\\s+by\\b", CASE_INSENSITIVE ); |
| 161 | + private static final Pattern UNION_KEYWORD_PATTERN = Pattern.compile( "\\bunion\\b", CASE_INSENSITIVE ); |
| 162 | + |
| 163 | + private static final Pattern SQL_STATEMENT_TYPE_PATTERN = |
| 164 | + Pattern.compile( "^(?:/\\*.*?\\*/)?\\s*(select|insert|update|delete)\\s+.*?", CASE_INSENSITIVE ); |
| 165 | + |
158 | 166 | private static final int PARAM_LIST_SIZE_LIMIT = 1000;
|
159 | 167 |
|
160 | 168 | public static final String PREFER_LONG_RAW = "hibernate.dialect.oracle.prefer_long_raw";
|
161 | 169 |
|
162 | 170 | private static final String yqmSelect =
|
163 |
| - "( TRUNC(%2$s, 'MONTH') + NUMTOYMINTERVAL(%1$s, 'MONTH') + ( LEAST( EXTRACT( DAY FROM %2$s ), EXTRACT( DAY FROM LAST_DAY( TRUNC(%2$s, 'MONTH') + NUMTOYMINTERVAL(%1$s, 'MONTH') ) ) ) - 1 ) )"; |
| 171 | + "(trunc(%2$s, 'MONTH') + numtoyminterval(%1$s, 'MONTH') + (least(extract(day from %2$s), extract(day from last_day(trunc(%2$s, 'MONTH') + numtoyminterval(%1$s, 'MONTH')))) - 1))"; |
164 | 172 |
|
165 | 173 | private static final String ADD_YEAR_EXPRESSION = String.format( yqmSelect, "?2*12", "?3" );
|
166 | 174 | private static final String ADD_QUARTER_EXPRESSION = String.format( yqmSelect, "?2*3", "?3" );
|
@@ -220,6 +228,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
|
220 | 228 | functionFactory.addMonths();
|
221 | 229 | functionFactory.monthsBetween();
|
222 | 230 | functionFactory.everyAny_minMaxCase();
|
| 231 | + functionFactory.repeat_rpad(); |
223 | 232 |
|
224 | 233 | functionFactory.radians_acos();
|
225 | 234 | functionFactory.degrees_acos();
|
@@ -273,6 +282,9 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
|
273 | 282 | new OracleTruncFunction( functionContributions.getTypeConfiguration() )
|
274 | 283 | );
|
275 | 284 | functionContributions.getFunctionRegistry().registerAlternateKey( "truncate", "trunc" );
|
| 285 | + |
| 286 | + functionFactory.array_oracle(); |
| 287 | + functionFactory.arrayAggregate_jsonArrayagg(); |
276 | 288 | }
|
277 | 289 |
|
278 | 290 | @Override
|
@@ -625,6 +637,10 @@ protected String columnType(int sqlTypeCode) {
|
625 | 637 | case REAL:
|
626 | 638 | // Oracle's 'real' type is actually double precision
|
627 | 639 | return "float(24)";
|
| 640 | + case DOUBLE: |
| 641 | + // Oracle's 'double precision' means float(126), and |
| 642 | + // we never need 126 bits (38 decimal digits) |
| 643 | + return "float(53)"; |
628 | 644 |
|
629 | 645 | case NUMERIC:
|
630 | 646 | case DECIMAL:
|
@@ -670,6 +686,9 @@ else if ( getVersion().isSameOrAfter( 12 ) ) {
|
670 | 686 | ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "blob", this ) );
|
671 | 687 | }
|
672 | 688 | }
|
| 689 | + |
| 690 | + ddlTypeRegistry.addDescriptor( new ArrayDdlTypeImpl( this, false ) ); |
| 691 | + ddlTypeRegistry.addDescriptor( TABLE, new ArrayDdlTypeImpl( this, false ) ); |
673 | 692 | }
|
674 | 693 |
|
675 | 694 | @Override
|
@@ -736,13 +755,20 @@ public JdbcType resolveSqlTypeDescriptor(
|
736 | 755 | }
|
737 | 756 | break;
|
738 | 757 | case Types.NUMERIC:
|
739 |
| - if ( scale == -127 ) { |
740 |
| - // For some reason, the Oracle JDBC driver reports FLOAT |
741 |
| - // as NUMERIC with scale -127 |
742 |
| - if ( precision <= getFloatPrecision() ) { |
743 |
| - return jdbcTypeRegistry.getDescriptor( Types.FLOAT ); |
| 758 | + if ( precision > 8 // precision of 0 means something funny |
| 759 | + // For some reason, the Oracle JDBC driver reports |
| 760 | + // FLOAT or DOUBLE as NUMERIC with scale -127 |
| 761 | + // (but note that expressions with unknown type |
| 762 | + // also get reported this way, so take care) |
| 763 | + && scale == -127 ) { |
| 764 | + if ( precision <= 24 ) { |
| 765 | + // Can be represented as a Java float |
| 766 | + return jdbcTypeRegistry.getDescriptor( FLOAT ); |
| 767 | + } |
| 768 | + else if ( precision <= 53 ) { |
| 769 | + // Can be represented as a Java double |
| 770 | + return jdbcTypeRegistry.getDescriptor( DOUBLE ); |
744 | 771 | }
|
745 |
| - return jdbcTypeRegistry.getDescriptor( Types.DOUBLE ); |
746 | 772 | }
|
747 | 773 | //intentional fall-through:
|
748 | 774 | case Types.DECIMAL:
|
@@ -825,6 +851,7 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
|
825 | 851 |
|
826 | 852 | if ( OracleJdbcHelper.isUsable( serviceRegistry ) ) {
|
827 | 853 | typeContributions.contributeJdbcTypeConstructor( OracleJdbcHelper.getArrayJdbcTypeConstructor( serviceRegistry ) );
|
| 854 | + typeContributions.contributeJdbcTypeConstructor( OracleJdbcHelper.getNestedTableJdbcTypeConstructor( serviceRegistry ) ); |
828 | 855 | }
|
829 | 856 | else {
|
830 | 857 | typeContributions.contributeJdbcType( OracleReflectionStructJdbcType.INSTANCE );
|
|
0 commit comments