[CALCITE-3612] Add TIME/TIMESTAMP WITH TIME ZONE in optimizer#1687
[CALCITE-3612] Add TIME/TIMESTAMP WITH TIME ZONE in optimizer#1687docete wants to merge 4 commits intoapache:mainfrom
Conversation
docete
commented
Dec 25, 2019
- Introduce TIME/TIMESTAMP WITH TIME ZONE types
- Introduce TimeWithTimeZone as internal representation of TIME WITH TIME ZONE type
- Introduce TimestampWithTimeZone as internal representation of TIMESTAMP WITH TIME ZONE type
- Introduce coercion rules for TIME/TIMESTAMP WITH TIME ZONE types
| import org.apache.calcite.util.ControlFlowException; | ||
| import org.apache.calcite.util.Pair; | ||
| import org.apache.calcite.util.Util; | ||
| import org.apache.calcite.util.*; |
There was a problem hiding this comment.
Don't use *, import classes one by one.
| return scaleIntervalToNumber(sourceType, targetType, convert); | ||
| } | ||
|
|
||
| private Expression converterToDate(RelDataType sourceType, Expression operand) { |
There was a problem hiding this comment.
I would prefer to split this refactoring with adding the new types into two PRs, as it will make clear what is added by this PR and what is newly added code. By doing so we could better review the new code.
Let's see what are other reviewers' opinions.
There was a problem hiding this comment.
The aim of the refactoring is make sure the length of a method is smaller than 370, and avoid complaining by checkstyle. I will split the refactoring part to a separate commit, that would clarify the PR.
| case TIME_WITH_TIME_ZONE: | ||
| return new TimeWithTimeZoneString(0, 0, 0, "UTC"); | ||
| case TIMESTAMP_WITH_TIME_ZONE: | ||
| return new TimestampWithTimeZoneString(0, 0, 0, 0, 0, 0, "UTC"); |
There was a problem hiding this comment.
Shouldn't 0 is January 1, 1970 UTC, assuming the millis are epoch millis (count from 1970-01-01 UTC)
There was a problem hiding this comment.
After double checked the ZERO of TIMESTAMP type, I think your are right. ZERO should be January 1, 1970 UTC.
| return false; | ||
| } | ||
| TimeWithTimeZone that = (TimeWithTimeZone) obj; | ||
| return milliOfDay == that.milliOfDay && timeZone == that.timeZone; |
There was a problem hiding this comment.
Should call timeZone.equals(that.timeZone) otherwise it is comparing the reference but not real value?
| public class TimestampWithTimeZone implements Comparable<TimestampWithTimeZone>, Serializable { | ||
| //~ Instance fields -------------------------------------------------------- | ||
|
|
||
| private final long millisecond; |
There was a problem hiding this comment.
is this epoch millis or just millis? If it is epoch millis, can you update comments to reflect it?
There was a problem hiding this comment.
The millisecond should be a zone-less TIMESTAMP(the internal representation of TIMESTAMP WITHOUT TIME ZONE). The java doc of the constructor has made it clearly.
There was a problem hiding this comment.
Can you point to me the class that represents TIMESTAMP WITHOUT TIME ZONE in Calcite? I want to double check what type of millis that saves internally?
There was a problem hiding this comment.
Just a long value. You can see BuiltInMethod.STRING_TO_TIMESTAMP
| return false; | ||
| } | ||
| TimestampWithTimeZone that = (TimestampWithTimeZone) obj; | ||
| return this.millisecond == that.millisecond && this.timeZone == that.timeZone; |
There was a problem hiding this comment.
this.timeZone.equals(that.timeZone)
| import org.apache.calcite.util.TimestampString; | ||
| import org.apache.calcite.util.TimestampWithTimeZoneString; | ||
| import org.apache.calcite.util.Util; | ||
| import org.apache.calcite.util.*; |
There was a problem hiding this comment.
Don't use *. Import classes one by one.
| final RexLiteral literalTimestampWithTZ = | ||
| rexBuilder.makeTimestampWithTimeZoneLiteral( | ||
| new TimestampWithTimeZoneString( | ||
| new TimestampString(2017, 7, 20, 8, 23, 45), |
There was a problem hiding this comment.
Can you test up to millis?
There was a problem hiding this comment.
I noticed the TIMESTAMP and TIMESTAMP WITH LOCAL TIME ZONE also ignored precision in RexToLixTranslator. See cast(TIMESTAMP as CHAR), I think we should follow that. And we could open another ticket to support precision of them.
| .getMillisSinceEpoch(); | ||
| } | ||
|
|
||
| public static int timeWithTimeZoneToTime(TimeWithTimeZone ttz) { |
There was a problem hiding this comment.
Do we need javadoc for these public static methods?
There was a problem hiding this comment.
I think the method name has documented it?
|
rebased to split the refactoring to a separate commit. |
| // SQL 2011 Part2 Section 4.6 General Rules 13.d | ||
| case TIMESTAMP_WITH_TIME_ZONE: | ||
| convert = Expressions.convert_( | ||
| Expressions.call(BuiltInMethod.FLOOR_DIV.method, |
There was a problem hiding this comment.
implement a timestampWithoutTimeZoneToDate and call it here?
There was a problem hiding this comment.
Not needed!
- Section 6.13 General Rules 13.d shows this can be computed as "CAST ( CAST ( VE AS TIMESTAMP WITHOUT TIME ZONE ) AS DATE )"
- the underlying TimestampWithTimeZone holds the same long value with Timestamp type, current implementation is more simple
There was a problem hiding this comment.
Yes. By reading the SQL standard I got the idea of the conversion path.
This suggestion is more from readability perspective. If you implements one more function that then code readers will know the equivalent implementation is CAST ( CAST ( VE AS TIMESTAMP WITHOUT TIME ZONE ) AS DATE ).
I had to read SQL standard cause I wasn't sure why there is a "magic" operation after casting to TIMESTAMP WITHOUT TIME ZONE.
Or maybe you can add a comment instead to say the implementation here is CAST ( CAST ( VE AS TIMESTAMP WITHOUT TIME ZONE ) AS DATE )
| Expressions.call(BuiltInMethod.TIME_ZONE.method, root))); | ||
| break; | ||
| // SQL 2011 Part2 Section 4.6 General Rules 15.e | ||
| case TIMESTAMP_WITH_TIME_ZONE: |
There was a problem hiding this comment.
implement a timestampWithoutTimeZoneToTimeWithoutTimeZone and call it here?
| operand, | ||
| Expressions.call(BuiltInMethod.TIME_ZONE.method, root))); | ||
| break; | ||
| // SQL 2011 Part2 Section 4.6 General Rules 15.e |
There was a problem hiding this comment.
I didn't find "general rules" under section 4.6 (was looking at page no.36)
SQL 2011 Part2 Section 4.6 Table 3 gives a very clear conversion table.
There was a problem hiding this comment.
Sorry, it should be Section 6.13 (begin with p243)
| return localTime + " " + ttz.getTimeZone().getID(); | ||
| } | ||
|
|
||
| public static TimeWithTimeZone toTimeWithTimeZone(String v, TimeZone sesstionTimeZone) { |
There was a problem hiding this comment.
rename to stringToTimeWithTimeZone?
| return new TimeWithTimeZone(milliOfDay, tstz.getTimeZone()); | ||
| } | ||
|
|
||
| public static TimestampWithTimeZone toTimestampWithTimeZone(String v, TimeZone sessionTimeZone) { |
There was a problem hiding this comment.
Maybe also rename and include string?
| public class TimestampWithTimeZone implements Comparable<TimestampWithTimeZone>, Serializable { | ||
| //~ Instance fields -------------------------------------------------------- | ||
|
|
||
| private final long millisecond; |
There was a problem hiding this comment.
Can you point to me the class that represents TIMESTAMP WITHOUT TIME ZONE in Calcite? I want to double check what type of millis that saves internally?
* Introduce TIME/TIMESTAMP WITH TIME ZONE types * Introduce TimeWithTimeZone as internal representation of TIME WITH TIME ZONE type * Introduce TimestampWithTimeZone as internal representation of TIMESTAMP WITH TIME ZONE type * Introduce coercion rules for TIME/TIMESTAMP WITH TIME ZONE types
|
rebase to resolve all conflicts |
|
@julianhyde Could you take a look at this if you are free? Hopefully I touched all the right places and didn't missing any thing. |
|
Would you like to pick up this work again? I can help on review/merge your work. |
|
@amaliujia Sorry for the late reply, I will rebase this PR in recent days. |
|
What's the status of this work? Is there someone that can get this to completion? This is a pretty significant hole in Calcite's SQL support. |
8a5cf83 to
cf7f71b
Compare