Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for precision for TIMESTAMP W/TZ in Postgresql type mapping #5105

Merged
merged 2 commits into from
Sep 9, 2020

Conversation

losipiuk
Copy link
Member

@losipiuk losipiuk commented Sep 8, 2020

No description provided.

@cla-bot cla-bot bot added the cla-signed label Sep 8, 2020
@losipiuk losipiuk requested a review from findepi September 8, 2020 20:27
@findepi
Copy link
Member

findepi commented Sep 9, 2020

Relates to #4570

@@ -434,8 +442,15 @@ public WriteMapping toWriteMapping(ConnectorSession session, Type type)
if (TIMESTAMP_MILLIS.equals(type)) {
return WriteMapping.longMapping("timestamp", timestampWriteFunction());
}
if (TIMESTAMP_WITH_TIME_ZONE.equals(type)) {
return WriteMapping.longMapping("timestamptz", timestampWithTimeZoneWriteFunction());
if (type instanceof TimestampWithTimeZoneType && ((TimestampWithTimeZoneType) type).getPrecision() <= 6) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Postgres currently supports p <=6 (according to docs), so we do not have behavioral regression here.
Worth mentioning in the commit message that we are leveraging this fact.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until 9 we would be fine. It would harder with 10,11,12 as I am not sure if that is compatible with JDBC. At least not via OffsetDateTime PSQL uses.

The ((TimestampWithTimeZoneType) type).getPrecision() <= 6 condition is merly a checkstate. I just did not want to have it explicitly in if (type instanceof TimestampWithTimeZoneType) {, so standard unsupported type handling logic triggers if for some magical reason we get timestamp with precision >6 (e.g with some future version of PSQL)

TIMESTAMP_WITH_TIME_ZONE,
timeStampWithTimeZoneReadFunction(),
timestampWithTimeZoneWriteFunction());
checkArgument(precision <= 6, "unsupported precision value");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add

// PostgreSQL currently supports precision up to microseconds

to argument that throwing is actually OK think to do

(statement, index, value) -> {
// PostgreSQL does not store zone information in "timestamp with time zone" data type
long epochSeconds = value.getEpochMillis() / MILLISECONDS_PER_SECOND;
long nanosOfSecond = value.getEpochMillis() % MICROSECONDS_PER_MILLISECOND * NANOSECONDS_PER_MILLISECOND + value.getPicosOfMilli() / PICOSECONDS_PER_NANOSECOND;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MICROSECONDS_PER_MILLISECOND -> MILLISECONDS_PER_SECOND

@martint is the % and / right here? or floorDiv instead?

do we have helper methods somewhere so that we do not have to ask the above question ever again?

else {
LongTimestampWithTimeZone value = (LongTimestampWithTimeZone) prestoNative;
long epochSeconds = value.getEpochMillis() / MILLISECONDS_PER_SECOND;
long nanosOfSecond = value.getEpochMillis() % MICROSECONDS_PER_MILLISECOND * NANOSECONDS_PER_MILLISECOND
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MICROSECONDS_PER_MILLISECOND -> ..

@@ -1141,16 +1141,16 @@ public void testTimestampWithTimeZone(boolean insertWithPresto)
}

@Test(dataProvider = "testTimestampWithTimeZoneDataProvider")
public void testArrayTimestampWithTimeZone(boolean insertWithPresto)
public void testArrayTimestampWithTimeZone(boolean insertWithPresto, int precision)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also add test what happens if we try create table with timestamp(7).

private static ZonedDateTime roundToPrecision(ZonedDateTime zonedDateTime, int precision)
{
int divisor = (int) Math.pow(10, 9 - precision);
return zonedDateTime.withNano(zonedDateTime.getNano() / divisor * divisor);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method is called "round to precision", but this truncates.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - previous version used to round :)

@losipiuk losipiuk force-pushed the lo/psql-timestamp-p branch from 7fa8471 to 2394c13 Compare September 9, 2020 10:21
@losipiuk
Copy link
Member Author

losipiuk commented Sep 9, 2020

AC

Add support for mapping TIMESTAMP WITH TIME ZONE from Presto to
PostgreSQL (and vice versa) for precisions 1 to 6. It covers all
precisions currently supported by PostgreSQL.
@losipiuk losipiuk force-pushed the lo/psql-timestamp-p branch from 2394c13 to e12f1ba Compare September 9, 2020 13:58
@losipiuk
Copy link
Member Author

losipiuk commented Sep 9, 2020

@findepi I reworked testing towards what we discussed

@losipiuk losipiuk merged commit 5671a6e into trinodb:master Sep 9, 2020
@losipiuk losipiuk mentioned this pull request Sep 11, 2020
9 tasks
@martint martint added this to the 342 milestone Sep 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

3 participants