-
Notifications
You must be signed in to change notification settings - Fork 843
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
TimeTest unit test appears to only pass in UTC #1048
Comments
we've always had problems with the tests passing in different timezones when daylight savings changes. If you can fix this that would be great |
But what is the fix? It /seems/ like it might actually be a code defect, not a test defect, but I am not certain. |
Indeed, changing PGResultSet to remove the special handling for 00:00:00 and 24:00:00 seems like the fix to me. |
be nice if whomever put that in there would comment why( hopefully it wasn't me) |
f2d8ec5
for history
Dave Cramer
…On 29 December 2017 at 10:24, Brett Okken ***@***.***> wrote:
Indeed, changing PGResultSet to remove the special handling for 00:00:00
and 24:00:00 seems like the fix to me.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1048 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAYz9gcpCnRTSCTxcpR5D1Nab5yJWz9xks5tFQRGgaJpZM4RPLn_>
.
|
So if I follow that correctly, the problem is when using LocalTime.MIN and LocalTime.MAX? |
This is really an artifact of not being able to map PostgreSQL times to java times. Do you have a specific issue that this is not working for ? |
Perhaps the solution here is to provide handling of 24:00:00 by massaging
to 23:59:99.999 and then using existing parsing logic.
I am simply trying to run unit tests. As part of changes to cache parsed
queries there are tests timing out on Travis-ci. I’m trying to recreate
locally and noticed this failure.
…On Fri, Dec 29, 2017 at 10:17 AM Dave Cramer ***@***.***> wrote:
This is really an artifact of not being able to map PostgreSQL times to
java times. Do you have a specific issue that this is not working for ?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1048 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AC26beorY76kw2SdEkyO7wbVsSo75NGrks5tFRB_gaJpZM4RPLn_>
.
|
So the problem is:
https://www.postgresql.org/docs/current/static/datatype-datetime.html
the low value is 00:00:00, and the high value is 24:00:00
hence the mapping
Dave Cramer
…On 29 December 2017 at 11:29, Brett Okken ***@***.***> wrote:
Perhaps the solution here is to provide handling of 24:00:00 by massaging
to 23:59:99.999 and then using existing parsing logic.
I am simply trying to run unit tests. As part of changes to cache parsed
queries there are tests timing out on Travis-ci. I’m trying to recreate
locally and noticed this failure.
On Fri, Dec 29, 2017 at 10:17 AM Dave Cramer ***@***.***>
wrote:
> This is really an artifact of not being able to map PostgreSQL times to
> java times. Do you have a specific issue that this is not working for ?
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <#1048 (comment)>,
or mute
> the thread
> <https://github.com/notifications/unsubscribe-auth/
AC26beorY76kw2SdEkyO7wbVsSo75NGrks5tFRB_gaJpZM4RPLn_>
> .
>
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1048 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAYz9kCqR-SsyKf3gLynnsfh41JXWBSrks5tFROEgaJpZM4RPLn_>
.
|
00:00:00 needs no special handling, but 24:00:00 does.
I think the best handling would be 23:59:59.999999, as that would mirror
LocalTime.MAX.
On Fri, Dec 29, 2017 at 10:39 AM Dave Cramer <notifications@github.com>
wrote:
… So the problem is:
https://www.postgresql.org/docs/current/static/datatype-datetime.html
the low value is 00:00:00, and the high value is 24:00:00
hence the mapping
Dave Cramer
On 29 December 2017 at 11:29, Brett Okken ***@***.***>
wrote:
> Perhaps the solution here is to provide handling of 24:00:00 by massaging
> to 23:59:99.999 and then using existing parsing logic.
> I am simply trying to run unit tests. As part of changes to cache parsed
> queries there are tests timing out on Travis-ci. I’m trying to recreate
> locally and noticed this failure.
>
> On Fri, Dec 29, 2017 at 10:17 AM Dave Cramer ***@***.***>
> wrote:
>
> > This is really an artifact of not being able to map PostgreSQL times to
> > java times. Do you have a specific issue that this is not working for ?
> >
> > —
> > You are receiving this because you authored the thread.
> > Reply to this email directly, view it on GitHub
> > <#1048 (comment)>,
> or mute
> > the thread
> > <https://github.com/notifications/unsubscribe-auth/
> AC26beorY76kw2SdEkyO7wbVsSo75NGrks5tFRB_gaJpZM4RPLn_>
> > .
> >
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <#1048 (comment)>,
or mute
> the thread
> <
https://github.com/notifications/unsubscribe-auth/AAYz9kCqR-SsyKf3gLynnsfh41JXWBSrks5tFROEgaJpZM4RPLn_
>
> .
>
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1048 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AC26bfZfcBBawjV-NccvOwnWgi7rv8dKks5tFRXagaJpZM4RPLn_>
.
|
And both should use the provided/determined calendar rather than assuming
local (current for 24:00) or UTC (current for 00:00).
On Fri, Dec 29, 2017 at 10:53 AM Brett Okken <brett.okken.os@gmail.com>
wrote:
… 00:00:00 needs no special handling, but 24:00:00 does.
I think the best handling would be 23:59:59.999999, as that would mirror
LocalTime.MAX.
On Fri, Dec 29, 2017 at 10:39 AM Dave Cramer ***@***.***>
wrote:
> So the problem is:
>
> https://www.postgresql.org/docs/current/static/datatype-datetime.html
>
> the low value is 00:00:00, and the high value is 24:00:00
>
> hence the mapping
>
> Dave Cramer
>
> On 29 December 2017 at 11:29, Brett Okken ***@***.***>
> wrote:
>
> > Perhaps the solution here is to provide handling of 24:00:00 by
> massaging
> > to 23:59:99.999 and then using existing parsing logic.
> > I am simply trying to run unit tests. As part of changes to cache parsed
> > queries there are tests timing out on Travis-ci. I’m trying to recreate
> > locally and noticed this failure.
> >
> > On Fri, Dec 29, 2017 at 10:17 AM Dave Cramer ***@***.***>
> > wrote:
> >
> > > This is really an artifact of not being able to map PostgreSQL times
> to
> > > java times. Do you have a specific issue that this is not working for
> ?
> > >
> > > —
> > > You are receiving this because you authored the thread.
> > > Reply to this email directly, view it on GitHub
> > > <#1048 (comment)
> >,
> > or mute
> > > the thread
> > > <https://github.com/notifications/unsubscribe-auth/
> > AC26beorY76kw2SdEkyO7wbVsSo75NGrks5tFRB_gaJpZM4RPLn_>
> > > .
> > >
> >
> > —
> > You are receiving this because you commented.
> > Reply to this email directly, view it on GitHub
> > <#1048 (comment)>,
> or mute
> > the thread
> > <
> https://github.com/notifications/unsubscribe-auth/AAYz9kCqR-SsyKf3gLynnsfh41JXWBSrks5tFROEgaJpZM4RPLn_
> >
> > .
> >
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <#1048 (comment)>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AC26bfZfcBBawjV-NccvOwnWgi7rv8dKks5tFRXagaJpZM4RPLn_>
> .
>
|
@vlsi comments? |
@bokken , what is the issue? The test you mentioned does call
There are
There's
|
The existing test fails when run in any timezone other than UTC/GMT (i.e. offset of 0). The explicit setting of time zone to GMT for that calendar is to calculate the offset for the local time zone. Note that Calendar instance is never used to interact with any of the pgjdbc methods. The existing TimeZone tests do not cover the special values for getTime of "00:00:00" or "24:00:00". The current behavior for both of those values is to ignore the calendar provided. I have added tests for both of those cases in PR #1049 In doing this, I have found an additional problem when |
I think the tests the behavior I am expecting for 00:00:00 is pretty straight foward. The handling of 24:00:00, however, is far trickier. If it is not massaged to 23:59:59.999999999, then the point in time represented is actually midnight the next day. Which is to say that 1970-01-01 24:00:00 is the same as 1970-01-02 00:00:00. Indeed, the java.sql.Time object |
The discussion for this is now over at #992. To summarize, java.sql.Time and getTime methods have always treated 24:00:00 to be the same as 00:00:00. The PR #1049 has tests covering 00:00:00, 24:00:00 and various time zone options along with proposed fixes for the issues identified. |
this artifact seems to be a mistake IMO. As noted on the hackers list https://www.postgresql.org/message-id/CADK3HHJgZ2dxdTOTYr4bD70ifzbT5k5xsRM%2Br%3DQAQfT8m4vj6Q%40mail.gmail.com 24:00:00 is exactly 1 day so treating it like 00:00:00 seems wrong. |
@davecramer That seems to be a difference between duration and time. 1 day is a duration. LocalTime actually provides pretty good semantics around this. One of the changes I also had to make in my PR was to handle the binary representation of 24:00:00 to LocalTime. The binary representation is 86,400,000,000 (exactly 1 day/24 hours in microseconds). Trying to create a LocalTime with that results in an IllegalArgumentException stating that the max allowed value is 85,399,999,999,999 (nano seconds). This is consistent with LocalTime not allowing a concept of 24:00:00; treating it the same as 00:00:00. |
@bokken ya, there is definitely an impedance mismatch between time and duration here. |
I think that the least wrong solution is to treat postgres 24:00:00 (string) and 86,400,000,000 (binary) as 00:00:00 and 0 respectively. It is not clear to me why postgres allows the representation of 2 midnight values, but since java only allows 1 (documented in java.sql.Time and actually enforced in LocalTime), massaging the second midnight into the first midnight seems reasonable. This is how java.sql.Time has been treated historically and I propose that it is the cleanest mapping for LocalTime a well. |
Also, this discussion has wandered a bit from what I originally reported (sorry). The problem I was originally reporting is how getTime is handling string values for time of 00:00:00 and 24:00:00. It appears that the changes in f2d8ec5 added specific handling, and that handling appears wrong to me. Specifically, for 24:00:00 it always uses the default time zone (ignoring the provided Calendar) and for 00:00:00 it always uses UTC (ignoring the provided Calendar and the local time zone when no Calendar). |
I'm beginning to think that the current behaviour is not that wrong. The reason this occurs is due to integer precision see https://www.postgresql.org/message-id/28026.1514742632%40sss.pgh.pa.us and note the following: anything beyond 6 9999995 produces 24:00:00 select '23:59:59.9999999'::time;
|
That feels... odd. So do we have consensus that 24:00:00 only exists to represent rounding error from 23:59:59.999999? {quote} I do not believe that is accurate. For timetz, the offset in the data type itself should be used and any provided Calendar should be ignored. For time (no time zone), the provided Calendar should be used, if no Calendar provided, the default TimeZone of the system should be used. |
TL;DR: I would refrain from committing any time-related changes unless those are proven to be blocker/critical and/or trivial ones. Frankly speaking, 42.2.0 release is a long overdue, and
Why do you think so? Do you know server sends binary timestamps without time zones? Don't you say the query might produce different |
I agree.
The one area I might disagree is the if/else introduced here which handles both string values incorrectly in most time zones. It is also inconsistent with binary representation in most time zones. I cannot think of a single use case where this fixes any behavior which was previously wrong. While there are a couple of cases where it is not wrong, that is kind of like a broken clock being right twice a day :)
Certainly not trivial. Timezones regularly make my head hurt.
The
Because that is how the jdbc doc says it should behave. Part of my proposed set of changes is that TimestampTZ should not be supported in binary format for the very reason that offset data is lost in the binary format. |
Technically speaking, PostgreSQL DB does not store timezone information. |
Now I see why, however please add explicit comments for that kind of changes. Otherwise the change is cryptic. In any way, the offset data is not lost as it was not there in the first place. DB just uses "current timezone" to fake the offset. It might be related to "connection timezone", however it does not matter much, as the offset is never stored in the data files. That is why I do not think "text" format contains more information than binary one. |
Just in case: timestamp_out: timestamp2tm is called with NULL for attimezone, thus it would use |
The TimeZoneTest seems to show that the string representation returns the offset that was stored. The test has set the default timezone to GMT+1. I am running this on a system where the timezone is America/Chicago (GMT-6), yet the string returned reflects GMT+3 that was inserted. |
Agreed. I commented on it at the end of the block adding binary OIDs. It did not seem to make sense to have that in the middle of that block, but I can certainly move it if that would help. |
I'm not convinced that we need to remove this. As @vlsi there is no timezone data in the server data. If the user wants binary timestamps and is aware of the issues then we should let them use them |
So somewhere either in the unit tests or some config I have not noticed in my local postrgresql instance, the "session" timezone is being set to GMT+3. That offset being returned led me to believe it was stored in the db. However, it introduces a different set of potential issues on how getTime should behave for timestamp columns. My initial thought is that the timestamp should be read to determine absolute point in time, then time converted to the provide calendar. My earlier comment about Calendar:
I was talking specifically about time and timez columns, not timestamps. As best I can tell, the timez column truly does store offset information in the database. In that case, the provided Calendar should not be used. For a simple time column, the provided Calendar (or determined default time zone), should always be used. |
Iirc it gets set in the startup message
…On Dec 31, 2017 6:51 PM, "Brett Okken" ***@***.***> wrote:
So somewhere either in the unit tests or some config I have not noticed in
my local postrgresql instance, the "session" timezone is being set to GMT+3.
That offset being returned led me to believe it was stored in the db.
Knowing that it is not stored, I would agree there is no need/value in
removing the binary support.
However, it introduces a different set of potential issues on how getTime
should behave for timestamp columns. My initial thought is that the
timestamp should be read to determine absolute point in time, then time
converted to the provide calendar.
My earlier comment about Calendar:
For timetz, the offset in the data type itself should be used and any
provided Calendar should be ignored. For time (no time zone), the provided
Calendar should be used, if no Calendar provided, the default TimeZone of
the system should be used.
I was talking specifically about time and timez columns, not timestamps.
As best I can tell, the timez column truly does store offset information in
the database. In that case, the provided Calendar should not be used. For a
simple time column, the provided Calendar (or determined default time
zone), should always be used.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1048 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAYz9nMhwpoMz9_jxdXRTEJZkj-CjP9Fks5tGB3mgaJpZM4RPLn_>
.
|
Well, PG's timez does have an offset field. What do you mean by "using offset information" when converting something like "15:40+04:00" into |
As I read the jdbc javdoc, that should result in a java.sql.Time object representing 1970-01-01 15:40:00 +04:00 And this is mostly how pgjdbc has behaved historically. The existing TimezoneTest mostly asserts this behavior. I have found 1 issue where, if a Calendar with TimeZone that is something like GMT+12 or more, the TimestampUtils.convertToTime method butchers the data. This is why the existing TimezoneTest shows getTime with different Calendars always returns the same value, until given a timezone of GMT+13, then it returns something different. The tests I have added cover this behavior in a more exhaustive way, testing many more timezones and covering both string and binary representations. Though given my surprise on behavior of timestamptz, I have been thinking about adding more tests with different explicit offsets for timestamptz columns. The only tests I have logically changed are the 2 Timezone tests referenced above which were asserting wrong behavior. The changes to "real" code I have proposed cover basically 3 things:
To muddy the waters even more, java 8 introduced new methods to move between java.sql.Time and LocalTime. I started a different issue to discuss that: #1050 |
Your move. Please, go ahead and represent |
This will print out: |
@bokken , thanks for bringing the issue up. On the other hand, by
I meant something like a3982b4 (a couple of lines changed in As you can see, it just adds time zone to the equation, and it does result in CI test failures: https://travis-ci.org/pgjdbc/pgjdbc/builds/326318944 TL;DR: it is preferred to have as short reproducers as it is possible, so I hope that suggests why I was not eager reading through https://github.com/pgjdbc/pgjdbc/pull/1049/files. There might be good stuff in #1049, however I would really like to see the problem first, only then discuss solutions. PS. I think MIN/MAX/24:00:00 is not tested properly, however we do have multiple issues on the subject. I'm inclined to close as much of them as it is possible, otherwise they will pile up with no good result. |
@vlsi, unfortunately, I do not know enough about travis to have even considered that sort of proposal. I attempted (though clearly inarticulately and certainly not early enough in conversation) to indicate that simply running the existing tests in a different default timezone caused failures.
Your changes in #1053 actually fairly closely match significant portions of #1049. The specific pieces which are different are the handling of 24:00:00 (whose meaning still does not seem clear to me and further discussion is absolutely warranted) and timestamptz (where I think the provided calendar should be used).
+1 |
The test creates a
java.sql.Time
object using the deprecated constructor setting hours, minutes and seconds to 0. This constructor interprets all of these values in the local timezone (using constructor from java.util.Date). This value is set to variablemidnight
.The value "00:00:00" is directly inserted to the table. This value is then read from the table.
PGResultSet
has specific logic for the string "00:00:00", always returningnew Time(0);
.The test then compares this value to
midnight
for equality. These values can only be equal if the local time zone is UTC so that the originalmidnight
has no offset.The behavior in
PGResultSet
seems wrong to me in that it ignores theCalendar
for the 2 special values of 00:00:00 and 24:00:00. But that may be overly simplistic.The text was updated successfully, but these errors were encountered: