22
33import java .time .LocalDateTime ;
44import java .util .List ;
5+ import java .util .concurrent .ConcurrentHashMap ;
56import org .hibernate .boot .model .FunctionContributions ;
67import org .hibernate .boot .model .TypeContributions ;
78import org .hibernate .dialect .Dialect ;
5152import static org .hibernate .type .SqlTypes .VARBINARY ;
5253import static org .hibernate .type .SqlTypes .VARCHAR ;
5354import org .hibernate .type .StandardBasicTypes ;
55+ import org .hibernate .type .descriptor .jdbc .JdbcType ;
56+ import org .hibernate .type .descriptor .jdbc .spi .JdbcTypeRegistry ;
5457import org .hibernate .type .descriptor .sql .internal .DdlTypeImpl ;
5558import org .hibernate .type .descriptor .sql .spi .DdlTypeRegistry ;
59+ import tech .ydb .hibernate .dialect .code .YdbJdbcCode ;
60+ import static tech .ydb .hibernate .dialect .code .YdbJdbcCode .DECIMAL_SHIFT ;
5661import tech .ydb .hibernate .dialect .exporter .EmptyExporter ;
5762import tech .ydb .hibernate .dialect .exporter .YdbIndexExporter ;
5863import tech .ydb .hibernate .dialect .hint .IndexQueryHintHandler ;
5964import tech .ydb .hibernate .dialect .hint .QueryHintHandler ;
6065import tech .ydb .hibernate .dialect .hint .ScanQueryHintHandler ;
6166import tech .ydb .hibernate .dialect .translator .YdbSqlAstTranslatorFactory ;
67+ import tech .ydb .hibernate .dialect .types .BigDecimalJavaType ;
68+ import tech .ydb .hibernate .dialect .types .DecimalJdbcType ;
6269import tech .ydb .hibernate .dialect .types .InstantJavaType ;
6370import tech .ydb .hibernate .dialect .types .InstantJdbcType ;
6471import tech .ydb .hibernate .dialect .types .LocalDateJavaType ;
6572import tech .ydb .hibernate .dialect .types .LocalDateJdbcType ;
6673import tech .ydb .hibernate .dialect .types .LocalDateTimeJavaType ;
6774import tech .ydb .hibernate .dialect .types .LocalDateTimeJdbcType ;
6875import static tech .ydb .hibernate .dialect .types .LocalDateTimeJdbcType .JDBC_TYPE_DATETIME_CODE ;
76+ import tech .ydb .hibernate .dialect .types .Uint8JdbcType ;
6977
7078/**
7179 * @author Kirill Kurdyukov
7280 */
7381public class YdbDialect extends Dialect {
74-
7582 private static final Exporter <ForeignKey > FOREIGN_KEY_EMPTY_EXPORTER = new EmptyExporter <>();
7683 private static final Exporter <Constraint > UNIQUE_KEY_EMPTY_EXPORTER = new EmptyExporter <>();
7784 private static final List <QueryHintHandler > QUERY_HINT_HANDLERS = List .of (
7885 IndexQueryHintHandler .INSTANCE ,
7986 ScanQueryHintHandler .INSTANCE
8087 );
88+ private static final ConcurrentHashMap <Integer , DecimalJdbcType > DECIMAL_JDBC_TYPE_CACHE = new ConcurrentHashMap <>();
8189
8290 public YdbDialect (DialectResolutionInfo dialectResolutionInfo ) {
8391 super (dialectResolutionInfo );
@@ -93,7 +101,7 @@ protected String columnType(int sqlTypeCode) {
93101 case BIGINT -> "Int64" ;
94102 case REAL , FLOAT -> "Float" ;
95103 case DOUBLE -> "Double" ;
96- case NUMERIC , DECIMAL -> "Decimal (22,9 )" ; // Fixed
104+ case NUMERIC , DECIMAL -> "Decimal($p, $s )" ;
97105 case DATE -> "Date" ;
98106 case JDBC_TYPE_DATETIME_CODE -> "Datetime" ;
99107 case TIME_WITH_TIMEZONE -> "TzDateTime" ;
@@ -117,6 +125,14 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
117125 typeContributions .contributeJdbcType (LocalDateJdbcType .INSTANCE );
118126 typeContributions .contributeJavaType (InstantJavaType .INSTANCE );
119127 typeContributions .contributeJdbcType (InstantJdbcType .INSTANCE );
128+ typeContributions .contributeJdbcType (new DecimalJdbcType (YdbJdbcCode .DECIMAL_22_9 ));
129+ typeContributions .contributeJdbcType (new DecimalJdbcType (YdbJdbcCode .DECIMAL_31_9 ));
130+ typeContributions .contributeJdbcType (new DecimalJdbcType (YdbJdbcCode .DECIMAL_35_0 ));
131+ typeContributions .contributeJdbcType (new DecimalJdbcType (YdbJdbcCode .DECIMAL_35_9 ));
132+
133+ // custom jdbc codec
134+ typeContributions .contributeJdbcType (Uint8JdbcType .INSTANCE );
135+ typeContributions .contributeJavaType (BigDecimalJavaType .INSTANCE_22_9 );
120136 }
121137
122138 @ Override
@@ -125,7 +141,33 @@ protected void registerColumnTypes(TypeContributions typeContributions, ServiceR
125141
126142 final DdlTypeRegistry ddlTypeRegistry = typeContributions .getTypeConfiguration ().getDdlTypeRegistry ();
127143
128- ddlTypeRegistry .addDescriptor (new DdlTypeImpl (JDBC_TYPE_DATETIME_CODE , "Datetime" , "Datetime" , this ));
144+ ddlTypeRegistry .addDescriptor (new DdlTypeImpl (YdbJdbcCode .DATETIME , "Datetime" , "Datetime" , this ));
145+ ddlTypeRegistry .addDescriptor (new DdlTypeImpl (YdbJdbcCode .UINT8 , "Uint8" , "Uint8" , this ));
146+ ddlTypeRegistry .addDescriptor (new DdlTypeImpl (YdbJdbcCode .DECIMAL_22_9 , "Decimal(22, 9)" , "Decimal(22, 9)" , this ));
147+ ddlTypeRegistry .addDescriptor (new DdlTypeImpl (YdbJdbcCode .DECIMAL_31_9 , "Decimal(31, 9)" , "Decimal(31, 9)" , this ));
148+ ddlTypeRegistry .addDescriptor (new DdlTypeImpl (YdbJdbcCode .DECIMAL_35_0 , "Decimal(35, 0)" , "Decimal(35, 0)" , this ));
149+ ddlTypeRegistry .addDescriptor (new DdlTypeImpl (YdbJdbcCode .DECIMAL_35_9 , "Decimal(35, 9)" , "Decimal(35, 9)" , this ));
150+ }
151+
152+ @ Override
153+ public JdbcType resolveSqlTypeDescriptor (
154+ String columnTypeName ,
155+ int jdbcTypeCode ,
156+ int precision ,
157+ int scale ,
158+ JdbcTypeRegistry jdbcTypeRegistry ) {
159+ if ((jdbcTypeCode == NUMERIC || jdbcTypeCode == DECIMAL ) && (precision != 0 || scale != 0 )) {
160+ int sqlCode = DECIMAL_SHIFT + (precision << 6 ) + scale ;
161+
162+ return DECIMAL_JDBC_TYPE_CACHE .computeIfAbsent (sqlCode , DecimalJdbcType ::new );
163+ }
164+
165+ return super .resolveSqlTypeDescriptor (columnTypeName , jdbcTypeCode , precision , scale , jdbcTypeRegistry );
166+ }
167+
168+ @ Override
169+ public int getDefaultDecimalPrecision () {
170+ return 22 ;
129171 }
130172
131173 @ Override
@@ -139,11 +181,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
139181
140182 functionContributions .getFunctionRegistry ().register (
141183 "current_time" ,
142- new CurrentFunction (
143- "current_time" ,
144- currentTime (),
145- localDateTimeType
146- )
184+ new CurrentFunction ("current_time" , currentTime (), localDateTimeType )
147185 );
148186 }
149187
0 commit comments