|  | 
| 105 | 105 | 
 | 
| 106 | 106 | import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate; | 
| 107 | 107 | import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode; | 
|  | 108 | +import static org.hibernate.query.common.TemporalUnit.DAY; | 
| 108 | 109 | import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING; | 
| 109 | 110 | import static org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers.impliedOrInvariant; | 
| 110 | 111 | import static org.hibernate.type.SqlTypes.BINARY; | 
| @@ -437,7 +438,7 @@ public String extractPattern(TemporalUnit unit) { | 
| 437 | 438 | 			case HOUR -> "to_number(to_char(?2,'%H'))"; | 
| 438 | 439 | 			case DAY_OF_WEEK -> "(weekday(?2)+1)"; | 
| 439 | 440 | 			case DAY_OF_MONTH -> "day(?2)"; | 
| 440 |  | -			case EPOCH -> "(to_number(cast(cast(sum(?2-datetime(1970-1-1) year to day) as interval day(9) to day) as varchar(12)))*86400+to_number(cast(cast(sum(cast(?2 as datetime hour to second)-datetime(00:00:00) hour to second) as interval second(6) to second) as varchar(9))))"; | 
|  | 441 | +			case EPOCH -> "(to_number(cast(cast((?2-datetime(1970-1-1) year to day) as interval day(9) to day) as varchar(12)))*86400+to_number(cast(cast((cast(?2 as datetime hour to second)-datetime(00:00:00) hour to second) as interval second(6) to second) as varchar(9))))"; | 
| 441 | 442 | 			default -> "?1(?2)"; | 
| 442 | 443 | 		}; | 
| 443 | 444 | 	} | 
| @@ -730,15 +731,25 @@ public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalT | 
| 730 | 731 | 			return "(?3-?2)"; | 
| 731 | 732 | 		} | 
| 732 | 733 | 		else { | 
|  | 734 | +			if ( fromTemporalType == TemporalType.DATE && toTemporalType == TemporalType.DATE ) { | 
|  | 735 | +				// special case: subtraction of two dates results in an integer number of days | 
|  | 736 | +				return switch ( unit ) { | 
|  | 737 | +					case NATIVE -> "to_number(cast(?3-?2 as lvarchar))*86400"; | 
|  | 738 | +					case YEAR, MONTH -> "to_number(cast(cast(extend(?3,year to month)-extend(?2,year to month) as interval ?1(9) to ?1) as varchar(12)))"; | 
|  | 739 | +					case DAY -> "to_number(cast(?3-?2 as lvarchar))"; | 
|  | 740 | +					case WEEK -> "floor(to_number(cast(?3-?2 as lvarchar))/7)"; | 
|  | 741 | +					default -> "to_number(cast(?3-?2 as lvarchar))" + DAY.conversionFactor( unit, this ); | 
|  | 742 | +				}; | 
|  | 743 | +			} | 
| 733 | 744 | 			return switch ( unit ) { | 
| 734 | 745 | 				case NATIVE -> | 
| 735 | 746 | 					fromTemporalType == TemporalType.TIME | 
| 736 | 747 | 							// arguably, we don't really need to retain the milliseconds for a time, since times don't usually come with millis | 
| 737 |  | -							? "(mod(to_number(cast(cast(sum(?3-?2) as interval second(6) to second) as varchar(9))),86400)+to_number(cast(cast(sum(?3-?2) as interval fraction to fraction) as varchar(6))))" | 
| 738 |  | -							: "(to_number(cast(cast(sum(?3-?2) as interval day(9) to day) as varchar(12)))*86400+mod(to_number(cast(cast(sum(?3-?2) as interval second(6) to second) as varchar(9))),86400)+to_number(cast(cast(sum(?3-?2) as interval fraction to fraction) as varchar(6))))"; | 
| 739 |  | -				case SECOND -> "to_number(cast(cast(sum(?3-?2) as interval second(9) to fraction) as varchar(15)))"; | 
| 740 |  | -				case NANOSECOND -> "(to_number(cast(cast(sum(?3-?2) as interval second(9) to fraction) as varchar(15)))*1e9)"; | 
| 741 |  | -				default -> "to_number(cast(cast(sum(?3-?2) as interval ?1(9) to ?1) as varchar(12)))"; | 
|  | 748 | +							? "(mod(to_number(cast(cast(?3-?2 as interval second(6) to second) as varchar(9))),86400)+to_number(cast(cast(?3-?2 as interval fraction to fraction) as varchar(6))))" | 
|  | 749 | +							: "(to_number(cast(cast(?3-?2 as interval day(9) to day) as varchar(12)))*86400+mod(to_number(cast(cast(?3-?2 as interval second(6) to second) as varchar(9))),86400)+to_number(cast(cast(?3-?2 as interval fraction to fraction) as varchar(6))))"; | 
|  | 750 | +				case SECOND -> "to_number(cast(cast(?3-?2 as interval second(9) to fraction) as varchar(15)))"; | 
|  | 751 | +				case NANOSECOND -> "(to_number(cast(cast(?3-?2 as interval second(9) to fraction) as varchar(15)))*1e9)"; | 
|  | 752 | +				default -> "to_number(cast(cast(?3-?2 as interval ?1(9) to ?1) as varchar(12)))"; | 
| 742 | 753 | 			}; | 
| 743 | 754 | 		} | 
| 744 | 755 | 	} | 
|  | 
0 commit comments