Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNOW-1170182: Return decimal as int in ARROW results configured by flag #1666

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/main/java/net/snowflake/client/core/SFBaseSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ public abstract class SFBaseSession {

private Map<String, Object> commonParameters;

private boolean isJdbcArrowTreatDecimalAsInt = true;

protected SFBaseSession(SFConnectionHandler sfConnectionHandler) {
this.sfConnectionHandler = sfConnectionHandler;
}
Expand Down Expand Up @@ -267,6 +269,14 @@ public void setJdbcTreatDecimalAsInt(boolean jdbcTreatDecimalAsInt) {
isJdbcTreatDecimalAsInt = jdbcTreatDecimalAsInt;
}

public boolean isJdbcArrowTreatDecimalAsInt() {
return isJdbcArrowTreatDecimalAsInt;
}

public void setJdbcArrowTreatDecimalAsInt(boolean jdbcArrowTreatDecimalAsInt) {
isJdbcArrowTreatDecimalAsInt = jdbcArrowTreatDecimalAsInt;
}

public String getServerUrl() {
if (connectionPropertiesMap.containsKey(SFSessionProperty.SERVER_URL)) {
return (String) connectionPropertiesMap.get(SFSessionProperty.SERVER_URL);
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 @@ -470,6 +470,12 @@ public void addSFSessionProperty(String propertyName, Object propertyValue) thro
}
break;

case JDBC_ARROW_TREAT_DECIMAL_AS_INT:
if (propertyValue != null) {
setJdbcArrowTreatDecimalAsInt(getBooleanValue(propertyValue));
}
break;

default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ public enum SFSessionProperty {

RETRY_TIMEOUT("retryTimeout", false, Integer.class),

ENABLE_PATTERN_SEARCH("enablePatternSearch", false, Boolean.class);
ENABLE_PATTERN_SEARCH("enablePatternSearch", false, Boolean.class),

JDBC_ARROW_TREAT_DECIMAL_AS_INT("jdbc_arrow_treat_decimal_as_int", false, Boolean.class);

// property key in string
private String propertyKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,11 @@ public BigDecimal toBigDecimal(int index) {
public Object toObject(int index) throws SFException {
if (bigIntVector.isNull(index)) {
return null;
} else {
return getLong(index);
} else if (!context.getSession().isJdbcArrowTreatDecimalAsInt()
sfc-gh-dprzybysz marked this conversation as resolved.
Show resolved Hide resolved
&& !context.getSession().isJdbcTreatDecimalAsInt()) {
return BigDecimal.valueOf(getLong(index), sfScale);
}
return getLong(index);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ public BigDecimal toBigDecimal(int index) throws SFException {

@Override
public Object toObject(int index) throws SFException {
return isNull(index) ? null : (long) getInt(index);
if (isNull(index)) {
return null;
} else if (!context.getSession().isJdbcArrowTreatDecimalAsInt()
&& !context.getSession().isJdbcTreatDecimalAsInt()) {
return BigDecimal.valueOf((long) getInt(index), sfScale);
}
return (long) getInt(index);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ public double toDouble(int index) throws SFException {
public Object toObject(int index) throws SFException {
if (isNull(index)) {
return null;
} else if (!context.getSession().isJdbcArrowTreatDecimalAsInt()
&& !context.getSession().isJdbcTreatDecimalAsInt()) {
return BigDecimal.valueOf((long) getShort(index), sfScale);
}
return (long) getShort(index);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,13 @@ public BigDecimal toBigDecimal(int index) throws SFException {

@Override
public Object toObject(int index) throws SFException {
return isNull(index) ? null : (long) toByte(index);
if (isNull(index)) {
return null;
} else if (!context.getSession().isJdbcArrowTreatDecimalAsInt()
&& !context.getSession().isJdbcTreatDecimalAsInt()) {
return BigDecimal.valueOf((long) getByte(index), sfScale);
}
return (long) toByte(index);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@
package net.snowflake.client.jdbc;

import net.snowflake.client.category.TestCategoryArrow;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import static org.junit.Assert.assertEquals;
sfc-gh-dprzybysz marked this conversation as resolved.
Show resolved Hide resolved

/**
* ResultSet integration tests for the latest JDBC driver. This doesn't work for the oldest
* supported driver. Drop this file when ResultSetLatestIT is dropped.
Expand Down
142 changes: 142 additions & 0 deletions src/test/java/net/snowflake/client/jdbc/ResultSetLatestIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ public ResultSetLatestIT() {
super(queryResultFormat);
}

private String createTableSql =
"Create or replace table get_object_for_numeric_types (c1 INT, c2 BIGINT, c3 SMALLINT, c4 TINYINT) ";
private String insertStmt =
"Insert into get_object_for_numeric_types (c1, c2, c3, c4) values (1000000000, 2000000000000000000000000, 3, 4)";
private String selectQuery = "Select * from get_object_for_numeric_types";
private String setJdbcTreatDecimalAsIntFalse =
"alter session set JDBC_TREAT_DECIMAL_AS_INT = false";

/**
* Test that when closing of results is interrupted by Thread.Interrupt(), the memory is released
* safely before driver execution ends.
Expand Down Expand Up @@ -971,4 +979,138 @@ public void testLargeStringRetrieval() throws SQLException {
fail("executeQuery should not fail");
}
}

sfc-gh-dprzybysz marked this conversation as resolved.
Show resolved Hide resolved
// Test setting new connection property jdbc_arrow_treat_decimal_as_int=false. Connection property introduced after version 3.15.0.
@Test
public void testGetObjectForArrowResultFormatJDBCArrowDecimalAsIntFalse() throws SQLException {
Properties properties = new Properties();
properties.put("jdbc_arrow_treat_decimal_as_int", false);
try (Connection con = getConnection(properties);
Statement stmt = con.createStatement()) {
stmt.execute("alter session set jdbc_query_result_format = 'ARROW'");
stmt.execute(createTableSql);
stmt.execute(insertStmt);

// Test with jdbc_arrow_treat_decimal_as_int=false and JDBC_TREAT_DECIMAL_AS_INT=true
try (ResultSet rs = stmt.executeQuery(selectQuery)) {
while(rs.next()) {
assertEquals("class java.lang.Long", rs.getObject(1).getClass().toString());
sfc-gh-dprzybysz marked this conversation as resolved.
Show resolved Hide resolved
assertEquals("class java.math.BigDecimal", rs.getObject(2).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(3).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(4).getClass().toString());
}
}

// Test with jdbc_arrow_treat_decimal_as_int=false and JDBC_TREAT_DECIMAL_AS_INT=false
stmt.execute(setJdbcTreatDecimalAsIntFalse);
try (ResultSet rs = stmt.executeQuery(selectQuery)) {
while (rs.next()) {
assertEquals("class java.math.BigDecimal", rs.getObject(1).getClass().toString());
sfc-gh-dprzybysz marked this conversation as resolved.
Show resolved Hide resolved
assertEquals("class java.math.BigDecimal", rs.getObject(2).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(3).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(4).getClass().toString());
}
}
}
}

// Test default setting of new connection property jdbc_arrow_treat_decimal_as_int=true. Connection property introduced after version 3.15.0.
@Test
public void testGetObjectForArrowResultFormatJDBCArrowDecimalAsIntTrue() throws SQLException {
try (Connection con = BaseJDBCTest.getConnection();
Statement stmt = con.createStatement()) {
stmt.execute("alter session set jdbc_query_result_format = 'ARROW'");
stmt.execute(createTableSql);
stmt.execute(insertStmt);

// Test with jdbc_arrow_treat_decimal_as_int=true and JDBC_TREAT_DECIMAL_AS_INT=true
try (ResultSet rs = stmt.executeQuery(selectQuery)) {
while(rs.next()) {
assertEquals("class java.lang.Long", rs.getObject(1).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(2).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(3).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(4).getClass().toString());
}
}

// Test with jdbc_arrow_treat_decimal_as_int=true and JDBC_TREAT_DECIMAL_AS_INT=false
stmt.execute(setJdbcTreatDecimalAsIntFalse);
try (ResultSet rs = stmt.executeQuery(selectQuery)) {
while (rs.next()) {
assertEquals("class java.lang.Long", rs.getObject(1).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(2).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(3).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(4).getClass().toString());
}
}
}
}

// Test setting new connection property jdbc_arrow_treat_decimal_as_int=false. Connection property
// introduced after version 3.15.0.
@Test
public void testGetObjectForJSONResultFormatJDBCArrowDecimalAsIntFalse() throws SQLException {
Properties properties = new Properties();
properties.put("jdbc_arrow_treat_decimal_as_int", false);
sfc-gh-dprzybysz marked this conversation as resolved.
Show resolved Hide resolved
try (Connection con = getConnection(properties);
Statement stmt = con.createStatement()) {
stmt.execute("alter session set jdbc_query_result_format = 'JSON'");
stmt.execute(createTableSql);
stmt.execute(insertStmt);

// Test with jdbc_arrow_treat_decimal_as_int=false and JDBC_TREAT_DECIMAL_AS_INT=true
try (ResultSet rs = stmt.executeQuery(selectQuery)) {
while (rs.next()) {
assertEquals("class java.lang.Long", rs.getObject(1).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(2).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(3).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(4).getClass().toString());
}
}

// Test with jdbc_arrow_treat_decimal_as_int=false and JDBC_TREAT_DECIMAL_AS_INT=false
stmt.execute(setJdbcTreatDecimalAsIntFalse);
try (ResultSet rs = stmt.executeQuery(selectQuery)) {
while (rs.next()) {
assertEquals("class java.math.BigDecimal", rs.getObject(1).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(2).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(3).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(4).getClass().toString());
}
}
}
}

// Test default setting of new connection property jdbc_arrow_treat_decimal_as_int=true.
// Connection property introduced after version 3.15.0.
@Test
public void testGetObjectForJSONResultFormatJDBCArrowDecimalAsIntTrue() throws SQLException {
try (Connection con = BaseJDBCTest.getConnection();
Statement stmt = con.createStatement()) {
stmt.execute("alter session set jdbc_query_result_format = 'JSON'");
stmt.execute(createTableSql);
stmt.execute(insertStmt);

// Test with jdbc_arrow_treat_decimal_as_int=true and JDBC_TREAT_DECIMAL_AS_INT=true
try (ResultSet rs = stmt.executeQuery(selectQuery)) {
while (rs.next()) {
assertEquals("class java.lang.Long", rs.getObject(1).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(2).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(3).getClass().toString());
assertEquals("class java.lang.Long", rs.getObject(4).getClass().toString());
}
}

// Test with jdbc_arrow_treat_decimal_as_int=true and JDBC_TREAT_DECIMAL_AS_INT=false
stmt.execute(setJdbcTreatDecimalAsIntFalse);
try (ResultSet rs = stmt.executeQuery(selectQuery)) {
while (rs.next()) {
assertEquals("class java.math.BigDecimal", rs.getObject(1).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(2).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(3).getClass().toString());
assertEquals("class java.math.BigDecimal", rs.getObject(4).getClass().toString());
}
}
}
}
}
Loading