-
Notifications
You must be signed in to change notification settings - Fork 627
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
Changes from all commits
f86ed2f
cb1d2ab
311a771
bca276e
3aaaf24
36be43a
7521106
033d183
b0d1159
7afaedf
72703ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -217,6 +217,14 @@ impl fmt::Display for AlterColumnOperation { | |
} | ||
} | ||
|
||
/// 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 { | ||
Unique, | ||
Key, | ||
Index, | ||
} | ||
/// A table-level constraint, specified in a `CREATE TABLE` or an | ||
/// `ALTER TABLE ADD <constraint>` statement. | ||
#[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
|
@@ -247,6 +255,19 @@ pub enum TableConstraint { | |
name: Option<Ident>, | ||
expr: Box<Expr>, | ||
}, | ||
/// Index in constraint, for mysql specific dialect. | ||
/// Deal with this pattern: | ||
/// 1. {INDEX | KEY} [index_name] [index_type] (key_part,...) | ||
/// 2. [CONSTRAINT [symbol]] UNIQUE [INDEX | KEY] | ||
/// [index_name] [index_type] (key_part,...) | ||
/// [index_option] | ||
/// | ||
Key { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. @RainJoe please LMK if I'm wrong, but Wouldn't be better to keep There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's not same. I have fixed it, PTAL @AugustoFKL |
||
name: Option<Ident>, | ||
columns: Vec<Ident>, | ||
/// key format, eg: unique/key/index | ||
format: KeyFormat, | ||
}, | ||
} | ||
|
||
impl fmt::Display for TableConstraint { | ||
|
@@ -256,13 +277,38 @@ impl fmt::Display for TableConstraint { | |
name, | ||
columns, | ||
is_primary, | ||
} => write!( | ||
f, | ||
"{}{} ({})", | ||
display_constraint_name(name), | ||
if *is_primary { "PRIMARY KEY" } else { "UNIQUE" }, | ||
display_comma_separated(columns) | ||
), | ||
} => { | ||
write!( | ||
f, | ||
"{}{} ({})", | ||
display_constraint_name(name), | ||
if *is_primary { "PRIMARY KEY" } else { "UNIQUE" }, | ||
display_comma_separated(columns) | ||
) | ||
} | ||
TableConstraint::Key { | ||
name, | ||
columns, | ||
format, | ||
} => { | ||
match *format { | ||
KeyFormat::Unique => { | ||
write!(f, "UNIQUE ")?; | ||
} | ||
KeyFormat::Key => { | ||
write!(f, "KEY ")?; | ||
} | ||
KeyFormat::Index => { | ||
write!(f, "INDEX ")?; | ||
} | ||
} | ||
write!( | ||
f, | ||
"{} ({})", | ||
display_key_name(name), | ||
display_comma_separated(columns) | ||
) | ||
} | ||
TableConstraint::ForeignKey { | ||
name, | ||
columns, | ||
|
@@ -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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. It's similar to |
||
struct KeyName<'a>(&'a Option<Ident>); | ||
impl<'a> fmt::Display for KeyName<'a> { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
if let Some(name) = self.0 { | ||
write!(f, "{}", name)?; | ||
} | ||
Ok(()) | ||
} | ||
} | ||
KeyName(name) | ||
} | ||
|
||
/// `<referential_action> = | ||
/// { RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT }` | ||
/// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2526,9 +2526,15 @@ impl<'a> Parser<'a> { | |
} else if self.parse_keywords(&[Keyword::ON, Keyword::UPDATE]) | ||
&& dialect_of!(self is MySqlDialect) | ||
{ | ||
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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. I mentioned it in my first comment. |
||
Ok(Some(ColumnOption::DialectSpecific(vec![ | ||
Token::make_keyword("ON UPDATE CURRENT_TIMESTAMP"), | ||
]))) | ||
} else { | ||
Ok(Some(ColumnOption::DialectSpecific(vec![ | ||
Token::make_keyword("ON UPDATE"), | ||
]))) | ||
} | ||
} else { | ||
Ok(None) | ||
} | ||
|
@@ -2562,10 +2568,39 @@ impl<'a> Parser<'a> { | |
None | ||
}; | ||
match self.next_token() { | ||
Token::Word(w) | ||
if (w.keyword == Keyword::KEY || w.keyword == Keyword::INDEX) | ||
&& dialect_of!(self is MySqlDialect) => | ||
{ | ||
let name = Some(self.parse_identifier()?); | ||
let columns = self.parse_parenthesized_column_list(Mandatory)?; | ||
match w.keyword { | ||
Keyword::KEY => Ok(Some(TableConstraint::Key { | ||
name, | ||
columns, | ||
format: KeyFormat::Key, | ||
})), | ||
Keyword::INDEX => Ok(Some(TableConstraint::Key { | ||
name, | ||
columns, | ||
format: KeyFormat::Index, | ||
})), | ||
_ => unreachable!(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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 commentThe 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 |
||
} | ||
} | ||
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) && name == None { | ||
//For mysql case: UNIQUE KEY (column_name), there is a little difference from CONSTRAINT constraint_name UNIQUE (column_name) | ||
let name = Some(self.parse_identifier()?); | ||
let columns = self.parse_parenthesized_column_list(Mandatory)?; | ||
return Ok(Some(TableConstraint::Key { | ||
name, | ||
columns, | ||
format: KeyFormat::Unique, | ||
})); | ||
} | ||
let columns = self.parse_parenthesized_column_list(Mandatory)?; | ||
Ok(Some(TableConstraint::Unique { | ||
|
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.Uh oh!
There was an error while loading. Please reload this page.
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.
Uh oh!
There was an error while loading. Please reload this page.
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 @alamb could you please leave your opinion? #665
Sorry the delay, busy week at work + college
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?