Skip to content

Commit

Permalink
Merge branch 'SNOW-1757822-zstd-decompression' of github.com:snowflak…
Browse files Browse the repository at this point in the history
…edb/snowflake-jdbc into SNOW-1757822-zstd-decompression
  • Loading branch information
sfc-gh-dheyman committed Oct 25, 2024
2 parents 49a364e + d74566a commit ad78c2b
Show file tree
Hide file tree
Showing 18 changed files with 758 additions and 725 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
**JDBC Driver 3.19.1**

- \||Please Refer to Release Notes at https://docs.snowflake.com/en/release-notes/clients-drivers/jdbc

**JDBC Driver 3.19.0**

- \||Please Refer to Release Notes at https://docs.snowflake.com/en/release-notes/clients-drivers/jdbc
Expand Down
4 changes: 2 additions & 2 deletions FIPS/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<parent>
<groupId>net.snowflake</groupId>
<artifactId>snowflake-jdbc-parent</artifactId>
<version>3.19.1-SNAPSHOT</version>
<version>3.19.1</version>
<relativePath>../parent-pom.xml</relativePath>
</parent>

<artifactId>snowflake-jdbc-fips</artifactId>
<version>3.19.1-SNAPSHOT</version>
<version>3.19.1</version>
<packaging>jar</packaging>

<name>snowflake-jdbc-fips</name>
Expand Down
2 changes: 1 addition & 1 deletion parent-pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>net.snowflake</groupId>
<artifactId>snowflake-jdbc-parent</artifactId>
<version>3.19.1-SNAPSHOT</version>
<version>3.19.1</version>
<packaging>pom</packaging>

<modules>
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
<parent>
<groupId>net.snowflake</groupId>
<artifactId>snowflake-jdbc-parent</artifactId>
<version>3.19.1-SNAPSHOT</version>
<version>3.19.1</version>
<relativePath>./parent-pom.xml</relativePath>
</parent>

<!-- Maven complains about using property here, but it makes install and deploy process easier to override final package names and localization -->
<artifactId>${artifactId}</artifactId>
<version>3.19.1-SNAPSHOT</version>
<version>3.19.1</version>
<packaging>jar</packaging>

