1515import org .hibernate .community .dialect .sequence .SequenceInformationExtractorTimesTenDatabaseImpl ;
1616import org .hibernate .community .dialect .sequence .TimesTenSequenceSupport ;
1717import org .hibernate .dialect .Dialect ;
18+ import org .hibernate .dialect .BooleanDecoder ;
1819import org .hibernate .dialect .function .CommonFunctionFactory ;
20+ import org .hibernate .dialect .function .OracleTruncFunction ;
21+ import org .hibernate .query .sqm .produce .function .StandardFunctionReturnTypeResolvers ;
1922import org .hibernate .dialect .lock .LockingStrategy ;
2023import org .hibernate .dialect .lock .PessimisticReadUpdateLockingStrategy ;
2124import org .hibernate .dialect .lock .PessimisticWriteUpdateLockingStrategy ;
3033import org .hibernate .metamodel .mapping .EntityMappingType ;
3134import org .hibernate .metamodel .spi .RuntimeModelCreationContext ;
3235import org .hibernate .persister .entity .EntityPersister ;
36+ import org .hibernate .query .sqm .CastType ;
3337import org .hibernate .query .sqm .IntervalType ;
3438import org .hibernate .query .common .TemporalUnit ;
3539import org .hibernate .query .sqm .mutation .internal .temptable .GlobalTemporaryTableInsertStrategy ;
3842import org .hibernate .query .sqm .mutation .spi .SqmMultiTableMutationStrategy ;
3943import org .hibernate .sql .ast .SqlAstTranslator ;
4044import org .hibernate .sql .ast .SqlAstTranslatorFactory ;
45+ import org .hibernate .sql .ast .SqlAstNodeRenderingMode ;
4146import org .hibernate .sql .ast .spi .StandardSqlAstTranslatorFactory ;
4247import org .hibernate .sql .ast .tree .Statement ;
4348import org .hibernate .sql .exec .spi .JdbcOperation ;
4853import org .hibernate .type .descriptor .jdbc .spi .JdbcTypeRegistry ;
4954import org .hibernate .type .spi .TypeConfiguration ;
5055
56+ import org .hibernate .type .BasicType ;
57+ import org .hibernate .type .BasicTypeRegistry ;
58+ import org .hibernate .dialect .function .StandardSQLFunction ;
59+ import org .hibernate .dialect .function .CurrentFunction ;
60+ import org .hibernate .query .sqm .produce .function .StandardFunctionArgumentTypeResolvers ;
61+ import java .util .Date ;
62+
5163import jakarta .persistence .TemporalType ;
5264
5365import static org .hibernate .dialect .SimpleDatabaseVersion .ZERO_VERSION ;
5668import static org .hibernate .query .sqm .produce .function .FunctionParameterType .STRING ;
5769
5870/**
59- * A SQL dialect for TimesTen 5.1.
71+ * A SQL dialect for Oracle TimesTen
6072 * <p>
6173 * Known limitations:
6274 * joined-subclass support because of no CASE support in TimesTen
6375 * No support for subqueries that includes aggregation
6476 * - size() in HQL not supported
6577 * - user queries that does subqueries with aggregation
66- * No CLOB/BLOB support
6778 * No cascade delete support.
6879 * No Calendar support
6980 * No support for updating primary keys.
@@ -87,6 +98,7 @@ protected String columnType(int sqlTypeCode) {
8798 // for the default Oracle type mode
8899 // TypeMode=0
89100 case SqlTypes .BOOLEAN :
101+ case SqlTypes .BIT :
90102 case SqlTypes .TINYINT :
91103 return "tt_tinyint" ;
92104 case SqlTypes .SMALLINT :
@@ -98,15 +110,26 @@ protected String columnType(int sqlTypeCode) {
98110 //note that 'binary_float'/'binary_double' might
99111 //be better mappings for Java Float/Double
100112
113+ case SqlTypes .VARCHAR :
114+ case SqlTypes .LONGVARCHAR :
115+ return "varchar2($l)" ;
116+
117+ case SqlTypes .LONGVARBINARY :
118+ return "varbinary($l)" ;
119+
101120 //'numeric'/'decimal' are synonyms for 'number'
102121 case SqlTypes .NUMERIC :
103122 case SqlTypes .DECIMAL :
104123 return "number($p,$s)" ;
124+ case SqlTypes .FLOAT :
125+ return "binary_float" ;
126+ case SqlTypes .DOUBLE :
127+ return "binary_double" ;
128+
105129 case SqlTypes .DATE :
106130 return "tt_date" ;
107131 case SqlTypes .TIME :
108132 return "tt_time" ;
109- //`timestamp` has more precision than `tt_timestamp`
110133 case SqlTypes .TIMESTAMP_WITH_TIMEZONE :
111134 return "timestamp($p)" ;
112135
@@ -154,22 +177,97 @@ public int getDefaultDecimalPrecision() {
154177 public void initializeFunctionRegistry (FunctionContributions functionContributions ) {
155178 super .initializeFunctionRegistry (functionContributions );
156179
157- CommonFunctionFactory functionFactory = new CommonFunctionFactory (functionContributions );
180+ final TypeConfiguration typeConfiguration = functionContributions .getTypeConfiguration ();
181+ CommonFunctionFactory functionFactory = new CommonFunctionFactory (functionContributions );
182+ final BasicTypeRegistry basicTypeRegistry = typeConfiguration .getBasicTypeRegistry ();
183+ final BasicType <Date > timestampType = basicTypeRegistry .resolve ( StandardBasicTypes .TIMESTAMP );
184+ final BasicType <String > stringType = basicTypeRegistry .resolve ( StandardBasicTypes .STRING );
185+ final BasicType <Long > longType = basicTypeRegistry .resolve ( StandardBasicTypes .LONG );
186+ final BasicType <Integer >intType = basicTypeRegistry .resolve ( StandardBasicTypes .INTEGER );
187+
188+ // String Functions
158189 functionFactory .trim2 ();
159- functionFactory .soundex ( );
160- functionFactory .trunc ();
190+ functionFactory .characterLength_length ( SqlAstNodeRenderingMode . DEFAULT );
191+ functionFactory .concat_pipeOperator ();
161192 functionFactory .toCharNumberDateTimestamp ();
162- functionFactory .ceiling_ceil ();
193+ functionFactory .char_chr ();
163194 functionFactory .instr ();
164195 functionFactory .substr ();
165196 functionFactory .substring_substr ();
166- functionFactory .leftRight_substr ();
167- functionFactory .char_chr ();
168- functionFactory .rownumRowid ();
169- functionFactory .sysdate ();
197+ functionFactory .soundex ();
198+
199+ // Date/Time Functions
200+ functionContributions .getFunctionRegistry ().register (
201+ "sysdate" , new CurrentFunction ("sysdate" , "sysdate" , timestampType )
202+ );
203+ functionContributions .getFunctionRegistry ().register (
204+ "getdate" , new CurrentFunction ("getdate" , "getdate()" , timestampType )
205+ );
206+
207+ // Multi-param date dialect functions
170208 functionFactory .addMonths ();
171209 functionFactory .monthsBetween ();
172210
211+ // Math functions
212+ functionFactory .ceiling_ceil ();
213+ functionFactory .radians_acos ();
214+ functionFactory .degrees_acos ();
215+ functionFactory .sinh ();
216+ functionFactory .tanh ();
217+ functionContributions .getFunctionRegistry ().register (
218+ "trunc" ,
219+ new OracleTruncFunction ( functionContributions .getTypeConfiguration () )
220+ );
221+ functionContributions .getFunctionRegistry ().registerAlternateKey ( "truncate" , "trunc" );
222+ functionFactory .round ();
223+
224+ // Bitwise functions
225+ functionContributions .getFunctionRegistry ()
226+ .patternDescriptorBuilder ( "bitor" , "(?1+?2-bitand(?1,?2))" )
227+ .setExactArgumentCount ( 2 )
228+ .setArgumentTypeResolver ( StandardFunctionArgumentTypeResolvers
229+ .ARGUMENT_OR_IMPLIED_RESULT_TYPE )
230+ .register ();
231+
232+ functionContributions .getFunctionRegistry ()
233+ .patternDescriptorBuilder ( "bitxor" , "(?1+?2-2*bitand(?1,?2))" )
234+ .setExactArgumentCount ( 2 )
235+ .setArgumentTypeResolver ( StandardFunctionArgumentTypeResolvers
236+ .ARGUMENT_OR_IMPLIED_RESULT_TYPE )
237+ .register ();
238+
239+ // Misc. functions
240+ functionContributions .getFunctionRegistry ().namedDescriptorBuilder ( "nvl" )
241+ .setMinArgumentCount ( 2 )
242+ .setArgumentTypeResolver ( StandardFunctionArgumentTypeResolvers .ARGUMENT_OR_IMPLIED_RESULT_TYPE )
243+ .setReturnTypeResolver ( StandardFunctionReturnTypeResolvers .useFirstNonNull () )
244+ .register ();
245+
246+ functionContributions .getFunctionRegistry ().register (
247+ "user" , new CurrentFunction ("user" , "user" , stringType )
248+ );
249+ functionContributions .getFunctionRegistry ().register (
250+ "rowid" , new CurrentFunction ("rowid" , "rowid" , stringType )
251+ );
252+ functionContributions .getFunctionRegistry ().register (
253+ "uid" , new CurrentFunction ("uid" , "uid" , intType )
254+ );
255+ functionContributions .getFunctionRegistry ().register (
256+ "rownum" , new CurrentFunction ("rownum" , "rownum" , longType )
257+ );
258+ functionContributions .getFunctionRegistry ().register (
259+ "vsize" , new StandardSQLFunction ("vsize" , StandardBasicTypes .DOUBLE )
260+ );
261+ functionContributions .getFunctionRegistry ().register (
262+ "SESSION_USER" , new CurrentFunction ("SESSION_USER" ,"SESSION_USER" , stringType )
263+ );
264+ functionContributions .getFunctionRegistry ().register (
265+ "SYSTEM_USER" , new CurrentFunction ("SYSTEM_USER" , "SYSTEM_USER" , stringType )
266+ );
267+ functionContributions .getFunctionRegistry ().register (
268+ "CURRENT_USER" , new CurrentFunction ("CURRENT_USER" ,"CURRENT_USER" , stringType )
269+ );
270+
173271 functionContributions .getFunctionRegistry ().registerBinaryTernaryPattern (
174272 "locate" ,
175273 functionContributions .getTypeConfiguration ().getBasicTypeRegistry ().resolve ( StandardBasicTypes .INTEGER ),
@@ -426,6 +524,106 @@ public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfi
426524 }
427525 }
428526
527+ @ Override
528+ public String getNativeIdentifierGeneratorStrategy () {
529+ return "sequence" ;
530+ }
531+
532+ @ Override
533+ public String currentDate () {
534+ return "sysdate" ;
535+ }
536+
537+ @ Override
538+ public String currentTime () {
539+ return "sysdate" ;
540+ }
541+
542+ @ Override
543+ public String currentTimestamp () {
544+ return "sysdate" ;
545+ }
546+
547+ @ Override
548+ public int getMaxVarcharLength () {
549+ // 1 to 4,194,304 bytes according to TimesTen Doc
550+ return 4194304 ;
551+ }
552+
553+ @ Override
554+ public int getMaxVarbinaryLength () {
555+ // 1 to 4,194,304 bytes according to TimesTen Doc
556+ return 4194304 ;
557+ }
558+
559+ @ Override
560+ public boolean isEmptyStringTreatedAsNull () {
561+ return true ;
562+ }
563+
564+ @ Override
565+ public boolean supportsTupleDistinctCounts () {
566+ return false ;
567+ }
568+
569+ @ Override
570+ public String getDual () {
571+ return "dual" ;
572+ }
573+
574+ @ Override
575+ public String getFromDualForSelectOnly () {
576+ return " from dual" ;
577+ }
578+
579+ @ Override
580+ public String castPattern (CastType from , CastType to ) {
581+ String result ;
582+ switch ( to ) {
583+ case INTEGER :
584+ case LONG :
585+ result = BooleanDecoder .toInteger ( from );
586+ if ( result != null ) {
587+ return result ;
588+ }
589+ break ;
590+ case STRING :
591+ switch ( from ) {
592+ case BOOLEAN :
593+ case INTEGER_BOOLEAN :
594+ case TF_BOOLEAN :
595+ case YN_BOOLEAN :
596+ return BooleanDecoder .toString ( from );
597+ case DATE :
598+ return "to_char(?1,'YYYY-MM-DD')" ;
599+ case TIME :
600+ return "to_char(?1,'HH24:MI:SS')" ;
601+ case TIMESTAMP :
602+ return "to_char(?1,'YYYY-MM-DD HH24:MI:SS.FF9')" ;
603+ }
604+ break ;
605+ case CLOB :
606+ return "to_clob(?1)" ;
607+ case DATE :
608+ if ( from == CastType .STRING ) {
609+ return "to_date(?1,'YYYY-MM-DD')" ;
610+ }
611+ break ;
612+ case TIME :
613+ if ( from == CastType .STRING ) {
614+ return "to_date(?1,'HH24:MI:SS')" ;
615+ }
616+ break ;
617+ case TIMESTAMP :
618+ if ( from == CastType .STRING ) {
619+ return "to_timestamp(?1,'YYYY-MM-DD HH24:MI:SS.FF9')" ;
620+ }
621+ break ;
622+ }
623+ return super .castPattern (from , to );
624+ }
625+
626+
429627 @ Override
430628 public boolean supportsRowValueConstructorSyntax () {
431629 return false ;
0 commit comments