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