4
4
5
5
package net .snowflake .client .core ;
6
6
7
- import static net .snowflake .client .jdbc .SnowflakeUtil .getTimestampFromType ;
8
-
9
7
import com .fasterxml .jackson .core .JsonProcessingException ;
10
8
import com .fasterxml .jackson .databind .JsonNode ;
11
9
import com .fasterxml .jackson .databind .ObjectMapper ;
16
14
import java .sql .Time ;
17
15
import java .sql .Timestamp ;
18
16
import java .sql .Types ;
19
- import java .time .Instant ;
20
- import java .time .ZoneOffset ;
21
- import java .util .HashMap ;
22
17
import java .util .Iterator ;
23
18
import java .util .Map ;
24
19
import java .util .Spliterator ;
33
28
import net .snowflake .client .jdbc .SnowflakeColumnMetadata ;
34
29
import net .snowflake .client .log .SFLogger ;
35
30
import net .snowflake .client .log .SFLoggerFactory ;
36
- import net .snowflake .client .util .TypeConverter ;
37
- import net .snowflake .common .core .SFTimestamp ;
38
- import net .snowflake .common .core .SnowflakeDateTimeFormat ;
31
+ import net .snowflake .client .util .JsonStringToTypeConverter ;
39
32
40
33
/** Abstract class used to represent snowflake result set in json format */
41
34
public abstract class SFJsonResultSet extends SFBaseResultSet {
@@ -102,13 +95,13 @@ public Object getObject(int columnIndex) throws SFException {
102
95
return getBoolean (columnIndex );
103
96
104
97
case Types .STRUCT :
105
- if (Boolean .valueOf (System .getProperty (STRUCTURED_TYPE_ENABLED_PROPERTY_NAME ))) {
98
+ if (Boolean .parseBoolean (System .getProperty (STRUCTURED_TYPE_ENABLED_PROPERTY_NAME ))) {
106
99
return getSqlInput ((String ) obj , columnIndex );
107
100
} else {
108
101
throw new SFException (ErrorCode .FEATURE_UNSUPPORTED , "data type: " + type );
109
102
}
110
103
case Types .ARRAY :
111
- if (Boolean .valueOf (System .getProperty (STRUCTURED_TYPE_ENABLED_PROPERTY_NAME ))) {
104
+ if (Boolean .parseBoolean (System .getProperty (STRUCTURED_TYPE_ENABLED_PROPERTY_NAME ))) {
112
105
return getArray (columnIndex );
113
106
} else {
114
107
throw new SFException (ErrorCode .FEATURE_UNSUPPORTED , "data type: " + type );
@@ -122,7 +115,7 @@ public Object getObject(int columnIndex) throws SFException {
122
115
@ Override
123
116
public Array getArray (int columnIndex ) throws SFException {
124
117
Object obj = getObjectInternal (columnIndex );
125
- return getArrayInternal ((String ) obj );
118
+ return getArrayInternal ((String ) obj , columnIndex );
126
119
}
127
120
128
121
@ Override
@@ -257,6 +250,8 @@ private Timestamp getTimestamp(int columnIndex) throws SFException {
257
250
return getTimestamp (columnIndex , TimeZone .getDefault ());
258
251
}
259
252
253
+ @ Override
254
+ @ SnowflakeJdbcInternalApi
260
255
public Converters getConverters () {
261
256
return converters ;
262
257
}
@@ -274,134 +269,116 @@ private Object getSqlInput(String input, int columnIndex) throws SFException {
274
269
}
275
270
}
276
271
277
- private SfSqlArray getArrayInternal (String obj ) throws SFException {
272
+ private SfSqlArray getArrayInternal (String obj , int columnIndex ) throws SFException {
278
273
try {
279
- SnowflakeColumnMetadata arrayMetadata = resultSetMetaData .getColumnMetadata ().get (0 );
280
- FieldMetadata fieldMetadata = arrayMetadata .getField (1 );
274
+ SnowflakeColumnMetadata arrayMetadata =
275
+ resultSetMetaData .getColumnMetadata ().get (columnIndex - 1 );
276
+ FieldMetadata fieldMetadata = arrayMetadata .getFields ().get (0 );
281
277
282
278
int columnSubType = fieldMetadata .getType ();
283
279
int columnType = ColumnTypeHelper .getColumnType (columnSubType , session );
284
280
int scale = fieldMetadata .getScale ();
285
281
286
282
ArrayNode arrayNode = (ArrayNode ) OBJECT_MAPPER .readTree (obj );
287
-
288
- Iterator nodeElements = arrayNode .elements ();
283
+ Iterator <JsonNode > nodeElements = arrayNode .elements ();
289
284
290
285
switch (columnSubType ) {
291
286
case Types .INTEGER :
287
+ return new SfSqlArray (
288
+ columnSubType ,
289
+ getStream (nodeElements , converters .integerConverter (columnType ))
290
+ .toArray (Integer []::new ));
292
291
case Types .SMALLINT :
292
+ return new SfSqlArray (
293
+ columnSubType ,
294
+ getStream (nodeElements , converters .smallIntConverter (columnType ))
295
+ .toArray (Short []::new ));
293
296
case Types .TINYINT :
294
- TypeConverter integerConverter =
295
- value -> converters .getNumberConverter ().getInt (value , Types .INTEGER );
296
297
return new SfSqlArray (
297
- columnSubType , getStream (nodeElements , integerConverter ).toArray (Integer []::new ));
298
+ columnSubType ,
299
+ getStream (nodeElements , converters .tinyIntConverter (columnType ))
300
+ .toArray (Byte []::new ));
298
301
case Types .BIGINT :
302
+ return new SfSqlArray (
303
+ columnSubType ,
304
+ getStream (nodeElements , converters .bigIntConverter (columnType )).toArray (Long []::new ));
299
305
case Types .DECIMAL :
300
306
case Types .NUMERIC :
301
- TypeConverter bigIntConverter =
302
- value -> converters .getNumberConverter ().getBigInt (value , Types .BIGINT );
303
307
return new SfSqlArray (
304
- columnSubType , convertToNumericArray (nodeElements , bigIntConverter ));
308
+ columnSubType ,
309
+ convertToFixedArray (nodeElements , converters .bigDecimalConverter (columnType )));
305
310
case Types .CHAR :
306
311
case Types .VARCHAR :
307
312
case Types .LONGNVARCHAR :
308
- TypeConverter varcharConverter = value -> value .toString ();
309
313
return new SfSqlArray (
310
- columnSubType , getStream (nodeElements , varcharConverter ).toArray (String []::new ));
314
+ columnSubType ,
315
+ getStream (nodeElements , converters .varcharConverter (columnType , columnSubType , scale ))
316
+ .toArray (String []::new ));
311
317
case Types .BINARY :
312
- TypeConverter bytesConverter =
313
- value ->
314
- converters .getBytesConverter ().getBytes (value , columnType , Types .BINARY , scale );
315
318
return new SfSqlArray (
316
- columnSubType , getStream (nodeElements , bytesConverter ).toArray (Object []::new ));
319
+ columnSubType ,
320
+ getStream (nodeElements , converters .bytesConverter (columnType , scale ))
321
+ .toArray (Byte [][]::new ));
317
322
case Types .FLOAT :
323
+ case Types .REAL :
324
+ return new SfSqlArray (
325
+ columnSubType ,
326
+ getStream (nodeElements , converters .floatConverter (columnType )).toArray (Float []::new ));
318
327
case Types .DOUBLE :
319
- TypeConverter doubleConverter =
320
- value -> converters .getNumberConverter ().getDouble (value , Types .DOUBLE );
321
328
return new SfSqlArray (
322
- columnSubType , getStream (nodeElements , doubleConverter ).toArray (Double []::new ));
329
+ columnSubType ,
330
+ getStream (nodeElements , converters .doubleConverter (columnType ))
331
+ .toArray (Double []::new ));
323
332
case Types .DATE :
324
- TypeConverter dateConverter =
325
- value -> {
326
- SnowflakeDateTimeFormat formatter =
327
- SnowflakeDateTimeFormat .fromSqlFormat (
328
- (String ) session .getCommonParameters ().get ("DATE_OUTPUT_FORMAT" ));
329
- SFTimestamp timestamp = formatter .parse ((String ) value );
330
- return Date .valueOf (
331
- Instant .ofEpochMilli (timestamp .getTime ()).atZone (ZoneOffset .UTC ).toLocalDate ());
332
- };
333
333
return new SfSqlArray (
334
- columnSubType , getStream (nodeElements , dateConverter ).toArray (Date []::new ));
334
+ columnSubType ,
335
+ getStream (nodeElements , converters .dateConverter (session )).toArray (Date []::new ));
335
336
case Types .TIME :
336
- TypeConverter timeConverter =
337
- value -> {
338
- SnowflakeDateTimeFormat formatter =
339
- SnowflakeDateTimeFormat .fromSqlFormat (
340
- (String ) session .getCommonParameters ().get ("TIME_OUTPUT_FORMAT" ));
341
- SFTimestamp timestamp = formatter .parse ((String ) value );
342
- return Time .valueOf (
343
- Instant .ofEpochMilli (timestamp .getTime ()).atZone (ZoneOffset .UTC ).toLocalTime ());
344
- };
345
337
return new SfSqlArray (
346
- columnSubType , getStream (nodeElements , timeConverter ).toArray (Time []::new ));
338
+ columnSubType ,
339
+ getStream (nodeElements , converters .timeConverter (session )).toArray (Time []::new ));
347
340
case Types .TIMESTAMP :
348
- TypeConverter timestampConverter =
349
- value -> {
350
- Timestamp result = getTimestampFromType (columnSubType , (String ) value , session );
351
- if (result != null ) {
352
- return result ;
353
- }
354
- return converters
355
- .getDateTimeConverter ()
356
- .getTimestamp (value , columnType , columnSubType , null , scale );
357
- };
358
341
return new SfSqlArray (
359
- columnSubType , getStream (nodeElements , timestampConverter ).toArray (Timestamp []::new ));
342
+ columnSubType ,
343
+ getStream (
344
+ nodeElements ,
345
+ converters .timestampConverter (columnSubType , columnType , scale , session ))
346
+ .toArray (Timestamp []::new ));
360
347
case Types .BOOLEAN :
361
- TypeConverter booleanConverter =
362
- value -> converters .getBooleanConverter ().getBoolean (value , columnType );
363
348
return new SfSqlArray (
364
- columnSubType , getStream (nodeElements , booleanConverter ).toArray (Boolean []::new ));
349
+ columnSubType ,
350
+ getStream (nodeElements , converters .booleanConverter (columnType ))
351
+ .toArray (Boolean []::new ));
365
352
case Types .STRUCT :
366
- TypeConverter structConverter =
367
- value -> {
368
- try {
369
- return OBJECT_MAPPER .readValue (value , Map .class );
370
- } catch (JsonProcessingException e ) {
371
- throw new SFException (e , ErrorCode .INVALID_STRUCT_DATA );
372
- }
373
- };
374
353
return new SfSqlArray (
375
- columnSubType , getStream (nodeElements , structConverter ).toArray (Map []::new ));
354
+ columnSubType ,
355
+ getStream (nodeElements , converters .structConverter (OBJECT_MAPPER ))
356
+ .toArray (Map []::new ));
376
357
case Types .ARRAY :
377
- TypeConverter arrayConverter =
378
- value -> {
379
- try {
380
- return OBJECT_MAPPER .readValue (value , HashMap [].class );
381
- } catch (JsonProcessingException e ) {
382
- throw new SFException (e , ErrorCode .INVALID_STRUCT_DATA );
383
- }
384
- };
385
358
return new SfSqlArray (
386
- columnSubType , getStream (nodeElements , arrayConverter ).toArray (Map [][]::new ));
359
+ columnSubType ,
360
+ getStream (nodeElements , converters .arrayConverter (OBJECT_MAPPER ))
361
+ .toArray (Map [][]::new ));
387
362
default :
388
- return null ;
363
+ throw new SFException (
364
+ ErrorCode .FEATURE_UNSUPPORTED ,
365
+ "Can't construct array for data type: " + columnSubType );
389
366
}
390
367
} catch (JsonProcessingException e ) {
391
368
throw new SFException (e , ErrorCode .INVALID_STRUCT_DATA );
392
369
}
393
370
}
394
371
395
- private Object [] convertToNumericArray (Iterator nodeElements , TypeConverter bigIntConverter ) {
372
+ private Object [] convertToFixedArray (
373
+ Iterator nodeElements , JsonStringToTypeConverter bigIntConverter ) {
396
374
AtomicInteger bigDecimalCount = new AtomicInteger ();
397
375
Object [] elements =
398
376
getStream (nodeElements , bigIntConverter )
399
- .map (
377
+ .peek (
400
378
elem -> {
401
379
if (elem instanceof BigDecimal ) {
402
380
bigDecimalCount .incrementAndGet ();
403
381
}
404
- return elem ;
405
382
})
406
383
.toArray (
407
384
size -> {
@@ -413,7 +390,7 @@ private Object[] convertToNumericArray(Iterator nodeElements, TypeConverter bigI
413
390
return elements ;
414
391
}
415
392
416
- private Stream getStream (Iterator nodeElements , TypeConverter converter ) {
393
+ private Stream getStream (Iterator nodeElements , JsonStringToTypeConverter converter ) {
417
394
return StreamSupport .stream (
418
395
Spliterators .spliteratorUnknownSize (nodeElements , Spliterator .ORDERED ), false )
419
396
.map (
@@ -426,8 +403,8 @@ private Stream getStream(Iterator nodeElements, TypeConverter converter) {
426
403
});
427
404
}
428
405
429
- private static Object convert (TypeConverter converter , JsonNode elem ) throws SFException {
430
- JsonNode node = elem ;
406
+ private static Object convert (JsonStringToTypeConverter converter , JsonNode node )
407
+ throws SFException {
431
408
if (node .isValueNode ()) {
432
409
return converter .convert (node .asText ());
433
410
} else {
0 commit comments