-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
sql: boundary dates are broken #20136
Comments
A data point:
So the value is properly there. It's the conversion during printing that fails. |
Okay so the proximate cause of the problem is that many computations involving DDate first convert the date (number of days since unix epoch) to a This multiplication currently happens at least in the following places:
So what are we going to do about this? First of all I am comfortable supporting a larger range of values inside the DB than can be conveyed over pgwire. Users can be informed of this protocol limitation and work around it by converting their dates to other things (e.g. strings) when sending/extracting their data. That said, even if we continue to use "number of days since epoch as int64" we must do something about the various conversions to "number of seconds", identified above, that are problematic because of the overflow. There are a few ways forward: A) either allow the range of DATE to be larger than that supported by TIMESTAMP/INTERVAL. If we do this, we must error out every time a large date is casted/converted to the other types, and special case large date comparisons with the other types. This will add overhead to all the methods identified above. B) or, refuse to let DATE values to exceed the range supported by TIMESTAMP/INTERVAL. If we do this, two separate concerns arise:
In an ideal world, we would have identified this earlier, prevent entry of large dates, and avoid adding the overhead to the various methods entirely. Then solution B above would clearly be superior. I am inclined to decide to ignore databases that already contain large dates, and fix the problem by adding the assertion on input (and casting from int to date) without adding the checks everywhere else - i.e. solution B without the extra costs. The rationale is that I would be surprised if any user would already have developed a use case for such large date values, so if such values slipped through they are likely mistakes in need to be corrected. If that assumption is wrong, changing the code as described above would merely cause any existing values in the database to become unusable -- they can still be edited / replaced. Meanwhile I'm not religious on this and adopting solution A with suitable rationale would be OK with me. From a code change perspective it's more expensive however. cc @bdarnell can you advise what you think is wisest? |
@justinj and @solongordon, I would like to suggest that you sit and brainstorm together what you personally think is the best approach here. I am thinking of you both because you were "paged in" on these issues recently. Perhaps having a casual look at what other db engines do could inform your discussion. |
Three more things:
|
I agree with restricting the range of DATE to match that of TIMESTAMP (although it's worth noting that postgres doesn't do this; their DATE type works further into the future than their TIMESTAMP type). And I'm OK with making this change without doing anything about existing large dates that may have been written. |
Aligning the accepted DATE and TIMESTAMP ranges sounds good to me. However TIMESTAMP itself is not perfect:
This behavior actually goes all the way back to Go's I would propose being more restrictive with our minimum supported timestamp/date. Matching the Postgres minimum of 4713 BC seems reasonable to me since it is the beginning of the Gregorian calendar. According to their docs this follows the SQL standard: https://www.postgresql.org/docs/current/static/datetime-units-history.html |
@knz Can we get a docs description this issue as a Known Limitation for 2.1? |
I think this is an experimental feature we do not otherwise document. Please check: do we have any doc about converting values of type INT(EGER) to TIME/DATE/TIMESTAMP? If not you can disregard this issue. Otherwise: """ CockroachDB supports an experimental extension to the SQL standard where an integer value can be converted to a DATE/TIME/TIMESTAMP value, taking the number as a number of seconds since the Unix epoch. This conversion is currently only well defined for a small range of integers and values that a large in magnitude will cause conversion errors. |
@knz It looks like there's a slight typo in this; can you clarify?
Looks like there's a word missing within |
yes sorry the correct phrasing is "This conversion is currently only well defined for a small range of integers, and values that are large in magnitude (alt phrasing: large in absolute values) will cause conversion errors." |
@mjibson ping |
Fixed by #36938 |
- Removed known limitation for Conversion of integers to date/time values(cockroachdb/cockroach/issues/20136) - Added PG-compatibility note to DATE page
- Removed known limitation for Conversion of integers to date/time values(cockroachdb/cockroach/issues/20136) - Added PG-compatibility note to DATE page
Something somewhere is overflowing. Assigning to @knz for triage.
The text was updated successfully, but these errors were encountered: