Skip to content

Commit 9a84730

Browse files
committed
SNOW-2249786 Initialize ObjectMapper once in result sets
1 parent cc49611 commit 9a84730

File tree

9 files changed

+128
-87
lines changed

9 files changed

+128
-87
lines changed

src/main/java/net/snowflake/client/core/ObjectMapperFactory.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44
import com.fasterxml.jackson.databind.DeserializationFeature;
55
import com.fasterxml.jackson.databind.MapperFeature;
66
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import java.text.SimpleDateFormat;
8+
import net.snowflake.client.log.SFLogger;
9+
import net.snowflake.client.log.SFLoggerFactory;
710

811
/**
912
* Factor method used to create ObjectMapper instance. All object mapper in JDBC should be created
1013
* by this method.
1114
*/
1215
public class ObjectMapperFactory {
16+
private static final SFLogger log = SFLoggerFactory.getLogger(ObjectMapperFactory.class);
17+
1318
@SnowflakeJdbcInternalApi
1419
// Snowflake allows up to 128M (after updating Max LOB size) string size and returns base64
1520
// encoded value that makes it up to 180M
@@ -35,4 +40,21 @@ public static ObjectMapper getObjectMapper() {
3540
StreamReadConstraints.builder().maxStringLength(maxJsonStringLength).build());
3641
return mapper;
3742
}
43+
44+
@SnowflakeJdbcInternalApi
45+
public static ObjectMapper getObjectMapperForSession(SFBaseSession session) {
46+
ObjectMapper mapper = getObjectMapper();
47+
if (session != null && session.getCommonParameters() != null) {
48+
// Set the mapper to use the session's object mapper settings
49+
Object dateOutputFormat = session.getCommonParameters().get("DATE_OUTPUT_FORMAT");
50+
if (dateOutputFormat != null) {
51+
mapper.setDateFormat(new SimpleDateFormat(String.valueOf(dateOutputFormat)));
52+
} else {
53+
log.debug("DATE_OUTPUT_FORMAT is not set in session parameters.");
54+
}
55+
} else {
56+
log.debug("Initialized object mapper without session or parameter settings.");
57+
}
58+
return mapper;
59+
}
3860
}

src/main/java/net/snowflake/client/core/SFArrowResultSet.java

