Permalink
Browse files

fix: handle Timestamp values with fractional seconds < 1 microsecond …

…correctly in PreparedStatement arguments (#1119)

When Timestamp values with nanosecond values < 1000 are submitted as arguments to a PreparedStatement,
avoid formatting them with a trailing dot '.' after the seconds part. This fixes a regression introduced
with PR #896.

closes #1117
  • Loading branch information...
stellingsimon authored and vlsi committed Feb 17, 2018
1 parent a8ef9f9 commit 8ff2a617c8a153eb364d8b762102b6b6b1cb53f8
@@ -654,17 +654,18 @@ private static void appendTime(StringBuilder sb, int hours, int minutes, int sec
sb.append(':');
sb.append(NUMBERS[seconds]);

// Add nanoseconds.
// Add microseconds, rounded.
// This won't work for server versions < 7.2 which only want
// a two digit fractional second, but we don't need to support 7.1
// anymore and getting the version number here is difficult.
//
if (nanos == 0) {
int microseconds = (nanos / 1000) + (((nanos % 1000) + 500) / 1000);
if (microseconds == 0) {
return;
}
sb.append('.');
int len = sb.length();
sb.append(nanos / 1000); // append microseconds
sb.append(microseconds);
int needZeros = 6 - (sb.length() - len);
if (needZeros > 0) {
sb.insert(len, ZEROS, 0, needZeros);
@@ -332,6 +332,10 @@ public void testGetTimestampWOTZ() throws SQLException {
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS6WOTZ_PGFORMAT + "'")));
assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS7WOTZ_PGFORMAT + "'")));
assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS8WOTZ_PGFORMAT + "'")));
assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS9WOTZ_PGFORMAT + "'")));

assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS1WOTZ_PGFORMAT + "'")));
@@ -347,6 +351,10 @@ public void testGetTimestampWOTZ() throws SQLException {
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS6WOTZ_PGFORMAT + "'")));
assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS7WOTZ_PGFORMAT + "'")));
assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS8WOTZ_PGFORMAT + "'")));
assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS9WOTZ_PGFORMAT + "'")));

assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS1WOTZ_PGFORMAT + "'")));
@@ -362,6 +370,10 @@ public void testGetTimestampWOTZ() throws SQLException {
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS6WOTZ_PGFORMAT + "'")));
assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS7WOTZ_PGFORMAT + "'")));
assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS8WOTZ_PGFORMAT + "'")));
assertEquals(1,
stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE, "'" + TS9WOTZ_PGFORMAT + "'")));

assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,
"'" + tsu.toString(null, new java.sql.Timestamp(tmpDate1WOTZ.getTime())) + "'")));
@@ -377,6 +389,8 @@ public void testGetTimestampWOTZ() throws SQLException {
"'" + tsu.toString(null, new java.sql.Timestamp(tmpDate6WOTZ.getTime())) + "'")));
assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,
"'" + tsu.toString(null, new java.sql.Timestamp(tmpDate7WOTZ.getTime())) + "'")));
assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,
"'" + tsu.toString(null, new java.sql.Timestamp(tmpDate8WOTZ.getTime())) + "'")));

assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,
"'" + tsu.toString(null, new java.sql.Timestamp(tmpTime1WOTZ.getTime())) + "'")));
@@ -392,11 +406,13 @@ public void testGetTimestampWOTZ() throws SQLException {
"'" + tsu.toString(null, new java.sql.Timestamp(tmpTime6WOTZ.getTime())) + "'")));
assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,
"'" + tsu.toString(null, new java.sql.Timestamp(tmpTime7WOTZ.getTime())) + "'")));
assertEquals(1, stmt.executeUpdate(TestUtil.insertSQL(TSWOTZ_TABLE,
"'" + tsu.toString(null, new java.sql.Timestamp(tmpTime8WOTZ.getTime())) + "'")));

// Fall through helper
timestampTestWOTZ();

assertEquals(35, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE));
assertEquals(43, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE));

