Skip to content

Commit 968bb6f

Browse files
committed
Simplify tests
1 parent 603e898 commit 968bb6f

File tree

2 files changed

+190
-171
lines changed

2 files changed

+190
-171
lines changed

presto-mysql/src/test/java/com/facebook/presto/plugin/mysql/TestMySqlTypeMapping.java

Lines changed: 94 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
import org.testng.annotations.Test;
3232

3333
import java.math.BigDecimal;
34+
import java.sql.Connection;
35+
import java.sql.DriverManager;
36+
import java.sql.ResultSet;
37+
import java.sql.Statement;
3438
import java.time.LocalDate;
3539
import java.time.ZoneId;
3640

@@ -53,6 +57,8 @@
5357
import static com.google.common.base.Strings.repeat;
5458
import static com.google.common.base.Verify.verify;
5559
import static java.lang.String.format;
60+
import static org.testng.Assert.assertEquals;
61+
import static org.testng.Assert.assertTrue;
5662

5763
@Test
5864
public class TestMySqlTypeMapping
@@ -254,124 +260,120 @@ public void testDate()
254260
}
255261

256262
@Test
257-
public void testDatetime()
263+
public void testDatetimeUnderlyingStorageVerification()
264+
throws Exception
258265
{
259-
try {
260-
assertUpdate("CREATE TABLE tpch.test_datetime (id INT PRIMARY KEY, dt DATETIME(6))");
261-
262-
assertUpdate("INSERT INTO tpch.test_datetime VALUES (1, '1970-01-01 00:00:00.000000')");
263-
264-
assertUpdate("INSERT INTO tpch.test_datetime VALUES (2, '2023-06-15 14:30:00.000000')");
265-
266-
for (String timeZoneId : ImmutableList.of("UTC", "America/New_York", "Asia/Tokyo", "Europe/Warsaw")) {
267-
Session session = Session.builder(getQueryRunner().getDefaultSession())
268-
.setTimeZoneKey(TimeZoneKey.getTimeZoneKey(timeZoneId))
269-
.setSystemProperty("legacy_timestamp", "false")
270-
.build();
271-
272-
assertQuery(
273-
session,
274-
"SELECT dt FROM mysql.tpch.test_datetime WHERE id = 1",
275-
"VALUES TIMESTAMP '1970-01-01 00:00:00.000000'");
276-
277-
assertQuery(
278-
session,
279-
"SELECT dt FROM mysql.tpch.test_datetime WHERE id = 2",
280-
"VALUES TIMESTAMP '2023-06-15 14:30:00.000000'");
281-
}
282-
}
283-
finally {
284-
assertUpdate("DROP TABLE IF EXISTS tpch.test_datetime");
285-
}
286-
}
266+
String jdbcUrl = mysqlContainer.getJdbcUrl();
267+
String jdbcUrlWithCredentials = format("%s%suser=%s&password=%s",
268+
jdbcUrl,
269+
jdbcUrl.contains("?") ? "&" : "?",
270+
mysqlContainer.getUsername(),
271+
mysqlContainer.getPassword());
272+
JdbcSqlExecutor jdbcExecutor = new JdbcSqlExecutor(jdbcUrlWithCredentials);
287273

