From fe56e25c212d3c2c1c1a5b4123fd1e7c9fcf446a Mon Sep 17 00:00:00 2001 From: Terry Chow <32403408+tkyc@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:48:47 -0700 Subject: [PATCH] Fixed timestamp zone format (#2497) * Fixed timestamp zone format * Fixed test, closed RS --- .../com/microsoft/sqlserver/jdbc/dtv.java | 2 - .../unit/statement/PreparedStatementTest.java | 45 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/dtv.java b/src/main/java/com/microsoft/sqlserver/jdbc/dtv.java index c4375846e..9ba2e83ce 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/dtv.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/dtv.java @@ -1614,8 +1614,6 @@ final void executeOp(DTVExecuteOp op) throws SQLServerException { op.execute(this, ((Geometry) value).serialize()); } else if (JDBCType.GEOGRAPHY == jdbcType) { op.execute(this, ((Geography) value).serialize()); - } else if (JDBCType.TIMESTAMP == jdbcType) { - op.execute(this, Timestamp.valueOf((String) value)); } else { if (null != cryptoMeta) { // if streaming types check for allowed data length in AE diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java index b21372c96..23c89071d 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java @@ -13,9 +13,14 @@ import java.lang.reflect.Field; import java.sql.BatchUpdateException; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.sql.Types; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.util.Date; import java.util.Random; import java.util.UUID; import java.util.concurrent.CountDownLatch; @@ -31,6 +36,7 @@ import com.microsoft.sqlserver.jdbc.TestUtils; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; @@ -51,6 +57,7 @@ public class PreparedStatementTest extends AbstractTest { final static String tableName2 = RandomUtil.getIdentifier("tableTestStatementPoolingInternal2"); final static String tableName3 = RandomUtil.getIdentifier("tableTestPreparedStatementWithSpPrepare"); final static String tableName4 = RandomUtil.getIdentifier("tableTestPreparedStatementWithMultipleParams"); + final static String tableName5 = RandomUtil.getIdentifier("tableTestPreparedStatementWithTimestamp"); @BeforeAll public static void setupTests() throws Exception { @@ -482,6 +489,43 @@ public void testPrepareRace() throws Exception { } } + @Test + public void testTimestampStringTimeZoneFormat() throws SQLException { + String SELECT_SQL = "SELECT id, created_date, deleted_date FROM " + + AbstractSQLGenerator.escapeIdentifier(tableName5) + " WHERE id = ?"; + String INSERT_SQL = "INSERT INTO " + AbstractSQLGenerator.escapeIdentifier(tableName5) + + " (id, created_date, deleted_date) VALUES (?, ?, ?)"; + String DATE_FORMAT_WITH_Z = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_WITH_Z); + + try (SQLServerConnection con = (SQLServerConnection) getConnection()) { + executeSQL(con, "create table " + AbstractSQLGenerator.escapeIdentifier(tableName5) + + "(id int, created_date datetime2, deleted_date datetime2)"); + } + + try (PreparedStatement selectStatement = connection.prepareCall(SELECT_SQL); + PreparedStatement insertStatement = connection.prepareCall(INSERT_SQL);) { + Date createdDate = Date.from(Instant.parse("2024-01-16T05:12:00Z")); + Date deletedDate = Date.from(Instant.parse("2024-01-16T06:34:00Z")); + int id = 1; + + insertStatement.setInt(1, id); + insertStatement.setObject(2, sdf.format(createdDate.getTime()), Types.TIMESTAMP); + insertStatement.setObject(3, sdf.format(deletedDate.getTime()), Types.TIMESTAMP); + + insertStatement.executeUpdate(); + + selectStatement.setInt(1, id); + + try (ResultSet result = selectStatement.executeQuery()) { + result.next(); + Assertions.assertEquals(id, result.getInt("id")); + Assertions.assertEquals(createdDate, new Date(result.getTimestamp("created_date").getTime())); + Assertions.assertEquals(deletedDate, new Date(result.getTimestamp("deleted_date").getTime())); + } + } + } + /** * Test handling of the two configuration knobs related to prepared statement handling. * @@ -880,6 +924,7 @@ private static void dropTables() throws Exception { TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName2), stmt); TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName3), stmt); TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName4), stmt); + TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName5), stmt); } }