[ 
https://issues.apache.org/jira/browse/CALCITE-3597?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16994412#comment-16994412
 ] 

Danny Chen commented on CALCITE-3597:
-------------------------------------

With some a little research of the code i found that:

* For Calcite itself, we would convert the Time/Date/Timestamp to internal 
storage type[1] use the method SqlFunctions#toLong(Timestamp)[2], that means 
the internal integer/long are all shift by the timeZone offset;
* When user use an UDF, these internal storage types would be converted back 
with method SqlFunctions#internalToTimestamp(long)[3]

When reference the java doc of SqlFunctions#toLong(Timestamp), it seems that it 
should only be used by UDF, and it should be the converse of 
SqlFunctions#internalToTimestamp(long).

That means:
{code:java}
y =  SqlFunctions.internalToTimestamp(SqlFunctions.toLong(y))
{code}

So at least, what we can conclude is that Calcite misuse these 2 functions or 
there is bug that needs to fix.

[1] 
https://github.com/apache/calcite/blob/d951844c464d41fe435977f12df975352d71226f/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumUtils.java#L193
[2] 
https://github.com/apache/calcite/blob/d951844c464d41fe435977f12df975352d71226f/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java#L1808
[3] 
https://github.com/apache/calcite/blob/d951844c464d41fe435977f12df975352d71226f/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java#L1969


> The conversion between java.sql.Timestamp and long is not asymmetric
> --------------------------------------------------------------------
>
>                 Key: CALCITE-3597
>                 URL: https://issues.apache.org/jira/browse/CALCITE-3597
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.21.0
>            Reporter: Zhenghua Gao
>            Priority: Major
>              Labels: pull-request-available
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> In Calcite, we use SqlFunctions.toLong(Timestamp) and 
> SqlFunctions.internalToTimestamp(long) to convert java.sql.Timestmap to 
> internal long and vice versa. The main logical inside is +/- local time zone 
> offset.
> But in the comments of TimeZone.getOffset(long date), the parameter 
> represents in milliseconds since January 1, 1970 00:00:00 GMT. It means that 
> there will one conversion above doesn't satisfy this hypothesis.
>  
> This causes many surprise to users:
> (1) some Daylight Saving Time changes:
>  
> {code:java}
> @Test public void testDayLightingSaving() {
>  TimeZone tz = TimeZone.getDefault();
>  TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
>  java.sql.Timestamp dst2018Begin = java.sql.Timestamp.valueOf("2018-03-11 
> 03:00:00");
>  assertThat(dst2018Begin, is(internalToTimestamp(toLong(dst2018Begin))));
>  TimeZone.setDefault(tz);
> }{code}
> fails with:
> {code:java}
> java.lang.AssertionError: 
> Expected: is <2018-03-11 04:00:00.0>
>  but: was <2018-03-11 03:00:00.0>
> Expected :is <2018-03-11 04:00:00.0>
> Actual :<2018-03-11 03:00:00.0>{code}
>  
> (2) "1900-01-01 00:00:00" Changes in some TimeZone
> {code:java}
> @Test public void test() {
>  TimeZone tz = TimeZone.getDefault();
>  TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
>  java.sql.Timestamp ts = java.sql.Timestamp.valueOf("1900-01-01 00:00:00");
>  assertThat(ts, is(internalToTimestamp(toLong(ts))));
>  TimeZone.setDefault(tz);
> }{code}
> fails with
> {code:java}
> java.lang.AssertionError: 
> Expected: is <1899-12-31 23:54:17.0>
>  but: was <1900-01-01 00:00:00.0>
> Expected :is <1899-12-31 23:54:17.0>
> Actual :<1900-01-01 00:00:00.0>
> {code}
>  
>  
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to