288-
@Test
289-
public void testTimestamp()
290-
{
291274
try {
292-
assertUpdate("CREATE TABLE tpch.test_timestamp_col (id INT PRIMARY KEY, ts TIMESTAMP(6))");
293-
294-
assertUpdate("INSERT INTO tpch.test_timestamp_col VALUES (1, '2023-06-15 14:30:00.000000')");
275+
jdbcExecutor.execute("CREATE TABLE tpch.test_datetime_storage (" +
276+
"id INT PRIMARY KEY, " +
277+
"dt DATETIME(6), " +
278+
"source VARCHAR(10))");
295279

296-
for (String timeZoneId : ImmutableList.of("UTC", "America/Los_Angeles", "Europe/Paris")) {
297-
Session session = Session.builder(getQueryRunner().getDefaultSession())
298-
.setTimeZoneKey(TimeZoneKey.getTimeZoneKey(timeZoneId))
299-
.setSystemProperty("legacy_timestamp", "false")
300-
.build();
280+
// MySQL insertion, MySQL retrieval, and Presto retrieval all agree on wall clock time
281+
jdbcExecutor.execute("INSERT INTO tpch.test_datetime_storage VALUES (1, '1970-01-01 00:00:00.000000', 'jdbc')");
301282

302-
assertQuery(
303-
session,
304-
"SELECT ts FROM mysql.tpch.test_timestamp_col WHERE id = 1",
305-
"VALUES TIMESTAMP '2023-06-15 14:30:00.000000'");
283+
try (Connection conn = DriverManager.getConnection(jdbcUrlWithCredentials);
284+
Statement stmt = conn.createStatement();
285+
ResultSet rs = stmt.executeQuery("SELECT CAST(dt AS CHAR) FROM tpch.test_datetime_storage WHERE id = 1")) {
286+
assertTrue(rs.next(), "Expected one row");
287+
String dbValue1 = rs.getString(1);
288+
assertEquals(dbValue1, "1970-01-01 00:00:00.000000", "JDBC insert should store wall clock time 1970-01-01 00:00:00 in DB");
306289
}
307-
}
308-
finally {
309-
assertUpdate("DROP TABLE IF EXISTS tpch.test_timestamp_col");
310-
}
311-
}
312-
313-
@Test
314-
public void testDatetimeLegacy()
315-
{
316-
try {
317-
assertUpdate("CREATE TABLE tpch.test_datetime_legacy (id INT PRIMARY KEY, dt DATETIME(6))");
318290

319-
assertUpdate("INSERT INTO tpch.test_datetime_legacy VALUES (1, '1970-01-01 00:00:00.000000')");
320-
321-
Session utcSession = Session.builder(getQueryRunner().getDefaultSession())
322-
.setTimeZoneKey(TimeZoneKey.getTimeZoneKey("UTC"))
323-
.setSystemProperty("legacy_timestamp", "true")
324-
.build();
325-
326-
Session nySession = Session.builder(getQueryRunner().getDefaultSession())
327-
.setTimeZoneKey(TimeZoneKey.getTimeZoneKey("America/New_York"))
328-
.setSystemProperty("legacy_timestamp", "true")
291+
Session session = Session.builder(getQueryRunner().getDefaultSession())
292+
.setSystemProperty("legacy_timestamp", "false")
329293
.build();
294+
assertQuery(session,
295+
"SELECT dt FROM mysql.tpch.test_datetime_storage WHERE id = 1",
296+
"VALUES TIMESTAMP '1970-01-01 00:00:00.000000'");
297+
298+
// Presto insertion, retrieval via MySQL, and retrieval via Presto all agree on wall clock time
299+
assertUpdate(session, "INSERT INTO mysql.tpch.test_datetime_storage VALUES (2, TIMESTAMP '2023-06-15 14:30:00.000000', 'presto')", 1);
300+
301+
try (Connection conn = DriverManager.getConnection(jdbcUrlWithCredentials);
302+
Statement stmt = conn.createStatement();
303+
ResultSet rs = stmt.executeQuery("SELECT CAST(dt AS CHAR) FROM tpch.test_datetime_storage WHERE id = 2")) {
304+
assertTrue(rs.next(), "Expected one row");
305+
String dbValue2 = rs.getString(1);
306+
assertEquals(dbValue2, "2023-06-15 14:30:00.000000", "Presto insert should store wall clock time 2023-06-15 14:30:00 in DB");
307+
}
330308

331-
assertQuery(
332-
utcSession,
333-
"SELECT dt FROM mysql.tpch.test_datetime_legacy WHERE id = 1",
334-
"VALUES TIMESTAMP '1970-01-01 07:00:00.000000'");
335-
336-
assertQuery(
337-
nySession,
338-
"SELECT dt FROM mysql.tpch.test_datetime_legacy WHERE id = 1",
339-
"VALUES TIMESTAMP '1970-01-01 02:00:00.000000'"); // 07:00 UTC = 02:00 EST
309+
assertQuery(session,
310+
"SELECT dt FROM mysql.tpch.test_datetime_storage WHERE id = 2",
311+
"VALUES TIMESTAMP '2023-06-15 14:30:00.000000'");
340312
}
341313
finally {
342-
assertUpdate("DROP TABLE IF EXISTS tpch.test_datetime_legacy");
314+
jdbcExecutor.execute("DROP TABLE IF EXISTS tpch.test_datetime_storage");
343315
}
344316
}
345317

346318
@Test
347-
public void testDatetimeWritePath()
319+
public void testDatetimeLegacyUnderlyingStorageVerification()
320+
throws Exception
348321
{
322+
String jdbcUrl = mysqlContainer.getJdbcUrl();
323+
String jdbcUrlWithCredentials = format("%s%suser=%s&password=%s",
324+
jdbcUrl,
325+
jdbcUrl.contains("?") ? "&" : "?",
326+
mysqlContainer.getUsername(),
327+
mysqlContainer.getPassword());
328+
JdbcSqlExecutor jdbcExecutor = new JdbcSqlExecutor(jdbcUrlWithCredentials);
329+
349330
try {
350-
assertUpdate("CREATE TABLE tpch.test_datetime_write (" +
331+
jdbcExecutor.execute("CREATE TABLE tpch.test_datetime_legacy_storage (" +
351332
"id INT PRIMARY KEY, " +
352333
"dt DATETIME(6), " +
353334
"source VARCHAR(10))");
354335

355-
assertUpdate("INSERT INTO tpch.test_datetime_write VALUES (1, '1970-01-01 00:00:00.000000', 'jdbc')");
336+
// MySQL insertion and MySQL retrieval agree, Presto incorrectly interprets DB value due to legacy mode
337+
jdbcExecutor.execute("INSERT INTO tpch.test_datetime_legacy_storage VALUES (1, '1970-01-01 00:00:00.000000', 'jdbc')");
356338

357-
Session session = Session.builder(getQueryRunner().getDefaultSession())
358-
.setSystemProperty("legacy_timestamp", "false")
359-
.build();
360-
assertUpdate(session, "INSERT INTO mysql.tpch.test_datetime_write VALUES (2, TIMESTAMP '1970-01-01 00:00:00.000000', 'presto')", 1);
361-
362-
assertUpdate("INSERT INTO tpch.test_datetime_write VALUES (3, '2023-06-15 14:30:00.000000', 'jdbc')");
363-
assertUpdate(session, "INSERT INTO mysql.tpch.test_datetime_write VALUES (4, TIMESTAMP '2023-06-15 14:30:00.000000', 'presto')", 1);
339+
// Prove that the value is 1970-01-01 00:00:00 by reading directly from the DB via JDBC
340+
try (Connection conn = DriverManager.getConnection(jdbcUrlWithCredentials);
341+
Statement stmt = conn.createStatement();
342+
ResultSet rs = stmt.executeQuery("SELECT CAST(dt AS CHAR) FROM tpch.test_datetime_legacy_storage WHERE id = 1")) {
343+
assertTrue(rs.next(), "Expected one row");
344+
String dbValue1 = rs.getString(1);
345+
assertEquals(dbValue1, "1970-01-01 00:00:00.000000", "JDBC insert should store wall clock time 1970-01-01 00:00:00 in DB");
346+
}
364347

365-
assertQuery(session,
366-
"SELECT dt FROM mysql.tpch.test_datetime_write WHERE id IN (1, 2) ORDER BY id",
367-
"VALUES TIMESTAMP '1970-01-01 00:00:00.000000', TIMESTAMP '1970-01-01 00:00:00.000000'");
348+
// In legacy mode, DB value 1970-01-01 00:00:00 is interpreted as if it's in JVM timezone (America/Bahia_Banderas UTC-7)
349+
// and then converted to the session timezone. Since both are the same (America/Bahia_Banderas),
350+
// the offset comes from treating the wall-clock DB time as UTC, resulting in 1969-12-31 20:00:00
351+
Session legacySession = Session.builder(getQueryRunner().getDefaultSession())
352+
.setSystemProperty("legacy_timestamp", "true")
353+
.build();
354+
assertQuery(legacySession,
355+
"SELECT dt FROM mysql.tpch.test_datetime_legacy_storage WHERE id = 1",
356+
"VALUES TIMESTAMP '1969-12-31 20:00:00.000000'");
357+
358+
// Presto insertion with legacy mode, verify DB storage via JDBC (should apply JVM timezone conversion during write)
359+
assertUpdate(legacySession, "INSERT INTO mysql.tpch.test_datetime_legacy_storage VALUES (2, TIMESTAMP '2023-06-15 14:30:00.000000', 'presto')", 1);
360+
361+
try (Connection conn = DriverManager.getConnection(jdbcUrlWithCredentials);
362+
Statement stmt = conn.createStatement();
363+
ResultSet rs = stmt.executeQuery("SELECT CAST(dt AS CHAR) FROM tpch.test_datetime_legacy_storage WHERE id = 2")) {
364+
assertTrue(rs.next(), "Expected one row");
365+
String dbValue2 = rs.getString(1);
366+
// JVM timezone is America/Bahia_Banderas (UTC-7), so 2023-06-15 14:30:00 becomes 2023-06-14 19:30:00.000000
367+
assertEquals(dbValue2, "2023-06-14 19:30:00.000000", "Legacy mode applies timezone conversion during write, expected 2023-06-14 19:30:00.000000");
368+
}
368369

369-
assertQuery(session,
370-
"SELECT dt FROM mysql.tpch.test_datetime_write WHERE id IN (3, 4) ORDER BY id",
371-
"VALUES TIMESTAMP '2023-06-15 14:30:00.000000', TIMESTAMP '2023-06-15 14:30:00.000000'");
370+
// Verify Presto reads it back correctly in legacy mode (round-trip should work)
371+
assertQuery(legacySession,
372+
"SELECT dt FROM mysql.tpch.test_datetime_legacy_storage WHERE id = 2",
373+
"VALUES TIMESTAMP '2023-06-15 14:30:00.000000'");
372374
}
373375
finally {
374-
assertUpdate("DROP TABLE IF EXISTS tpch.test_datetime_write");
376+
jdbcExecutor.execute("DROP TABLE IF EXISTS tpch.test_datetime_legacy_storage");
375377
}
376378
}
377379

0 commit comments

Comments
 (0)