-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Use JVM time zone rules in Joda #11891
Conversation
Posted JodaOrg/joda-time#491 to request opinion from joda author |
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 haven't really go into the conversion logics yet (needed to read a little about the implementation on joda/jdk code), I added some comments for other parts.
presto-main/src/main/java/com/facebook/presto/tz/JdkBasedZoneInfoProvider.java
Outdated
Show resolved
Hide resolved
presto-main/src/test/java/com/facebook/presto/tz/TestJdkBasedZoneInfoProvider.java
Outdated
Show resolved
Hide resolved
@@ -2186,13 +2186,13 @@ | |||
2177 CST6CDT | |||
2178 Cuba | |||
2179 EET | |||
2180 EST | |||
# 2180 EST # not in java.time |
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 should removed it probably from a while back. Currently, when we run following query in presto-cli:
SELECT CAST('2018-10-28 14:44:59.000 EST' AS TIMESTAMP WITH TIME ZONE)
we got error:
Error fetching next at https://[2401:db00:1010:811a:face:0:1:0]:7778/v1/statement/20181110_024907_49716_ysdca/2 returned an invalid response: JsonResponse
java.time.zone.ZoneRulesException: Unknown time-zone ID: EST
How do you find out which timezone to be removed?
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 think "2040 Canada/East-Saskatchewan" also got removed in 2017
http://mm.icann.org/pipermail/tz-announce/2017-October/000047.html
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 assume TestTimeZoneUtils won't be very useful anymore since joda/jdk timezones are unified.
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.
Can we have a test for zone-index contents?
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.
Can we have a test for zone-index contents?
We already have one in TestTimeZoneUtils
. I updated it.
think "2040 Canada/East-Saskatchewan" also got removed in 2017
Updated in the preceding commit.
// * static initializer of DateTimeZoneIndex | ||
|
||
@BeforeClass | ||
protected void registerFunctions() |
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.
See comment above, we probably don't need to rely on the system property. Joda allows you to override the default provider.
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.
Sorry about the bad name.
This is not really setting it. It's more like validating it (as evidenced by the error message in catch). However, when you run this in IntelliJ, it does provide the convenience of setting it for you (only when doing so is safe).
presto-main/pom.xml
Outdated
@@ -407,6 +407,9 @@ | |||
<excludes> | |||
<exclude>**/TestLocalExecutionPlanner.java</exclude> | |||
</excludes> | |||
<systemPropertyVariables> | |||
<org.joda.time.DateTimeZone.Provider>com.facebook.presto.tz.JdkBasedZoneInfoProvider</org.joda.time.DateTimeZone.Provider> |
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.
Does joda support service loader? Or any other way to make this be loaded more reliably?
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.
@Override | ||
public int hashCode() | ||
{ | ||
return Objects.hash(super.hashCode(), zoneRules); |
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.
is hashcode compatible with equals? hashcode consults super's fields and equals does not (it would be correct for equals to do this)
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.
There is no field in the super class. Making things even more interesting, super does have an implementation for hashCode
, but not equals
. This is very uncommon.
The equals
and hashCode
implementation here are generated by IntelliJ.
I think the implementation is correct as is. However, it indeed looks very suspicious.
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.
Looking at the classes it appears that subclasses are not equals
to each other, and instead you need an exact type match. Providing a default implementation for hashCode
is a bit wonky and some of the subclasses override that also. I suggest we simply implement both equals
and hashCode
and we base them solely on getID()
.
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.
Naive question -- do we need hashCode/equals at all?
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.
The super class declared equals
as abstract so it must be implemented.
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.
Lets make this just return getID().hashCode();
presto-main/src/test/java/com/facebook/presto/tz/TestJdkBasedZoneInfoProvider.java
Outdated
Show resolved
Hide resolved
@@ -2186,13 +2186,13 @@ | |||
2177 CST6CDT | |||
2178 Cuba | |||
2179 EET | |||
2180 EST | |||
# 2180 EST # not in java.time |
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.
Can we have a test for zone-index contents?
// Otherwise, the zone-internal cache won't be useful. | ||
// Joda's default Provider implementation, ZoneInfoProvider, caches with SoftReference. | ||
// This implementation didn't use SoftReference for simplicity. | ||
zoneCache = CacheBuilder.newBuilder().build(new CacheLoader<String, DateTimeZone>() |
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.
Does it take a long time to load every time zone? If not, why not just load everything ahead of time?
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.
Ran a quick test. On my mac from cold boot, this takes 250 ms, so I would just load everything up front:
@Test
public void test()
{
JdkBasedZoneInfoProvider jdkBasedZoneInfoProvider = new JdkBasedZoneInfoProvider();
Set<String> availableIDs = jdkBasedZoneInfoProvider.getAvailableIDs();
for (String availableID : availableIDs) {
jdkBasedZoneInfoProvider.getZone(availableID);
}
}
presto-spi/src/main/resources/com/facebook/presto/spi/type/zone-index.properties
Show resolved
Hide resolved
presto-main/src/main/java/com/facebook/presto/tz/JdkBasedDateTimeZone.java
Outdated
Show resolved
Hide resolved
presto-main/src/main/java/com/facebook/presto/tz/JdkBasedDateTimeZone.java
Outdated
Show resolved
Hide resolved
presto-main/src/test/java/com/facebook/presto/tz/TestJdkBasedZoneInfoProvider.java
Outdated
Show resolved
Hide resolved
One more thing. The DateTimeZone class is Serializable, so I would either make that fail or test that it works as expected. |
Can you tell me how to do this right? |
I just read through the existing serialization code, and it appears to be doing the correct thing. When a |
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.
There are some follow up comments, but this looking good to me.
@Override | ||
public int hashCode() | ||
{ | ||
return Objects.hash(super.hashCode(), zoneRules); |
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.
The super class declared equals
as abstract so it must be implemented.
public class JdkBasedZoneInfoProvider | ||
implements Provider | ||
{ | ||
private final Map<String, DateTimeZone> zones; |
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.
Is there any reason to not make this static
?
presto-main/src/main/java/com/facebook/presto/tz/JdkBasedZoneInfoProvider.java
Outdated
Show resolved
Hide resolved
presto-spi/src/main/resources/com/facebook/presto/spi/type/zone-index.properties
Show resolved
Hide resolved
presto-spi/src/main/resources/com/facebook/presto/spi/type/zone-index.properties
Show resolved
Hide resolved
ca2eb59
to
1856039
Compare
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.
Comments addressed, @dain
// this is before the first transition | ||
return instant; | ||
} | ||
return previousTransition.toEpochSecond() * 1000 - 1; |
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.
In addition to addressing your comments, I added + 1
and - 1
here. I also added a bunch of tests. Please take a look.
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.
Please add a comment here.
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.
Some minor comments. There are still build failures.
// this is before the first transition | ||
return instant; | ||
} | ||
return previousTransition.toEpochSecond() * 1000 - 1; |
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.
Please add a comment here.
return false; | ||
} | ||
JdkBasedDateTimeZone that = (JdkBasedDateTimeZone) o; | ||
return Objects.equals(zoneRules, that.zoneRules); |
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.
Lets make this just return getID().equals(that.getId());
@Override | ||
public int hashCode() | ||
{ | ||
return Objects.hash(super.hashCode(), zoneRules); |
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.
Lets make this just return getID().hashCode();
95b4757
to
4de19a2
Compare
Not ready to merge due to issues related to spi and class loader. |
I talked to @dain and @electrum separately offline about this. To summarize, Proposed Goals:
Proposed Approach:
Question:
|
JodaToJavaTimeBridge? |
What is the benefit of putting this in |
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.
Looks good to me.
@electrum do you have any comments on the documentation change?
registers a custom Joda-Time zone provider at startup time, which makes | ||
Joda-Time delegate to JVM's built-in zone rules. The zone provider | ||
can be found in the above package. If the dependency is not declared, | ||
a class loading error will occur. |
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.
cc @electrum ^^^
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.
Documentation looks good
|
||
.. note:: | ||
|
||
For any connector that uses Joda-Time, it must declare a runtime |
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.
Use code quotes for "runtime"
For any connector that uses Joda-Time, it must declare a runtime | ||
dependency on `joda-to-java-time-bridge <https://github.com/airlift/joda-to-java-time-bridge/blob/master/README.md>`_. | ||
Presto internally uses ``java.time`` for certain date/time | ||
computations. As a result, to avoid incorrect results, Presto |
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.
As a result -> Thus
(avoid using "result" twice in slightly different ways)
Presto internally uses ``java.time`` for certain date/time | ||
computations. As a result, to avoid incorrect results, Presto | ||
registers a custom Joda-Time zone provider at startup time, which makes | ||
Joda-Time delegate to JVM's built-in zone rules. The zone provider |
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.
to JVM -> to the JVM
Mixed use of joda and java.time results in two different versions of tzdata being used at the same time for a query. This has lead to inconsistencies that had resulted in incorrect query results, and query execution failure. This commit makes joda and java.time use the same tzdata by making joda delegate to java.time for all time zone rules.
Fixes #8233, fixes #11855 depends on #11890