Skip to content

Commit 1900dcd

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 1900dcd

File tree

8 files changed

+174
-248
lines changed

8 files changed

+174
-248
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 & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
484484
if ( supportsRecursiveCTE() ) {
485485
functionFactory.generateSeries_recursive( getMaximumSeriesSize(), false, true );
486486
}
487+
488+
functionFactory.hex( "hex(?1)" );
489+
if ( getDB2Version().isSameOrAfter( 11 ) ) {
490+
functionFactory.sha( "hash(?1, 2)" );
491+
functionFactory.md5( "hash(?1, 0)" );
492+
}
487493
}
488494

489495
/**
@@ -522,7 +528,7 @@ public long getFractionalSecondPrecisionInNanos() {
522528
@Override
523529
public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
524530
if ( getDB2Version().isBefore( 11 ) ) {
525-
return DB2Dialect.timestampdiffPatternV10( unit, fromTemporalType, toTemporalType );
531+
return timestampdiffPatternV10( unit, fromTemporalType, toTemporalType );
526532
}
527533
final StringBuilder pattern = new StringBuilder();
528534
final String fromExpression;
@@ -558,22 +564,30 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT
558564
switch ( unit ) {
559565
case NATIVE:
560566
case NANOSECOND:
561-
pattern.append( "(seconds_between(" );
567+
pattern.append( "(seconds_between(date_trunc('second'," );
568+
pattern.append( toExpression );
569+
pattern.append( "),date_trunc('second'," );
570+
pattern.append( fromExpression );
571+
pattern.append( "))" );
562572
break;
563573
//note: DB2 does have weeks_between()
564574
case MONTH:
565575
case QUARTER:
566576
// the months_between() function results
567577
// in a non-integral value, so trunc() it
568578
pattern.append( "trunc(months_between(" );
579+
pattern.append( toExpression );
580+
pattern.append( ',' );
581+
pattern.append( fromExpression );
582+
pattern.append( ')' );
569583
break;
570584
default:
571585
pattern.append( "?1s_between(" );
586+
pattern.append( toExpression );
587+
pattern.append( ',' );
588+
pattern.append( fromExpression );
589+
pattern.append( ')' );
572590
}
573-
pattern.append( toExpression );
574-
pattern.append( ',' );
575-
pattern.append( fromExpression );
576-
pattern.append( ')' );
577591
switch ( unit ) {
578592
case NATIVE:
579593
pattern.append( "+(microsecond(");
@@ -599,6 +613,97 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT
599613
return pattern.toString();
600614
}
601615

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

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

1033+
@Override
1034+
public boolean supportsIsTrue() {
1035+
return getDB2Version().isSameOrAfter( 11 );
1036+
}
1037+
9121038
@Override
9131039
public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(
9141040
EntityMappingType rootEntityDescriptor,
@@ -950,6 +1076,11 @@ public boolean supportsLobValueChangePropagation() {
9501076
return false;
9511077
}
9521078

1079+
@Override
1080+
public boolean useInputStreamToInsertBlob() {
1081+
return false;
1082+
}
1083+
9531084
@Override
9541085
public boolean doesReadCommittedCauseWritersToBlockReaders() {
9551086
return true;

0 commit comments

Comments
 (0)