stmt.close();
}
@@ -436,6 +452,12 @@ public void testSetTimestampWOTZ() throws SQLException {
pstmt.setTimestamp(1, TS7WOTZ);
assertEquals(1, pstmt.executeUpdate());

pstmt.setTimestamp(1, TS8WOTZ);
assertEquals(1, pstmt.executeUpdate());

pstmt.setTimestamp(1, TS9WOTZ);
assertEquals(1, pstmt.executeUpdate());

// With java.sql.Timestamp
pstmt.setObject(1, TS1WOTZ, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());
@@ -451,6 +473,10 @@ public void testSetTimestampWOTZ() throws SQLException {
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, TS7WOTZ, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, TS8WOTZ, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, TS9WOTZ, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());

// With Strings
pstmt.setObject(1, TS1WOTZ_PGFORMAT, Types.TIMESTAMP);
@@ -467,6 +493,10 @@ public void testSetTimestampWOTZ() throws SQLException {
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, TS7WOTZ_PGFORMAT, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, TS8WOTZ_PGFORMAT, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, TS9WOTZ_PGFORMAT, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());

// With java.sql.Date
pstmt.setObject(1, tmpDate1WOTZ, Types.TIMESTAMP);
@@ -483,6 +513,8 @@ public void testSetTimestampWOTZ() throws SQLException {
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, tmpDate7WOTZ, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, tmpDate8WOTZ, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());

// With java.sql.Time
pstmt.setObject(1, tmpTime1WOTZ, Types.TIMESTAMP);
@@ -499,10 +531,12 @@ public void testSetTimestampWOTZ() throws SQLException {
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, tmpTime7WOTZ, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());
pstmt.setObject(1, tmpTime8WOTZ, Types.TIMESTAMP);
assertEquals(1, pstmt.executeUpdate());
// Fall through helper
timestampTestWOTZ();

assertEquals(35, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE));
assertEquals(43, stmt.executeUpdate("DELETE FROM " + TSWOTZ_TABLE));

pstmt.close();
stmt.close();
@@ -663,6 +697,24 @@ private void timestampTestWOTZ() throws SQLException {
tString = rs.getString(1);
assertNotNull(tString);
assertEquals(TS7WOTZ_PGFORMAT, tString);

assertTrue(rs.next());
t = rs.getTimestamp(1);
assertNotNull(t);
assertEquals(TS8WOTZ, t);

tString = rs.getString(1);
assertNotNull(tString);
assertEquals(TS8WOTZ_PGFORMAT, tString);

assertTrue(rs.next());
t = rs.getTimestamp(1);
assertNotNull(t);
assertEquals(TS9WOTZ_ROUNDED, t);

tString = rs.getString(1);
assertNotNull(tString);
assertEquals(TS9WOTZ_ROUNDED_PGFORMAT, tString);
}

// Testing for Date
@@ -701,6 +753,11 @@ private void timestampTestWOTZ() throws SQLException {
assertNotNull(t);
assertEquals(tmpDate7WOTZ.getTime(), t.getTime());

assertTrue(rs.next());
t = rs.getTimestamp(1);
assertNotNull(t);
assertEquals(tmpDate8WOTZ.getTime(), t.getTime());

// Testing for Time
assertTrue(rs.next());
t = rs.getTimestamp(1);
@@ -737,6 +794,11 @@ private void timestampTestWOTZ() throws SQLException {
assertNotNull(t);
assertEquals(tmpTime7WOTZ.getTime(), t.getTime());

assertTrue(rs.next());
t = rs.getTimestamp(1);
assertNotNull(t);
assertEquals(tmpTime8WOTZ.getTime(), t.getTime());

assertTrue(!rs.next()); // end of table. Fail if more entries exist.

rs.close();
@@ -816,6 +878,17 @@ private void timestampTestWOTZ() throws SQLException {
getTimestamp(2000, 7, 7, 15, 0, 0, 0, null);
private static final String TS7WOTZ_PGFORMAT = "2000-07-07 15:00:00";

private static final java.sql.Timestamp TS8WOTZ =
getTimestamp(2000, 7, 7, 15, 0, 0, 20400000, null);
private static final String TS8WOTZ_PGFORMAT = "2000-07-07 15:00:00.0204";

private static final java.sql.Timestamp TS9WOTZ =
getTimestamp(2000, 2, 7, 15, 0, 0, 789, null);
private static final String TS9WOTZ_PGFORMAT = "2000-02-07 15:00:00.000000789";
private static final java.sql.Timestamp TS9WOTZ_ROUNDED =
getTimestamp(2000, 2, 7, 15, 0, 0, 1000, null);
private static final String TS9WOTZ_ROUNDED_PGFORMAT = "2000-02-07 15:00:00.000001";

private static final String TSWTZ_TABLE = "testtimestampwtz";
private static final String TSWOTZ_TABLE = "testtimestampwotz";
private static final String DATE_TABLE = "testtimestampdate";
@@ -843,6 +916,7 @@ private void timestampTestWOTZ() throws SQLException {
private static final java.sql.Date tmpTime6WOTZ = new java.sql.Date(TS6WOTZ.getTime());
private static final java.sql.Date tmpDate7WOTZ = new java.sql.Date(TS7WOTZ.getTime());
private static final java.sql.Time tmpTime7WOTZ = new java.sql.Time(TS7WOTZ.getTime());

private static final java.sql.Date tmpDate8WOTZ = new java.sql.Date(TS8WOTZ.getTime());
private static final java.sql.Time tmpTime8WOTZ = new java.sql.Time(TS8WOTZ.getTime());

}

0 comments on commit 8ff2a61

Please sign in to comment.