2727import  org .hibernate .exception .ConstraintViolationException ;
2828import  org .hibernate .exception .LockAcquisitionException ;
2929import  org .hibernate .exception .spi .SQLExceptionConversionDelegate ;
30+ import  org .hibernate .query .sqm .CastType ;
31+ import  org .hibernate .query .sqm .IntervalType ;
3032import  org .hibernate .type .descriptor .jdbc .VarcharUUIDJdbcType ;
3133import  org .hibernate .dialect .function .CaseLeastGreatestEmulation ;
3234import  org .hibernate .dialect .function .CommonFunctionFactory ;
110112import  static  org .hibernate .type .SqlTypes .UUID ;
111113import  static  org .hibernate .type .SqlTypes .VARBINARY ;
112114import  static  org .hibernate .type .SqlTypes .VARCHAR ;
113- import  static  org .hibernate .type .descriptor .DateTimeUtils .JDBC_ESCAPE_END ;
114- import  static  org .hibernate .type .descriptor .DateTimeUtils .JDBC_ESCAPE_START_DATE ;
115- import  static  org .hibernate .type .descriptor .DateTimeUtils .JDBC_ESCAPE_START_TIME ;
116- import  static  org .hibernate .type .descriptor .DateTimeUtils .JDBC_ESCAPE_START_TIMESTAMP ;
117115import  static  org .hibernate .type .descriptor .DateTimeUtils .appendAsDate ;
118116import  static  org .hibernate .type .descriptor .DateTimeUtils .appendAsLocalTime ;
119117import  static  org .hibernate .type .descriptor .DateTimeUtils .appendAsTime ;
120- import  static  org .hibernate .type .descriptor .DateTimeUtils .appendAsTimestampWithMicros ;
118+ import  static  org .hibernate .type .descriptor .DateTimeUtils .appendAsTimestampWithMillis ;
121119
122120/** 
123121 * Dialect for Informix 7.31.UD3 with Informix 
@@ -285,8 +283,9 @@ public int getDefaultDecimalPrecision() {
285283
286284	@ Override 
287285	public  int  getDefaultTimestampPrecision () {
288- 		//the maximum 
289- 		return  5 ;
286+ 		//the maximum is 5, but default to 3 
287+ 		//because Informix defaults to milliseconds 
288+ 		return  3 ;
290289	}
291290
292291	@ Override 
@@ -424,21 +423,14 @@ protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
424423	 */ 
425424	@ Override 
426425	public  String  extractPattern (TemporalUnit  unit ) {
427- 		switch  (unit ) {
428- 			case  SECOND :
429- 				return  "to_number(to_char(?2,'%S'))" ;
430- 			case  MINUTE :
431- 				return  "to_number(to_char(?2,'%M'))" ;
432- 			case  HOUR :
433- 				return  "to_number(to_char(?2,'%H'))" ;
434- 			case  DAY_OF_WEEK :
435- 				return  "(weekday(?2)+1)" ;
436- 			case  DAY_OF_MONTH :
437- 				return  "day(?2)" ;
438- 			default :
439- 				//I think week() returns the ISO week number 
440- 				return  "?1(?2)" ;
441- 		}
426+ 		return  switch  ( unit  ) {
427+ 			case  SECOND  -> "to_number(to_char(?2,'%S'))" ;
428+ 			case  MINUTE  -> "to_number(to_char(?2,'%M'))" ;
429+ 			case  HOUR  -> "to_number(to_char(?2,'%H'))" ;
430+ 			case  DAY_OF_WEEK  -> "(weekday(?2)+1)" ;
431+ 			case  DAY_OF_MONTH  -> "day(?2)" ;
432+ 			default  -> "?1(?2)" ;
433+ 		};
442434	}
443435
444436	@ Override 
@@ -545,6 +537,18 @@ public boolean supportsIfExistsBeforeConstraintName() {
545537		return  getVersion ().isSameOrAfter ( 11 , 70  );
546538	}
547539
540+ 	@ Override 
541+ 	public  String  getCascadeConstraintsString () {
542+ 		return  getVersion ().isSameOrAfter ( 12 , 10  )
543+ 				? " cascade" 
544+ 				: "" ;
545+ 	}
546+ 
547+ 	@ Override 
548+ 	public  boolean  dropConstraints () {
549+ 		return  !getVersion ().isSameOrAfter ( 12 , 10  );
550+ 	}
551+ 
548552	@ Override 
549553	public  boolean  supportsOrderByInSubquery () {
550554		// This is just a guess 
@@ -664,7 +668,60 @@ public boolean isCurrentTimestampSelectStringCallable() {
664668
665669	@ Override 
666670	public  String  getCurrentTimestampSelectString () {
667- 		return  "select distinct current timestamp from informix.systables" ;
671+ 		return  "select sysdate" ;
672+ 	}
673+ 
674+ 	@ Override  @ SuppressWarnings ("deprecation" )
675+ 	public  String  timestampaddPattern (TemporalUnit  unit , TemporalType  temporalType , IntervalType  intervalType ) {
676+ 		return  intervalType  != null  ? "(?2 + ?3)"  : "(?3 + "  + intervalPattern ( unit  ) + ")" ;
677+ 	}
678+ 
679+ 	private  static  String  intervalPattern (TemporalUnit  unit ) {
680+ 		return  switch  (unit ) {
681+ 			case  NANOSECOND  -> "?2/1e9 * interval (1) second to fraction" ;
682+ 			case  NATIVE , SECOND  -> "?2 * interval (1) second to fraction" ;
683+ 			case  QUARTER  -> "?2 * interval (3) month to month" ;
684+ 			case  WEEK  -> "?2 * interval (7) day to day" ;
685+ 			default  -> "?2 * interval (1) "  + unit  + " to "  + unit ;
686+ 		};
687+ 	}
688+ 
689+ 	@ Override 
690+ 	public  long  getFractionalSecondPrecisionInNanos () {
691+ 		// Informix actually supports up to 10 microseconds 
692+ 		// but defaults to milliseconds (so use that) 
693+ 		return  1_000_000 ;
694+ 	}
695+ 
696+ 	@ Override  @ SuppressWarnings ("deprecation" )
697+ 	public  String  timestampdiffPattern (TemporalUnit  unit , TemporalType  fromTemporalType , TemporalType  toTemporalType ) {
698+ 		return  unit  == null 
699+ 				? "(?3-?2)" 
700+ 				: extractPattern ( unit  )
701+ 						.replace ( "?1" , unit .toString () )
702+ 						.replace ( "?2" , "?3-?2"  );
703+ 	}
704+ 
705+ 	@ Override 
706+ 	public  String  castPattern (CastType  from , CastType  to ) {
707+ 		if  ( from  == CastType .BOOLEAN  ) {
708+ 			switch  ( to  ) {
709+ 				case  STRING :
710+ 					return  "trim(case ?1 when 't' then 'true' when 'f' then 'false' else null end)" ;
711+ 				case  TF_BOOLEAN :
712+ 					return  "upper(cast(?1 as varchar))" ;
713+ 				case  YN_BOOLEAN :
714+ 					return  "case ?1 when 't' then 'Y' when 'f' then 'N' else null end" ;
715+ 				case  INTEGER_BOOLEAN :
716+ 					return  "case ?1 when 't' then 1 when 'f' then 0 else null end" ;
717+ 			}
718+ 		}
719+ 		return  super .castPattern ( from , to  );
720+ 	}
721+ 
722+ 	@ Override 
723+ 	public  void  appendBinaryLiteral (SqlAppender  appender , byte [] bytes ) {
724+ 		throw  new  UnsupportedOperationException ( "Informix does not support binary literals"  );
668725	}
669726
670727	@ Override 
@@ -764,7 +821,9 @@ public Exporter<Table> getTableExporter() {
764821
765822	@ Override 
766823	public  void  appendBooleanValueString (SqlAppender  appender , boolean  bool ) {
824+ 		appender .appendSql ( "cast("  );
767825		appender .appendSql ( bool  ? "'t'"  : "'f'"  );
826+ 		appender .appendSql ( " as boolean)"  );
768827	}
769828
770829	@ Override 
@@ -774,7 +833,7 @@ public String currentDate() {
774833
775834	@ Override 
776835	public  String  currentTime () {
777- 		return  currentTimestamp () ;
836+ 		return  "current hour to fraction" ;
778837	}
779838
780839	@ Override 
@@ -851,21 +910,19 @@ public void appendDateTimeLiteral(
851910			TemporalAccessor  temporalAccessor ,
852911			TemporalType  precision ,
853912			TimeZone  jdbcTimeZone ) {
913+ 		appender .append ( "datetime ("  );
854914		switch  ( precision  ) {
855915			case  DATE :
856- 				appender .appendSql ( JDBC_ESCAPE_START_DATE  );
857916				appendAsDate ( appender , temporalAccessor  );
858- 				appender .appendSql ( JDBC_ESCAPE_END  );
917+ 				appender .appendSql ( ") year to day"  );
859918				break ;
860919			case  TIME :
861- 				appender .appendSql ( JDBC_ESCAPE_START_TIME  );
862920				appendAsTime ( appender , temporalAccessor , supportsTemporalLiteralOffset (), jdbcTimeZone  );
863- 				appender .appendSql ( JDBC_ESCAPE_END  );
921+ 				appender .appendSql ( ") hour to fraction"  );
864922				break ;
865923			case  TIMESTAMP :
866- 				appender .appendSql ( JDBC_ESCAPE_START_TIMESTAMP  );
867- 				appendAsTimestampWithMicros ( appender , temporalAccessor , supportsTemporalLiteralOffset (), jdbcTimeZone  );
868- 				appender .appendSql ( JDBC_ESCAPE_END  );
924+ 				appendAsTimestampWithMillis ( appender , temporalAccessor , supportsTemporalLiteralOffset (), jdbcTimeZone  );
925+ 				appender .appendSql ( ") year to fraction"  );
869926				break ;
870927			default :
871928				throw  new  IllegalArgumentException ();
@@ -874,21 +931,19 @@ public void appendDateTimeLiteral(
874931
875932	@ Override 
876933	public  void  appendDateTimeLiteral (SqlAppender  appender , Date  date , TemporalType  precision , TimeZone  jdbcTimeZone ) {
934+ 		appender .append ( "datetime ("  );
877935		switch  ( precision  ) {
878936			case  DATE :
879- 				appender .appendSql ( JDBC_ESCAPE_START_DATE  );
880937				appendAsDate ( appender , date  );
881- 				appender .appendSql ( JDBC_ESCAPE_END  );
938+ 				appender .appendSql ( ") year to day"  );
882939				break ;
883940			case  TIME :
884- 				appender .appendSql ( JDBC_ESCAPE_START_TIME  );
885941				appendAsLocalTime ( appender , date  );
886- 				appender .appendSql ( JDBC_ESCAPE_END  );
942+ 				appender .appendSql ( ") hour to fraction"  );
887943				break ;
888944			case  TIMESTAMP :
889- 				appender .appendSql ( JDBC_ESCAPE_START_TIMESTAMP  );
890- 				appendAsTimestampWithMicros ( appender , date , jdbcTimeZone  );
891- 				appender .appendSql ( JDBC_ESCAPE_END  );
945+ 				appendAsTimestampWithMillis ( appender , date , jdbcTimeZone  );
946+ 				appender .appendSql ( ") year to fraction"  );
892947				break ;
893948			default :
894949				throw  new  IllegalArgumentException ();
@@ -944,11 +999,6 @@ public String getDual() {
944999		return  "(select 0 from systables where tabid=1)" ;
9451000	}
9461001
947- 	@ Override 
948- 	public  String  getFromDualForSelectOnly () {
949- 		return  " from "  + getDual () + " dual" ;
950- 	}
951- 
9521002	@ Override 
9531003	public  boolean  supportsRowValueConstructorSyntax () {
9541004		return  false ;
0 commit comments