Skip to content

Commit 911b03d

Browse files
Merge branch 'master' into SNOW-1016470-increase-code-coverage-to-at-least-90
2 parents ef4bbed + 7825cce commit 911b03d

File tree

4 files changed

+70
-21
lines changed

4 files changed

+70
-21
lines changed

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,6 @@ private static WorkloadIdentityAttestation getWorkloadIdentityAttestation(SFLogi
386386

387387
static void checkIfExperimentalAuthnEnabled(AuthenticatorType authenticator) throws SFException {
388388
if (authenticator.equals(AuthenticatorType.PROGRAMMATIC_ACCESS_TOKEN)
389-
|| authenticator.equals(AuthenticatorType.OAUTH_CLIENT_CREDENTIALS)
390-
|| authenticator.equals(AuthenticatorType.OAUTH_AUTHORIZATION_CODE)
391389
|| authenticator.equals(AuthenticatorType.WORKLOAD_IDENTITY)) {
392390
boolean experimentalAuthenticationMethodsEnabled =
393391
Boolean.parseBoolean(systemGetEnv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION"));

src/main/java/net/snowflake/client/core/bind/BindUploader.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ public class BindUploader implements Closeable {
5252

5353
private int fileCount = 0;
5454

55-
private final DateFormat timestampFormat;
55+
private final DateFormat utcTimestampFormat;
56+
private final DateFormat localTimestampFormat;
5657
private final DateFormat dateFormat;
5758
private final SimpleDateFormat timeFormat;
5859
private final String createStageSQL;
59-
private Calendar cal;
6060

6161
static class ColumnTypeDataPair {
6262
public String type;
@@ -86,15 +86,20 @@ private BindUploader(SFBaseSession session, String stageDir) {
8686
+ " field_optionally_enclosed_by='\"'"
8787
+ ")";
8888

89-
cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
90-
cal.clear();
89+
Calendar utcCalendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
90+
utcCalendar.clear();
9191

92-
this.timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.");
93-
this.timestampFormat.setCalendar(cal);
92+
Calendar localCalendar = new GregorianCalendar(TimeZone.getDefault());
93+
localCalendar.clear();
94+
95+
this.utcTimestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.");
96+
this.utcTimestampFormat.setCalendar(utcCalendar);
97+
this.localTimestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.");
98+
this.localTimestampFormat.setCalendar(localCalendar);
9499
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd");
95-
this.dateFormat.setCalendar(cal);
100+
this.dateFormat.setCalendar(utcCalendar);
96101
this.timeFormat = new SimpleDateFormat("HH:mm:ss.");
97-
this.timeFormat.setCalendar(cal);
102+
this.timeFormat.setCalendar(utcCalendar);
98103
}
99104

100105
private synchronized String synchronizedDateFormat(String o) {
@@ -113,7 +118,7 @@ private synchronized String synchronizedTimeFormat(String o) {
113118
int nano = times.right;
114119

115120
Time v1 = new Time(sec * 1000);
116-
String formatWithDate = timestampFormat.format(v1) + String.format("%09d", nano);
121+
String formatWithDate = utcTimestampFormat.format(v1) + String.format("%09d", nano);
117122
// Take out the Date portion of the formatted string. Only time data is needed.
118123
return formatWithDate.substring(11);
119124
}
@@ -159,16 +164,12 @@ private synchronized String synchronizedTimestampFormat(String o, String type) {
159164
// For timestamp_ntz, use UTC timezone. For timestamp_ltz, use the local timezone to minimise
160165
// the gap.
161166
if ("TIMESTAMP_LTZ".equals(type)) {
162-
TimeZone tz = TimeZone.getDefault();
163-
cal.setTimeZone(tz);
164-
cal.clear();
165-
timestampFormat.setCalendar(cal);
166167
offsetId = ZoneId.systemDefault().getRules().getOffset(Instant.ofEpochMilli(v1.getTime()));
168+
return localTimestampFormat.format(v1) + String.format("%09d", nano) + " " + offsetId;
167169
} else {
168170
offsetId = ZoneOffset.UTC;
171+
return utcTimestampFormat.format(v1) + String.format("%09d", nano) + " " + offsetId;
169172
}
170-
171-
return timestampFormat.format(v1) + String.format("%09d", nano) + " " + offsetId;
172173
}
173174

174175
/**

src/test/java/net/snowflake/client/core/SessionUtilTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,11 @@ public void shouldProperlyCheckIfExperimentalAuthEnabled() {
256256
snowflakeUtilMockedStatic
257257
.when(() -> SnowflakeUtil.systemGetEnv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION"))
258258
.thenReturn(null);
259-
assertThrows(
260-
SFException.class,
259+
assertDoesNotThrow(
261260
() ->
262261
SessionUtil.checkIfExperimentalAuthnEnabled(
263262
AuthenticatorType.OAUTH_AUTHORIZATION_CODE));
264-
assertThrows(
265-
SFException.class,
263+
assertDoesNotThrow(
266264
() ->
267265
SessionUtil.checkIfExperimentalAuthnEnabled(
268266
AuthenticatorType.OAUTH_CLIENT_CREDENTIALS));

src/test/java/net/snowflake/client/jdbc/BindingDataLatestIT.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
import static org.junit.jupiter.api.Assertions.assertTrue;
77

88
import java.sql.Connection;
9+
import java.sql.Date;
910
import java.sql.PreparedStatement;
1011
import java.sql.ResultSet;
1112
import java.sql.SQLException;
1213
import java.sql.Statement;
1314
import java.sql.Timestamp;
15+
import java.time.ZoneId;
16+
import java.time.ZonedDateTime;
1417
import java.util.Calendar;
1518
import java.util.TimeZone;
1619
import net.snowflake.client.AbstractDriverIT;
@@ -288,6 +291,55 @@ public void testTimestampBindingWithLTZTypeForDayLightSavingTimeZone() throws SQ
288291
}
289292
}
290293

294+
/**
295+
* Test that binding TIMESTAMP_LTZ does not affect other date time bindings time zones as a side
296+
* effect
297+
*
298+
* <p>This test cannot run on the GitHub testing because of the "ALTER SESSION SET
299+
* CLIENT_STAGE_ARRAY_BINDING_THRESHOLD" This command should be executed with the system admin.
300+
*
301+
* @throws SQLException
302+
*/
303+
@Test
304+
@DontRunOnGithubActions
305+
public void testTimestampLtzBindingNoLongerBreaksOtherDatetimeBindings() throws SQLException {
306+
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
307+
try (Connection connection = getConnection();
308+
Statement statement = connection.createStatement()) {
309+
try {
310+
statement.execute(
311+
"create or replace table stageinsertdates(ind int, t1 timestamp_ltz, d1 date)");
312+
Date date1 =
313+
new java.sql.Date(
314+
ZonedDateTime.of(2016, 2, 19, 0, 0, 0, 0, ZoneId.systemDefault())
315+
.toInstant()
316+
.toEpochMilli());
317+
Timestamp ts1 = new Timestamp(date1.getTime());
318+
// insert using stage binding
319+
statement.execute("ALTER SESSION SET CLIENT_STAGE_ARRAY_BINDING_THRESHOLD = 1");
320+
try (PreparedStatement prepStatement =
321+
connection.prepareStatement("insert into stageinsertdates values (?,?, ?)")) {
322+
prepStatement.setInt(1, 1);
323+
prepStatement.setTimestamp(2, ts1);
324+
prepStatement.setDate(3, date1);
325+
prepStatement.addBatch();
326+
prepStatement.executeBatch();
327+
prepStatement.getConnection().commit();
328+
}
329+
330+
try (ResultSet rs1 = statement.executeQuery("select * from stageinsertdates")) {
331+
assertTrue(rs1.next());
332+
333+
assertEquals(1, rs1.getInt(1));
334+
assertEquals(ts1, rs1.getTimestamp(2));
335+
assertEquals(date1, rs1.getDate(3));
336+
}
337+
} finally {
338+
TimeZone.setDefault(origTz);
339+
}
340+
}
341+
}
342+
291343
public void executePsStatementForTimestampTest(
292344
Connection connection, String tableName, Timestamp timestamp) throws SQLException {
293345
try (PreparedStatement prepStatement =

0 commit comments

Comments
 (0)