diff --git a/ci/build.sh b/ci/build.sh index 24e80d5cb739..5ecef0cb7612 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -58,10 +58,8 @@ elif [ "$RDBMS" == "oracle_db23c" ]; then export SERVICE=$(echo $INFO | jq -r '.database' | jq -r '.service') # I have no idea why, but these tests don't seem to work on CI... goal="-Pdb=oracle_cloud_db23c -DrunID=$RUNID -DdbHost=$HOST -DdbService=$SERVICE" -elif [ "$RDBMS" == "db2" ]; then +elif [ "$RDBMS" == "db2" ] || [ "$RDBMS" == "db2_11_5" ]; then goal="-Pdb=db2_ci" -elif [ "$RDBMS" == "db2_10_5" ]; then - goal="-Pdb=db2" elif [ "$RDBMS" == "mssql" ] || [ "$RDBMS" == "mssql_2017" ]; then goal="-Pdb=mssql_ci" # Exclude some Sybase tests on CI because they use `xmltable` function which has a memory leak on the DB version in CI diff --git a/docker_db.sh b/docker_db.sh index a409c0b864b7..3d5a530d16a3 100755 --- a/docker_db.sh +++ b/docker_db.sh @@ -290,7 +290,7 @@ edb_17() { } db2() { - db2_11_5 + db2_12_1 } db2_11_5() { @@ -306,26 +306,17 @@ db2_11_5() { $PRIVILEGED_CLI $CONTAINER_CLI exec -t db2 su - orm_test bash -c ". /database/config/orm_test/sqllib/db2profile; /database/config/orm_test/sqllib/bin/db2 'connect to orm_test'; /database/config/orm_test/sqllib/bin/db2 'CREATE USER TEMPORARY TABLESPACE usr_tbsp MANAGED BY AUTOMATIC STORAGE'" } -db2_10_5() { +db2_12_1() { $PRIVILEGED_CLI $CONTAINER_CLI rm -f db2 || true - # The sha represents the tag 10.5.0.5-3.10.0 - $PRIVILEGED_CLI $CONTAINER_CLI run --name db2 --privileged -e DB2INST1_PASSWORD=db2inst1-pwd -e LICENSE=accept -p 50000:50000 -d ${DB_IMAGE_DB2_10_5:-quay.io/hibernate/db2express-c@sha256:a499afd9709a1f69fb41703e88def9869955234c3525547e2efc3418d1f4ca2b} db2start + $PRIVILEGED_CLI $CONTAINER_CLI run --name db2 --privileged -e DB2INSTANCE=orm_test -e DB2INST1_PASSWORD=orm_test -e DBNAME=orm_test -e LICENSE=accept -e AUTOCONFIG=false -e ARCHIVE_LOGS=false -e TO_CREATE_SAMPLEDB=false -e REPODB=false -p 50000:50000 -d ${DB_IMAGE_DB2_11_5:-icr.io/db2_community/db2:12.1.2.0} # Give the container some time to start OUTPUT= - while [[ $OUTPUT != *"DB2START"* ]]; do + while [[ $OUTPUT != *"INSTANCE"* ]]; do echo "Waiting for DB2 to start..." sleep 10 OUTPUT=$($PRIVILEGED_CLI $CONTAINER_CLI logs db2 2>&1) done - $PRIVILEGED_CLI $CONTAINER_CLI exec -t db2 su - db2inst1 bash -c "/home/db2inst1/sqllib/bin/db2 create database orm_test && - /home/db2inst1/sqllib/bin/db2 'connect to orm_test' && - /home/db2inst1/sqllib/bin/db2 'CREATE BUFFERPOOL BP8K pagesize 8K' && - /home/db2inst1/sqllib/bin/db2 'CREATE SYSTEM TEMPORARY TABLESPACE STB_8 PAGESIZE 8K BUFFERPOOL BP8K' && - /home/db2inst1/sqllib/bin/db2 'CREATE BUFFERPOOL BP16K pagesize 16K' && - /home/db2inst1/sqllib/bin/db2 'CREATE SYSTEM TEMPORARY TABLESPACE STB_16 PAGESIZE 16K BUFFERPOOL BP16K' && - /home/db2inst1/sqllib/bin/db2 'CREATE BUFFERPOOL BP32K pagesize 32K' && - /home/db2inst1/sqllib/bin/db2 'CREATE SYSTEM TEMPORARY TABLESPACE STB_32 PAGESIZE 32K BUFFERPOOL BP32K' && - /home/db2inst1/sqllib/bin/db2 'CREATE USER TEMPORARY TABLESPACE usr_tbsp MANAGED BY AUTOMATIC STORAGE'" + $PRIVILEGED_CLI $CONTAINER_CLI exec -t db2 su - orm_test bash -c ". /database/config/orm_test/sqllib/db2profile; /database/config/orm_test/sqllib/bin/db2 'connect to orm_test'; /database/config/orm_test/sqllib/bin/db2 'CREATE USER TEMPORARY TABLESPACE usr_tbsp MANAGED BY AUTOMATIC STORAGE'" } db2_spatial() { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java index da0bea1227ff..e52db4d1f4fc 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java @@ -10,7 +10,6 @@ import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; import org.hibernate.community.dialect.sequence.LegacyDB2SequenceSupport; -import org.hibernate.dialect.DB2Dialect; import org.hibernate.dialect.DB2GetObjectExtractor; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.dialect.Dialect; @@ -484,6 +483,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio if ( supportsRecursiveCTE() ) { functionFactory.generateSeries_recursive( getMaximumSeriesSize(), false, true ); } + + functionFactory.hex( "hex(?1)" ); + if ( getDB2Version().isSameOrAfter( 11 ) ) { + functionFactory.sha( "hash(?1, 2)" ); + functionFactory.md5( "hash(?1, 0)" ); + } } /** @@ -522,7 +527,7 @@ public long getFractionalSecondPrecisionInNanos() { @Override public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) { if ( getDB2Version().isBefore( 11 ) ) { - return DB2Dialect.timestampdiffPatternV10( unit, fromTemporalType, toTemporalType ); + return timestampdiffPatternV10( unit, fromTemporalType, toTemporalType ); } final StringBuilder pattern = new StringBuilder(); final String fromExpression; @@ -558,7 +563,11 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT switch ( unit ) { case NATIVE: case NANOSECOND: - pattern.append( "(seconds_between(" ); + pattern.append( "(seconds_between(date_trunc('second'," ); + pattern.append( toExpression ); + pattern.append( "),date_trunc('second'," ); + pattern.append( fromExpression ); + pattern.append( "))" ); break; //note: DB2 does have weeks_between() case MONTH: @@ -566,14 +575,18 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT // the months_between() function results // in a non-integral value, so trunc() it pattern.append( "trunc(months_between(" ); + pattern.append( toExpression ); + pattern.append( ',' ); + pattern.append( fromExpression ); + pattern.append( ')' ); break; default: pattern.append( "?1s_between(" ); + pattern.append( toExpression ); + pattern.append( ',' ); + pattern.append( fromExpression ); + pattern.append( ')' ); } - pattern.append( toExpression ); - pattern.append( ',' ); - pattern.append( fromExpression ); - pattern.append( ')' ); switch ( unit ) { case NATIVE: pattern.append( "+(microsecond("); @@ -599,6 +612,97 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT return pattern.toString(); } + @SuppressWarnings("deprecation") + public static String timestampdiffPatternV10(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) { + final boolean isTime = fromTemporalType == TemporalType.TIME || toTemporalType == TemporalType.TIME; + final String fromExpression; + final String toExpression; + if ( unit.isDateUnit() ) { + if ( fromTemporalType == TemporalType.TIME ) { + fromExpression = "timestamp('1970-01-01',?2)"; + } + else { + fromExpression = "?2"; + } + if ( toTemporalType == TemporalType.TIME ) { + toExpression = "timestamp('1970-01-01',?3)"; + } + else { + toExpression = "?3"; + } + } + else { + if ( fromTemporalType == TemporalType.DATE ) { + fromExpression = "cast(?2 as timestamp)"; + } + else { + fromExpression = "?2"; + } + if ( toTemporalType == TemporalType.DATE ) { + toExpression = "cast(?3 as timestamp)"; + } + else { + toExpression = "?3"; + } + } + switch ( unit ) { + case NATIVE: + if ( isTime ) { + return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))"; + } + else { + return "(select (days(t2)-days(t1))*86400+(midnight_seconds(t2)-midnight_seconds(t1))+(microsecond(t2)-microsecond(t1))/1e6 " + + "from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))"; + } + case NANOSECOND: + if ( isTime ) { + return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))*1e9"; + } + else { + return "(select (days(t2)-days(t1))*86400+(midnight_seconds(t2)-midnight_seconds(t1))*1e9+(microsecond(t2)-microsecond(t1))*1e3 " + + "from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))"; + } + case SECOND: + if ( isTime ) { + return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))"; + } + else { + return "(select (days(t2)-days(t1))*86400+(midnight_seconds(t2)-midnight_seconds(t1)) " + + "from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))"; + } + case MINUTE: + if ( isTime ) { + return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))/60"; + } + else { + return "(select (days(t2)-days(t1))*1440+(midnight_seconds(t2)-midnight_seconds(t1))/60 from " + + "lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))"; + } + case HOUR: + if ( isTime ) { + return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))/3600"; + } + else { + return "(select (days(t2)-days(t1))*24+(midnight_seconds(t2)-midnight_seconds(t1))/3600 " + + "from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))"; + } + case YEAR: + return "(year(" + toExpression + ")-year(" + fromExpression + "))"; + // the months_between() function results + // in a non-integral value, so trunc() it + case MONTH: + return "trunc(months_between(" + toExpression + ',' + fromExpression + "))"; + case QUARTER: + return "trunc(months_between(" + toExpression + ',' + fromExpression + ")/3)"; + case WEEK: + return "int((days" + toExpression + ")-days(" + fromExpression + "))/7)"; + case DAY: + return "(days(" + toExpression + ")-days(" + fromExpression + "))"; + default: + throw new UnsupportedOperationException( "Unsupported unit: " + unit ); + } + } + @Override public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) { final StringBuilder pattern = new StringBuilder(); @@ -902,6 +1006,22 @@ public boolean supportsCommentOn() { return true; } + @Override + public String getAlterColumnTypeString(String columnName, String columnType, String columnDefinition) { + // would need multiple statements to 'set not null'/'drop not null', 'set default'/'drop default', 'set generated', etc + return "alter column " + columnName + " set data type " + columnType; + } + + @Override + public boolean supportsAlterColumnType() { + return getVersion().isSameOrAfter( 10, 5 ); + } + + @Override + public boolean supportsIfExistsBeforeTableName() { + return getVersion().isSameOrAfter( 11, 5 ); + } + @Override public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy( EntityMappingType rootEntityDescriptor, @@ -909,6 +1029,11 @@ public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy( return new CteMutationStrategy( rootEntityDescriptor, runtimeModelCreationContext ); } + @Override + public boolean supportsIsTrue() { + return getDB2Version().isSameOrAfter( 11 ); + } + @Override public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy( EntityMappingType rootEntityDescriptor, @@ -950,6 +1075,11 @@ public boolean supportsLobValueChangePropagation() { return false; } + @Override + public boolean useInputStreamToInsertBlob() { + return false; + } + @Override public boolean doesReadCommittedCauseWritersToBlockReaders() { return true; diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacySqlAstTranslator.java index 23403b587513..0b317ad48713 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacySqlAstTranslator.java @@ -40,15 +40,15 @@ protected boolean shouldEmulateFetchClause(QueryPart queryPart) { if ( useOffsetFetchClause( queryPart ) && !isRowsOnlyFetchClauseType( queryPart ) ) { return true; } - // According to LegacyDB2LimitHandler, variable limit also isn't supported before 7.10 - return version.isBefore(7, 10) + // According to LegacyDB2LimitHandler, variable limit also isn't supported before 7.1 + return version.isBefore(7, 1) && queryPart.getFetchClauseExpression() != null && !( queryPart.getFetchClauseExpression() instanceof Literal ); } @Override protected boolean supportsOffsetClause() { - return version.isSameOrAfter(7, 10); + return version.isSameOrAfter(7, 1); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java index 19bbe7af91d2..35b304630cb7 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java @@ -15,13 +15,11 @@ import org.hibernate.dialect.function.CommonFunctionFactory; import org.hibernate.dialect.function.CountFunction; import org.hibernate.dialect.function.DB2FormatEmulation; -import org.hibernate.dialect.function.DB2PositionFunction; import org.hibernate.dialect.function.DB2SubstringFunction; import org.hibernate.dialect.function.TrimFunction; import org.hibernate.dialect.identity.DB2IdentityColumnSupport; import org.hibernate.dialect.identity.IdentityColumnSupport; import org.hibernate.dialect.pagination.DB2LimitHandler; -import org.hibernate.dialect.pagination.LegacyDB2LimitHandler; import org.hibernate.dialect.pagination.LimitHandler; import org.hibernate.dialect.sequence.DB2SequenceSupport; import org.hibernate.dialect.sequence.SequenceSupport; @@ -86,8 +84,6 @@ import org.hibernate.type.descriptor.jdbc.ObjectNullResolvingJdbcType; import org.hibernate.type.descriptor.jdbc.OffsetDateTimeJdbcType; import org.hibernate.type.descriptor.jdbc.OffsetTimeJdbcType; -import org.hibernate.type.descriptor.jdbc.SmallIntJdbcType; -import org.hibernate.type.descriptor.jdbc.VarbinaryJdbcType; import org.hibernate.type.descriptor.jdbc.XmlJdbcType; import org.hibernate.type.descriptor.jdbc.ZonedDateTimeJdbcType; import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry; @@ -118,7 +114,6 @@ import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode; import static org.hibernate.type.SqlTypes.BINARY; import static org.hibernate.type.SqlTypes.BLOB; -import static org.hibernate.type.SqlTypes.BOOLEAN; import static org.hibernate.type.SqlTypes.CLOB; import static org.hibernate.type.SqlTypes.DECIMAL; import static org.hibernate.type.SqlTypes.NUMERIC; @@ -135,7 +130,7 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithNanos; /** - * A {@linkplain Dialect SQL dialect} for Db2 for LUW (Linux, Unix, and Windows) version 10.5 and above. + * A {@linkplain Dialect SQL dialect} for Db2 for LUW (Linux, Unix, and Windows) version 11.1 and above. *
* Please refer to the
* Db2 documentation.
@@ -147,7 +142,7 @@
*/
public class DB2Dialect extends Dialect {
- final static DatabaseVersion MINIMUM_VERSION = DatabaseVersion.make( 10, 5 );
+ final static DatabaseVersion MINIMUM_VERSION = DatabaseVersion.make( 11, 1 );
private static final int BIND_PARAMETERS_NUMBER_LIMIT = 32_767;
private static final String FOR_READ_ONLY_SQL = " for read only with rs";
@@ -157,10 +152,7 @@ public class DB2Dialect extends Dialect {
private static final String FOR_SHARE_SKIP_LOCKED_SQL = FOR_SHARE_SQL + SKIP_LOCKED_SQL;
private static final String FOR_UPDATE_SKIP_LOCKED_SQL = FOR_UPDATE_SQL + SKIP_LOCKED_SQL;
- private final LimitHandler limitHandler =
- getDB2Version().isBefore( 11, 1 )
- ? LegacyDB2LimitHandler.INSTANCE
- : DB2LimitHandler.INSTANCE;
+ private final LimitHandler limitHandler = DB2LimitHandler.INSTANCE;
private final UniqueDelegate uniqueDelegate = createUniqueDelegate();
private final StandardTableExporter db2TableExporter = new StandardTableExporter( this ) {
@Override
@@ -210,13 +202,6 @@ public int getDefaultStatementBatchSize() {
@Override
protected String columnType(int sqlTypeCode) {
return switch (sqlTypeCode) {
- case BOOLEAN ->
- // prior to DB2 11, the 'boolean' type existed,
- // but was not allowed as a column type
- getDB2Version().isBefore( 11 )
- ? "smallint"
- : super.columnType( sqlTypeCode );
-
case TINYINT -> "smallint"; // no tinyint
// HHH-12827: map them both to the same type to avoid problems with schema update
@@ -229,17 +214,6 @@ protected String columnType(int sqlTypeCode) {
case TIMESTAMP_WITH_TIMEZONE -> "timestamp($p)";
case TIME, TIME_WITH_TIMEZONE -> "time";
- case BINARY ->
- // should use 'binary' since version 11
- getDB2Version().isBefore( 11 )
- ? "char($l) for bit data"
- : super.columnType( sqlTypeCode );
- case VARBINARY ->
- // should use 'varbinary' since version 11
- getDB2Version().isBefore( 11 )
- ? "varchar($l) for bit data"
- : super.columnType( sqlTypeCode );
-
default -> super.columnType( sqlTypeCode );
};
}
@@ -285,14 +259,9 @@ public boolean supportsUserDefinedTypes() {
return true;
}
- @Override
- protected boolean supportsPredicateAsExpression() {
- return getDB2Version().isSameOrAfter( 11 );
- }
-
@Override
public boolean supportsDistinctFromPredicate() {
- return getDB2Version().isSameOrAfter( 11, 1 );
+ return true;
}
@Override
@@ -351,33 +320,15 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
functionFactory.regrLinearRegressionAggregates();
functionFactory.variance();
functionFactory.hypotheticalOrderedSetAggregates_windowEmulation();
- if ( getDB2Version().isSameOrAfter( 11 ) ) {
- functionFactory.position();
- functionFactory.overlayLength_overlay( false );
- functionFactory.median();
- functionFactory.inverseDistributionOrderedSetAggregates();
- functionFactory.stddevPopSamp();
- functionFactory.varPopSamp();
- functionFactory.varianceSamp();
- functionFactory.dateTrunc();
- functionFactory.trunc_dateTrunc();
- }
- else {
- // Before version 11, the position function required the use of the code units
- functionContributions.getFunctionRegistry().register(
- "position",
- new DB2PositionFunction( functionContributions.getTypeConfiguration() )
- );
- // Before version 11, the overlay function required the use of the code units
- functionFactory.overlayLength_overlay( true );
- // ordered set aggregate functions are only available as of version 11, and we can't reasonably emulate them
- // so no percent_rank, cume_dist, median, mode, percentile_cont or percentile_disc
- functionContributions.getFunctionRegistry().registerAlternateKey( "stddev_pop", "stddev" );
- functionFactory.stddevSamp_sumCount();
- functionContributions.getFunctionRegistry().registerAlternateKey( "var_pop", "variance" );
- functionFactory.varSamp_sumCount();
- functionFactory.trunc_dateTrunc_trunc();
- }
+ functionFactory.position();
+ functionFactory.overlayLength_overlay( false );
+ functionFactory.median();
+ functionFactory.inverseDistributionOrderedSetAggregates();
+ functionFactory.stddevPopSamp();
+ functionFactory.varPopSamp();
+ functionFactory.varianceSamp();
+ functionFactory.dateTrunc();
+ functionFactory.trunc_dateTrunc();
functionFactory.addYearsMonthsDaysHoursMinutesSeconds();
functionFactory.yearsMonthsDaysHoursMinutesSecondsBetween();
@@ -446,30 +397,22 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
functionFactory.windowFunctions();
functionFactory.listagg( null );
- if ( getDB2Version().isSameOrAfter( 11 ) ) {
- functionFactory.jsonValue_db2();
- functionFactory.jsonQuery_no_passing();
- functionFactory.jsonExists_no_passing();
- functionFactory.jsonObject_db2();
- functionFactory.jsonArray_db2();
- functionFactory.jsonArrayAgg_db2();
- functionFactory.jsonObjectAgg_db2();
- functionFactory.jsonTable_db2( getMaximumSeriesSize() );
- }
+ functionFactory.jsonValue_db2();
+ functionFactory.jsonQuery_no_passing();
+ functionFactory.jsonExists_no_passing();
+ functionFactory.jsonObject_db2();
+ functionFactory.jsonArray_db2();
+ functionFactory.jsonArrayAgg_db2();
+ functionFactory.jsonObjectAgg_db2();
+ functionFactory.jsonTable_db2( getMaximumSeriesSize() );
functionFactory.xmlelement();
functionFactory.xmlcomment();
functionFactory.xmlforest();
functionFactory.xmlconcat();
functionFactory.xmlpi();
- if ( getDB2Version().isSameOrAfter( 11 ) ) {
- functionFactory.xmlquery_db2();
- functionFactory.xmlexists();
- }
- else {
- functionFactory.xmlquery_db2_legacy();
- functionFactory.xmlexists_db2_legacy();
- }
+ functionFactory.xmlquery_db2();
+ functionFactory.xmlexists();
functionFactory.xmlagg();
functionFactory.xmltable_db2();
@@ -477,10 +420,8 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
functionFactory.generateSeries_recursive( getMaximumSeriesSize(), false, true );
functionFactory.hex( "hex(?1)" );
- if ( getDB2Version().isSameOrAfter( 11 ) ) {
- functionFactory.sha( "hash(?1, 2)" );
- functionFactory.md5( "hash(?1, 0)" );
- }
+ functionFactory.sha( "hash(?1, 2)" );
+ functionFactory.md5( "hash(?1, 0)" );
}
/**
@@ -518,9 +459,6 @@ public long getFractionalSecondPrecisionInNanos() {
@Override @SuppressWarnings("deprecation")
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
- if ( getDB2Version().isBefore( 11 ) ) {
- return timestampdiffPatternV10( unit, fromTemporalType, toTemporalType );
- }
final StringBuilder pattern = new StringBuilder();
final String fromExpression;
final String toExpression;
@@ -592,97 +530,6 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT
return pattern.toString();
}
- @SuppressWarnings("deprecation")
- public static String timestampdiffPatternV10(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
- final boolean isTime = fromTemporalType == TemporalType.TIME || toTemporalType == TemporalType.TIME;
- final String fromExpression;
- final String toExpression;
- if ( unit.isDateUnit() ) {
- if ( fromTemporalType == TemporalType.TIME ) {
- fromExpression = "timestamp('1970-01-01',?2)";
- }
- else {
- fromExpression = "?2";
- }
- if ( toTemporalType == TemporalType.TIME ) {
- toExpression = "timestamp('1970-01-01',?3)";
- }
- else {
- toExpression = "?3";
- }
- }
- else {
- if ( fromTemporalType == TemporalType.DATE ) {
- fromExpression = "cast(?2 as timestamp)";
- }
- else {
- fromExpression = "?2";
- }
- if ( toTemporalType == TemporalType.DATE ) {
- toExpression = "cast(?3 as timestamp)";
- }
- else {
- toExpression = "?3";
- }
- }
- switch ( unit ) {
- case NATIVE:
- if ( isTime ) {
- return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))";
- }
- else {
- return "(select (days(t2)-days(t1))*86400+(midnight_seconds(t2)-midnight_seconds(t1))+(microsecond(t2)-microsecond(t1))/1e6 " +
- "from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
- }
- case NANOSECOND:
- if ( isTime ) {
- return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))*1e9";
- }
- else {
- return "(select (days(t2)-days(t1))*86400+(midnight_seconds(t2)-midnight_seconds(t1))*1e9+(microsecond(t2)-microsecond(t1))*1e3 " +
- "from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
- }
- case SECOND:
- if ( isTime ) {
- return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))";
- }
- else {
- return "(select (days(t2)-days(t1))*86400+(midnight_seconds(t2)-midnight_seconds(t1)) " +
- "from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
- }
- case MINUTE:
- if ( isTime ) {
- return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))/60";
- }
- else {
- return "(select (days(t2)-days(t1))*1440+(midnight_seconds(t2)-midnight_seconds(t1))/60 from " +
- "lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
- }
- case HOUR:
- if ( isTime ) {
- return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))/3600";
- }
- else {
- return "(select (days(t2)-days(t1))*24+(midnight_seconds(t2)-midnight_seconds(t1))/3600 " +
- "from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
- }
- case YEAR:
- return "(year(" + toExpression + ")-year(" + fromExpression + "))";
- // the months_between() function results
- // in a non-integral value, so trunc() it
- case MONTH:
- return "trunc(months_between(" + toExpression + ',' + fromExpression + "))";
- case QUARTER:
- return "trunc(months_between(" + toExpression + ',' + fromExpression + ")/3)";
- case WEEK:
- return "int((days" + toExpression + ")-days(" + fromExpression + "))/7)";
- case DAY:
- return "(days(" + toExpression + ")-days(" + fromExpression + "))";
- default:
- throw new UnsupportedOperationException( "Unsupported unit: " + unit );
- }
- }
-
@Override @SuppressWarnings("deprecation")
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
final StringBuilder pattern = new StringBuilder();
@@ -847,7 +694,7 @@ public String getForUpdateString() {
@Override
public boolean supportsSkipLocked() {
- // Introduced in 11.5: https://www.ibm.com/docs/en/db2/11.5?topic=statement-concurrent-access-resolution-clause
+ // Introduced in 11.5.4: https://www.ibm.com/docs/en/db2/11.5?topic=statement-concurrent-access-resolution-clause
return getDB2Version().isSameOrAfter( 11, 5 );
}
@@ -1004,7 +851,7 @@ public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(
@Override
public boolean supportsIsTrue() {
- return getDB2Version().isSameOrAfter( 11 );
+ return true;
}
@Override
@@ -1062,12 +909,6 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration().getJdbcTypeRegistry();
- if ( getDB2Version().isBefore( 11 ) ) {
- jdbcTypeRegistry.addDescriptor( Types.BOOLEAN, SmallIntJdbcType.INSTANCE );
- // Binary literals were only added in 11. See https://www.ibm.com/support/knowledgecenter/SSEPGG_11.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000731.html#d79816e393
- jdbcTypeRegistry.addDescriptor( Types.VARBINARY, VarbinaryJdbcType.INSTANCE_WITHOUT_LITERALS );
- }
-
jdbcTypeRegistry.addDescriptor( XmlJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptor( DB2StructJdbcType.INSTANCE );
@@ -1130,9 +971,7 @@ public