|
15 | 15 | import java.util.List; |
16 | 16 | import java.util.Map; |
17 | 17 |
|
18 | | -import io.grpc.netty.shaded.io.netty.util.collection.IntObjectHashMap; |
19 | | -import io.grpc.netty.shaded.io.netty.util.collection.IntObjectMap; |
20 | | - |
21 | 18 | import tech.ydb.jdbc.YdbConst; |
22 | 19 | import tech.ydb.table.values.DecimalType; |
23 | 20 | import tech.ydb.table.values.DecimalValue; |
|
29 | 26 | public class YdbTypes { |
30 | 27 | private static final YdbTypes INSTANCE = new YdbTypes(); |
31 | 28 |
|
32 | | - private final IntObjectMap<Type> typeBySqlType; |
| 29 | + private final Map<Integer, Type> typeBySqlType; |
33 | 30 | private final Map<Class<?>, Type> typeByClass; |
34 | 31 |
|
35 | | - private final Map<Type, Integer> sqlTypeByPrimitiveNumId; |
36 | | - |
37 | 32 | private YdbTypes() { |
38 | | - typeBySqlType = new IntObjectHashMap<>(18 + PrimitiveType.values().length); |
| 33 | + typeBySqlType = new HashMap<>(); |
39 | 34 |
|
40 | 35 | // Store custom type ids to use it for PrepaparedStatement.setObject |
41 | | - for (PrimitiveType type: PrimitiveType.values()) { |
42 | | - typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + type.ordinal(), type); |
43 | | - } |
| 36 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 0, PrimitiveType.Bool); |
| 37 | + |
| 38 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 1, PrimitiveType.Int8); |
| 39 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 2, PrimitiveType.Uint8); |
| 40 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 3, PrimitiveType.Int16); |
| 41 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 4, PrimitiveType.Uint16); |
| 42 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 5, PrimitiveType.Int32); |
| 43 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 6, PrimitiveType.Uint32); |
| 44 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 7, PrimitiveType.Int64); |
| 45 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 8, PrimitiveType.Uint64); |
| 46 | + |
| 47 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 9, PrimitiveType.Float); |
| 48 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 10, PrimitiveType.Double); |
| 49 | + |
| 50 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 11, PrimitiveType.Bytes); |
| 51 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 12, PrimitiveType.Text); |
| 52 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 13, PrimitiveType.Yson); |
| 53 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 14, PrimitiveType.Json); |
| 54 | + |
| 55 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 15, PrimitiveType.Uuid); |
| 56 | + |
| 57 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 16, PrimitiveType.Date); |
| 58 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 17, PrimitiveType.Datetime); |
| 59 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 18, PrimitiveType.Timestamp); |
| 60 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 19, PrimitiveType.Interval); |
| 61 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 20, PrimitiveType.TzDate); |
| 62 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 21, PrimitiveType.TzDatetime); |
| 63 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 22, PrimitiveType.TzTimestamp); |
| 64 | + |
| 65 | + typeBySqlType.put(YdbConst.SQL_KIND_PRIMITIVE + 23, PrimitiveType.JsonDocument); |
44 | 66 |
|
45 | 67 | typeBySqlType.put(Types.VARCHAR, PrimitiveType.Text); |
46 | 68 | typeBySqlType.put(Types.BIGINT, PrimitiveType.Int64); |
@@ -104,71 +126,21 @@ private YdbTypes() { |
104 | 126 | typeByClass.put(DecimalValue.class, DecimalType.getDefault()); |
105 | 127 | typeByClass.put(BigDecimal.class, DecimalType.getDefault()); |
106 | 128 | typeByClass.put(Duration.class, PrimitiveType.Interval); |
107 | | - |
108 | | - sqlTypeByPrimitiveNumId = new HashMap<>(PrimitiveType.values().length); |
109 | | - for (PrimitiveType id : PrimitiveType.values()) { |
110 | | - final int sqlType; |
111 | | - switch (id) { |
112 | | - case Text: |
113 | | - case Json: |
114 | | - case JsonDocument: |
115 | | - case Uuid: |
116 | | - sqlType = Types.VARCHAR; |
117 | | - break; |
118 | | - case Bytes: |
119 | | - case Yson: |
120 | | - sqlType = Types.BINARY; |
121 | | - break; |
122 | | - case Bool: |
123 | | - sqlType = Types.BOOLEAN; |
124 | | - break; |
125 | | - case Int8: |
126 | | - case Int16: |
127 | | - sqlType = Types.SMALLINT; |
128 | | - break; |
129 | | - case Uint8: |
130 | | - case Int32: |
131 | | - case Uint16: |
132 | | - sqlType = Types.INTEGER; |
133 | | - break; |
134 | | - case Uint32: |
135 | | - case Int64: |
136 | | - case Uint64: |
137 | | - case Interval: |
138 | | - sqlType = Types.BIGINT; |
139 | | - break; |
140 | | - case Float: |
141 | | - sqlType = Types.FLOAT; |
142 | | - break; |
143 | | - case Double: |
144 | | - sqlType = Types.DOUBLE; |
145 | | - break; |
146 | | - case Date: |
147 | | - sqlType = Types.DATE; |
148 | | - break; |
149 | | - case Datetime: |
150 | | - sqlType = Types.TIMESTAMP; |
151 | | - break; |
152 | | - case Timestamp: |
153 | | - sqlType = Types.TIMESTAMP; |
154 | | - break; |
155 | | - case TzDate: |
156 | | - case TzDatetime: |
157 | | - case TzTimestamp: |
158 | | - sqlType = Types.TIMESTAMP_WITH_TIMEZONE; |
159 | | - break; |
160 | | - default: |
161 | | - sqlType = Types.JAVA_OBJECT; |
162 | | - } |
163 | | - sqlTypeByPrimitiveNumId.put(id, sqlType); |
164 | | - } |
165 | 129 | } |
166 | 130 |
|
167 | 131 | public static Type findType(Object obj, int sqlType) { |
168 | 132 | return INSTANCE.findTypeImpl(obj, sqlType); |
169 | 133 | } |
170 | 134 |
|
171 | 135 | private Type findTypeImpl(Object obj, int sqlType) { |
| 136 | + if ((sqlType & YdbConst.SQL_KIND_DECIMAL) != 0) { |
| 137 | + int precision = ((sqlType - YdbConst.SQL_KIND_DECIMAL) >> 5); |
| 138 | + int scale = ((sqlType - YdbConst.SQL_KIND_DECIMAL) & 0b11111); |
| 139 | + if (precision > 0 && precision < 36 && scale >= 0 && scale <= precision) { |
| 140 | + return DecimalType.of(precision, scale); |
| 141 | + } |
| 142 | + } |
| 143 | + |
172 | 144 | if (typeBySqlType.containsKey(sqlType)) { |
173 | 145 | return typeBySqlType.get(sqlType); |
174 | 146 | } |
@@ -196,14 +168,54 @@ public static int toSqlType(Type type) { |
196 | 168 | private int toSqlTypeImpl(Type type) { |
197 | 169 | switch (type.getKind()) { |
198 | 170 | case PRIMITIVE: |
199 | | - if (!sqlTypeByPrimitiveNumId.containsKey(type)) { |
200 | | - throw new RuntimeException("Internal error. Unsupported YDB type: " + type); |
| 171 | + switch ((PrimitiveType) type) { |
| 172 | + case Text: |
| 173 | + case Json: |
| 174 | + case JsonDocument: |
| 175 | + case Uuid: |
| 176 | + return Types.VARCHAR; |
| 177 | + case Bytes: |
| 178 | + case Yson: |
| 179 | + return Types.BINARY; |
| 180 | + case Bool: |
| 181 | + return Types.BOOLEAN; |
| 182 | + case Int8: |
| 183 | + case Int16: |
| 184 | + return Types.SMALLINT; |
| 185 | + case Uint8: |
| 186 | + case Int32: |
| 187 | + case Uint16: |
| 188 | + return Types.INTEGER; |
| 189 | + case Uint32: |
| 190 | + case Int64: |
| 191 | + case Uint64: |
| 192 | + case Interval: |
| 193 | + return Types.BIGINT; |
| 194 | + case Float: |
| 195 | + return Types.FLOAT; |
| 196 | + case Double: |
| 197 | + return Types.DOUBLE; |
| 198 | + case Date: |
| 199 | + return Types.DATE; |
| 200 | + case Datetime: |
| 201 | + return Types.TIMESTAMP; |
| 202 | + case Timestamp: |
| 203 | + return Types.TIMESTAMP; |
| 204 | + case TzDate: |
| 205 | + case TzDatetime: |
| 206 | + case TzTimestamp: |
| 207 | + return Types.TIMESTAMP_WITH_TIMEZONE; |
| 208 | + default: |
| 209 | + return Types.JAVA_OBJECT; |
201 | 210 | } |
202 | | - return sqlTypeByPrimitiveNumId.get(type); |
203 | 211 | case OPTIONAL: |
204 | 212 | return toSqlTypeImpl(type.unwrapOptional()); |
205 | 213 | case DECIMAL: |
206 | | - return Types.DECIMAL; |
| 214 | + DecimalType decimal = (DecimalType) type; |
| 215 | + if (DecimalType.getDefault().equals(type)) { |
| 216 | + return Types.DECIMAL; |
| 217 | + } |
| 218 | + return YdbConst.SQL_KIND_DECIMAL + decimal.getPrecision() << 5 + decimal.getScale(); |
207 | 219 | case STRUCT: |
208 | 220 | return Types.STRUCT; |
209 | 221 | case LIST: |
@@ -287,8 +299,6 @@ private List<Type> getAllDatabaseTypesImpl() { |
287 | 299 | DecimalType.getDefault()); |
288 | 300 | } |
289 | 301 |
|
290 | | - // |
291 | | - |
292 | 302 | private int getSqlPrecisionImpl(PrimitiveType type) { |
293 | 303 | switch (type) { |
294 | 304 | case Bool: |
|
0 commit comments