Skip to content

Commit

Permalink
Merge branch 'oauth-code-flow' of github.com:snowflakedb/snowflake-jd…
Browse files Browse the repository at this point in the history
…bc into oauth-code-flow
  • Loading branch information
sfc-gh-dheyman committed Dec 4, 2024
2 parents 4662dfc + dc578a7 commit c110329
Show file tree
Hide file tree
Showing 22 changed files with 338 additions and 77 deletions.
22 changes: 16 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,22 @@ Snowflake JDBC Driver

.. image:: http://img.shields.io/:license-Apache%202-brightgreen.svg
:target: http://www.apache.org/licenses/LICENSE-2.0.txt

.. image:: https://maven-badges.herokuapp.com/maven-central/net.snowflake/snowflake-jdbc/badge.svg?style=plastic
:target: https://repo1.maven.org/maven2/net/snowflake/snowflake-jdbc/


Snowflake provides a JDBC type 4 driver that supports core functionality, allowing Java program to connect to Snowflake.

.. |maven-snowflake-jdbc| image:: https://maven-badges.herokuapp.com/maven-central/net.snowflake/snowflake-jdbc/badge.svg?style=plastic
:target: https://repo1.maven.org/maven2/net/snowflake/snowflake-jdbc/

.. |maven-snowflake-jdbc-fips| image:: https://maven-badges.herokuapp.com/maven-central/net.snowflake/snowflake-jdbc-fips/badge.svg?style=plastic
:target: https://repo1.maven.org/maven2/net/snowflake/snowflake-jdbc-fips/

.. |maven-snowflake-jdbc-thin| image:: https://maven-badges.herokuapp.com/maven-central/net.snowflake/snowflake-jdbc-thin/badge.svg?style=plastic
:target: https://repo1.maven.org/maven2/net/snowflake/snowflake-jdbc-thin/

- snowflake-jdbc (fat-jar): |maven-snowflake-jdbc|
- snowflake-jdbc-fips (FIPS compliant fat-jar): |maven-snowflake-jdbc-fips|
- snowflake-jdbc-thin (thin-jar): |maven-snowflake-jdbc-thin|

Prerequisites
=============

Expand Down Expand Up @@ -45,7 +55,7 @@ or for FIPS compliant fat-jar
<version>{version}</version>
</dependency>
or for experimental thin-jar
or for thin-jar

.. code-block:: xml
Expand Down Expand Up @@ -79,7 +89,7 @@ Build from Source Code
../mvnw org.apache.maven.plugins:maven-install-plugin:3.1.1:install-file -Dfile=target/snowflake-jdbc-fips.jar -DpomFile=./public_pom.xml
cd -
4. Build the experimental thin-jar and install it in local maven repository by running:
4. Build the thin-jar and install it in local maven repository by running:

