-
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 date, time and timestamp literals #10921
Implement date, time and timestamp literals #10921
Conversation
Review ChecklistHello reviewers! 👋 Please follow this checklist when reviewing this Pull Request. General
Bug fixes
Non-trivial changes
New/Existing features
Backward compatibility
|
@GuptaManan100 This adds a number of shift / reduce conflicts and I was wondering if you think it's possible to fix those or not here. |
The other main question I have here is how to deal with values that aren't valid date, time or timestamps. What is the general approach we should take for those? |
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.
The shift-reduce conflicts have been fixed using precedence rules.
STRING_TYPE_PREFIX_NON_KEYWORD
is used to resolve shift-reduce conflicts occurring due to column_name symbol and being able to use keywords like DATE and TIME as prefixes to strings to denote their type. The shift-reduce conflict occurs because after seeing one of these non-reserved keywords, if we see a STRING, then we can either shift to use the STRING typed rule in literal or reduce the non-reserved keyword into column_name and eventually use a rule from simple_expr. The way to fix this conflict is to give shifting higher precedence than reducing.
32731aa
to
f6f7e20
Compare
@GuptaManan100 @systay I've also added logic here to validate the actual literals and tried to match MySQL behavior within reason. |
The CI failure here in |
Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
… column names Signed-off-by: Manan Gupta <manan@planetscale.com>
…used to type cast STRINGS Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
f6f7e20
to
5106666
Compare
This adds additional validation of date, time and timestamp literals. It uses the same validation the evalengine already uses today which is more restricted than MySQL itself but seems good enough for now. It consolidates the parsing into one place so if the syntax allowed is extended, we only have to update one location. Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
5106666
to
a48a161
Compare
@@ -541,6 +541,7 @@ const ( | |||
ERInvalidCastToJSON = 3147 | |||
ERJSONValueTooBig = 3150 | |||
ERJSONDocumentTooDeep = 3157 | |||
ERWrongValue = 1525 |
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.
This is the same error type as MySQL:
mysql> select date'foo';
ERROR 1525 (HY000): Incorrect DATE value: 'foo'
@@ -189,6 +189,7 @@ var stateToMysqlCode = map[vterrors.State]struct { | |||
vterrors.WrongNumberOfColumnsInSelect: {num: ERWrongNumberOfColumnsInSelect, state: SSWrongNumberOfColumns}, | |||
vterrors.WrongTypeForVar: {num: ERWrongTypeForVar, state: SSClientError}, | |||
vterrors.WrongValueForVar: {num: ERWrongValueForVar, state: SSClientError}, | |||
vterrors.WrongValue: {num: ERWrongValue, state: SSUnknownSQLState}, |
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.
The SQL state here is also in MySQL unknown (HY000
):
mysql> select date'foo';
ERROR 1525 (HY000): Incorrect DATE value: 'foo'
@@ -146,6 +163,11 @@ func (nz *normalizer) convertLiteralDedup(node *Literal, cursor *Cursor) { | |||
|
|||
// convertLiteral converts an Literal without the dedup. | |||
func (nz *normalizer) convertLiteral(node *Literal, cursor *Cursor) { | |||
err := validateLiteral(node) |
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.
Tried various approaches, but injecting this in the normalization step seemed the easiest but it needs to be checked then from here and also in convertLiteralDedup
.
@@ -235,39 +235,27 @@ func compareNumeric(v1, v2 *EvalResult) (int, error) { | |||
func parseDate(expr *EvalResult) (t time.Time, err error) { |
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.
Unified what this function depends on also into the single parsing logic in the sqlparser
package.
} | ||
t, err = sqlparser.ParseTime(expr.string()) | ||
return |
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.
The new logic above should be equivalent to trying things in the loop. The error message depends on the last type checked, but that already was the case anyway.
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.
I like this approach 🥇
Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
57046c3
to
865d610
Compare
…o#929) * Implement date, time and timestamp literals Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com> * feat: add a test that verifies we can use date, timestamp and time as column names Signed-off-by: Manan Gupta <manan@planetscale.com> * feat: add precedence rule for non-reserved-keywords that can also be used to type cast STRINGS Signed-off-by: Manan Gupta <manan@planetscale.com> * test: fix tpch test to not expect syntax error Signed-off-by: Manan Gupta <manan@planetscale.com> * feat: make parser Signed-off-by: Manan Gupta <manan@planetscale.com> * Add validate of date style literals This adds additional validation of date, time and timestamp literals. It uses the same validation the evalengine already uses today which is more restricted than MySQL itself but seems good enough for now. It consolidates the parsing into one place so if the syntax allowed is extended, we only have to update one location. Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com> * Implement more complete TIME parsing support Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com> Co-authored-by: Manan Gupta <manan@planetscale.com> Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
This implements the
date
,time
andtimestamp
literals in the parser and ensures that bind variables also can be generated using these literals.Related Issue(s)
Part of #8604
Checklist