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 .RowLockStrategy ;
1920import org .hibernate .dialect .function .CommonFunctionFactory ;
21+ import org .hibernate .dialect .function .OracleTruncFunction ;
22+ import org .hibernate .query .sqm .produce .function .StandardFunctionReturnTypeResolvers ;
2023import org .hibernate .dialect .lock .LockingStrategy ;
2124import org .hibernate .dialect .lock .OptimisticForceIncrementLockingStrategy ;
2225import org .hibernate .dialect .lock .OptimisticLockingStrategy ;
3437import org .hibernate .metamodel .mapping .EntityMappingType ;
3538import org .hibernate .metamodel .spi .RuntimeModelCreationContext ;
3639import org .hibernate .persister .entity .Lockable ;
40+ import org .hibernate .query .sqm .CastType ;
3741import org .hibernate .query .sqm .IntervalType ;
3842import org .hibernate .query .sqm .TemporalUnit ;
3943import org .hibernate .query .sqm .mutation .internal .temptable .GlobalTemporaryTableInsertStrategy ;
4246import org .hibernate .query .sqm .mutation .spi .SqmMultiTableMutationStrategy ;
4347import org .hibernate .sql .ast .SqlAstTranslator ;
4448import org .hibernate .sql .ast .SqlAstTranslatorFactory ;
49+ import org .hibernate .sql .ast .SqlAstNodeRenderingMode ;
4550import org .hibernate .sql .ast .spi .StandardSqlAstTranslatorFactory ;
4651import org .hibernate .sql .ast .tree .Statement ;
4752import org .hibernate .sql .exec .spi .JdbcOperation ;
5257import org .hibernate .type .descriptor .jdbc .spi .JdbcTypeRegistry ;
5358import org .hibernate .type .spi .TypeConfiguration ;
5459
60+ import org .hibernate .type .BasicType ;
61+ import org .hibernate .type .BasicTypeRegistry ;
62+ import org .hibernate .type .StandardBasicTypes ;
63+ import org .hibernate .dialect .function .StandardSQLFunction ;
64+ import org .hibernate .dialect .function .CurrentFunction ;
65+ import org .hibernate .query .sqm .produce .function .StandardFunctionArgumentTypeResolvers ;
66+ import jakarta .persistence .GenerationType ;
67+ import java .util .Date ;
68+
5569import jakarta .persistence .TemporalType ;
5670
5771import static org .hibernate .dialect .SimpleDatabaseVersion .ZERO_VERSION ;
5872import static org .hibernate .query .sqm .produce .function .FunctionParameterType .INTEGER ;
5973import static org .hibernate .query .sqm .produce .function .FunctionParameterType .STRING ;
6074
6175/**
62- * A SQL dialect for TimesTen 5.1.
76+ * A SQL dialect for Oracle TimesTen
6377 * <p>
6478 * Known limitations:
6579 * joined-subclass support because of no CASE support in TimesTen
6680 * No support for subqueries that includes aggregation
6781 * - size() in HQL not supported
6882 * - user queries that does subqueries with aggregation
69- * No CLOB/BLOB support
7083 * No cascade delete support.
7184 * No Calendar support
7285 * No support for updating primary keys.
@@ -90,6 +103,7 @@ protected String columnType(int sqlTypeCode) {
90103 // for the default Oracle type mode
91104 // TypeMode=0
92105 case SqlTypes .BOOLEAN :
106+ case SqlTypes .BIT :
93107 case SqlTypes .TINYINT :
94108 return "tt_tinyint" ;
95109 case SqlTypes .SMALLINT :
@@ -101,15 +115,26 @@ protected String columnType(int sqlTypeCode) {
101115 //note that 'binary_float'/'binary_double' might
102116 //be better mappings for Java Float/Double
103117
118+ case SqlTypes .VARCHAR :
119+ case SqlTypes .LONGVARCHAR :
120+ return "varchar2($l)" ;
121+
122+ case SqlTypes .LONGVARBINARY :
123+ return "varbinary($l)" ;
124+
104125 //'numeric'/'decimal' are synonyms for 'number'
105126 case SqlTypes .NUMERIC :
106127 case SqlTypes .DECIMAL :
107128 return "number($p,$s)" ;
129+ case SqlTypes .FLOAT :
130+ return "binary_float" ;
131+ case SqlTypes .DOUBLE :
132+ return "binary_double" ;
133+
108134 case SqlTypes .DATE :
109135 return "tt_date" ;
110136 case SqlTypes .TIME :
111137 return "tt_time" ;
112- //`timestamp` has more precision than `tt_timestamp`
113138 case SqlTypes .TIMESTAMP_WITH_TIMEZONE :
114139 return "timestamp($p)" ;
115140
@@ -157,22 +182,97 @@ public int getDefaultDecimalPrecision() {
157182 public void initializeFunctionRegistry (FunctionContributions functionContributions ) {
158183 super .initializeFunctionRegistry (functionContributions );
159184
160- CommonFunctionFactory functionFactory = new CommonFunctionFactory (functionContributions );
185+ final TypeConfiguration typeConfiguration = functionContributions .getTypeConfiguration ();
186+ CommonFunctionFactory functionFactory = new CommonFunctionFactory (functionContributions );
187+ final BasicTypeRegistry basicTypeRegistry = typeConfiguration .getBasicTypeRegistry ();
188+ final BasicType <Date > timestampType = basicTypeRegistry .resolve ( StandardBasicTypes .TIMESTAMP );
189+ final BasicType <String > stringType = basicTypeRegistry .resolve ( StandardBasicTypes .STRING );
190+ final BasicType <Long > longType = basicTypeRegistry .resolve ( StandardBasicTypes .LONG );
191+ final BasicType <Integer >intType = basicTypeRegistry .resolve ( StandardBasicTypes .INTEGER );
192+
193+ // String Functions
161194 functionFactory .trim2 ();
162- functionFactory .soundex ( );
163- functionFactory .trunc ();
195+ functionFactory .characterLength_length ( SqlAstNodeRenderingMode . DEFAULT );
196+ functionFactory .concat_pipeOperator ();
164197 functionFactory .toCharNumberDateTimestamp ();
165- functionFactory .ceiling_ceil ();
198+ functionFactory .char_chr ();
166199 functionFactory .instr ();
167200 functionFactory .substr ();
168201 functionFactory .substring_substr ();
169- functionFactory .leftRight_substr ();
170- functionFactory .char_chr ();
171- functionFactory .rownumRowid ();
172- functionFactory .sysdate ();
202+ functionFactory .soundex ();
203+
204+ // Date/Time Functions
205+ functionContributions .getFunctionRegistry ().register (
206+ "sysdate" , new CurrentFunction ("sysdate" , "sysdate" , timestampType )
207+ );
208+ functionContributions .getFunctionRegistry ().register (
209+ "getdate" , new CurrentFunction ("getdate" , "getdate()" , timestampType )
210+ );
211+
212+ // Multi-param date dialect functions
173213 functionFactory .addMonths ();
174214 functionFactory .monthsBetween ();
175215
216+ // Math functions
217+ functionFactory .ceiling_ceil ();
218+ functionFactory .radians_acos ();
219+ functionFactory .degrees_acos ();
220+ functionFactory .sinh ();
221+ functionFactory .tanh ();
222+ functionContributions .getFunctionRegistry ().register (
223+ "trunc" ,
224+ new OracleTruncFunction ( functionContributions .getTypeConfiguration () )
225+ );
226+ functionContributions .getFunctionRegistry ().registerAlternateKey ( "truncate" , "trunc" );
227+ functionFactory .round ();
228+
229+ // Bitwise functions
230+ functionContributions .getFunctionRegistry ()
231+ .patternDescriptorBuilder ( "bitor" , "(?1+?2-bitand(?1,?2))" )
232+ .setExactArgumentCount ( 2 )
233+ .setArgumentTypeResolver ( StandardFunctionArgumentTypeResolvers
234+ .ARGUMENT_OR_IMPLIED_RESULT_TYPE )
235+ .register ();
236+
237+ functionContributions .getFunctionRegistry ()
238+ .patternDescriptorBuilder ( "bitxor" , "(?1+?2-2*bitand(?1,?2))" )
239+ .setExactArgumentCount ( 2 )
240+ .setArgumentTypeResolver ( StandardFunctionArgumentTypeResolvers
241+ .ARGUMENT_OR_IMPLIED_RESULT_TYPE )
242+ .register ();
243+
244+ // Misc. functions
245+ functionContributions .getFunctionRegistry ().namedDescriptorBuilder ( "nvl" )
246+ .setMinArgumentCount ( 2 )
247+ .setArgumentTypeResolver ( StandardFunctionArgumentTypeResolvers .ARGUMENT_OR_IMPLIED_RESULT_TYPE )
248+ .setReturnTypeResolver ( StandardFunctionReturnTypeResolvers .useFirstNonNull () )
249+ .register ();
250+
251+ functionContributions .getFunctionRegistry ().register (
252+ "user" , new CurrentFunction ("user" , "user" , stringType )
253+ );
254+ functionContributions .getFunctionRegistry ().register (
255+ "rowid" , new CurrentFunction ("rowid" , "rowid" , stringType )
256+ );
257+ functionContributions .getFunctionRegistry ().register (
258+ "uid" , new CurrentFunction ("uid" , "uid" , intType )
259+ );
260+ functionContributions .getFunctionRegistry ().register (
261+ "rownum" , new CurrentFunction ("rownum" , "rownum" , longType )
262+ );
263+ functionContributions .getFunctionRegistry ().register (
264+ "vsize" , new StandardSQLFunction ("vsize" , StandardBasicTypes .DOUBLE )
265+ );
266+ functionContributions .getFunctionRegistry ().register (
267+ "SESSION_USER" , new CurrentFunction ("SESSION_USER" ,"SESSION_USER" , stringType )
268+ );
269+ functionContributions .getFunctionRegistry ().register (
270+ "SYSTEM_USER" , new CurrentFunction ("SYSTEM_USER" , "SYSTEM_USER" , stringType )
271+ );
272+ functionContributions .getFunctionRegistry ().register (
273+ "CURRENT_USER" , new CurrentFunction ("CURRENT_USER" ,"CURRENT_USER" , stringType )
274+ );
275+
176276 functionContributions .getFunctionRegistry ().registerBinaryTernaryPattern (
177277 "locate" ,
178278 functionContributions .getTypeConfiguration ().getBasicTypeRegistry ().resolve ( StandardBasicTypes .INTEGER ),
@@ -251,9 +351,10 @@ public RowLockStrategy getWriteRowLockStrategy() {
251351 return RowLockStrategy .COLUMN ;
252352 }
253353
354+
254355 @ Override
255- public String getForUpdateString (String aliases ) {
256- return " for update of " + aliases ;
356+ public String getForUpdateString () {
357+ return " for update" ;
257358 }
258359
259360 @ Override
@@ -426,4 +527,104 @@ public String getSelectClauseNullString(int sqlType, TypeConfiguration typeConfi
426527 }
427528 }
428529
530+ @ Override
531+ public String getNativeIdentifierGeneratorStrategy () {
532+ return "sequence" ;
533+ }
534+
535+ @ Override
536+ public String currentDate () {
537+ return "sysdate" ;
538+ }
539+
540+ @ Override
541+ public String currentTime () {
542+ return "sysdate" ;
543+ }
544+
545+ @ Override
546+ public String currentTimestamp () {
547+ return "sysdate" ;
548+ }
549+
550+ @ Override
551+ public int getMaxVarcharLength () {
552+ // 1 to 4,194,304 bytes according to TimesTen Doc
553+ return 4194304 ;
554+ }
555+
556+ @ Override
557+ public int getMaxVarbinaryLength () {
558+ // 1 to 4,194,304 bytes according to TimesTen Doc
559+ return 4194304 ;
560+ }
561+
562+ @ Override
563+ public boolean isEmptyStringTreatedAsNull () {
564+ return true ;
565+ }
566+
567+ @ Override
568+ public boolean supportsTupleDistinctCounts () {
569+ return false ;
570+ }
571+
572+ @ Override
573+ public String getDual () {
574+ return "dual" ;
575+ }
576+
577+ @ Override
578+ public String getFromDualForSelectOnly () {
579+ return " from dual" ;
580+ }
581+
582+ @ Override
583+ public String castPattern (CastType from , CastType to ) {
584+ String result ;
585+ switch ( to ) {
586+ case INTEGER :
587+ case LONG :
588+ result = BooleanDecoder .toInteger ( from );
589+ if ( result != null ) {
590+ return result ;
591+ }
592+ break ;
593+ case STRING :
594+ switch ( from ) {
595+ case BOOLEAN :
596+ case INTEGER_BOOLEAN :
597+ case TF_BOOLEAN :
598+ case YN_BOOLEAN :
599+ return BooleanDecoder .toString ( from );
600+ case DATE :
601+ return "to_char(?1,'YYYY-MM-DD')" ;
602+ case TIME :
603+ return "to_char(?1,'HH24:MI:SS')" ;
604+ case TIMESTAMP :
605+ return "to_char(?1,'YYYY-MM-DD HH24:MI:SS.FF9')" ;
606+ }
607+ break ;
608+ case CLOB :
609+ return "to_clob(?1)" ;
610+ case DATE :
611+ if ( from == CastType .STRING ) {
612+ return "to_date(?1,'YYYY-MM-DD')" ;
613+ }
614+ break ;
615+ case TIME :
616+ if ( from == CastType .STRING ) {
617+ return "to_date(?1,'HH24:MI:SS')" ;
618+ }
619+ break ;
620+ case TIMESTAMP :
621+ if ( from == CastType .STRING ) {
622+ return "to_timestamp(?1,'YYYY-MM-DD HH24:MI:SS.FF9')" ;
623+ }
624+ break ;
625+ }
626+ return super .castPattern (from , to );
627+ }
628+
629+
429630}
0 commit comments