.. code-block:: bash
Expand Down
54 changes: 33 additions & 21 deletions src/main/java/net/snowflake/client/core/SFArrowResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import java.util.stream.Stream;
import net.snowflake.client.core.arrow.ArrayConverter;
import net.snowflake.client.core.arrow.ArrowVectorConverter;
import net.snowflake.client.core.arrow.StructConverter;
import net.snowflake.client.core.arrow.StructObjectWrapper;
import net.snowflake.client.core.arrow.VarCharConverter;
import net.snowflake.client.core.arrow.VectorTypeConverter;
import net.snowflake.client.core.json.Converters;
Expand Down Expand Up @@ -576,16 +576,19 @@ public Object getObject(int columnIndex) throws SFException {
converter.setSessionTimeZone(sessionTimeZone);
Object obj = converter.toObject(index);
boolean isStructuredType = resultSetMetaData.isStructuredTypeColumn(columnIndex);
if (type == Types.STRUCT && isStructuredType) {
if (converter instanceof VarCharConverter) {
return createJsonSqlInput(columnIndex, obj);
} else if (converter instanceof StructConverter) {
return createArrowSqlInput(columnIndex, (Map<String, Object>) obj);
if (isVarcharConvertedStruct(type, isStructuredType, converter)) {
if (obj != null) {
return new StructObjectWrapper((String) obj, createJsonSqlInput(columnIndex, obj));
}
}
return obj;
}

private boolean isVarcharConvertedStruct(
int type, boolean isStructuredType, ArrowVectorConverter converter) {
return type == Types.STRUCT && isStructuredType && converter instanceof VarCharConverter;
}

private Object createJsonSqlInput(int columnIndex, Object obj) throws SFException {
try {
if (obj == null) {
Expand All @@ -605,15 +608,6 @@ private Object createJsonSqlInput(int columnIndex, Object obj) throws SFExceptio
}
}

private Object createArrowSqlInput(int columnIndex, Map<String, Object> input)
throws SFException {
if (input == null) {
return null;
}
return new ArrowSqlInput(
input, session, converters, resultSetMetaData.getColumnFields(columnIndex));
}

@Override
public Array getArray(int columnIndex) throws SFException {
ArrowVectorConverter converter = currentChunkIterator.getCurrentConverter(columnIndex - 1);
Expand All @@ -625,16 +619,19 @@ public Array getArray(int columnIndex) throws SFException {
}
if (converter instanceof VarCharConverter) {
return getJsonArray((String) obj, columnIndex);
} else if (converter instanceof ArrayConverter) {
return getArrowArray((List<Object>) obj, columnIndex);
} else if (converter instanceof VectorTypeConverter) {
return getArrowArray((List<Object>) obj, columnIndex);
} else if (converter instanceof ArrayConverter || converter instanceof VectorTypeConverter) {
StructObjectWrapper structObjectWrapper = (StructObjectWrapper) obj;
return getArrowArray(
structObjectWrapper.getJsonString(),
(List<Object>) structObjectWrapper.getObject(),
columnIndex);
} else {
throw new SFException(queryId, ErrorCode.INVALID_STRUCT_DATA);
}
}

private SfSqlArray getArrowArray(List<Object> elements, int columnIndex) throws SFException {
private SfSqlArray getArrowArray(String text, List<Object> elements, int columnIndex)
throws SFException {
try {
List<FieldMetadata> fieldMetadataList = resultSetMetaData.getColumnFields(columnIndex);
if (fieldMetadataList.size() != 1) {
Expand All @@ -651,62 +648,74 @@ private SfSqlArray getArrowArray(List<Object> elements, int columnIndex) throws
switch (columnType) {
case Types.INTEGER:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.integerConverter(columnType))
.toArray(Integer[]::new));
case Types.SMALLINT:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.smallIntConverter(columnType))
.toArray(Short[]::new));
case Types.TINYINT:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.tinyIntConverter(columnType))
.toArray(Byte[]::new));
case Types.BIGINT:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.bigIntConverter(columnType)).toArray(Long[]::new));
case Types.DECIMAL:
case Types.NUMERIC:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.bigDecimalConverter(columnType))
.toArray(BigDecimal[]::new));
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGNVARCHAR:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.varcharConverter(columnType, columnSubType, scale))
.toArray(String[]::new));
case Types.BINARY:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.bytesConverter(columnType, scale))
.toArray(Byte[][]::new));
case Types.FLOAT:
case Types.REAL:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.floatConverter(columnType)).toArray(Float[]::new));
case Types.DOUBLE:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.doubleConverter(columnType))
.toArray(Double[]::new));
case Types.DATE:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.dateFromIntConverter(sessionTimeZone))
.toArray(Date[]::new));
case Types.TIME:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.timeFromIntConverter(scale)).toArray(Time[]::new));
case Types.TIMESTAMP:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(
elements,
Expand All @@ -715,13 +724,16 @@ private SfSqlArray getArrowArray(List<Object> elements, int columnIndex) throws
.toArray(Timestamp[]::new));
case Types.BOOLEAN:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, converters.booleanConverter(columnType))
.toArray(Boolean[]::new));
case Types.STRUCT:
return new SfSqlArray(columnSubType, mapAndConvert(elements, e -> e).toArray(Map[]::new));
return new SfSqlArray(
text, columnSubType, mapAndConvert(elements, e -> e).toArray(Map[]::new));
case Types.ARRAY:
return new SfSqlArray(
text,
columnSubType,
mapAndConvert(elements, e -> ((List) e).stream().toArray(Map[]::new))
.toArray(Map[][]::new));
Expand Down
19 changes: 17 additions & 2 deletions src/main/java/net/snowflake/client/core/SFBaseResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ protected SQLInput createJsonSqlInputForColumn(
}

