-
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
Add TIME column type and datum. #19923
Conversation
Nice work! thanks for the hard work and sorry for the last-minute code shuffle. I'd like to look at this too, Justin please let me know when you're seeing the dust settle. I don't want to disturb the conversation until then. |
Thanks @knz! Would be happy for your feedback. Review status: 0 of 39 files reviewed at latest revision, all discussions resolved, some commit checks failed. Comments from Reviewable |
a695ece
to
c0c6ab6
Compare
Super solid first PR! Mostly just nit comments. If you add Just looking at this list:
Would you also mind adding a short jdbc test? I think it's a good idea to test stuff against jdbc specifically since it tends to do a lot more funky stuff with its pg_catalog introspection than other drivers. Reviewed 39 of 39 files at r1, 4 of 4 files at r2. pkg/sql/logictest/testdata/logic_test/time, line 187 at r1 (raw file):
We also support constructing arrays in the form pkg/sql/logictest/testdata/logic_test/time, line 35 at r2 (raw file):
Is it also worth testing other types -> pkg/sql/logictest/testdata/logic_test/time, line 213 at r2 (raw file):
We don't do it everywhere but here as well I think it's a good idea to annotate these expects with the expected pgcode: pkg/sql/parser/builtins.go, line 1382 at r1 (raw file):
Hm, I hadn't noticed we do this elsewhere, but in the worst case this could result in a bunch of extra allocations (although I think pkg/sql/parser/expr.go, line 1117 at r1 (raw file):
Do we have any tests for casting from a collated string? I don't expect that it would have any issues, but it would be good to test that case. pkg/sql/parser/parse_test.go, line 506 at r2 (raw file):
Do we test that this syntax has the expected semantics anywhere? pkg/sql/pgwire/types.go, line 619 at r1 (raw file):
We don't do it everywhere currently, but new errors should have a pg error code ( pkg/sql/pgwire/testdata/time_test.json, line 1 at r1 (raw file):
Personally I think the value-add of these binary tests is somewhat dubious, lol, but I guess it's good that we have the explicit binary format tested somewhere. pkg/sql/sqlbase/table.go, line 1829 at r1 (raw file):
How come this uses pkg/util/timeofday/time_of_day.go, line 26 at r1 (raw file):
Since we only have pkg/util/timeofday/time_of_day.go, line 35 at r2 (raw file):
this paradigm is still so weird to me pkg/util/timeofday/time_of_day.go, line 37 at r2 (raw file):
Doesn't matter much since this is such a universal constant, but could even write this as pkg/util/timeofday/time_of_day.go, line 41 at r2 (raw file):
nit: I don't care either way, but if you prefer something slightly shorter you can write this Should we consider asserting (probably returning an error) that the values all fall within the expected ranges? I'm not sure if that's desirable or not, this function might be more convenient if it doesn't do that. pkg/util/timeofday/time_of_day_test.go, line 36 at r1 (raw file):
pkg/util/timeofday/time_of_day_test.go, line 56 at r1 (raw file):
It can be nice in cases like this to use a subtest:
and then the failure is already annotated for you with the case that failed (you can also run Comments from Reviewable |
Congrats on the first PR! Reviewed 39 of 39 files at r1, 4 of 4 files at r2. pkg/sql/parser/datum_test.go, line 22 at r2 (raw file):
Move that down. pkg/sql/parser/eval.go, line 2558 at r2 (raw file):
For the cast from pkg/sql/parser/eval.go, line 2762 at r2 (raw file):
When I try this in Postgres I get pkg/sql/parser/eval.go, line 2764 at r2 (raw file):
No cast from pkg/sql/pgwire/binary_test.go, line 235 at r2 (raw file):
While you're here, do you mind moving these two tests above pkg/sql/pgwire/types.go, line 423 at r2 (raw file):
Add to this that " The function will then return the resulting buffer." like we have below. pkg/sql/pgwire/testdata/time_test.json, line 1 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
I disagree @justinj, they've caught a number of issues in the past for data types with more complicated binary representations like pkg/util/timeofday/time_of_day.go, line 37 at r2 (raw file): Previously, justinj (Justin Jaffray) wrote…
Or even better, pkg/util/timeofday/time_of_day.go, line 41 at r2 (raw file):
nit, just call this pkg/util/timeofday/time_of_day.go, line 58 at r2 (raw file):
Should this be a method on pkg/util/timeofday/time_of_day.go, line 69 at r2 (raw file):
Same here, I think these would be more idiomatic as methods. That's what pkg/util/timeofday/time_of_day_test.go, line 36 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
Yeah, Comments from Reviewable |
Awesome first PR :)! Made a few remarks. Review status: all files reviewed at latest revision, 27 unresolved discussions, some commit checks failed. pkg/sql/parser/eval.go, line 464 at r2 (raw file):
There's another binary operator involving pkg/sql/parser/eval.go, line 2597 at r2 (raw file):
As a heads up, it seems postgres doesn't allow casting to float unless the time has a timezone. I'm not sure if this will change our decision on supporting time-of-day to float casting. Furthermore, from observation, it seems like it's just outright broken for both cases, hah. postgres=# select TIME WITH TIME ZONE '20:38:40' AT TIME ZONE 'EST5EDT';
timezone
-------------
20:38:40-05
(1 row)
postgres=# select (TIME WITH TIME ZONE '20:38:40' AT TIME ZONE 'EST5EDT')::FLOAT;
ERROR: cannot cast type time with time zone to double precision
LINE 1: ...ME WITH TIME ZONE '20:38:40' AT TIME ZONE 'EST5EDT')::FLOAT;
^ pkg/sql/pgwire/testdata/time_test.json, line 1 at r2 (raw file):
We use Comments from Reviewable |
Review status: all files reviewed at latest revision, 27 unresolved discussions, some commit checks failed. pkg/sql/parser/eval.go, line 2597 at r2 (raw file): Previously, lego (Joey Pereira) wrote…
Oof. Looks like you just can't cast So you'll want to remove these casts. This helps hide the internal bits about what the actual int timeofday actually stores behind the scenes, so it makes sense why not to have these. (and probably the same for decimal as nathan said) Comments from Reviewable |
c0c6ab6
to
f50f14c
Compare
Review status: 26 of 44 files reviewed at latest revision, 27 unresolved discussions. pkg/sql/logictest/testdata/logic_test/time, line 187 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
Done. pkg/sql/logictest/testdata/logic_test/time, line 35 at r2 (raw file): Previously, justinj (Justin Jaffray) wrote…
Shoot, for some reason I thought Postgres didn't allow casting timestamp to time so didn't support it. But I just double-checked and it does. I'll add this. Added the following casts:
pkg/sql/logictest/testdata/logic_test/time, line 213 at r2 (raw file): Previously, justinj (Justin Jaffray) wrote…
Good to know. Done. pkg/sql/parser/builtins.go, line 1382 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
Should we make a separate issue to track this? One extra string allocation for a short string doesn't strike me as terribly wasteful, but not sure how sensitive we are to this stuff. pkg/sql/parser/datum_test.go, line 22 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Done. pkg/sql/parser/eval.go, line 464 at r2 (raw file): Previously, lego (Joey Pereira) wrote…
Missed that one! Thanks. I added pkg/sql/parser/eval.go, line 2558 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Yeah, meant to remove this. Thanks. pkg/sql/parser/eval.go, line 2597 at r2 (raw file): Previously, lego (Joey Pereira) wrote…
Yeah, meant to remove this. Thanks. pkg/sql/parser/eval.go, line 2762 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Meant to remove this. For some reason we do allow this cast for timestamps and dates, which Postgres also does not. pkg/sql/parser/eval.go, line 2764 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Yup, missed this. Done. pkg/sql/parser/expr.go, line 1117 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
Nope. Added a logic test. pkg/sql/parser/parse_test.go, line 506 at r2 (raw file): Previously, justinj (Justin Jaffray) wrote…
Don't think so. Added a logic test. pkg/sql/pgwire/binary_test.go, line 235 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Done. pkg/sql/pgwire/types.go, line 619 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
Ah ok. Is that also the case for protocol-level errors like these? Not sure the best way to force this in pkg/sql/pgwire/types.go, line 423 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Done. pkg/sql/sqlbase/table.go, line 1829 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
We discussed in person and the pkg/util/timeofday/time_of_day.go, line 26 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
Oh, good point. Yeah now that you mention it, it's irrespective of time zone. I'll fix my comments. pkg/util/timeofday/time_of_day.go, line 37 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Done, though this meant casting to pkg/util/timeofday/time_of_day.go, line 41 at r2 (raw file): Previously, justinj (Justin Jaffray) wrote…
Yeah, given that it works fine if you exceed the ranges I'm tempted to keep it as-is. pkg/util/timeofday/time_of_day.go, line 41 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Done. pkg/util/timeofday/time_of_day.go, line 58 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Yeah, I wondered about this. Happy to go with methods. Done. pkg/util/timeofday/time_of_day.go, line 69 at r2 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Done. pkg/util/timeofday/time_of_day_test.go, line 36 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
Done. pkg/util/timeofday/time_of_day_test.go, line 56 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
Ah cool, I changed it up. Let me know if it's what you had in mind. Comments from Reviewable |
Review status: 26 of 44 files reviewed at latest revision, 20 unresolved discussions, some commit checks pending. pkg/sql/pgwire/testdata/time_test.json, line 1 at r2 (raw file): Previously, lego (Joey Pereira) wrote…
I think I tried running that and got a cryptic error, so I ended up exporting data from Postgres in binary format via Comments from Reviewable |
Ok! Can you open an issue to improve our coverage of This modulo some small comments! If anyone else has any comments feel free to bring them up cc @knz @jordanlewis Reviewed 18 of 18 files at r3. pkg/sql/logictest/testdata/logic_test/time, line 213 at r2 (raw file): Previously, solongordon wrote…
Sorry about leading you astray on the directive name! pkg/sql/parser/builtins.go, line 1382 at r1 (raw file): Previously, solongordon wrote…
Yeah I think it's probably not too big of a deal. If you have a large result set that you're calling this function on it could result in doing the allocation unnecessarily for every row. I'll leave it up to @knz to share his thoughts on if doing that preprocessing is worthwhile. pkg/sql/parser/builtins.go, line 1440 at r3 (raw file):
nit: it's idiomatic to just omit the pkg/sql/parser/builtins.go, line 1460 at r3 (raw file):
ditto pkg/sql/parser/builtins.go, line 1479 at r3 (raw file):
ditto pkg/sql/parser/builtins.go, line 1497 at r3 (raw file):
ditto pkg/sql/pgwire/types.go, line 619 at r1 (raw file): Previously, solongordon wrote…
Ah, I see, yeah, sort of a pain to generate this particular case in psql... I guess just leave it for now until we do the eventual purging from pkg/sql/pgwire/testdata/time_test.json, line 1 at r1 (raw file): Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
I guess I don't see the value these provide over one or more driver tests, which are more legible and test the same thing? But I also didn't realize they were auto-generated, that seems useful then! pkg/util/timeofday/time_of_day.go, line 37 at r2 (raw file): Previously, solongordon wrote…
Hm, I have no strong opinion! Up to you. pkg/util/timeofday/time_of_day_test.go, line 56 at r1 (raw file): Previously, solongordon wrote…
Yup looks good to me! Comments from Reviewable |
f50f14c
to
66dbbb5
Compare
Review status: 43 of 44 files reviewed at latest revision, 22 unresolved discussions. pkg/sql/parser/builtins.go, line 1440 at r3 (raw file): Previously, justinj (Justin Jaffray) wrote…
Done. pkg/sql/parser/builtins.go, line 1460 at r3 (raw file): Previously, justinj (Justin Jaffray) wrote…
Done. pkg/sql/parser/builtins.go, line 1479 at r3 (raw file): Previously, justinj (Justin Jaffray) wrote…
Done. pkg/sql/parser/builtins.go, line 1497 at r3 (raw file): Previously, justinj (Justin Jaffray) wrote…
Done. Comments from Reviewable |
Review status: 43 of 44 files reviewed at latest revision, 22 unresolved discussions, some commit checks failed. pkg/sql/pgwire/testdata/time_test.json, line 1 at r2 (raw file): Previously, solongordon wrote…
Yea it's no longer working and there haven't been any changes on our end. cc @mjibson
Comments from Reviewable |
66dbbb5
to
80e5dc3
Compare
Review status: 41 of 45 files reviewed at latest revision, 21 unresolved discussions, some commit checks pending. pkg/sql/pgwire/testdata/time_test.json, line 1 at r2 (raw file): Previously, lego (Joey Pereira) wrote…
I won't try and get it working as part of this PR but at @LEGO's suggestion I added my test cases to the script. Comments from Reviewable |
Reviewed 22 of 39 files at r1, 2 of 4 files at r2, 17 of 18 files at r3, 4 of 4 files at r4. pkg/sql/copy_in_test.go, line 171 at r4 (raw file):
If INT and INTERVAL were indeed missing, I'd argue this should be populated in a separate commit. pkg/sql/logictest/testdata/logic_test/time, line 199 at r4 (raw file):
I'm missing TIME and INT (both ways) pkg/sql/parser/builtins.go, line 1382 at r1 (raw file): Previously, justinj (Justin Jaffray) wrote…
So the problem is that next to the SQL shorthand syntax pkg/sql/parser/datum.go, line 1444 at r4 (raw file):
simpler: v, ok := other.(*DTime)
if !ok {
panic(...)
} pkg/sql/parser/eval.go, line 2762 at r2 (raw file): Previously, solongordon wrote…
Yes we found it rather useful. pkg/util/timeofday/time_of_day.go, line 35 at r2 (raw file): Previously, justinj (Justin Jaffray) wrote…
(it's garbage. garbage, I tell you!) pkg/util/timeofday/time_of_day.go, line 50 at r4 (raw file):
That's also an expensive roundtrip via the
pkg/util/timeofday/time_of_day.go, line 55 at r4 (raw file):
Calling these 4 methods on return (t.Unix()%secondsPerDay)*1000000 + t.Nanosecond()/nanosPerMicro pkg/util/timeofday/time_of_day.go, line 70 at r4 (raw file):
I do not like this Do you really need adding a duration containing days/months? The following code is suitable for
Comments from Reviewable |
Review status: all files reviewed at latest revision, 27 unresolved discussions, some commit checks failed. pkg/util/timeofday/time_of_day.go, line 70 at r4 (raw file): Previously, knz (kena) wrote…
Please disregard my previous comment. I was not fully awake yet. Of course the day and month components of a Duration never impact a time computation. So this method can always be simplified to this: func (t TimeOfDay) Add(d duration.Duration) TimeOfDay {
return d.Nanos/nanosPerMicro + t
} Comments from Reviewable |
Review status: all files reviewed at latest revision, 27 unresolved discussions, some commit checks failed. pkg/sql/copy_in_test.go, line 171 at r4 (raw file): Previously, knz (kena) wrote…
They actually weren't missing, just handled separately from this pkg/sql/logictest/testdata/logic_test/time, line 199 at r4 (raw file): Previously, knz (kena) wrote…
Will do, though INT is currently not supported. By the way, is pkg/sql/parser/builtins.go, line 1382 at r1 (raw file): Previously, knz (kena) wrote…
Opened #19965. pkg/sql/parser/eval.go, line 2762 at r2 (raw file): Previously, knz (kena) wrote…
Would you suggest doing the same for Comments from Reviewable |
80e5dc3
to
78aa168
Compare
Review status: 36 of 44 files reviewed at latest revision, 27 unresolved discussions. pkg/sql/parser/datum.go, line 1444 at r4 (raw file): Previously, knz (kena) wrote…
Done. pkg/sql/parser/eval.go, line 2762 at r2 (raw file): Previously, solongordon wrote…
Followed up with @knz "in person". We'll hold off on adding these casts for TIME until the need arises. pkg/util/timeofday/time_of_day.go, line 50 at r4 (raw file): Previously, knz (kena) wrote…
Done. I ended up making pkg/util/timeofday/time_of_day.go, line 55 at r4 (raw file): Previously, knz (kena) wrote…
Done. pkg/util/timeofday/time_of_day.go, line 70 at r4 (raw file): Previously, knz (kena) wrote…
Good point! I had to add a bit of modular arithmetic but otherwise works great. Comments from Reviewable |
2b6f173
to
45d9dab
Compare
Reviewed 48 of 50 files at r5. pkg/sql/copy_in_test.go, line 171 at r4 (raw file): Previously, solongordon wrote…
Yes it makes sense! pkg/sql/logictest/testdata/logic_test/time, line 199 at r4 (raw file): Previously, solongordon wrote…
Ok given we're postponing conversions <-> INT. pkg/util/timeofday/time_of_day.go, line 49 at r5 (raw file):
Can you provide a few example input values with expected output value (or better: write a test). pkg/util/timeofday/time_of_day.go, line 74 at r5 (raw file):
Add a comment to explain why this is necessary (and what fails otherwise). pkg/util/timeofday/time_of_day.go, line 87 at r5 (raw file):
Comments from Reviewable |
Reviewed 2 of 50 files at r5. Comments from Reviewable |
45d9dab
to
da286a1
Compare
Review status: all files reviewed at latest revision, 25 unresolved discussions, all commit checks successful. pkg/util/timeofday/time_of_day.go, line 49 at r5 (raw file): Previously, knz (kena) wrote…
Simplified this a bit and made it more clear. pkg/util/timeofday/time_of_day.go, line 74 at r5 (raw file): Previously, knz (kena) wrote…
Done. pkg/util/timeofday/time_of_day.go, line 87 at r5 (raw file): Previously, knz (kena) wrote…
Done. Comments from Reviewable |
da286a1
to
f3bc5c2
Compare
This is an implementation of the PostgreSQL TIME type, which represents time of day (no date). We store this as an int64 representing microseconds since midnight. Note that this commit does not attempt to support any new time formats beyond what we already support in the time portion of TIMESTAMP. This means that many formats which Postgres accepts (`04:05`, `040506`, `04:05 PM`, `allballs`) are not yet handled. We also do not support TIME WITH TIME ZONE, which the Postgres docs describe as having "questionable usefulness." Fixes cockroachdb#16490. Release note: Added support for TIME data type.
f3bc5c2
to
067a6c6
Compare
This is an implementation of the PostgreSQL TIME type, which represents
time of day (no date). We store this as an int64 representing
microseconds since midnight UTC.
Note that this commit does not attempt to support any new time formats
beyond what we already support in the time portion of TIMESTAMP. This
means that many formats which Postgres accepts (
04:05
,040506
,04:05 PM
,allballs
) are not yet handled.We also do not support TIME WITH TIME ZONE, which the Postgres docs
describe as having "questionable usefulness."
Fixes #16490.