-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Implement temporal comparisons #17826
base: main
Are you sure you want to change the base?
Implement temporal comparisons #17826
Conversation
Review ChecklistHello reviewers! 👋 Please follow this checklist when reviewing this Pull Request. General
Tests
Documentation
New flags
If a workflow is added or modified:
Backward compatibility
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #17826 +/- ##
==========================================
- Coverage 67.45% 67.42% -0.03%
==========================================
Files 1592 1592
Lines 258167 258554 +387
==========================================
+ Hits 174143 174338 +195
- Misses 84024 84216 +192 ☔ View full report in Codecov by Sentry. |
766be25
to
39089b4
Compare
This is currently missing and leads to incorrect types to be returned for `LEAST` & `GREATEST` as comparison functions. There's a little mismatch here in behavior compared to MySQL which I argue is actually a bug in MySQL. In MySQL, a temporal type always has the binary collation: ``` mysql> select NOW(6), collation(NOW(6)); +----------------------------+-------------------+ | NOW(6) | collation(NOW(6)) | +----------------------------+-------------------+ | 2025-02-19 15:33:21.732301 | binary | +----------------------------+-------------------+ 1 row in set (0.00 sec) ``` On MySQL 8.4, this results in: ``` mysql> select GREATEST(NOW(6), NOW(6)), collation(GREATEST(NOW(6), NOW(6))); +----------------------------+-------------------------------------+ | GREATEST(NOW(6), NOW(6)) | collation(GREATEST(NOW(6), NOW(6))) | +----------------------------+-------------------------------------+ | 2025-02-19 15:35:00.921308 | latin1_swedish_ci | +----------------------------+-------------------------------------+ 1 row in set (0.00 sec) ``` But on MySQL 8.0, it returns: ``` mysql> select GREATEST(NOW(6), NOW(6)), collation(GREATEST(NOW(6), NOW(6))); +----------------------------+-------------------------------------+ | GREATEST(NOW(6), NOW(6)) | collation(GREATEST(NOW(6), NOW(6))) | +----------------------------+-------------------------------------+ | 2025-02-19 15:35:00.921308 | utf8mb4_0900_ai_ci | +----------------------------+-------------------------------------+ 1 row in set (0.00 sec) ``` Neither of these collations make sense, because it really should not change the collation and return `binary` still. That is what Vitess still does with the changes here (hence the addition to the test framework to allow skipping the collation check). I'll also report the issue upstream to make it behave correctly there as well. Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
39089b4
to
a693845
Compare
@@ -119,7 +119,7 @@ func TestCompilerReference(t *testing.T) { | |||
var supported, total int | |||
env := evalengine.EmptyExpressionEnv(venv) | |||
|
|||
tc.Run(func(query string, row []sqltypes.Value) { | |||
tc.Run(func(query string, row []sqltypes.Value, skipCollationCheck bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we use skipCollationCheck
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@systay This currently doesn't do collations checks anyway, so I don't think it really matters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@systay This did remind me that we actually should validate the collation. We still ignore this flag though, since our evalengine and compiler should always match.
The ignore collation flag is for where explicitly don't 100% match MySQL (due to bugs, arguably broken behavior etc).
Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
@@ -22,6 +22,7 @@ import ( | |||
"vitess.io/vitess/go/mysql/collations" | |||
"vitess.io/vitess/go/mysql/collations/charset" | |||
"vitess.io/vitess/go/mysql/collations/colldata" | |||
datetime2 "vitess.io/vitess/go/mysql/datetime" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: another solution would be to use the variable name datetimes
in the functions, and keep import named datetime
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
This is currently missing and leads to incorrect types to be returned for
LEAST
&GREATEST
as comparison functions.There's a little mismatch here in behavior compared to MySQL which I argue is actually a bug in MySQL. In MySQL, a temporal type always has the binary collation:
On MySQL 8.4, this results in:
But on MySQL 8.0, it returns:
Neither of these collations make sense, because it really should not change the collation and return
binary
still. That is what Vitess still does with the changes here (hence the addition to the test framework to allow skipping the collation check).I'll also report the issue upstream to make it behave correctly there as well.
Marked this also for backporting since using these types today leads to a panic on queries.
Related Issue(s)
Fixes #17750
Checklist