<name>${artifactId}</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1649,6 +1649,7 @@ private void uploadStream() throws SnowflakeSQLException {
/** Download a file from remote, and return an input stream */
@Override
public InputStream downloadStream(String fileName) throws SnowflakeSQLException {
logger.debug("Downloading file as stream: {}", fileName);
if (stageInfo.getStageType() == StageInfo.StageType.LOCAL_FS) {
logger.error("downloadStream function doesn't support local file system", false);

Expand All @@ -1662,14 +1663,32 @@ public InputStream downloadStream(String fileName) throws SnowflakeSQLException

remoteLocation remoteLocation = extractLocationAndPath(stageInfo.getLocation());

String stageFilePath = fileName;
// when downloading files as stream there should be only one file in source files
String sourceLocation =
sourceFiles.stream()
.findFirst()
.orElseThrow(
() ->
new SnowflakeSQLException(
queryID,
SqlState.NO_DATA,
ErrorCode.FILE_NOT_FOUND.getMessageCode(),
session,
"File not found: " + fileName));

if (!fileName.equals(sourceLocation)) {
// filename may be different from source location e.g. in git repositories
logger.debug("Changing file to download location from {} to {}", fileName, sourceLocation);
}
String stageFilePath = sourceLocation;

if (!remoteLocation.path.isEmpty()) {
stageFilePath = SnowflakeUtil.concatFilePathNames(remoteLocation.path, fileName, "/");
stageFilePath = SnowflakeUtil.concatFilePathNames(remoteLocation.path, sourceLocation, "/");
}
logger.debug("Stage file path for {} is {}", sourceLocation, stageFilePath);

RemoteStoreFileEncryptionMaterial encMat = srcFileToEncMat.get(fileName);
String presignedUrl = srcFileToPresignedUrl.get(fileName);
RemoteStoreFileEncryptionMaterial encMat = srcFileToEncMat.get(sourceLocation);
String presignedUrl = srcFileToPresignedUrl.get(sourceLocation);

return storageFactory
.createClient(stageInfo, parallel, encMat, session)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* @author azhan attempts to test the CLIENT_MEMORY_LIMIT working in multi-threading
*/
@Category(TestCategoryOthers.class)
public class ClientMemoryLimitParallelIT {
public class ClientMemoryLimitParallelIT extends BaseJDBCWithSharedConnectionIT {
private static Logger LOGGER =
LoggerFactory.getLogger(ClientMemoryLimitParallelIT.class.getName());

Expand Down Expand Up @@ -64,16 +64,14 @@ public class ClientMemoryLimitParallelIT {

@Before
public void setUp() throws SQLException {
try (Connection con = getConnection();
Statement statement = con.createStatement()) {
try (Statement statement = connection.createStatement()) {
statement.execute(createTestTableSQL);
}
}

@After
public void tearDown() throws SQLException {
try (Connection con = getConnection();
Statement statement = con.createStatement()) {
try (Statement statement = connection.createStatement()) {
statement.execute("drop table if exists testtable_cml");
}
}
Expand Down Expand Up @@ -126,8 +124,7 @@ public void run() {
@Test
public void testQueryNotHanging() throws SQLException {
Properties paramProperties = new Properties();
try (Connection connection = getConnection(paramProperties);
Statement statement = connection.createStatement()) {
try (Statement statement = connection.createStatement()) {
queryRows(statement, 100, 160);
}
}
Expand Down
102 changes: 46 additions & 56 deletions src/test/java/net/snowflake/client/jdbc/ConnectionIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

/** Connection integration tests */
@Category(TestCategoryConnection.class)
public class ConnectionIT extends BaseJDBCTest {
public class ConnectionIT extends BaseJDBCWithSharedConnectionIT {
// create a local constant for this code for testing purposes (already defined in GS)
public static final int INVALID_CONNECTION_INFO_CODE = 390100;
private static final int SESSION_CREATION_OBJECT_DOES_NOT_EXIST_NOT_AUTHORIZED = 390201;
Expand Down Expand Up @@ -90,10 +90,9 @@ public void testSimpleConnection() throws SQLException {
public void test300ConnectionsWithSingleClientInstance() throws SQLException {
// concurrent testing
int size = 300;
try (Connection con = getConnection();
Statement statement = con.createStatement()) {
String database = con.getCatalog();
String schema = con.getSchema();
try (Statement statement = connection.createStatement()) {
String database = connection.getCatalog();
String schema = connection.getSchema();
statement.execute(
"create or replace table bigTable(rowNum number,rando "
+ "number) as (select seq4(),"
Expand Down Expand Up @@ -168,8 +167,7 @@ public void testProdConnectivity() throws SQLException {

@Test
public void testSetCatalogSchema() throws Throwable {
try (Connection connection = getConnection();
Statement statement = connection.createStatement()) {
try (Statement statement = connection.createStatement()) {
String db = connection.getCatalog();
String schema = connection.getSchema();
connection.setCatalog(db);
Expand Down Expand Up @@ -220,31 +218,30 @@ public void testDataCompletenessInLowMemory() throws Exception {
public void testConnectionGetAndSetDBAndSchema() throws SQLException {
final String SECOND_DATABASE = "SECOND_DATABASE";
final String SECOND_SCHEMA = "SECOND_SCHEMA";
try (Connection con = getConnection();
Statement statement = con.createStatement()) {
try (Statement statement = connection.createStatement()) {
try {
final String database = TestUtil.systemGetEnv("SNOWFLAKE_TEST_DATABASE").toUpperCase();
final String schema = TestUtil.systemGetEnv("SNOWFLAKE_TEST_SCHEMA").toUpperCase();

assertEquals(database, con.getCatalog());
assertEquals(schema, con.getSchema());
assertEquals(database, connection.getCatalog());
assertEquals(schema, connection.getSchema());

statement.execute(String.format("create or replace database %s", SECOND_DATABASE));
statement.execute(String.format("create or replace schema %s", SECOND_SCHEMA));
statement.execute(String.format("use database %s", database));

con.setCatalog(SECOND_DATABASE);
assertEquals(SECOND_DATABASE, con.getCatalog());
assertEquals("PUBLIC", con.getSchema());
connection.setCatalog(SECOND_DATABASE);
assertEquals(SECOND_DATABASE, connection.getCatalog());
assertEquals("PUBLIC", connection.getSchema());

con.setSchema(SECOND_SCHEMA);
assertEquals(SECOND_SCHEMA, con.getSchema());
connection.setSchema(SECOND_SCHEMA);
assertEquals(SECOND_SCHEMA, connection.getSchema());

statement.execute(String.format("use database %s", database));
statement.execute(String.format("use schema %s", schema));

assertEquals(database, con.getCatalog());
assertEquals(schema, con.getSchema());
assertEquals(database, connection.getCatalog());
assertEquals(schema, connection.getSchema());
} finally {
statement.execute(String.format("drop database if exists %s", SECOND_DATABASE));
}
Expand All @@ -253,40 +250,39 @@ public void testConnectionGetAndSetDBAndSchema() throws SQLException {

@Test
public void testConnectionClientInfo() throws SQLException {
try (Connection con = getConnection()) {
Properties property = con.getClientInfo();
assertEquals(0, property.size());
Properties clientInfo = new Properties();
clientInfo.setProperty("name", "Peter");
clientInfo.setProperty("description", "SNOWFLAKE JDBC");
try {
con.setClientInfo(clientInfo);
fail("setClientInfo should fail for any parameter.");
} catch (SQLClientInfoException e) {
assertEquals(SqlState.INVALID_PARAMETER_VALUE, e.getSQLState());
assertEquals(200047, e.getErrorCode());
assertEquals(2, e.getFailedProperties().size());
}
try {
con.setClientInfo("ApplicationName", "valueA");
fail("setClientInfo should fail for any parameter.");
} catch (SQLClientInfoException e) {
assertEquals(SqlState.INVALID_PARAMETER_VALUE, e.getSQLState());
assertEquals(200047, e.getErrorCode());
assertEquals(1, e.getFailedProperties().size());
}
Properties property = connection.getClientInfo();
assertEquals(0, property.size());
Properties clientInfo = new Properties();
clientInfo.setProperty("name", "Peter");
clientInfo.setProperty("description", "SNOWFLAKE JDBC");
try {
connection.setClientInfo(clientInfo);
fail("setClientInfo should fail for any parameter.");
} catch (SQLClientInfoException e) {
assertEquals(SqlState.INVALID_PARAMETER_VALUE, e.getSQLState());
assertEquals(200047, e.getErrorCode());
assertEquals(2, e.getFailedProperties().size());
}
try {
connection.setClientInfo("ApplicationName", "valueA");
fail("setClientInfo should fail for any parameter.");
} catch (SQLClientInfoException e) {
assertEquals(SqlState.INVALID_PARAMETER_VALUE, e.getSQLState());
assertEquals(200047, e.getErrorCode());
assertEquals(1, e.getFailedProperties().size());
}
}

// only support get and set
@Test
public void testNetworkTimeout() throws SQLException {
try (Connection con = getConnection()) {
int millis = con.getNetworkTimeout();
assertEquals(0, millis);
con.setNetworkTimeout(null, 200);
assertEquals(200, con.getNetworkTimeout());
}
int millis = connection.getNetworkTimeout();
assertEquals(0, millis);
connection.setNetworkTimeout(null, 200);
assertEquals(200, connection.getNetworkTimeout());
// Reset timeout to 0 since we are reusing connection in tests
connection.setNetworkTimeout(null, 0);
assertEquals(0, millis);
}

@Test
Expand Down Expand Up @@ -725,18 +721,14 @@ public void testHeartbeatFrequencyTooLarge() throws Exception {

@Test
public void testNativeSQL() throws Throwable {
try (Connection connection = getConnection()) {
// today returning the source SQL.
assertEquals("select 1", connection.nativeSQL("select 1"));
}
// today returning the source SQL.
assertEquals("select 1", connection.nativeSQL("select 1"));
}

@Test
public void testGetTypeMap() throws Throwable {
try (Connection connection = getConnection()) {
// return an empty type map. setTypeMap is not supported.
assertEquals(Collections.emptyMap(), connection.getTypeMap());
}
// return an empty type map. setTypeMap is not supported.
assertEquals(Collections.emptyMap(), connection.getTypeMap());
}

@Test
Expand Down Expand Up @@ -829,7 +821,6 @@ public void testReadDateAfterSplittingResultSet() throws Exception {

@Test
public void testResultSetsClosedByStatement() throws SQLException {
Connection connection = getConnection();
Statement statement2 = connection.createStatement();
ResultSet rs1 = statement2.executeQuery("select 2;");
ResultSet rs2 = statement2.executeQuery("select 2;");
Expand All @@ -846,7 +837,6 @@ public void testResultSetsClosedByStatement() throws SQLException {
assertTrue(rs2.isClosed());
assertTrue(rs3.isClosed());
assertTrue(rs4.isClosed());
connection.close();
}

@Test
Expand Down
35 changes: 13 additions & 22 deletions src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLHandshakeException;
import net.snowflake.client.ConditionalIgnoreRule;
Expand Down Expand Up @@ -1316,7 +1315,7 @@ public void testDownloadStreamWithFileNotFoundException() throws SQLException {
.unwrap(SnowflakeConnection.class)
.downloadStream("@testDownloadStream_stage", "/fileNotExist.gz", true);
} catch (SQLException ex) {
assertThat(ex.getErrorCode(), is(ErrorCode.S3_OPERATION_ERROR.getMessageCode()));
assertThat(ex.getErrorCode(), is(ErrorCode.FILE_NOT_FOUND.getMessageCode()));
}
long endDownloadTime = System.currentTimeMillis();
// S3Client retries some exception for a default timeout of 5 minutes
Expand Down Expand Up @@ -1630,28 +1629,20 @@ public void shouldFailOnSslExceptionWithLinkToTroubleShootingGuide() throws Inte
properties.put("password", "testpassword");
properties.put("ocspFailOpen", Boolean.FALSE.toString());

int maxRetries = 5;
int retry = 0;

// *.badssl.com may fail on timeouts
while (retry < maxRetries) {
try {
DriverManager.getConnection("jdbc:snowflake://expired.badssl.com/", properties);
fail("should fail");
} catch (SQLException e) {
if (!(e.getCause() instanceof SSLHandshakeException)) {
retry++;
Thread.sleep(1000 * new Random().nextInt(3));
continue;
}
assertThat(e.getCause(), instanceOf(SSLHandshakeException.class));
assertTrue(
e.getMessage()
.contains(
"https://docs.snowflake.com/en/user-guide/client-connectivity-troubleshooting/overview"));
try {
DriverManager.getConnection("jdbc:snowflake://expired.badssl.com/", properties);
fail("should fail");
} catch (SQLException e) {
// *.badssl.com may fail with timeout
if (!(e.getCause() instanceof SSLHandshakeException)
&& e.getCause().getMessage().toLowerCase().contains("timed out")) {
return;
}
assertThat(e.getCause(), instanceOf(SSLHandshakeException.class));
assertTrue(
e.getMessage()
.contains(
"https://docs.snowflake.com/en/user-guide/client-connectivity-troubleshooting/overview"));
}
fail("All retries failed");
}
}
Loading

0 comments on commit ad78c2b

Please sign in to comment.