Skip to content

Commit e769668

Browse files
committed
HHH-18639 Remove support for DB2 versions older than 11.1 and start testing with DB2 12.1
1 parent a5319ed commit e769668

File tree

10 files changed

+191
-289
lines changed

10 files changed

+191
-289
lines changed

ci/build.sh

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,8 @@ elif [ "$RDBMS" == "oracle_db23c" ]; then
5858
export SERVICE=$(echo $INFO | jq -r '.database' | jq -r '.service')
5959
# I have no idea why, but these tests don't seem to work on CI...
6060
goal="-Pdb=oracle_cloud_db23c -DrunID=$RUNID -DdbHost=$HOST -DdbService=$SERVICE"
61-
elif [ "$RDBMS" == "db2" ]; then
61+
elif [ "$RDBMS" == "db2" ] || [ "$RDBMS" == "db2_11_5" ]; then
6262
goal="-Pdb=db2_ci"
63-
elif [ "$RDBMS" == "db2_10_5" ]; then
64-
goal="-Pdb=db2"
6563
elif [ "$RDBMS" == "mssql" ] || [ "$RDBMS" == "mssql_2017" ]; then
6664
goal="-Pdb=mssql_ci"
6765
# Exclude some Sybase tests on CI because they use `xmltable` function which has a memory leak on the DB version in CI

docker_db.sh

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ edb_17() {
290290
}
291291

292292
db2() {
293-
db2_11_5
293+
db2_12_1
294294
}
295295

