Skip to content
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

pgdate: Improve handling of negative years #35602

Merged
merged 1 commit into from
Mar 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/datetime
Original file line number Diff line number Diff line change
Expand Up @@ -1193,3 +1193,33 @@ query T
SELECT date_trunc('month', "date") AS date_trunc_month_created_at FROM "topics";
----
2017-12-01 00:00:00 +0000 UTC


# Test negative years to ensure they can round-trip through the parser.
# Also ensure that we don't trigger any of the "convenience" rules.
subtest regression_35255

query T
SELECT '-56325279622-12-26'::DATE
----
-56325279622-12-26 00:00:00 +0000 +0000

query T
SELECT '-5632-12-26'::DATE
----
-5632-12-26 00:00:00 +0000 +0000

query T
SELECT '-563-12-26'::DATE
----
-0563-12-26 00:00:00 +0000 +0000

query T
SELECT '-56-12-26'::DATE
----
-0056-12-26 00:00:00 +0000 +0000

query T
SELECT '-5-12-26'::DATE
----
-0005-12-26 00:00:00 +0000 +0000
9 changes: 6 additions & 3 deletions pkg/util/timeutil/pgdate/field_extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,13 @@ func (fe *fieldExtract) interpretNumber(chunk numberChunk, textMonth bool) error
case fe.Wants(fieldYear) && fe.Wants(fieldMonth) && fe.Wants(fieldDay):
// Example: All date formats, we're starting from scratch.
switch {
case chunk.magnitude >= 6:
case chunk.magnitude >= 6 && chunk.separator != '-':
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, why do you exclude the sign here?

// Example: "YYMMDD"
// ^^^^^^
// Example: "YYYYMMDD"
// ^^^^^^^^
// We're looking at some kind of concatenated date.
// We're looking at some kind of concatenated date. We do want
// to exclude large-magnitude, negative years from this test.

// Record whether or not it's a two-digit year.
fe.tweakYear = chunk.magnitude == 6
Expand All @@ -350,7 +351,9 @@ func (fe *fieldExtract) interpretNumber(chunk numberChunk, textMonth bool) error
// year-first mode, we'll accept the first chunk and possibly
// adjust a two-digit value later on. This means that
// 99 would get adjusted to 1999, but 0099 would not.
if chunk.magnitude <= 2 {
if chunk.separator == '-' {
chunk.v *= -1
} else if chunk.magnitude <= 2 {
fe.tweakYear = true
}
return fe.SetChunk(fieldYear, chunk)
Expand Down
2 changes: 1 addition & 1 deletion pkg/util/timeutil/pgdate/parsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func ParseTimestamp(now time.Time, mode ParseMode, s string) (time.Time, error)

// badFieldPrefixError constructs a CodeInvalidDatetimeFormatError pgerror.
func badFieldPrefixError(field field, prefix rune) error {
return inputErrorf("unexpected separator '%v' for field %s", prefix, field.Pretty())
return inputErrorf("unexpected separator '%s' for field %s", string(prefix), field.Pretty())
}

// inputErrorf returns a CodeInvalidDatetimeFormatError pgerror.
Expand Down