-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Add GRACE PERIOD to SHOW CREATE MATERIALIZED VIEW #27529
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
base: master
Are you sure you want to change the base?
Conversation
8701367 to
7e3c950
Compare
| public static IntervalLiteral formatDayTimeInterval(Duration duration) | ||
| { | ||
| long millis = duration.toMillis(); | ||
| Period period = new Period(Math.abs(millis)).normalizedStandard(PeriodType.dayTime()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add
IntervalLiteral.Sign sign = millis < 0 ? NEGATIVE : POSITIVE;so that abs is not scary
|
|
||
| PeriodFormatterBuilder builder = new PeriodFormatterBuilder(); | ||
| PeriodFormatterBuilder builder = new PeriodFormatterBuilder() | ||
| .printZeroIfSupported(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why so? code comment
| break; | ||
| } | ||
| builder.appendLiteral(":"); | ||
| builder.minimumPrintedDigits(2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why so? code comment
| @Test | ||
| void testDayTimeIntervalRoundTrip() | ||
| { | ||
| testDayTimeIntervalRoundTrip("0", SECOND, Optional.empty()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd rather have this take SQL interval string as input to test roundtrip.
That would be testing at the level at which things must be stable, and without adding too many layers IMO.
| if (period.getDays() > 0) { | ||
| startField = DAY; | ||
| if (period.getSeconds() > 0 || period.getMillis() > 0) { | ||
| endField = Optional.of(SECOND); | ||
| value = INTERVAL_DAY_SECOND_FORMATTER.print(period); | ||
| } | ||
| else if (period.getMinutes() > 0) { | ||
| endField = Optional.of(MINUTE); | ||
| value = INTERVAL_DAY_MINUTE_FORMATTER.print(period); | ||
| } | ||
| else if (period.getHours() > 0) { | ||
| endField = Optional.of(HOUR); | ||
| value = INTERVAL_DAY_HOUR_FORMATTER.print(period); | ||
| } | ||
| else { | ||
| endField = Optional.empty(); | ||
| value = INTERVAL_DAY_FORMATTER.print(period); | ||
| } | ||
| } | ||
| else if (period.getHours() > 0) { | ||
| startField = HOUR; | ||
| if (period.getSeconds() > 0 || period.getMillis() > 0) { | ||
| endField = Optional.of(SECOND); | ||
| value = INTERVAL_HOUR_SECOND_FORMATTER.print(period); | ||
| } | ||
| else if (period.getMinutes() > 0) { | ||
| endField = Optional.of(MINUTE); | ||
| value = INTERVAL_HOUR_MINUTE_FORMATTER.print(period); | ||
| } | ||
| else { | ||
| endField = Optional.empty(); | ||
| value = INTERVAL_HOUR_FORMATTER.print(period); | ||
| } | ||
| } | ||
| else if (period.getMinutes() > 0) { | ||
| startField = MINUTE; | ||
| if (period.getSeconds() > 0 || period.getMillis() > 0) { | ||
| endField = Optional.of(SECOND); | ||
| value = INTERVAL_MINUTE_SECOND_FORMATTER.print(period); | ||
| } | ||
| else { | ||
| endField = Optional.empty(); | ||
| value = INTERVAL_MINUTE_FORMATTER.print(period); | ||
| } | ||
| } | ||
| else { | ||
| startField = SECOND; | ||
| endField = Optional.empty(); | ||
| value = INTERVAL_SECOND_FORMATTER.print(period); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks terribly verbose, but i don't know how to improve it. ok to keep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One option is to reuse the function we use for casts:
trino/client/trino-client/src/main/java/io/trino/client/IntervalDayTime.java
Lines 52 to 73 in 518b244
| public static String formatMillis(long millis) | |
| { | |
| if (millis == Long.MIN_VALUE) { | |
| return LONG_MIN_VALUE; | |
| } | |
| String sign = ""; | |
| if (millis < 0) { | |
| sign = "-"; | |
| millis = -millis; | |
| } | |
| long day = millis / MILLIS_IN_DAY; | |
| millis %= MILLIS_IN_DAY; | |
| long hour = millis / MILLIS_IN_HOUR; | |
| millis %= MILLIS_IN_HOUR; | |
| long minute = millis / MILLIS_IN_MINUTE; | |
| millis %= MILLIS_IN_MINUTE; | |
| long second = millis / MILLIS_IN_SECOND; | |
| millis %= MILLIS_IN_SECOND; | |
| return format("%s%d %02d:%02d:%02d.%03d", sign, day, hour, minute, second, millis); | |
| } |
but then the output is verbose:
trino/core/trino-main/src/test/java/io/trino/type/TestIntervalDayTime.java
Lines 431 to 434 in 518b244
| assertThat(assertions.expression("CAST(a AS varchar)") | |
| .binding("a", "INTERVAL '12' DAY")) | |
| .hasType(VARCHAR) | |
| .isEqualTo("12 00:00:00.000"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep in mind this is coming: #27539
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep in mind this is coming: #27539
Thanks for the link!
i skimmed the PR and it looks mostly backwards compatible.
The code in this PR takes java time interval and formats it as a SQL literal, so it should work both before and after the same.
One option is to reuse the function we use for casts
Sounds much simpler. How would that look like @piotrrzysko ?
Would we still output CREATE MV statement that can be pasted back into CLI and run?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A prototype: piotrrzysko@962fe50
I added tests that demonstrate the formatted result can be parsed back into the original input (expressed in milliseconds, since the original format is not retained).
The only downside I see in this approach, as mentioned earlier, is that the formatted values are not succinct (e.g., INTERVAL '1' HOUR becomes INTERVAL '0 01:00:00.000' DAY TO SECOND).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't preserve original syntax (1 hour = 60 minutes and we don't distinguish)
I agree that INTERVAL '1' HOUR looks nicer than INTERVAL '0 01:00:00.000' DAY TO SECOND.
But less code looks nicer to me.
What I am worried is that "reuse the function we use for casts" may be "opportunistic reuse" -- reuse of something that does what we need today, but has different design constrains and so can change in the future.
Unless/until we have confirmation "the function we use for casts" is guaranteed to produce a string literal that we can put directly into a SQL, let's not use it.
|
please rebase |
Description
This PR adds support for displaying the
GRACE PERIODclause in the output ofSHOW CREATE MATERIALIZED VIEW.Additional context and related issues
Release notes
( ) This is not user-visible or is docs only, and no release notes are required.
( ) Release notes are required. Please propose a release note for me.
(x) Release notes are required, with the following suggested text: