-
Notifications
You must be signed in to change notification settings - Fork 605
support general typed string literals #187
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
support general typed string literals #187
Conversation
8487d2e
to
731f400
Compare
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.
Thanks for doing this! The comments below are mainly nits, as usual, but I do think it's important to switch back to using a TypedString
(a la MaterializeInc/materialize@d6b24fb) instead of converting DATE 'yyyy-mm-dd
to a Cast
, and to fix the NOT 'a' like 'b'
bug (possibly by disallowing the custom data types as part of a "typed string" - MaterializeInc's version of the parser seems to have disabled this feature at all).
Thank you for the feedback! I'll try to have another look at this later on this week. |
@@ -34,6 +34,15 @@ macro_rules! parser_err { | |||
}; | |||
} | |||
|
|||
// Returns a successful result if the optional expression is some | |||
macro_rules! return_ok_if_some { |
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.
Let me know what you think about this name: it seemed a little closer to what's happening.
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 thought maybe_parse
could return a Result
(return_if_ok!(self.maybe_parse(|parser| {
), but this is probably fine too.
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.
Oh sure, happy to do it that way if you prefer!
@@ -34,6 +34,15 @@ macro_rules! parser_err { | |||
}; | |||
} | |||
|
|||
// Returns a successful result if the optional expression is some | |||
macro_rules! return_ok_if_some { |
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 thought maybe_parse
could return a Result
(return_if_ok!(self.maybe_parse(|parser| {
), but this is probably fine too.
src/parser.rs
Outdated
// Single-quoted strings are parsed as custom data types, however this not desirable | ||
// when we are handling input like `"NOT 'a' NOT LIKE 'b'"` because this will produce a |
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 doesn't seem right. Any name (Word
in our parlance), not a 'string', will be accepted as a custom data type, even when it's a keyword that should be handled by the code below.
src/parser.rs
Outdated
DataType::Interval => parser.parse_literal_interval(), | ||
// Single-quoted strings are parsed as custom data types, however this not desirable | ||
// when we are handling input like `"NOT 'a' NOT LIKE 'b'"` because this will produce a | ||
// TypedString instead of a SingleQuotedString. Further, this leads to issues where the |
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.
a TypedString[NOT 'a'] instead of Unary NOT?
src/parser.rs
Outdated
// Single-quoted strings are parsed as custom data types, however this not desirable | ||
// when we are handling input like `"NOT 'a' NOT LIKE 'b'"` because this will produce a | ||
// TypedString instead of a SingleQuotedString. Further, this leads to issues where the | ||
// same input will yield a BinaryOperator instead of the correct UnaryOperator. Here we |
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 don't understand this. If it's important, an example to demonstrate it would be welcome.
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 can remove this, it's just explaining why our test would fail if we didn't explicitly handle DataType::Custom
by returning an error (e.g. it will parse as a BinaryOperator instead of an UnaryOperator).
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.
Would it be better to change this entire comment to say something to the effect of we don't accept the type 'string' syntax for the custom data types? (Borrowing from your comment below.)
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.
It will parse as a BinaryOperator instead of an UnaryOperator
I don't understand what will parse as BinaryOperator.
Would it be better to change this entire comment to say something to the effect of we don't accept the type 'string' syntax for the custom data types? (Borrowing from your comment below.)
I think both the description of what returning an Err()
here does and the non-obvious example of NOT 'x' LIKE 'y'
should stay in the comment. I'm just trying to make sure I understand the examples and that they are clearly described.
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 don't understand what will parse as BinaryOperator.
Here I mean the direct example given in the comment of "NOT 'a' NOT LIKE 'b'"
.
I think both the description of what returning an Err() here does and the non-obvious example of NOT 'x' LIKE 'y' should stay in the comment. I'm just trying to make sure I understand the examples and that they are clearly described.
Sure, makes sense. I may be approaching the limits of my (admittedly shallow) understanding of the library here so I may need to defer to you for how you'd like to document that.
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.
Here I mean the direct example given in the comment of "NOT 'a' NOT LIKE 'b'".
Ah, sorry for being dense.
src/parser.rs
Outdated
// Single-quoted strings are parsed as custom data types, however this not desirable | ||
// when we are handling input like `"NOT 'a' NOT LIKE 'b'"` because this will produce a | ||
// TypedString instead of a SingleQuotedString. Further, this leads to issues where the | ||
// same input will yield a BinaryOperator instead of the correct UnaryOperator. Here we | ||
// handle that specific case by returning an 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.
"...we don't accept the type 'string'
syntax for the custom data types at all."
src/parser.rs
Outdated
// Check if the recently consumed '(' started a derived table, in which case we've | ||
// parsed the subquery, followed by the closing ')', and the alias of the derived | ||
// table. In the example above this is case (3). | ||
// | ||
// A parsing error from `parse_derived_table_factor` indicates that the '(' we've | ||
// recently consumed does not start a derived table (cases 1, 2, or 4). Ignore the | ||
// error and back up to where we after the opening '('. |
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 comments' text does not match their new location in the code. I can update the wording if you like.
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.
Sure, that would be helpful if you don't mind. 🙂
4b4e73d
to
2fa9479
Compare
This is a direct port of MaterializeInc/materialize#3146. It provides support for e.g. Postgres syntax where any string literal may be preceded by a type name. Fixes apache#168.
2fa9479
to
51cb5c7
Compare
Pull Request Test Coverage Report for Build 132531077
💛 - Coveralls |
I rebased this off of master (and squashed to avoid having to resolve the merge conflicts in each commit) so this should now incorporate the mainline changes. |
Excellent. I pushed an update to the comments, let me know if they make sense, and I think this is ready to merge? |
// PosgreSQL allows almost any identifier to be used as custom data type name, | ||
// and we support that in `parse_data_type()`. But unlike Postgres we don't | ||
// have a list of globally reserved keywords (since they vary across dialects), | ||
// so given `NOT 'a' LIKE 'b'`, we'd accept `NOT` as a possible custom data type | ||
// name, resulting in `NOT 'a'` being recognized as a `TypedString` instead of | ||
// an unary negation `NOT ('a' LIKE 'b')`. To solve this, we don't accept the | ||
// `type 'string'` syntax for the custom data types at all. |
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 reads so much better. Thank you!
Amazing. Thank you! It looks good to me. Really appreciate all the detailed feedback and of course patience. 🙂 |
Thank you as well! |
This is a direct port of MaterializeInc/materialize#3146. It provides
support for e.g. Postgres syntax where any string literal may be
preceded by a type name.
Fixes #168.