@@ -484,6 +484,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
484
484
if ( supportsRecursiveCTE () ) {
485
485
functionFactory .generateSeries_recursive ( getMaximumSeriesSize (), false , true );
486
486
}
487
+
488
+ functionFactory .hex ( "hex(?1)" );
489
+ if ( getDB2Version ().isSameOrAfter ( 11 ) ) {
490
+ functionFactory .sha ( "hash(?1, 2)" );
491
+ functionFactory .md5 ( "hash(?1, 0)" );
492
+ }
487
493
}
488
494
489
495
/**
@@ -522,7 +528,7 @@ public long getFractionalSecondPrecisionInNanos() {
522
528
@ Override
523
529
public String timestampdiffPattern (TemporalUnit unit , TemporalType fromTemporalType , TemporalType toTemporalType ) {
524
530
if ( getDB2Version ().isBefore ( 11 ) ) {
525
- return DB2Dialect . timestampdiffPatternV10 ( unit , fromTemporalType , toTemporalType );
531
+ return timestampdiffPatternV10 ( unit , fromTemporalType , toTemporalType );
526
532
}
527
533
final StringBuilder pattern = new StringBuilder ();
528
534
final String fromExpression ;
@@ -558,22 +564,30 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT
558
564
switch ( unit ) {
559
565
case NATIVE :
560
566
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 ( "))" );
562
572
break ;
563
573
//note: DB2 does have weeks_between()
564
574
case MONTH :
565
575
case QUARTER :
566
576
// the months_between() function results
567
577
// in a non-integral value, so trunc() it
568
578
pattern .append ( "trunc(months_between(" );
579
+ pattern .append ( toExpression );
580
+ pattern .append ( ',' );
581
+ pattern .append ( fromExpression );
582
+ pattern .append ( ')' );
569
583
break ;
570
584
default :
571
585
pattern .append ( "?1s_between(" );
586
+ pattern .append ( toExpression );
587
+ pattern .append ( ',' );
588
+ pattern .append ( fromExpression );
589
+ pattern .append ( ')' );
572
590
}
573
- pattern .append ( toExpression );
574
- pattern .append ( ',' );
575
- pattern .append ( fromExpression );
576
- pattern .append ( ')' );
577
591
switch ( unit ) {
578
592
case NATIVE :
579
593
pattern .append ( "+(microsecond(" );
@@ -599,6 +613,97 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT
599
613
return pattern .toString ();
600
614
}
601
615
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
+
602
707
@ Override
603
708
public String timestampaddPattern (TemporalUnit unit , TemporalType temporalType , IntervalType intervalType ) {
604
709
final StringBuilder pattern = new StringBuilder ();
@@ -902,13 +1007,34 @@ public boolean supportsCommentOn() {
902
1007
return true ;
903
1008
}
904
1009
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
+
905
1026
@ Override
906
1027
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy (
907
1028
EntityMappingType rootEntityDescriptor ,
908
1029
RuntimeModelCreationContext runtimeModelCreationContext ) {
909
1030
return new CteMutationStrategy ( rootEntityDescriptor , runtimeModelCreationContext );
910
1031
}
911
1032
1033
+ @ Override
1034
+ public boolean supportsIsTrue () {
1035
+ return getDB2Version ().isSameOrAfter ( 11 );
1036
+ }
1037
+
912
1038
@ Override
913
1039
public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy (
914
1040
EntityMappingType rootEntityDescriptor ,
@@ -950,6 +1076,11 @@ public boolean supportsLobValueChangePropagation() {
950
1076
return false ;
951
1077
}
952
1078
1079
+ @ Override
1080
+ public boolean useInputStreamToInsertBlob () {
1081
+ return false ;
1082
+ }
1083
+
953
1084
@ Override
954
1085
public boolean doesReadCommittedCauseWritersToBlockReaders () {
955
1086
return true ;
0 commit comments