Skip to content

Commit

Permalink
Support CTAS with timestamp(>6) with time zone in PostgreSQL
Browse files Browse the repository at this point in the history
  • Loading branch information
findepi committed Oct 1, 2020
1 parent 16d0745 commit fbd4ca7
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -463,15 +463,16 @@ public WriteMapping toWriteMapping(ConnectorSession session, Type type)
verify(timestampType.getPrecision() > TimestampType.MAX_SHORT_PRECISION);
return WriteMapping.objectMapping(format("timestamp(%s)", POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION), longTimestampWriteFunction());
}
if (type instanceof TimestampWithTimeZoneType && ((TimestampWithTimeZoneType) type).getPrecision() <= POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION) {
int precision = ((TimestampWithTimeZoneType) type).getPrecision();
String postgresType = format("timestamptz(%d)", precision);
if (precision <= TimestampWithTimeZoneType.MAX_SHORT_PRECISION) {
return WriteMapping.longMapping(postgresType, shortTimestampWithTimeZoneWriteFunction());
}
else {
return WriteMapping.objectMapping(postgresType, longTimestampWithTimeZoneWriteFunction());
if (type instanceof TimestampWithTimeZoneType) {
TimestampWithTimeZoneType timestampWithTimeZoneType = (TimestampWithTimeZoneType) type;
if (timestampWithTimeZoneType.getPrecision() <= POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION) {
String dataType = format("timestamptz(%d)", timestampWithTimeZoneType.getPrecision());
if (timestampWithTimeZoneType.getPrecision() <= TimestampWithTimeZoneType.MAX_SHORT_PRECISION) {
return WriteMapping.longMapping(dataType, shortTimestampWithTimeZoneWriteFunction());
}
return WriteMapping.objectMapping(dataType, longTimestampWithTimeZoneWriteFunction());
}
return WriteMapping.objectMapping(format("timestamptz(%d)", POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION), longTimestampWithTimeZoneWriteFunction());
}
if (TinyintType.TINYINT.equals(type)) {
return WriteMapping.longMapping("smallint", tinyintWriteFunction());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,9 @@ public Object[][] testTimestampDataProvider()
};
}

/**
* @see #testTimestampWithTimeZoneCoercion
*/
@Test(dataProvider = "trueFalse", dataProviderClass = DataProviders.class)
public void testTimestampWithTimeZone(boolean insertWithPresto)
{
Expand Down Expand Up @@ -1370,13 +1373,57 @@ public void testTimestampWithTimeZone(boolean insertWithPresto)
}
}

/**
* Additional test supplementing {@link #testTimestampWithTimeZone} with values that do not necessarily round-trip, including
* timestamp precision higher than expressible with {@code ZonedDateTime}.
*
* @see #testTimestamp
*/
@Test
public void testCreateTableWithInvalidTimestampWithTimeZone()
public void testTimestampWithTimeZoneCoercion()
throws SQLException
{
String tableName = "test_create_table_with_invalid_timestamp_with_time_zone";
assertQueryFails(
"CREATE TABLE " + tableName + " AS " + "SELECT * FROM (VALUES(CAST(null AS TIMESTAMP(7) WITH TIME ZONE))) t(invalid_column)",
"Unsupported column type: timestamp\\(7\\) with time zone");
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00 UTC'", "TIMESTAMP '1970-01-01 00:00:00 UTC'");

testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.1 UTC'", "TIMESTAMP '1970-01-01 00:00:00.1 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.9 UTC'", "TIMESTAMP '1970-01-01 00:00:00.9 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123 UTC'", "TIMESTAMP '1970-01-01 00:00:00.123 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123000 UTC'", "TIMESTAMP '1970-01-01 00:00:00.123000 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.999 UTC'", "TIMESTAMP '1970-01-01 00:00:00.999 UTC'");
// max supported precision
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123456 UTC'", "TIMESTAMP '1970-01-01 00:00:00.123456 UTC'");

testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.1 UTC'", "TIMESTAMP '2020-09-27 12:34:56.1 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.9 UTC'", "TIMESTAMP '2020-09-27 12:34:56.9 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.123 UTC'", "TIMESTAMP '2020-09-27 12:34:56.123 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.123000 UTC'", "TIMESTAMP '2020-09-27 12:34:56.123000 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.999 UTC'", "TIMESTAMP '2020-09-27 12:34:56.999 UTC'");
// max supported precision
testCreateTableAsAndInsertConsistency("TIMESTAMP '2020-09-27 12:34:56.123456 UTC'", "TIMESTAMP '2020-09-27 12:34:56.123456 UTC'");

// round down
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.1234561 UTC'", "TIMESTAMP '1970-01-01 00:00:00.123456 UTC'");

// nanoc round up, end result rounds down
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123456499 UTC'", "TIMESTAMP '1970-01-01 00:00:00.123456 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.123456499999 UTC'", "TIMESTAMP '1970-01-01 00:00:00.123456 UTC'");

// round up
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.1234565 UTC'", "TIMESTAMP '1970-01-01 00:00:00.123457 UTC'");

// max precision
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.111222333444 UTC'", "TIMESTAMP '1970-01-01 00:00:00.111222 UTC'");

// round up to next second
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 00:00:00.9999995 UTC'", "TIMESTAMP '1970-01-01 00:00:01.000000 UTC'");

// round up to next day
testCreateTableAsAndInsertConsistency("TIMESTAMP '1970-01-01 23:59:59.9999995 UTC'", "TIMESTAMP '1970-01-02 00:00:00.000000 UTC'");

// negative epoch
testCreateTableAsAndInsertConsistency("TIMESTAMP '1969-12-31 23:59:59.9999995 UTC'", "TIMESTAMP '1970-01-01 00:00:00.000000 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '1969-12-31 23:59:59.999999499999 UTC'", "TIMESTAMP '1969-12-31 23:59:59.999999 UTC'");
testCreateTableAsAndInsertConsistency("TIMESTAMP '1969-12-31 23:59:59.9999994 UTC'", "TIMESTAMP '1969-12-31 23:59:59.999999 UTC'");
}

@Test(dataProvider = "trueFalse", dataProviderClass = DataProviders.class)
Expand Down

0 comments on commit fbd4ca7

Please sign in to comment.