|
43 | 43 |
|
44 | 44 | import java.math.BigDecimal; |
45 | 45 | import java.math.RoundingMode; |
| 46 | +import java.sql.SQLException; |
46 | 47 | import java.text.NumberFormat; |
47 | 48 | import java.time.LocalDate; |
48 | 49 | import java.time.LocalDateTime; |
|
100 | 101 | import static io.prestosql.testing.datatype.DataType.timestampDataType; |
101 | 102 | import static io.prestosql.testing.datatype.DataType.varbinaryDataType; |
102 | 103 | import static io.prestosql.testing.datatype.DataType.varcharDataType; |
| 104 | +import static io.prestosql.testing.sql.TestTable.randomTableSuffix; |
103 | 105 | import static io.prestosql.type.JsonType.JSON; |
104 | 106 | import static io.prestosql.type.UuidType.UUID; |
105 | 107 | import static java.lang.String.format; |
|
113 | 115 | import static java.util.function.Function.identity; |
114 | 116 | import static java.util.stream.Collectors.joining; |
115 | 117 | import static java.util.stream.Collectors.toList; |
| 118 | +import static org.assertj.core.api.Assertions.assertThat; |
116 | 119 |
|
117 | 120 | public class TestPostgreSqlTypeMapping |
118 | 121 | extends AbstractTestQueryFramework |
@@ -1007,6 +1010,9 @@ public void testTime(boolean insertWithPresto, ZoneId sessionZone) |
1007 | 1010 | } |
1008 | 1011 | } |
1009 | 1012 |
|
| 1013 | + /** |
| 1014 | + * @see #testTimestampCoercion |
| 1015 | + */ |
1010 | 1016 | @Test(dataProvider = "testTimestampDataProvider") |
1011 | 1017 | public void testTimestamp(boolean insertWithPresto, ZoneId sessionZone) |
1012 | 1018 | { |
@@ -1052,6 +1058,60 @@ public void testTimestamp(boolean insertWithPresto, ZoneId sessionZone) |
1052 | 1058 | } |
1053 | 1059 | } |
1054 | 1060 |
|
| 1061 | + /** |
| 1062 | + * Additional test supplementing {@link #testTimestamp} with values that do not necessarily round-trip, including |
| 1063 | + * timestamp precision higher than expressible with {@code LocalDateTime}. |
| 1064 | + * |
| 1065 | + * @see #testTimestamp |
| 1066 | + */ |
| 1067 | + @Test |
| 1068 | + public void testTimestampCoercion() |
| 1069 | + throws SQLException |
| 1070 | + { |
| 1071 | + // precision 0 ends up as precision 0 |
| 1072 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00'", "TIMESTAMP '1970-01-01 00:00:00'"); |
| 1073 | + |
| 1074 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.1'", "TIMESTAMP '1970-01-01 00:00:00.1'"); |
| 1075 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.9'", "TIMESTAMP '1970-01-01 00:00:00.9'"); |
| 1076 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123'", "TIMESTAMP '1970-01-01 00:00:00.123'"); |
| 1077 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123000'", "TIMESTAMP '1970-01-01 00:00:00.123000'"); |
| 1078 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.999'", "TIMESTAMP '1970-01-01 00:00:00.999'"); |
| 1079 | + // max supported precision |
| 1080 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123456'", "TIMESTAMP '1970-01-01 00:00:00.123456'"); |
| 1081 | + |
| 1082 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.1'", "TIMESTAMP '2020-09-27 12:34:56.1'"); |
| 1083 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.9'", "TIMESTAMP '2020-09-27 12:34:56.9'"); |
| 1084 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.123'", "TIMESTAMP '2020-09-27 12:34:56.123'"); |
| 1085 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.123000'", "TIMESTAMP '2020-09-27 12:34:56.123000'"); |
| 1086 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.999'", "TIMESTAMP '2020-09-27 12:34:56.999'"); |
| 1087 | + // max supported precision |
| 1088 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.123456'", "TIMESTAMP '2020-09-27 12:34:56.123456'"); |
| 1089 | + |
| 1090 | + // round down |
| 1091 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.1234561'", "TIMESTAMP '1970-01-01 00:00:00.123456'"); |
| 1092 | + |
| 1093 | + // nanoc round up, end result rounds down |
| 1094 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123456499'", "TIMESTAMP '1970-01-01 00:00:00.123456'"); |
| 1095 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123456499999'", "TIMESTAMP '1970-01-01 00:00:00.123456'"); |
| 1096 | + |
| 1097 | + // round up |
| 1098 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.1234565'", "TIMESTAMP '1970-01-01 00:00:00.123457'"); |
| 1099 | + |
| 1100 | + // max precision |
| 1101 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.111222333444'", "TIMESTAMP '1970-01-01 00:00:00.111222'"); |
| 1102 | + |
| 1103 | + // round up to next second |
| 1104 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.9999995'", "TIMESTAMP '1970-01-01 00:00:01.000000'"); |
| 1105 | + |
| 1106 | + // round up to next day |
| 1107 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 23:59:59.9999995'", "TIMESTAMP '1970-01-02 00:00:00.000000'"); |
| 1108 | + |
| 1109 | + // negative epoch |
| 1110 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1969-12-31 23:59:59.9999995'", "TIMESTAMP '1970-01-01 00:00:00.000000'"); |
| 1111 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1969-12-31 23:59:59.999999499999'", "TIMESTAMP '1969-12-31 23:59:59.999999'"); |
| 1112 | + testCreateTableAsAndInsertConsistency("TIMESTAMP '1969-12-31 23:59:59.9999994'", "TIMESTAMP '1969-12-31 23:59:59.999999'"); |
| 1113 | + } |
| 1114 | + |
1055 | 1115 | @Test(dataProvider = "testTimestampDataProvider") |
1056 | 1116 | public void testArrayTimestamp(boolean insertWithPresto, ZoneId sessionZone) |
1057 | 1117 | { |
@@ -1421,6 +1481,25 @@ private void testUnsupportedDataTypeConvertedToVarchar(Session session, String d |
1421 | 1481 | } |
1422 | 1482 | } |
1423 | 1483 |
|
| 1484 | + private void testCreateTableAsAndInsertConsistency(String inputLiteral, String expectedResult) |
| 1485 | + throws SQLException |
| 1486 | + { |
| 1487 | + String tableName = "test_ctas_and_insert_" + randomTableSuffix(); |
| 1488 | + |
| 1489 | + // CTAS |
| 1490 | + assertUpdate("CREATE TABLE " + tableName + " AS SELECT " + inputLiteral + " a", 1); |
| 1491 | + assertThat(query("SELECT a FROM " + tableName)) |
| 1492 | + .matches("VALUES " + expectedResult); |
| 1493 | + |
| 1494 | + // INSERT as a control query, where the coercion is done by the engine |
| 1495 | + postgreSqlServer.execute("DELETE FROM tpch." + tableName); |
| 1496 | + assertUpdate("INSERT INTO " + tableName + " (a) VALUES (" + inputLiteral + ")", 1); |
| 1497 | + assertThat(query("SELECT a FROM " + tableName)) |
| 1498 | + .matches("VALUES " + expectedResult); |
| 1499 | + |
| 1500 | + assertUpdate("DROP TABLE " + tableName); |
| 1501 | + } |
| 1502 | + |
1424 | 1503 | public static DataType<ZonedDateTime> timestampWithTimeZoneDataType(int precision, boolean insertWithPresto) |
1425 | 1504 | { |
1426 | 1505 | if (insertWithPresto) { |
|
0 commit comments