@SnowflakeJdbcInternalApi
protected SfSqlArray getJsonArray(String obj, int columnIndex) throws SFException {
protected SfSqlArray getJsonArray(String arrayString, int columnIndex) throws SFException {
try {
List<FieldMetadata> fieldMetadataList = resultSetMetaData.getColumnFields(columnIndex);
if (fieldMetadataList.size() != 1) {
Expand All @@ -288,73 +288,85 @@ protected SfSqlArray getJsonArray(String obj, int columnIndex) throws SFExceptio
int columnType = ColumnTypeHelper.getColumnType(columnSubType, session);
int scale = fieldMetadata.getScale();

ArrayNode arrayNode = (ArrayNode) OBJECT_MAPPER.readTree(obj);
ArrayNode arrayNode = (ArrayNode) OBJECT_MAPPER.readTree(arrayString);
Iterator<JsonNode> nodeElements = arrayNode.elements();

switch (columnType) {
case Types.INTEGER:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().integerConverter(columnType))
.toArray(Integer[]::new));
case Types.SMALLINT:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().smallIntConverter(columnType))
.toArray(Short[]::new));
case Types.TINYINT:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().tinyIntConverter(columnType))
.toArray(Byte[]::new));
case Types.BIGINT:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().bigIntConverter(columnType))
.toArray(Long[]::new));
case Types.DECIMAL:
case Types.NUMERIC:
return new SfSqlArray(
arrayString,
columnSubType,
convertToFixedArray(
getStream(nodeElements, getConverters().bigDecimalConverter(columnType))));
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGNVARCHAR:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(
nodeElements,
getConverters().varcharConverter(columnType, columnSubType, scale))
.toArray(String[]::new));
case Types.BINARY:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().bytesConverter(columnType, scale))
.toArray(Byte[][]::new));
case Types.FLOAT:
case Types.REAL:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().floatConverter(columnType))
.toArray(Float[]::new));
case Types.DOUBLE:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().doubleConverter(columnType))
.toArray(Double[]::new));
case Types.DATE:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().dateStringConverter(session))
.toArray(Date[]::new));
case Types.TIME:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().timeFromStringConverter(session))
.toArray(Time[]::new));
case Types.TIMESTAMP:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(
nodeElements,
Expand All @@ -364,16 +376,19 @@ protected SfSqlArray getJsonArray(String obj, int columnIndex) throws SFExceptio
.toArray(Timestamp[]::new));
case Types.BOOLEAN:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().booleanConverter(columnType))
.toArray(Boolean[]::new));
case Types.STRUCT:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().structConverter(OBJECT_MAPPER))
.toArray(Map[]::new));
case Types.ARRAY:
return new SfSqlArray(
arrayString,
columnSubType,
getStream(nodeElements, getConverters().arrayConverter(OBJECT_MAPPER))
.toArray(Map[][]::new));
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/net/snowflake/client/core/SFJsonResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.sql.Types;
import java.util.List;
import java.util.TimeZone;
import net.snowflake.client.core.arrow.StructObjectWrapper;
import net.snowflake.client.core.json.Converters;
import net.snowflake.client.jdbc.ErrorCode;
import net.snowflake.client.jdbc.FieldMetadata;
Expand Down Expand Up @@ -87,7 +88,7 @@ public Object getObject(int columnIndex) throws SFException {

case Types.STRUCT:
if (resultSetMetaData.isStructuredTypeColumn(columnIndex)) {
return getSqlInput((String) obj, columnIndex);
return new StructObjectWrapper((String) obj, getSqlInput((String) obj, columnIndex));
} else {
throw new SFException(ErrorCode.FEATURE_UNSUPPORTED, "data type: " + type);
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/net/snowflake/client/core/SFSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import net.snowflake.client.jdbc.telemetry.Telemetry;
import net.snowflake.client.jdbc.telemetry.TelemetryClient;
import net.snowflake.client.jdbc.telemetryOOB.TelemetryService;
import net.snowflake.client.log.JDK14Logger;
import net.snowflake.client.log.SFLogger;
import net.snowflake.client.log.SFLoggerFactory;
import net.snowflake.client.log.SFLoggerUtil;
Expand Down Expand Up @@ -435,6 +436,11 @@ public void addSFSessionProperty(String propertyName, Object propertyValue) thro
tracingLevel = Level.parse(((String) propertyValue).toUpperCase());
}
break;
case JAVA_LOGGING_CONSOLE_STD_OUT:
if (propertyValue != null && (Boolean) propertyValue) {
JDK14Logger.useStdOutConsoleHandler();
}
break;

case DISABLE_SOCKS_PROXY:
// note: if any session has this parameter, it will be used for all
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ public enum SFSessionProperty {

HTTP_CLIENT_CONNECTION_TIMEOUT("HTTP_CLIENT_CONNECTION_TIMEOUT", false, Integer.class),

HTTP_CLIENT_SOCKET_TIMEOUT("HTTP_CLIENT_SOCKET_TIMEOUT", false, Integer.class);
HTTP_CLIENT_SOCKET_TIMEOUT("HTTP_CLIENT_SOCKET_TIMEOUT", false, Integer.class),

JAVA_LOGGING_CONSOLE_STD_OUT("JAVA_LOGGING_CONSOLE_STD_OUT", false, Boolean.class);

// property key in string
private String propertyKey;
Expand Down
Loading

0 comments on commit c110329

Please sign in to comment.