diff --git a/src/main/java/net/snowflake/client/core/ArrowSqlInput.java b/src/main/java/net/snowflake/client/core/ArrowSqlInput.java index b84be490c..017823718 100644 --- a/src/main/java/net/snowflake/client/core/ArrowSqlInput.java +++ b/src/main/java/net/snowflake/client/core/ArrowSqlInput.java @@ -4,6 +4,8 @@ package net.snowflake.client.core; +import static net.snowflake.client.jdbc.SnowflakeUtil.mapSFExceptionToSQLException; + import java.math.BigDecimal; import java.sql.Date; import java.sql.SQLData; @@ -20,12 +22,10 @@ import net.snowflake.client.util.ThrowingBiFunction; import org.apache.arrow.vector.util.JsonStringHashMap; -import static net.snowflake.client.jdbc.SnowflakeUtil.mapSFExceptionToSQLException; - @SnowflakeJdbcInternalApi public class ArrowSqlInput extends BaseSqlInput { - private final JsonStringHashMap input; + private final JsonStringHashMap input; private final Iterator structuredTypeFields; private int currentIndex = 0; @@ -36,11 +36,11 @@ public ArrowSqlInput( List fields) { super(session, converters, fields); this.structuredTypeFields = input.values().iterator(); - this.input = input; + this.input = input; } public Map getInput() { - return input; + return input; } @Override @@ -80,7 +80,8 @@ public short readShort() throws SQLException { return withNextValue( (value, fieldMetadata) -> { int columnType = ColumnTypeHelper.getColumnType(fieldMetadata.getType(), session); - return mapSFExceptionToSQLException(() -> converters.getNumberConverter().getShort(value, columnType)); + return mapSFExceptionToSQLException( + () -> converters.getNumberConverter().getShort(value, columnType)); }); } @@ -89,7 +90,8 @@ public int readInt() throws SQLException { return withNextValue( (value, fieldMetadata) -> { int columnType = ColumnTypeHelper.getColumnType(fieldMetadata.getType(), session); - return mapSFExceptionToSQLException(() -> converters.getNumberConverter().getInt(value, columnType)); + return mapSFExceptionToSQLException( + () -> converters.getNumberConverter().getInt(value, columnType)); }); } @@ -98,7 +100,8 @@ public long readLong() throws SQLException { return withNextValue( (value, fieldMetadata) -> { int columnType = ColumnTypeHelper.getColumnType(fieldMetadata.getType(), session); - return mapSFExceptionToSQLException(() -> converters.getNumberConverter().getLong(value, columnType)); + return mapSFExceptionToSQLException( + () -> converters.getNumberConverter().getLong(value, columnType)); }); } @@ -107,7 +110,8 @@ public float readFloat() throws SQLException { return withNextValue( (value, fieldMetadata) -> { int columnType = ColumnTypeHelper.getColumnType(fieldMetadata.getType(), session); - return mapSFExceptionToSQLException(() -> converters.getNumberConverter().getFloat(value, columnType)); + return mapSFExceptionToSQLException( + () -> converters.getNumberConverter().getFloat(value, columnType)); }); } @@ -116,7 +120,8 @@ public double readDouble() throws SQLException { return withNextValue( (value, fieldMetadata) -> { int columnType = ColumnTypeHelper.getColumnType(fieldMetadata.getType(), session); - return mapSFExceptionToSQLException(() -> converters.getNumberConverter().getDouble(value, columnType)); + return mapSFExceptionToSQLException( + () -> converters.getNumberConverter().getDouble(value, columnType)); }); } @@ -174,8 +179,8 @@ public Timestamp readTimestamp(TimeZone tz) throws SQLException { if (value == null) { return null; } - int columnType = ColumnTypeHelper.getColumnType(fieldMetadata.getType(), session); - int columnSubType = fieldMetadata.getType(); + int columnType = ColumnTypeHelper.getColumnType(fieldMetadata.getType(), session); + int columnSubType = fieldMetadata.getType(); int scale = fieldMetadata.getScale(); return mapSFExceptionToSQLException( () -> @@ -184,7 +189,7 @@ public Timestamp readTimestamp(TimeZone tz) throws SQLException { .getTimestamp( (JsonStringHashMap) value, columnType, - columnSubType, + columnSubType, tz, scale)); }); diff --git a/src/main/java/net/snowflake/client/core/JsonSqlInput.java b/src/main/java/net/snowflake/client/core/JsonSqlInput.java index bf210db02..0ae79096a 100644 --- a/src/main/java/net/snowflake/client/core/JsonSqlInput.java +++ b/src/main/java/net/snowflake/client/core/JsonSqlInput.java @@ -21,7 +21,6 @@ import net.snowflake.client.core.structs.SQLDataCreationHelper; import net.snowflake.client.jdbc.FieldMetadata; import net.snowflake.client.jdbc.SnowflakeLoggedFeatureNotSupportedException; -import net.snowflake.client.jdbc.SnowflakeUtil; import net.snowflake.client.util.ThrowingTriFunction; import net.snowflake.common.core.SFTimestamp; import net.snowflake.common.core.SnowflakeDateTimeFormat; diff --git a/src/main/java/net/snowflake/client/core/SFArrowResultSet.java b/src/main/java/net/snowflake/client/core/SFArrowResultSet.java index 22f0609ca..f98fdd8c2 100644 --- a/src/main/java/net/snowflake/client/core/SFArrowResultSet.java +++ b/src/main/java/net/snowflake/client/core/SFArrowResultSet.java @@ -528,7 +528,7 @@ private Object createJsonSqlInput(int columnIndex, Object obj) throws SFExceptio return new JsonSqlInput( jsonNode, session, - converters, + converters, resultSetMetaData.getColumnMetadata().get(columnIndex - 1).getFields(), sessionTimezone); } catch (JsonProcessingException e) { @@ -540,7 +540,7 @@ private Object createArrowSqlInput(int columnIndex, JsonStringHashMap> entriesList = (List>) vector.getObject(index); - return entriesList.stream().collect(Collectors.toMap(entry-> entry.get("key").toString(), entry -> entry.get("value"))); - } + @Override + public Object toObject(int index) throws SFException { + List> entriesList = + (List>) vector.getObject(index); + return entriesList.stream() + .collect( + Collectors.toMap(entry -> entry.get("key").toString(), entry -> entry.get("value"))); + } - @Override - public String toString(int index) throws SFException { - return vector.getObject(index).toString(); - } + @Override + public String toString(int index) throws SFException { + return vector.getObject(index).toString(); + } } diff --git a/src/main/java/net/snowflake/client/core/arrow/StructuredTypeDateTimeConverter.java b/src/main/java/net/snowflake/client/core/arrow/StructuredTypeDateTimeConverter.java index 5f32e76a0..c5ff2d19b 100644 --- a/src/main/java/net/snowflake/client/core/arrow/StructuredTypeDateTimeConverter.java +++ b/src/main/java/net/snowflake/client/core/arrow/StructuredTypeDateTimeConverter.java @@ -16,7 +16,6 @@ import net.snowflake.client.core.SFException; import net.snowflake.client.core.SnowflakeJdbcInternalApi; import net.snowflake.client.jdbc.ErrorCode; -import net.snowflake.client.jdbc.SnowflakeType; import net.snowflake.client.jdbc.SnowflakeUtil; import org.apache.arrow.vector.util.JsonStringHashMap; @@ -47,23 +46,33 @@ public StructuredTypeDateTimeConverter( } public Timestamp getTimestamp( - JsonStringHashMap obj, int columnType, int columnSubType, TimeZone tz, int scale) + JsonStringHashMap obj, + int columnType, + int columnSubType, + TimeZone tz, + int scale) throws SFException { if (tz == null) { tz = TimeZone.getDefault(); } - if ( Types.TIMESTAMP == columnType) { + if (Types.TIMESTAMP == columnType) { if (SnowflakeUtil.EXTRA_TYPES_TIMESTAMP_LTZ == columnSubType) { return convertTimestampLtz(obj, scale); } else { return convertTimestampNtz(obj, tz, scale); } - } else if (Types.TIMESTAMP_WITH_TIMEZONE == columnType && SnowflakeUtil.EXTRA_TYPES_TIMESTAMP_TZ == columnSubType) { + } else if (Types.TIMESTAMP_WITH_TIMEZONE == columnType + && SnowflakeUtil.EXTRA_TYPES_TIMESTAMP_TZ == columnSubType) { return convertTimestampTz(obj, scale); } throw new SFException( ErrorCode.INVALID_VALUE_CONVERT, - "Unexpected Arrow Field for columnType " + columnType + " , column subtype " + columnSubType + " , and object type " + obj.getClass()); + "Unexpected Arrow Field for columnType " + + columnType + + " , column subtype " + + columnSubType + + " , and object type " + + obj.getClass()); } public Date getDate(int value, TimeZone tz) throws SFException { diff --git a/src/main/java/net/snowflake/client/core/structs/StructureTypeHelper.java b/src/main/java/net/snowflake/client/core/structs/StructureTypeHelper.java index 1f44779dd..46e8bb2e8 100644 --- a/src/main/java/net/snowflake/client/core/structs/StructureTypeHelper.java +++ b/src/main/java/net/snowflake/client/core/structs/StructureTypeHelper.java @@ -5,7 +5,8 @@ @SnowflakeJdbcInternalApi public class StructureTypeHelper { private static final String STRUCTURED_TYPE_ENABLED_PROPERTY_NAME = "STRUCTURED_TYPE_ENABLED"; - private static boolean structuredTypeEnabled = true; + private static boolean structuredTypeEnabled = + Boolean.valueOf(System.getProperty(STRUCTURED_TYPE_ENABLED_PROPERTY_NAME)); public static boolean isStructureTypeEnabled() { return structuredTypeEnabled; diff --git a/src/main/java/net/snowflake/client/jdbc/ArrowResultChunk.java b/src/main/java/net/snowflake/client/jdbc/ArrowResultChunk.java index 2bed387f1..123eb0139 100644 --- a/src/main/java/net/snowflake/client/jdbc/ArrowResultChunk.java +++ b/src/main/java/net/snowflake/client/jdbc/ArrowResultChunk.java @@ -13,7 +13,32 @@ import net.snowflake.client.core.DataConversionContext; import net.snowflake.client.core.SFBaseSession; import net.snowflake.client.core.SFException; -import net.snowflake.client.core.arrow.*; +import net.snowflake.client.core.arrow.ArrowResultChunkIndexSorter; +import net.snowflake.client.core.arrow.ArrowVectorConverter; +import net.snowflake.client.core.arrow.BigIntToFixedConverter; +import net.snowflake.client.core.arrow.BigIntToScaledFixedConverter; +import net.snowflake.client.core.arrow.BigIntToTimeConverter; +import net.snowflake.client.core.arrow.BigIntToTimestampLTZConverter; +import net.snowflake.client.core.arrow.BigIntToTimestampNTZConverter; +import net.snowflake.client.core.arrow.BitToBooleanConverter; +import net.snowflake.client.core.arrow.DateConverter; +import net.snowflake.client.core.arrow.DecimalToScaledFixedConverter; +import net.snowflake.client.core.arrow.DoubleToRealConverter; +import net.snowflake.client.core.arrow.IntToFixedConverter; +import net.snowflake.client.core.arrow.IntToScaledFixedConverter; +import net.snowflake.client.core.arrow.IntToTimeConverter; +import net.snowflake.client.core.arrow.MapConverter; +import net.snowflake.client.core.arrow.SmallIntToFixedConverter; +import net.snowflake.client.core.arrow.SmallIntToScaledFixedConverter; +import net.snowflake.client.core.arrow.StructConverter; +import net.snowflake.client.core.arrow.ThreeFieldStructToTimestampTZConverter; +import net.snowflake.client.core.arrow.TinyIntToFixedConverter; +import net.snowflake.client.core.arrow.TinyIntToScaledFixedConverter; +import net.snowflake.client.core.arrow.TwoFieldStructToTimestampLTZConverter; +import net.snowflake.client.core.arrow.TwoFieldStructToTimestampNTZConverter; +import net.snowflake.client.core.arrow.TwoFieldStructToTimestampTZConverter; +import net.snowflake.client.core.arrow.VarBinaryToBinaryConverter; +import net.snowflake.client.core.arrow.VarCharConverter; import net.snowflake.client.log.SFLogger; import net.snowflake.client.log.SFLoggerFactory; import net.snowflake.common.core.SqlState; diff --git a/src/main/java/net/snowflake/client/jdbc/SnowflakeBaseResultSet.java b/src/main/java/net/snowflake/client/jdbc/SnowflakeBaseResultSet.java index 67aa870a9..426ebae06 100644 --- a/src/main/java/net/snowflake/client/jdbc/SnowflakeBaseResultSet.java +++ b/src/main/java/net/snowflake/client/jdbc/SnowflakeBaseResultSet.java @@ -37,8 +37,14 @@ import java.util.List; import java.util.Map; import java.util.TimeZone; - -import net.snowflake.client.core.*; +import net.snowflake.client.core.ArrowSqlInput; +import net.snowflake.client.core.ColumnTypeHelper; +import net.snowflake.client.core.JsonSqlInput; +import net.snowflake.client.core.ObjectMapperFactory; +import net.snowflake.client.core.SFArrowResultSet; +import net.snowflake.client.core.SFBaseResultSet; +import net.snowflake.client.core.SFBaseSession; +import net.snowflake.client.core.SFException; import net.snowflake.client.core.structs.SQLDataCreationHelper; import net.snowflake.client.log.SFLogger; import net.snowflake.client.log.SFLoggerFactory; @@ -1356,7 +1362,8 @@ public T getObject(int columnIndex, Class type) throws SQLException { Object object = getObject(columnIndex); if (object instanceof JsonSqlInput) { JsonNode jsonNode = ((JsonSqlInput) object).getInput(); - return (T) OBJECT_MAPPER.convertValue(jsonNode, new TypeReference>() {}); + return (T) + OBJECT_MAPPER.convertValue(jsonNode, new TypeReference>() {}); } else { return (T) ((ArrowSqlInput) object).getInput(); } @@ -1399,10 +1406,11 @@ public List getList(int columnIndex, Class type) throws SQLException { } public T[] getArray(int columnIndex, Class type) throws SQLException { - int columnSubType = resultSetMetaData.getInternalColumnType(columnIndex); - int columnType = ColumnTypeHelper.getColumnType(columnSubType, session); - ; - int scale = resultSetMetaData.getScale(columnIndex); + FieldMetadata fieldMetadata = + sfBaseResultSet.getMetaData().getColumnMetadata().get(columnIndex - 1).getFields().get(0); + int columnSubType = fieldMetadata.getType(); + int columnType = ColumnTypeHelper.getColumnType(fieldMetadata.getType(), session); + int scale = fieldMetadata.getScale(); TimeZone tz = sfBaseResultSet.getSessionTimeZone(); Object[] objects = (Object[]) getArray(columnIndex).getArray(); T[] arr = (T[]) java.lang.reflect.Array.newInstance(type, objects.length); @@ -1412,12 +1420,12 @@ public T[] getArray(int columnIndex, Class type) throws SQLException { Map data = (Map) value; SQLData instance = (SQLData) SQLDataCreationHelper.create(type); SQLInput sqlInput = - new JsonSqlInput( - OBJECT_MAPPER.convertValue(data, JsonNode.class), - session, - sfBaseResultSet.getConverters(), - sfBaseResultSet.getMetaData().getColumnMetadata().get(columnIndex - 1).getFields(), - sfBaseResultSet.getSessionTimezone()); + new JsonSqlInput( + OBJECT_MAPPER.convertValue(data, JsonNode.class), + session, + sfBaseResultSet.getConverters(), + sfBaseResultSet.getMetaData().getColumnMetadata().get(columnIndex - 1).getFields(), + sfBaseResultSet.getSessionTimezone()); instance.readSQL(sqlInput, null); arr[counter++] = (T) instance; } else if (String.class.isAssignableFrom(type)) { @@ -1504,8 +1512,8 @@ public T[] getArray(int columnIndex, Class type) throws SQLException { (T) sfBaseResultSet .getConverters() - .getDateTimeConverter() - .getDate(value, columnType, columnSubType, tz, scale)); + .dateConverter(session) + .convert((String) value)); } else if (Time.class.isAssignableFrom(type)) { arr[counter++] = mapSFExceptionToSQLException( @@ -1513,20 +1521,20 @@ public T[] getArray(int columnIndex, Class type) throws SQLException { (T) sfBaseResultSet .getConverters() - .getDateTimeConverter() - .getTime(value, columnType, columnSubType, tz, scale)); + .timeConverter(session) + .convert((String) value)); } else if (Timestamp.class.isAssignableFrom(type)) { mapSFExceptionToSQLException( () -> (T) sfBaseResultSet .getConverters() - .getDateTimeConverter() - .getTimestamp(value, columnType, columnSubType, tz, scale)); + .timestampConverter(columnSubType, columnType, scale, session, null, tz) + .convert((String) value)); } else if (BigDecimal.class.isAssignableFrom(type)) { arr[counter++] = (T) getBigDecimal(columnIndex); } else { - logger.warn( + logger.debug( "Unsupported type passed to getArray(int columnIndex, Class type): " + type.getName()); throw new SQLException( @@ -1538,15 +1546,17 @@ public T[] getArray(int columnIndex, Class type) throws SQLException { } public Map getMap(int columnIndex, Class type) throws SQLException { - int columnType = resultSetMetaData.getInternalColumnType(columnIndex); - int columnSubType = resultSetMetaData.getInternalColumnType(columnIndex); - int scale = resultSetMetaData.getScale(columnIndex); + FieldMetadata valueFieldMetadata = + sfBaseResultSet.getMetaData().getColumnMetadata().get(columnIndex - 1).getFields().get(1); + int columnSubType = valueFieldMetadata.getType(); + int columnType = ColumnTypeHelper.getColumnType(valueFieldMetadata.getType(), session); + int scale = valueFieldMetadata.getScale(); TimeZone tz = sfBaseResultSet.getSessionTimeZone(); Object object = getObject(columnIndex); Map map; if (object instanceof JsonSqlInput) { JsonNode jsonNode = ((JsonSqlInput) object).getInput(); - map = OBJECT_MAPPER.convertValue(jsonNode, new TypeReference>() {}); + map = OBJECT_MAPPER.convertValue(jsonNode, new TypeReference>() {}); } else { map = (Map) object; } @@ -1556,17 +1566,28 @@ public Map getMap(int columnIndex, Class type) throws SQLExcep SQLData instance = (SQLData) SQLDataCreationHelper.create(type); SQLInput sqlInput; if (object instanceof JsonSqlInput) { - sqlInput = new JsonSqlInput( + sqlInput = + new JsonSqlInput( (((JsonSqlInput) object).getInput()).get(entry.getKey()), session, sfBaseResultSet.getConverters(), - sfBaseResultSet.getMetaData().getColumnMetadata().get(columnIndex - 1).getFields(), + sfBaseResultSet + .getMetaData() + .getColumnMetadata() + .get(columnIndex - 1) + .getFields(), sfBaseResultSet.getSessionTimezone()); } else { - sqlInput = new ArrowSqlInput((JsonStringHashMap) entry.getValue(), + sqlInput = + new ArrowSqlInput( + (JsonStringHashMap) entry.getValue(), session, sfBaseResultSet.getConverters(), - sfBaseResultSet.getMetaData().getColumnMetadata().get(columnIndex - 1).getFields()); + sfBaseResultSet + .getMetaData() + .getColumnMetadata() + .get(columnIndex - 1) + .getFields()); } instance.readSQL(sqlInput, null); resultMap.put(entry.getKey(), (T) instance); @@ -1668,19 +1689,20 @@ public Map getMap(int columnIndex, Class type) throws SQLExcep } else if (Date.class.isAssignableFrom(type)) { resultMap.put( entry.getKey(), - mapSFExceptionToSQLException( - () -> (T) convertToDate(entry.getValue(), columnType, columnSubType, tz, scale))); + mapSFExceptionToSQLException(() -> (T) convertToDate(entry.getValue(), tz))); } else if (Time.class.isAssignableFrom(type)) { resultMap.put( entry.getKey(), - mapSFExceptionToSQLException( - () -> (T) convertToTime(entry.getValue(), columnType, columnSubType, tz, scale))); + mapSFExceptionToSQLException(() -> (T) convertToTime(entry.getValue(), tz, scale))); } else if (Timestamp.class.isAssignableFrom(type)) { resultMap.put( entry.getKey(), mapSFExceptionToSQLException( - () -> (T) convertToTimestamp(entry.getValue(), columnType, columnSubType, tz, scale))); + () -> + (T) + convertToTimestamp( + entry.getValue(), columnType, columnSubType, tz, scale))); } else { logger.debug( @@ -1720,45 +1742,42 @@ public boolean isWrapperFor(Class iface) throws SQLException { return iface.isInstance(this); } - private Date convertToDate(Object object, int columnType, int columnSubType, TimeZone tz, int scale) throws SFException { + private Date convertToDate(Object object, TimeZone tz) throws SFException { if (sfBaseResultSet instanceof SFArrowResultSet) { return sfBaseResultSet - .getConverters() - .getStructuredTypeDateTimeConverter() - .getDate((int) object, tz); + .getConverters() + .getStructuredTypeDateTimeConverter() + .getDate((int) object, tz); } else { - return sfBaseResultSet - .getConverters() - .getDateTimeConverter() - .getDate(object, columnType, columnSubType, tz, scale); + return (Date) sfBaseResultSet.getConverters().dateConverter(session).convert((String) object); } } - private Time convertToTime(Object object, int columnType, int columnSubType, TimeZone tz, int scale) throws SFException { - if (sfBaseResultSet instanceof SFArrowResultSet) { - return sfBaseResultSet - .getConverters() - .getStructuredTypeDateTimeConverter() - .getTime((int) object, scale); - } else { - return sfBaseResultSet - .getConverters() - .getDateTimeConverter() - .getTime(object, columnType, columnSubType, tz, scale); - } + private Time convertToTime(Object object, TimeZone tz, int scale) throws SFException { + if (sfBaseResultSet instanceof SFArrowResultSet) { + return sfBaseResultSet + .getConverters() + .getStructuredTypeDateTimeConverter() + .getTime((long) object, scale); + } else { + return (Time) sfBaseResultSet.getConverters().timeConverter(session).convert((String) object); } + } - private Timestamp convertToTimestamp(Object object, int columnType, int columnSubType, TimeZone tz, int scale) throws SFException { - if (sfBaseResultSet instanceof SFArrowResultSet) { - return sfBaseResultSet - .getConverters() - .getStructuredTypeDateTimeConverter() - .getTimestamp((JsonStringHashMap) object, columnType, columnSubType, tz, scale); - } else { - return sfBaseResultSet - .getConverters() - .getDateTimeConverter() - .getTimestamp(object, columnType, columnSubType, tz, scale); - } - } + private Timestamp convertToTimestamp( + Object object, int columnType, int columnSubType, TimeZone tz, int scale) throws SFException { + if (sfBaseResultSet instanceof SFArrowResultSet) { + return sfBaseResultSet + .getConverters() + .getStructuredTypeDateTimeConverter() + .getTimestamp( + (JsonStringHashMap) object, columnType, columnSubType, tz, scale); + } else { + return (Timestamp) + sfBaseResultSet + .getConverters() + .timestampConverter(columnSubType, columnType, scale, session, null, tz) + .convert((String) object); + } + } } diff --git a/src/main/java/net/snowflake/client/jdbc/SnowflakeResultSetSerializableV1.java b/src/main/java/net/snowflake/client/jdbc/SnowflakeResultSetSerializableV1.java index a7a1a7e98..5a7821e0b 100644 --- a/src/main/java/net/snowflake/client/jdbc/SnowflakeResultSetSerializableV1.java +++ b/src/main/java/net/snowflake/client/jdbc/SnowflakeResultSetSerializableV1.java @@ -599,7 +599,7 @@ public static SnowflakeResultSetSerializableV1 create( resultSetSerializable.parameters = SessionUtil.getCommonParams(rootNode.path("data").path("parameters")); if (resultSetSerializable.parameters.isEmpty()) { - resultSetSerializable.parameters = sfSession.getCommonParameters(); + resultSetSerializable.parameters = new HashMap<>(sfSession.getCommonParameters()); resultSetSerializable.setStatemementLevelParameters(sfStatement.getStatementParameters()); } diff --git a/src/main/java/net/snowflake/client/jdbc/SnowflakeUtil.java b/src/main/java/net/snowflake/client/jdbc/SnowflakeUtil.java index e3e58fa30..00f698cfd 100644 --- a/src/main/java/net/snowflake/client/jdbc/SnowflakeUtil.java +++ b/src/main/java/net/snowflake/client/jdbc/SnowflakeUtil.java @@ -43,7 +43,6 @@ import net.snowflake.client.log.SFLogger; import net.snowflake.client.log.SFLoggerFactory; import net.snowflake.client.util.ThrowingCallable; -import net.snowflake.common.core.SnowflakeDateTimeFormat; import net.snowflake.common.core.SqlState; import net.snowflake.common.util.ClassUtil; import net.snowflake.common.util.FixedViewColumn; diff --git a/src/test/java/net/snowflake/client/AbstractDriverIT.java b/src/test/java/net/snowflake/client/AbstractDriverIT.java index e8354604b..b44cc31ef 100644 --- a/src/test/java/net/snowflake/client/AbstractDriverIT.java +++ b/src/test/java/net/snowflake/client/AbstractDriverIT.java @@ -321,12 +321,9 @@ public static Connection getConnection( properties.put("schema", params.get("schema")); properties.put("warehouse", params.get("warehouse")); properties.put("ssl", params.get("ssl")); - properties.put("proxyHost", "localhost"); - properties.put("proxyPort", "8080"); - properties.put("useProxy", "true"); properties.put("internal", Boolean.TRUE.toString()); // TODO: do we need this? - properties.put("insecureMode", true); // use OCSP for all tests. + properties.put("insecureMode", false); // use OCSP for all tests. if (injectSocketTimeout > 0) { properties.put("injectSocketTimeout", String.valueOf(injectSocketTimeout)); diff --git a/src/test/java/net/snowflake/client/jdbc/ResultSetStructuredTypesLatestIT.java b/src/test/java/net/snowflake/client/jdbc/ResultSetStructuredTypesLatestIT.java index 40a967140..81833c8dc 100644 --- a/src/test/java/net/snowflake/client/jdbc/ResultSetStructuredTypesLatestIT.java +++ b/src/test/java/net/snowflake/client/jdbc/ResultSetStructuredTypesLatestIT.java @@ -38,7 +38,7 @@ public class ResultSetStructuredTypesLatestIT extends BaseJDBCTest { private final ResultSetFormatType queryResultFormat; public ResultSetStructuredTypesLatestIT() { - this(ResultSetFormatType.NATIVE_ARROW); + this(ResultSetFormatType.JSON); } protected ResultSetStructuredTypesLatestIT(ResultSetFormatType queryResultFormat) { @@ -50,6 +50,7 @@ public Connection init() throws SQLException { try (Statement stmt = conn.createStatement()) { stmt.execute("alter session set ENABLE_STRUCTURED_TYPES_IN_CLIENT_RESPONSE = true"); stmt.execute("alter session set IGNORE_CLIENT_VESRION_IN_STRUCTURED_TYPES_RESPONSE = true"); + stmt.execute("ALTER SESSION SET TIMEZONE = 'Europe/Warsaw'"); stmt.execute( "alter session set jdbc_query_result_format = '" + queryResultFormat.sessionParameterTypeValue @@ -68,16 +69,12 @@ public void clean() throws Exception { SnowflakeObjectTypeFactories.unregister(AllTypesClass.class); } - // TODO Structured types feature exists only on QA environments @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapStructToObjectWithFactory() throws SQLException { testMapJson(true); } - // TODO Structured types feature exists only on QA environments @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapStructToObjectWithReflection() throws SQLException { testMapJson(false); testMapJson(true); @@ -95,7 +92,6 @@ private void testMapJson(boolean registerFactory) throws SQLException { }); } - // TODO Structured types feature exists only on QA environments @Test @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapStructAllTypes() throws SQLException { @@ -176,7 +172,6 @@ private void testMapAllTypes(boolean registerFactory) throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapJsonToMap() throws SQLException { withFirstRow( "SELECT OBJECT_CONSTRUCT('string','a','string2',1)", @@ -188,7 +183,6 @@ public void testMapJsonToMap() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testReturnAsArrayOfSqlData() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); SnowflakeObjectTypeFactories.register(SimpleClass.class, SimpleClass::new); @@ -204,10 +198,9 @@ public void testReturnAsArrayOfSqlData() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testReturnAsArrayOfString() throws SQLException { - Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); - withFirstRow( + Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); + withFirstRow( "SELECT ARRAY_CONSTRUCT('one', 'two','three')::ARRAY(VARCHAR)", (resultSet) -> { String[] resultArray = @@ -219,10 +212,9 @@ public void testReturnAsArrayOfString() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testReturnAsListOfIntegers() throws SQLException { - Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); - withFirstRow( + Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); + withFirstRow( "SELECT ARRAY_CONSTRUCT(1,2,3)::ARRAY(INTEGER)", (resultSet) -> { List resultList = @@ -234,7 +226,6 @@ public void testReturnAsListOfIntegers() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testReturnAsMap() throws SQLException { SnowflakeObjectTypeFactories.register(SimpleClass.class, SimpleClass::new); withFirstRow( @@ -249,7 +240,18 @@ public void testReturnAsMap() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) + public void testReturnAsMapOfTimestampsNtz() throws SQLException { + withFirstRow( + "SELECT {'x': TO_TIMESTAMP_NTZ('2021-12-23 09:44:44'), 'y': TO_TIMESTAMP_NTZ('2021-12-24 09:55:55')}::MAP(VARCHAR, TIMESTAMP)", + (resultSet) -> { + Map map = + resultSet.unwrap(SnowflakeBaseResultSet.class).getMap(1, Timestamp.class); + assertEquals(Timestamp.valueOf(LocalDateTime.of(2021, 12, 23, 9, 44, 44)), map.get("x")); + assertEquals(Timestamp.valueOf(LocalDateTime.of(2021, 12, 24, 9, 55, 55)), map.get("y")); + }); + } + + @Test public void testReturnAsMapOfLong() throws SQLException { withFirstRow( "SELECT {'x':1, 'y':2, 'z':3}::MAP(VARCHAR, BIGINT)", @@ -262,22 +264,45 @@ public void testReturnAsMapOfLong() throws SQLException { }); } - @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) - public void testReturnAsMapOfTimestampsNTz() throws SQLException { - withFirstRow( - "SELECT {'x': TO_TIMESTAMP_NTZ('2021-12-23 09:44:44'), 'y': TO_TIMESTAMP_NTZ('2021-12-24 09:55:55')}::MAP(VARCHAR, TIMESTAMP)", - (resultSet) -> { - Map map = resultSet.unwrap(SnowflakeBaseResultSet.class).getMap(1, Timestamp.class); - assertEquals( - Timestamp.valueOf(LocalDateTime.of(2021, 12, 23, 10, 44, 44)), map.get("x")); - assertEquals( - Timestamp.valueOf(LocalDateTime.of(2021, 12, 24, 10, 55, 55)), map.get("y")); - }); - } + @Test + public void testReturnAsMapOfTimestamp() throws SQLException { + withFirstRow( + "SELECT {'x':'2021-12-22 09:43:44.000 +0100', 'y':'2021-12-22 10:43:44.000 +0100'}::MAP(VARCHAR, TIMESTAMP)", + (resultSet) -> { + Map map = + resultSet.unwrap(SnowflakeBaseResultSet.class).getMap(1, Timestamp.class); + assertEquals(Timestamp.valueOf(LocalDateTime.of(2021, 12, 22, 9, 43, 44)), map.get("x")); + assertEquals(Timestamp.valueOf(LocalDateTime.of(2021, 12, 22, 10, 43, 44)), map.get("y")); + }); + } + + @Test + public void testReturnAsMapOfDate() throws SQLException { + withFirstRow( + "SELECT {'x':'2023-12-24', 'y':'2023-12-25'}::MAP(VARCHAR, DATE)", + (resultSet) -> { + Map map = + resultSet.unwrap(SnowflakeBaseResultSet.class).getMap(1, Date.class); + assertEquals( + Date.valueOf(LocalDate.of(2023, 12, 24)).toString(), map.get("x").toString()); + assertEquals( + Date.valueOf(LocalDate.of(2023, 12, 25)).toString(), map.get("y").toString()); + }); + } + + @Test + public void testReturnAsMapOfTime() throws SQLException { + withFirstRow( + "SELECT {'x':'12:34:56', 'y':'12:34:58'}::MAP(VARCHAR, TIME)", + (resultSet) -> { + Map map = + resultSet.unwrap(SnowflakeBaseResultSet.class).getMap(1, Time.class); + assertEquals(Time.valueOf(LocalTime.of(12, 34, 56)), map.get("x")); + assertEquals(Time.valueOf(LocalTime.of(12, 34, 58)), map.get("y")); + }); + } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testReturnAsMapOfBoolean() throws SQLException { withFirstRow( "SELECT {'x':'true', 'y':0}::MAP(VARCHAR, BOOLEAN)", @@ -290,7 +315,6 @@ public void testReturnAsMapOfBoolean() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testReturnAsList() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); SnowflakeObjectTypeFactories.register(SimpleClass.class, SimpleClass::new); @@ -304,9 +328,7 @@ public void testReturnAsList() throws SQLException { }); } - // TODO Structured types feature exists only on QA environments @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapStructsFromChunks() throws SQLException { withFirstRow( "select {'string':'a'}::OBJECT(string VARCHAR) FROM TABLE(GENERATOR(ROWCOUNT=>30000))", @@ -319,7 +341,6 @@ public void testMapStructsFromChunks() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapIntegerArray() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -333,7 +354,6 @@ public void testMapIntegerArray() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapFixedToLongArray() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -347,7 +367,6 @@ public void testMapFixedToLongArray() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapDecimalArray() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); // when: jdbc_treat_decimal_as_int=true scale=0 @@ -392,7 +411,6 @@ public void testMapDecimalArray() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapVarcharArray() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -407,7 +425,6 @@ public void testMapVarcharArray() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapDatesArray() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -420,7 +437,6 @@ public void testMapDatesArray() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapTimeArray() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -433,7 +449,6 @@ public void testMapTimeArray() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapTimestampArray() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -448,7 +463,6 @@ public void testMapTimestampArray() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapBooleanArray() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -461,7 +475,6 @@ public void testMapBooleanArray() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapBinaryArray() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -474,7 +487,6 @@ public void testMapBinaryArray() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapArrayOfStructToMap() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -487,7 +499,6 @@ public void testMapArrayOfStructToMap() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testMapArrayOfArrays() throws SQLException { Assume.assumeTrue(queryResultFormat != ResultSetFormatType.NATIVE_ARROW); withFirstRow( @@ -500,7 +511,6 @@ public void testMapArrayOfArrays() throws SQLException { } @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) public void testColumnTypeWhenStructureTypeIsDisabled() throws Exception { withStructureTypeTemporaryDisabled( () -> {