Lines changed: 41 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
/** Arrow result set implementation */
5454
public class SFArrowResultSet extends SFBaseResultSet implements DataConversionContext {
5555
private static final SFLogger logger = SFLoggerFactory.getLogger(SFArrowResultSet.class);
56-
private static final ObjectMapper OBJECT_MAPPER = ObjectMapperFactory.getObjectMapper();
5756

5857
/** iterator over current arrow result chunk */
5958
private ArrowChunkIterator currentChunkIterator;
@@ -113,6 +112,8 @@ public class SFArrowResultSet extends SFBaseResultSet implements DataConversionC
113112

114113
@SnowflakeJdbcInternalApi protected Converters converters;
115114

115+
private final ObjectMapper objectMapper;
116+
116117
/**
117118
* Constructor takes a result from the API response that we get from executing a SQL statement.
118119
*
@@ -212,6 +213,7 @@ public SFArrowResultSet(
212213
this.treatNTZAsUTC = resultSetSerializable.getTreatNTZAsUTC();
213214
this.formatDateWithTimezone = resultSetSerializable.getFormatDateWithTimeZone();
214215
this.useSessionTimezone = resultSetSerializable.getUseSessionTimezone();
216+
objectMapper = ObjectMapperFactory.getObjectMapperForSession(session);
215217

216218
// sort result set if needed
217219
String rowsetBase64 = resultSetSerializable.getFirstChunkStringData();
@@ -595,7 +597,7 @@ private StructObjectWrapper getObjectRepresentation(int columnIndex, boolean wit
595597
JsonSqlInput jsonSqlInput = createJsonSqlInput(columnIndex, obj);
596598
return new StructObjectWrapper(jsonSqlInput.getText(), jsonSqlInput);
597599
} else if (type == Types.ARRAY) {
598-
SfSqlArray sfArray = getJsonArray((String) obj, columnIndex);
600+
SfSqlArray sfArray = getJsonArray((String) obj, columnIndex, objectMapper);
599601
return new StructObjectWrapper(sfArray.getText(), sfArray);
600602
} else {
601603
throw new SFException(queryId, ErrorCode.INVALID_STRUCT_DATA);
@@ -637,7 +639,7 @@ private JsonSqlInput createJsonSqlInput(int columnIndex, Object obj) throws SFEx
637639
return null;
638640
}
639641
String text = (String) obj;
640-
JsonNode jsonNode = OBJECT_MAPPER.readTree(text);
642+
JsonNode jsonNode = objectMapper.readTree(text);
641643
return new JsonSqlInput(
642644
text,
643645
jsonNode,
@@ -660,7 +662,7 @@ public Array getArray(int columnIndex) throws SFException {
660662
return null;
661663
}
662664
if (converter instanceof VarCharConverter) {
663-
return getJsonArray((String) obj, columnIndex);
665+
return getJsonArray((String) obj, columnIndex, objectMapper);
664666
} else if (converter instanceof ArrayConverter || converter instanceof VectorTypeConverter) {
665667
String jsonString = converter.toString(index);
666668
return getArrowArray(jsonString, (List<Object>) obj, columnIndex);
@@ -686,109 +688,96 @@ private SfSqlArray getArrowArray(String text, List<Object> elements, int columnI
686688

687689
switch (columnType) {
688690
case Types.INTEGER:
689-
return new SfSqlArray(
691+
return getSfSqlArray(
690692
text,
691693
columnSubType,
692694
mapAndConvert(elements, converters.integerConverter(columnType))
693-
.toArray(Integer[]::new),
694-
session);
695+
.toArray(Integer[]::new));
695696
case Types.SMALLINT:
696-
return new SfSqlArray(
697+
return getSfSqlArray(
697698
text,
698699
columnSubType,
699700
mapAndConvert(elements, converters.smallIntConverter(columnType))
700-
.toArray(Short[]::new),
701-
session);
701+
.toArray(Short[]::new));
702702
case Types.TINYINT:
703-
return new SfSqlArray(
703+
return getSfSqlArray(
704704
text,
705705
columnSubType,
706-
mapAndConvert(elements, converters.tinyIntConverter(columnType)).toArray(Byte[]::new),
707-
session);
706+
mapAndConvert(elements, converters.tinyIntConverter(columnType))
707+
.toArray(Byte[]::new));
708708
case Types.BIGINT:
709-
return new SfSqlArray(
709+
return getSfSqlArray(
710710
text,
711711
columnSubType,
712-
mapAndConvert(elements, converters.bigIntConverter(columnType)).toArray(Long[]::new),
713-
session);
712+
mapAndConvert(elements, converters.bigIntConverter(columnType)).toArray(Long[]::new));
714713
case Types.DECIMAL:
715714
case Types.NUMERIC:
716-
return new SfSqlArray(
715+
return getSfSqlArray(
717716
text,
718717
columnSubType,
719718
mapAndConvert(elements, converters.bigDecimalConverter(columnType))
720-
.toArray(BigDecimal[]::new),
721-
session);
719+
.toArray(BigDecimal[]::new));
722720
case Types.CHAR:
723721
case Types.VARCHAR:
724722
case Types.LONGNVARCHAR:
725-
return new SfSqlArray(
723+
return getSfSqlArray(
726724
text,
727725
columnSubType,
728726
mapAndConvert(elements, converters.varcharConverter(columnType, columnSubType, scale))
729-
.toArray(String[]::new),
730-
session);
727+
.toArray(String[]::new));
731728
case Types.BINARY:
732-
return new SfSqlArray(
729+
return getSfSqlArray(
733730
text,
734731
columnSubType,
735732
mapAndConvert(elements, converters.bytesConverter(columnType, scale))
736-
.toArray(Byte[][]::new),
737-
session);
733+
.toArray(Byte[][]::new));
738734
case Types.FLOAT:
739735
case Types.REAL:
740-
return new SfSqlArray(
736+
return getSfSqlArray(
741737
text,
742738
columnSubType,
743-
mapAndConvert(elements, converters.floatConverter(columnType)).toArray(Float[]::new),
744-
session);
739+
mapAndConvert(elements, converters.floatConverter(columnType)).toArray(Float[]::new));
745740
case Types.DOUBLE:
746-
return new SfSqlArray(
741+
return getSfSqlArray(
747742
text,
748743
columnSubType,
749744
mapAndConvert(elements, converters.doubleConverter(columnType))
750-
.toArray(Double[]::new),
751-
session);
745+
.toArray(Double[]::new));
752746
case Types.DATE:
753-
return new SfSqlArray(
747+
return getSfSqlArray(
754748
text,
755749
columnSubType,
756750
mapAndConvert(elements, converters.dateFromIntConverter(sessionTimeZone))
757-
.toArray(Date[]::new),
758-
session);
751+
.toArray(Date[]::new));
759752
case Types.TIME:
760-
return new SfSqlArray(
753+
return getSfSqlArray(
761754
text,
762755
columnSubType,
763-
mapAndConvert(elements, converters.timeFromIntConverter(scale)).toArray(Time[]::new),
764-
session);
756+
mapAndConvert(elements, converters.timeFromIntConverter(scale)).toArray(Time[]::new));
765757
case Types.TIMESTAMP:
766-
return new SfSqlArray(
758+
return getSfSqlArray(
767759
text,
768760
columnSubType,
769761
mapAndConvert(
770762
elements,
771763
converters.timestampFromStructConverter(
772764
columnType, columnSubType, sessionTimeZone, scale))
773-
.toArray(Timestamp[]::new),
774-
session);
765+
.toArray(Timestamp[]::new));
775766
case Types.BOOLEAN:
776-
return new SfSqlArray(
767+
return getSfSqlArray(
777768
text,
778769
columnSubType,
779770
mapAndConvert(elements, converters.booleanConverter(columnType))
780-
.toArray(Boolean[]::new),
781-
session);
771+
.toArray(Boolean[]::new));
782772
case Types.STRUCT:
783-
return new SfSqlArray(
784-
text, columnSubType, mapAndConvert(elements, e -> e).toArray(Map[]::new), session);
773+
return getSfSqlArray(
774+
text, columnSubType, mapAndConvert(elements, e -> e).toArray(Map[]::new));
785775
case Types.ARRAY:
786-
return new SfSqlArray(
776+
return getSfSqlArray(
787777
text,
788778
columnSubType,
789779
mapAndConvert(elements, e -> ((List) e).stream().toArray(Map[]::new))
790-
.toArray(Map[][]::new),
791-
session);
780+
.toArray(Map[][]::new));
792781
default:
793782
throw new SFException(
794783
queryId,
@@ -800,6 +789,10 @@ private SfSqlArray getArrowArray(String text, List<Object> elements, int columnI
800789
}
801790
}
802791

792+
private SfSqlArray getSfSqlArray(String text, int columnSubType, Object[] array) {
793+
return new SfSqlArray(text, columnSubType, array, session, objectMapper);
794+
}
795+
803796
private <T> Stream<T> mapAndConvert(List<Object> elements, Converter<T> converter) {
804797
return elements.stream()
805798
.map(

src/main/java/net/snowflake/client/core/SFBaseResultSet.java

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ protected SQLInput createJsonSqlInputForColumn(
272272
}
273273

274274
@SnowflakeJdbcInternalApi
275-
protected SfSqlArray getJsonArray(String arrayString, int columnIndex) throws SFException {
275+
protected SfSqlArray getJsonArray(String arrayString, int columnIndex, ObjectMapper objectMapper)
276+
throws SFException {
276277
try {
277278
List<FieldMetadata> fieldMetadataList = resultSetMetaData.getColumnFields(columnIndex);
278279
if (fieldMetadataList.size() != 1) {
@@ -297,36 +298,41 @@ protected SfSqlArray getJsonArray(String arrayString, int columnIndex) throws SF
297298
columnSubType,
298299
getStream(nodeElements, getConverters().integerConverter(columnType))
299300
.toArray(Integer[]::new),
300-
session);
301+
session,
302+
objectMapper);
301303
case Types.SMALLINT:
302304
return new SfSqlArray(
303305
arrayString,
304306
columnSubType,
305307
getStream(nodeElements, getConverters().smallIntConverter(columnType))
306308
.toArray(Short[]::new),
307-
session);
309+
session,
310+
objectMapper);
308311
case Types.TINYINT:
309312
return new SfSqlArray(
310313
arrayString,
311314
columnSubType,
312315
getStream(nodeElements, getConverters().tinyIntConverter(columnType))
313316
.toArray(Byte[]::new),
314-
session);
317+
session,
318+
objectMapper);
315319
case Types.BIGINT:
316320
return new SfSqlArray(
317321
arrayString,
318322
columnSubType,
319323
getStream(nodeElements, getConverters().bigIntConverter(columnType))
320324
.toArray(Long[]::new),
321-
session);
325+
session,
326+
objectMapper);
322327
case Types.DECIMAL:
323328
case Types.NUMERIC:
324329
return new SfSqlArray(
325330
arrayString,
326331
columnSubType,
327332
convertToFixedArray(
328333
getStream(nodeElements, getConverters().bigDecimalConverter(columnType))),
329-
session);
334+
session,
335+
objectMapper);
330336
case Types.CHAR:
331337
case Types.VARCHAR:
332338
case Types.LONGNVARCHAR:
@@ -337,43 +343,49 @@ protected SfSqlArray getJsonArray(String arrayString, int columnIndex) throws SF
337343
nodeElements,
338344
getConverters().varcharConverter(columnType, columnSubType, scale))
339345
.toArray(String[]::new),
340-
session);
346+
session,
347+
objectMapper);
341348
case Types.BINARY:
342349
return new SfSqlArray(
343350
arrayString,
344351
columnSubType,
345352
getStream(nodeElements, getConverters().bytesConverter(columnType, scale))
346353
.toArray(Byte[][]::new),
347-
session);
354+
session,
355+
objectMapper);
348356
case Types.FLOAT:
349357
case Types.REAL:
350358
return new SfSqlArray(
351359
arrayString,
352360
columnSubType,
353361
getStream(nodeElements, getConverters().floatConverter(columnType))
354362
.toArray(Float[]::new),
355-
session);
363+
session,
364+
objectMapper);
356365
case Types.DOUBLE:
357366
return new SfSqlArray(
358367
arrayString,
359368
columnSubType,
360369
getStream(nodeElements, getConverters().doubleConverter(columnType))
361370
.toArray(Double[]::new),
362-
session);
371+
session,
372+
objectMapper);
363373
case Types.DATE:
364374
return new SfSqlArray(
365375
arrayString,
366376
columnSubType,
367377
getStream(nodeElements, getConverters().dateStringConverter(session))
368378
.toArray(Date[]::new),
369-
session);
379+
session,
380+
objectMapper);
370381
case Types.TIME:
371382
return new SfSqlArray(
372383
arrayString,
373384
columnSubType,
374385
getStream(nodeElements, getConverters().timeFromStringConverter(session))
375386
.toArray(Time[]::new),
376-
session);
387+
session,
388+
objectMapper);
377389
case Types.TIMESTAMP:
378390
return new SfSqlArray(
379391
arrayString,
@@ -384,28 +396,32 @@ protected SfSqlArray getJsonArray(String arrayString, int columnIndex) throws SF
384396
.timestampFromStringConverter(
385397
columnSubType, columnType, scale, session, null, sessionTimeZone))
386398
.toArray(Timestamp[]::new),
387-
session);
399+
session,
400+
objectMapper);
388401
case Types.BOOLEAN:
389402
return new SfSqlArray(
390403
arrayString,
391404
columnSubType,
392405
getStream(nodeElements, getConverters().booleanConverter(columnType))
393406
.toArray(Boolean[]::new),
394-
session);
407+
session,
408+
objectMapper);
395409
case Types.STRUCT:
396410
return new SfSqlArray(
397411
arrayString,
398412
columnSubType,
399413
getStream(nodeElements, getConverters().structConverter(OBJECT_MAPPER))
400414
.toArray(Map[]::new),
401-
session);
415+
session,
416+
objectMapper);
402417
case Types.ARRAY:
403418
return new SfSqlArray(
404419
arrayString,
405420
columnSubType,
406421
getStream(nodeElements, getConverters().arrayConverter(OBJECT_MAPPER))
407422
.toArray(Map[][]::new),
408-
session);
423+
session,
424+
objectMapper);
409425
default:
410426
throw new SFException(
411427
ErrorCode.FEATURE_UNSUPPORTED,

0 commit comments

Comments
 (0)