Skip to content

SQL: Fix getTime() methods in JDBC #40484

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

Merged
merged 3 commits into from
Mar 27, 2019
Merged

Conversation

matriv
Copy link
Contributor

@matriv matriv commented Mar 26, 2019

Previously, getTime(colIdx/colLabel) and
getObject(colIdx/colLabel, java.sql.Time.class) methods were computing
the time from a ZonedDateTime by applying day in millis modulo on the epoch millis
of the ZonedDateTime object. This is wrong as we need to keep the time
related fields at the timezone of the ZonedDateTime object and just
set the date info to the epoch date (01/01/1970).

Additionally fixes a testing issue as the original timezone id is converted
to an offset string when parsing the response from the server.

Previously, `getTime(colIdx/colLabel)` and
`getObject(colIdx/colLabel, java.sql.Time.class)` methods were computing
the time from a `ZonedDateTime` by applying day in millis modulo on the epoch millis
of the `ZonedDateTime` object. This is wrong as we need to keep the time
related fields at the timezone of the `ZonedDateTime` object and just
set the date info to the epoch date (01/01/1970).

Additionally fixes a testing issue as the original timezone id is converted
to an offset string when parsing the response from the server.
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-search

@@ -1748,4 +1753,8 @@ private Connection esWithLeniency(boolean multiValueLeniency) throws SQLExceptio
private String asDateString(long millis) {
return of(millis, timeZoneId);
}

private ZoneId getZoneFromOffset(Long randomLongDate) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this reveals an issue with how we send the respond from the server.
Shouldn't we keep for example Australia/Tasmania instead of +10:00`?
@costin @astefan what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

+10:00 is static for any timestamp, but Australia/Tasmania offset might change (cause of test failure before).

Copy link
Member

Choose a reason for hiding this comment

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

ZoneId is better I would argue though at the same time, if this is a cause for failure it might mean that the offset rules on the server are different than that on the client which is an issue on itself.

Copy link
Contributor

Choose a reason for hiding this comment

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

I kind of agree that +10:00 is ambiguous, but can there be an actual issue here?
Different offset rules on server and on the client can probably happen when different Java versions are used (and offset/timezone impl. differ between the two).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The "issue" is that +10:00 is static, it doesn't include DST and it doesn't include any changes in the offset of a timezone (in our example: Australia/Tasmania) that can happen over the years for certain timezones. So if the client would further need to process the result "looses" this info from the result returned, but it still poccesses the Australia/Tasmania since this was the timezone string it set as connection/REST property.

Copy link
Member

@costin costin left a comment

Choose a reason for hiding this comment

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

Left some comments

return sb.toString();
}

private static void rowAsString(ResultSet rs, StringBuilder sb, StringBuilder column, int columns) throws SQLException {
Copy link
Member

Choose a reason for hiding this comment

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

The method signature seems incorrect column seems to be used only locally and sb can be returned by the method - passing them as arguments doesn't offer any value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix, just used the automatic refactoring.

@@ -1748,4 +1753,8 @@ private Connection esWithLeniency(boolean multiValueLeniency) throws SQLExceptio
private String asDateString(long millis) {
return of(millis, timeZoneId);
}

private ZoneId getZoneFromOffset(Long randomLongDate) {
Copy link
Member

Choose a reason for hiding this comment

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

ZoneId is better I would argue though at the same time, if this is a cause for failure it might mean that the offset rules on the server are different than that on the client which is an issue on itself.

doWithQuery(SELECT_ALL_FIELDS, (results) -> {
results.next();

java.sql.Time expectedTime = new java.sql.Time(randomLongDate % 86400000L);
ZoneId zoneId = getZoneFromOffset(randomLongDate);
java.sql.Time expectedTime = new java.sql.Time(
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be extracted in a utils class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Didn't do it as it's used only once here, but I can extract it.

Copy link
Contributor

@astefan astefan left a comment

Choose a reason for hiding this comment

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

LGTM

@@ -1748,4 +1753,8 @@ private Connection esWithLeniency(boolean multiValueLeniency) throws SQLExceptio
private String asDateString(long millis) {
return of(millis, timeZoneId);
}

private ZoneId getZoneFromOffset(Long randomLongDate) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I kind of agree that +10:00 is ambiguous, but can there be an actual issue here?
Different offset rules on server and on the client can probably happen when different Java versions are used (and offset/timezone impl. differ between the two).

@matriv matriv requested a review from costin March 27, 2019 09:35
Copy link
Member

@costin costin left a comment

Choose a reason for hiding this comment

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

LGTM

@matriv matriv merged commit 2221cc7 into elastic:master Mar 27, 2019
@matriv matriv deleted the mt/fix-jdbc-time branch March 27, 2019 16:13
matriv added a commit that referenced this pull request Mar 27, 2019
Previously, `getTime(colIdx/colLabel)` and
`getObject(colIdx/colLabel, java.sql.Time.class)` methods were computing
the time from a `ZonedDateTime` by applying day in millis modulo on the epoch millis
of the `ZonedDateTime` object. This is wrong as we need to keep the time
related fields at the timezone of the `ZonedDateTime` object and just
set the date info to the epoch date (01/01/1970).

Additionally fixes a testing issue as the original timezone id is converted
to an offset string when parsing the response from the server.
matriv added a commit that referenced this pull request Mar 27, 2019
Previously, `getTime(colIdx/colLabel)` and
`getObject(colIdx/colLabel, java.sql.Time.class)` methods were computing
the time from a `ZonedDateTime` by applying day in millis modulo on the epoch millis
of the `ZonedDateTime` object. This is wrong as we need to keep the time
related fields at the timezone of the `ZonedDateTime` object and just
set the date info to the epoch date (01/01/1970).

Additionally fixes a testing issue as the original timezone id is converted
to an offset string when parsing the response from the server.
matriv added a commit that referenced this pull request Mar 27, 2019
Previously, `getTime(colIdx/colLabel)` and
`getObject(colIdx/colLabel, java.sql.Time.class)` methods were computing
the time from a `ZonedDateTime` by applying day in millis modulo on the epoch millis
of the `ZonedDateTime` object. This is wrong as we need to keep the time
related fields at the timezone of the `ZonedDateTime` object and just
set the date info to the epoch date (01/01/1970).

Additionally fixes a testing issue as the original timezone id is converted
to an offset string when parsing the response from the server.
matriv added a commit that referenced this pull request Mar 27, 2019
Previously, `getTime(colIdx/colLabel)` and
`getObject(colIdx/colLabel, java.sql.Time.class)` methods were computing
the time from a `ZonedDateTime` by applying day in millis modulo on the epoch millis
of the `ZonedDateTime` object. This is wrong as we need to keep the time
related fields at the timezone of the `ZonedDateTime` object and just
set the date info to the epoch date (01/01/1970).

Additionally fixes a testing issue as the original timezone id is converted
to an offset string when parsing the response from the server.
@matriv
Copy link
Contributor Author

matriv commented Mar 27, 2019

Backported to 7.x. with 8e049c5
to 7.0 with e39e40b
to 6.7 with e4d41d3
to 6.6 with f6072e5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants