-
Notifications
You must be signed in to change notification settings - Fork 626
Fix create statement for mysql #602
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
RainJoe
commented
Sep 5, 2022
- Add ON UPDATE CURRENT_TIMESTAMP support.
- Add KEY/INDEX support
src/ast/ddl.rs
Outdated
@@ -256,11 +263,38 @@ impl fmt::Display for TableConstraint { | |||
name, | |||
columns, | |||
is_primary, | |||
is_mysql_unique_key, |
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 a bad design that can turn this code huge when considering other dialects.
If you really
need the dialect info here, maybe you could have the Dialect
itself, not that level of specificity here.
Since there are 3 possible options, couldn't we use an enum variant? Like:
pub enum UniqueType {
PrimaryKey,
Key,
Simple
}
(ignore the horrible naming, but you got the idea hehe)
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.
Use enum variant would not work, i think using specific dialect is a good solution, but when I add dialect trait in TableConstrait struct, the compiler says: the trait bound dyn dialect::Dialect: Clone
is not satisfied。
There may not have explict constrait
key word in mysql create statement, constraint
keyword is optional, like:
CREATE TABLE table_name(
column_name1 column_definition,
column_name2 column_definition,
...,
[CONSTRAINT constraint_name]
UNIQUE(column_name1,column_name2)
);
so use the origin display_constraint_name
method not work,This is why I use is_mysql_unique_key
to distinguish mysql dialect specifically.
I haven't been able to find an elegant way to solve it yet, any good idea?
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.
Use enum variant would not work
Why would this not work?
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.
If I remove is_mysql_unique_key
and use the original display method, then run the parse_table_colum_option_key test, it would panic, the painc message show the difference:
thread parse_table_colum_option_key panicked at assertion failed: (left == right)
left: "CREATE TABLE foo (modification_time DATETIME ON UPDATE, UNIQUE KEY u_m_t (modification_time))",
right: "CREATE TABLE foo (modification_time DATETIME ON UPDATE, CONSTRAINT u_m_t UNIQUE (modification_time))", src/test_utils.rs:95:13
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.
@RainJoe but you can still use an enum or something like that. Using a single boolean makes the expansion difficult, and doesn't make that much sense as it is really specific information added to the general AST. Using an enum there allows the upper levels to match and handle as desired when, for example, they're using the PostgreSQL dialect.
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.
@AugustoFKL Thanks for your suggestion,I will make some modifications and create a now PR later.
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 your contribution @RainJoe
I suggest following the idea of @AugustoFKL and using an enum variant to describe the different possible parsed versions of the CONSTRAINT
s keyword.
I am not familiar with the differences in syntax -- perhaps if you could summarize the differences in the description of this PR we could offer some more helpful feedback
@@ -247,6 +249,11 @@ pub enum TableConstraint { | |||
name: Option<Ident>, | |||
expr: Box<Expr>, | |||
}, | |||
Key { |
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.
Can you please add comments here about what this field means / how it maps back to SQL?
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.
@RainJoe please LMK if I'm wrong, but UNIQUE KEY
isn't the same as a UNIQUE
constraint, while only KEY
refers to the same as CREATE INDEX
?
Wouldn't be better to keep UNIQUE [KEY | INDEX]
as a UNIQUE
table constraint?
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.
Yes, it's not same. I have fixed it, PTAL @AugustoFKL
src/ast/ddl.rs
Outdated
@@ -228,6 +229,7 @@ pub enum TableConstraint { | |||
columns: Vec<Ident>, | |||
/// Whether this is a `PRIMARY KEY` or just a `UNIQUE` constraint | |||
is_primary: bool, | |||
is_mysql_unique_key: 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.
Please add comments to this field explaining what it means (aka how is this different)
src/ast/ddl.rs
Outdated
@@ -256,11 +263,38 @@ impl fmt::Display for TableConstraint { | |||
name, | |||
columns, | |||
is_primary, | |||
is_mysql_unique_key, |
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.
Use enum variant would not work
Why would this not work?
Pull Request Test Coverage Report for Build 3169255008
💛 - Coveralls |
@AugustoFKL PTAL |
@@ -247,6 +249,11 @@ pub enum TableConstraint { | |||
name: Option<Ident>, | |||
expr: Box<Expr>, | |||
}, | |||
Key { |
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.
@RainJoe please LMK if I'm wrong, but UNIQUE KEY
isn't the same as a UNIQUE
constraint, while only KEY
refers to the same as CREATE INDEX
?
Wouldn't be better to keep UNIQUE [KEY | INDEX]
as a UNIQUE
table constraint?
src/parser.rs
Outdated
Token::Word(w) if w.keyword == Keyword::PRIMARY || w.keyword == Keyword::UNIQUE => { | ||
let is_primary = w.keyword == Keyword::PRIMARY; | ||
if is_primary { | ||
self.expect_keyword(Keyword::KEY)?; | ||
} else if dialect_of!(self is MySqlDialect) { |
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.
Please add the GenericDialect
here. The idea of that, as long as I understood by this comment, is to support everything possible.
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's hard to cover all dialects now. so using the specific dialect to avoid affecting other dialects.
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.
@RainJoe THeGenericDialect
is the one that contains literally EVERY single possible AST structure. Therefore, it should contemplate any possible query
dialect_of!(self is GenericDialect | MySqlDialect)
should be enough
columns, | ||
format: KeyFormat::Index, | ||
})), | ||
_ => unreachable!(), |
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.
Please replace this with an error. I left a possible approach for cases like that 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.
There would be only two cases, and both of them are covered, so it's actually unreachable.
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.
Fine, but can't you return an error here?
It's better to have an error (like the self.expected(...)
) than having a unreachable
Ok(Some(ColumnOption::DialectSpecific(vec![ | ||
Token::make_keyword("ON UPDATE"), | ||
]))) | ||
if self.parse_keyword(Keyword::CURRENT_TIMESTAMP) { |
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.
Why did it change?
It's not related to your PR, so shouldn't have changed 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.
I mentioned it in my first comment.
@@ -428,6 +474,19 @@ fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ { | |||
ConstraintName(name) | |||
} | |||
|
|||
fn display_key_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ { |
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.
Too much complex, this isn't necessary at all...
Please can you try to make it simple? LMK if you need any help
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's similar to display_constraint_name
methed, the name
dose not implement display method, so i think it's necessary to do this.
/// For mysql index, here may be there format for index, there patterns are similar。 | ||
#[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | ||
pub enum KeyFormat { |
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.
As I stated in another comment, UNIQUE
is a constraint. Please don't change the current handle structure for it, as this doesn't make sense. You're changing the AST to match only one dialect.
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.
If you don't do this. this libarary would never support for mysql create statement. I think we should make it work first, and if someone have a better solution,we can apply it later.
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.
@RainJoe would you mind if I tried a different approach and you took a look in a day or two?
Sorry for asking that, I know that this has been your work, don't want to look like throwing that away
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.
Of course not. waitting for your approach.
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.
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.
@AugustoFKL Thanks for your work, but it didn't solve my problem, maybe I would just use my fork repository. It's seems hard to consider all possible scenarios.
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.
@RainJoe can you give examples of what you intend about this task?
The index usage itself is being parsed... What is the syntax you need?
Marking as draft as it seems to be waiting on feedback. Please mark as ready for review if/when it is |