296296
db2_11_5() {
@@ -306,26 +306,17 @@ db2_11_5() {
306306
$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'"
307307
}
308308

309-
db2_10_5() {
309+
db2_12_1() {
310310
$PRIVILEGED_CLI $CONTAINER_CLI rm -f db2 || true
311-
# The sha represents the tag 10.5.0.5-3.10.0
312-
$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
311+
$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}
313312
# Give the container some time to start
314313
OUTPUT=
315-
while [[ $OUTPUT != *"DB2START"* ]]; do
314+
while [[ $OUTPUT != *"INSTANCE"* ]]; do
316315
echo "Waiting for DB2 to start..."
317316
sleep 10
318317
OUTPUT=$($PRIVILEGED_CLI $CONTAINER_CLI logs db2 2>&1)
319318
done
320-
$PRIVILEGED_CLI $CONTAINER_CLI exec -t db2 su - db2inst1 bash -c "/home/db2inst1/sqllib/bin/db2 create database orm_test &&
321-
/home/db2inst1/sqllib/bin/db2 'connect to orm_test' &&
322-
/home/db2inst1/sqllib/bin/db2 'CREATE BUFFERPOOL BP8K pagesize 8K' &&
323-
/home/db2inst1/sqllib/bin/db2 'CREATE SYSTEM TEMPORARY TABLESPACE STB_8 PAGESIZE 8K BUFFERPOOL BP8K' &&
324-
/home/db2inst1/sqllib/bin/db2 'CREATE BUFFERPOOL BP16K pagesize 16K' &&
325-
/home/db2inst1/sqllib/bin/db2 'CREATE SYSTEM TEMPORARY TABLESPACE STB_16 PAGESIZE 16K BUFFERPOOL BP16K' &&
326-
/home/db2inst1/sqllib/bin/db2 'CREATE BUFFERPOOL BP32K pagesize 32K' &&
327-
/home/db2inst1/sqllib/bin/db2 'CREATE SYSTEM TEMPORARY TABLESPACE STB_32 PAGESIZE 32K BUFFERPOOL BP32K' &&
328-
/home/db2inst1/sqllib/bin/db2 'CREATE USER TEMPORARY TABLESPACE usr_tbsp MANAGED BY AUTOMATIC STORAGE'"
319+
$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'"
329320
}
330321

331322
db2_spatial() {

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java

Lines changed: 137 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import org.hibernate.boot.model.FunctionContributions;
1111
import org.hibernate.boot.model.TypeContributions;
1212
import org.hibernate.community.dialect.sequence.LegacyDB2SequenceSupport;
13-
import org.hibernate.dialect.DB2Dialect;
1413
import org.hibernate.dialect.DB2GetObjectExtractor;
1514
import org.hibernate.dialect.DatabaseVersion;
1615
import org.hibernate.dialect.Dialect;
@@ -484,6 +483,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
484483
if ( supportsRecursiveCTE() ) {
485484
functionFactory.generateSeries_recursive( getMaximumSeriesSize(), false, true );
486485
}
486+
487+
functionFactory.hex( "hex(?1)" );
488+
if ( getDB2Version().isSameOrAfter( 11 ) ) {
489+
functionFactory.sha( "hash(?1, 2)" );
490+
functionFactory.md5( "hash(?1, 0)" );
491+
}
487492
}
488493

489494
/**
@@ -522,7 +527,7 @@ public long getFractionalSecondPrecisionInNanos() {
522527
@Override
523528
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
524529
if ( getDB2Version().isBefore( 11 ) ) {
525-
return DB2Dialect.timestampdiffPatternV10( unit, fromTemporalType, toTemporalType );
530+
return timestampdiffPatternV10( unit, fromTemporalType, toTemporalType );
526531
}
527532
final StringBuilder pattern = new StringBuilder();
528533
final String fromExpression;
@@ -558,22 +563,30 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT
558563
switch ( unit ) {
559564
case NATIVE:
560565
case NANOSECOND:
561-
pattern.append( "(seconds_between(" );
566+
pattern.append( "(seconds_between(date_trunc('second'," );
567+
pattern.append( toExpression );
568+
pattern.append( "),date_trunc('second'," );
569+
pattern.append( fromExpression );
570+
pattern.append( "))" );
562571
break;
563572
//note: DB2 does have weeks_between()
564573
case MONTH:
565574
case QUARTER:
566575
// the months_between() function results
567576
// in a non-integral value, so trunc() it
568577
pattern.append( "trunc(months_between(" );
578+
pattern.append( toExpression );
579+
pattern.append( ',' );
580+
pattern.append( fromExpression );
581+
pattern.append( ')' );
569582
break;
570583
default:
571584
pattern.append( "?1s_between(" );
585+
pattern.append( toExpression );
586+
pattern.append( ',' );
587+
pattern.append( fromExpression );
588+
pattern.append( ')' );
572589
}
573-
pattern.append( toExpression );
574-
pattern.append( ',' );
575-
pattern.append( fromExpression );
576-
pattern.append( ')' );
577590
switch ( unit ) {
578591
case NATIVE:
579592
pattern.append( "+(microsecond(");
@@ -599,6 +612,97 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT
599612
return pattern.toString();
600613
}
601614

615+
@SuppressWarnings("deprecation")
616+
public static String timestampdiffPatternV10(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
617+
final boolean isTime = fromTemporalType == TemporalType.TIME || toTemporalType == TemporalType.TIME;
618+
final String fromExpression;
619+
final String toExpression;
620+
if ( unit.isDateUnit() ) {
621+
if ( fromTemporalType == TemporalType.TIME ) {
622+
fromExpression = "timestamp('1970-01-01',?2)";
623+
}
624+
else {
625+
fromExpression = "?2";
626+
}
627+
if ( toTemporalType == TemporalType.TIME ) {
628+
toExpression = "timestamp('1970-01-01',?3)";
629+
}
630+
else {
631+
toExpression = "?3";
632+
}
633+
}
634+
else {
635+
if ( fromTemporalType == TemporalType.DATE ) {
636+
fromExpression = "cast(?2 as timestamp)";
637+
}
638+
else {
639+
fromExpression = "?2";
640+
}
641+
if ( toTemporalType == TemporalType.DATE ) {
642+
toExpression = "cast(?3 as timestamp)";
643+
}
644+
else {
645+
toExpression = "?3";
646+
}
647+
}
648+
switch ( unit ) {
649+
case NATIVE:
650+
if ( isTime ) {
651+
return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))";
652+
}
653+
else {
654+
return "(select (days(t2)-days(t1))*86400+(midnight_seconds(t2)-midnight_seconds(t1))+(microsecond(t2)-microsecond(t1))/1e6 " +
655+
"from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
656+
}
657+
case NANOSECOND:
658+
if ( isTime ) {
659+
return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))*1e9";
660+
}
661+
else {
662+
return "(select (days(t2)-days(t1))*86400+(midnight_seconds(t2)-midnight_seconds(t1))*1e9+(microsecond(t2)-microsecond(t1))*1e3 " +
663+
"from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
664+
}
665+
case SECOND:
666+
if ( isTime ) {
667+
return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))";
668+
}
669+
else {
670+
return "(select (days(t2)-days(t1))*86400+(midnight_seconds(t2)-midnight_seconds(t1)) " +
671+
"from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
672+
}
673+
case MINUTE:
674+
if ( isTime ) {
675+
return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))/60";
676+
}
677+
else {
678+
return "(select (days(t2)-days(t1))*1440+(midnight_seconds(t2)-midnight_seconds(t1))/60 from " +
679+
"lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
680+
}
681+
case HOUR:
682+
if ( isTime ) {
683+
return "(midnight_seconds(" + toExpression + ")-midnight_seconds(" + fromExpression + "))/3600";
684+
}
685+
else {
686+
return "(select (days(t2)-days(t1))*24+(midnight_seconds(t2)-midnight_seconds(t1))/3600 " +
687+
"from lateral(values(" + fromExpression + ',' + toExpression + ")) as temp(t1,t2))";
688+
}
689+
case YEAR:
690+
return "(year(" + toExpression + ")-year(" + fromExpression + "))";
691+
// the months_between() function results
692+
// in a non-integral value, so trunc() it
693+
case MONTH:
694+
return "trunc(months_between(" + toExpression + ',' + fromExpression + "))";
695+
case QUARTER:
696+
return "trunc(months_between(" + toExpression + ',' + fromExpression + ")/3)";
697+
case WEEK:
698+
return "int((days" + toExpression + ")-days(" + fromExpression + "))/7)";
699+
case DAY:
700+
return "(days(" + toExpression + ")-days(" + fromExpression + "))";
701+
default:
702+
throw new UnsupportedOperationException( "Unsupported unit: " + unit );
703+
}
704+
}
705+
602706
@Override
603707
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType, IntervalType intervalType) {
604708
final StringBuilder pattern = new StringBuilder();
@@ -902,13 +1006,34 @@ public boolean supportsCommentOn() {
9021006
return true;
9031007
}
9041008

1009+
@Override
1010+
public String getAlterColumnTypeString(String columnName, String columnType, String columnDefinition) {
1011+
// would need multiple statements to 'set not null'/'drop not null', 'set default'/'drop default', 'set generated', etc
1012+
return "alter column " + columnName + " set data type " + columnType;
1013+
}
1014+
1015+
@Override
1016+
public boolean supportsAlterColumnType() {
1017+
return getVersion().isSameOrAfter( 10, 5 );
1018+
}
1019+
1020+
@Override
1021+
public boolean supportsIfExistsBeforeTableName() {
1022+
return getVersion().isSameOrAfter( 11, 5 );
1023+
}
1024+
9051025
@Override
9061026
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
9071027
EntityMappingType rootEntityDescriptor,
9081028
RuntimeModelCreationContext runtimeModelCreationContext) {
9091029
return new CteMutationStrategy( rootEntityDescriptor, runtimeModelCreationContext );
9101030
}
9111031

1032+
@Override
1033+
public boolean supportsIsTrue() {
1034+
return getDB2Version().isSameOrAfter( 11 );
1035+
}
1036+
9121037
@Override
9131038
public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(
9141039
EntityMappingType rootEntityDescriptor,
@@ -950,6 +1075,11 @@ public boolean supportsLobValueChangePropagation() {
9501075
return false;
9511076
}
9521077

1078+
@Override
1079+
public boolean useInputStreamToInsertBlob() {
1080+
return false;
1081+
}
1082+
9531083
@Override
9541084
public boolean doesReadCommittedCauseWritersToBlockReaders() {
9551085
return true;

0 commit comments

Comments
 (0)