-
Notifications
You must be signed in to change notification settings - Fork 606
Add support for generated virtual columns with expression #1051
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
Conversation
LGTM. |
There's one test covering the same But I can add this for SQLite & MySQL too. 👍 If SQLite & MySQL have the same syntax for this, do you prefer me to copy & paste the test into their respective modules, or set up one test to run with both of them? I'll copy-paste for now. |
Pull Request Test Coverage Report for Build 6961152498Warning: This coverage report may be inaccurate.We've detected an issue with your CI configuration that might affect the accuracy of this pull request's coverage report.
💛 - Coveralls |
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.
Thank you for this contribution @takluyver (and the review @tobyhede ). I left some comments -- let me know what you think
@@ -435,7 +446,6 @@ fn sqlite_with_options(options: ParserOptions) -> TestedDialects { | |||
|
|||
fn sqlite_and_generic() -> TestedDialects { | |||
TestedDialects { | |||
// we don't have a separate SQLite dialect, so test only the generic dialect for now |
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.
👍 nice drive by cleanup
#[test] | ||
fn parse_create_table_gencol() { | ||
let sql_default = "CREATE TABLE t1 (a INT, b INT GENERATED ALWAYS AS (a * 2))"; | ||
let sql_virt = "CREATE TABLE t1 (a INT, b INT GENERATED ALWAYS AS (a * 2) VIRTUAL)"; |
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.
What do you think about adding additional support to the AST so you can recover the original SQL --- as implemented now this change will not permit people to know when the original query had VIRTUAL
or not
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.
Virtual is the default, so adding the marker doesn't make a logical difference (at least in the databases I found that support this). Elsewhere in the tests, it looks like you don't preserve differences like this - e.g. SHOW COLUMNS
vs SHOW FIELDS
in the MySQL tests. But if you'd like to preserve this one, I'm happy to do that. 🙂
If so, I would probably introduce an enum called something like GenExpressionQualifier
(though that's an ugly name...), which could be None, Virtual or Stored. The Stored option would then be redundant with GeneratedAs::ExpStored
.
(For my next PR, I'm planning to make the GENERATED ALWAYS
keywords optional - as they are in MySQL and SQLite. Let me know if you want the presence or absence of those to be preserved 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.
Elsewhere in the tests, it looks like you don't preserve differences like this - e.g. SHOW COLUMNS vs SHOW FIELDS in the MySQL tests. But if you'd like to preserve this one, I'm happy to do that. 🙂
Yes, it is true that this crate is not always consistent. However, for newly added code let's try and preserve the ability to round trip the AST (though I see there is no note describing that detail on https://github.com/sqlparser-rs/sqlparser-rs -- I will try and add a note when I have time)
Let me know if you want the presence or absence of those to be preserved too.)
yes, please
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.
OK, the latest commit (6d69a43) preserves the distinction between VIRTUAL
, STORED
and no qualifier. As I mentioned, that does mean there are two fields which both record if STORED
was used. That's not so tidy, but it preserves compatibility for any code that's checking for GeneratedAs::ExpStored
.
I've called the new field & enum generation_expr_mode
& GeneratedExpressionMode
, which are both quite a mouthful. Let me know if you have a better name for this. 🙂
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.
filed #1052 to document this property
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.
Thank you @takluyver -- looks good to me
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] | ||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | ||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] | ||
pub enum GeneratedExpressionMode { |
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.
👍 looks good to me -- I don't have a better name for this
Ooops, I left some debugging bits in the tests. I've removed them now - do you prefer me to squash that into the previous commit and force-push the branch? |
On merge all the commits will be squashed into a single commit, so I would prefer that you just push new commits to your branch / PR as it makes reviewing the deltas easier |
Thanks again @takluyver |
This allows the SQLite & MySQL syntax for generated virtual columns, addressing the second part of #1050.
I've done a partial survey of what different databases support for generated columns:
GENERATED AS
syntax, but it doesn't seem to overlap with the other DBs above at all - it's something to do with versioning records, with no space for arbitrary expressions - docs. I haven't tried to cover this in this PR.It looks like the generated-column code before this PR is based on Postgres.
I've expanded the meaning of
GeneratedAs::ExpStored
, which the docs previously described as Postgres specific, to any column generated from an expressions and stored.GeneratedAs::Always
withgeneration_expr
present now represents a VIRTUAL column in SQLite or MySQL. It might be neater to make stored/virtual separate from always/by-default, but that would be an API break.