Implement some MySQL specific syntax and extend the UPDATE statement (#375)

* * implement the ON DUPLICATE KEY syntax for MySQL in an INSERT statement

* * add MySQL to the cli example
* remove the dialect check for the ON DUPLICATE KEY insert to support
  custom dialects and unwrap some missing results

* * use the Assignment DataType for the ON DUPLICATE KEY UPDATE

* * add support for table aliases in an UPDATE statement
* add support for JOINS in an UPDATE statement (for MySQL)

* * implement the MySQL ALTER TABLE CHANGE COLUMN syntax

* * fix the formatting of the else * rename the parse_identifiers_strict
  to parse_identifiers_non_keywords

* Parse SUBSTRING calls that are separated with a comma instead of
keywords

* Fix the linting errors

Co-authored-by: Piotr <piotr.morawski@nc-vision.com>
Co-authored-by: Piotr Morawski <contact@peter-morawski.de>
This commit is contained in:
Andrew Lamb 2021-12-10 14:46:11 -05:00 committed by GitHub
parent 40d67aab87
commit 82eaae1522
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 489 additions and 18 deletions

View file

@ -141,25 +141,25 @@ fn parse_update() {
let sql = "UPDATE t SET a = 1, b = 2, c = 3 WHERE d";
match verified_stmt(sql) {
Statement::Update {
table_name,
table,
assignments,
selection,
..
} => {
assert_eq!(table_name.to_string(), "t".to_string());
assert_eq!(table.to_string(), "t".to_string());
assert_eq!(
assignments,
vec![
Assignment {
id: "a".into(),
id: vec!["a".into()],
value: Expr::Value(number("1")),
},
Assignment {
id: "b".into(),
id: vec!["b".into()],
value: Expr::Value(number("2")),
},
Assignment {
id: "c".into(),
id: vec!["c".into()],
value: Expr::Value(number("3")),
},
]
@ -186,6 +186,55 @@ fn parse_update() {
);
}
#[test]
fn parse_update_with_table_alias() {
let sql = "UPDATE users AS u SET u.username = 'new_user' WHERE u.username = 'old_user'";
match verified_stmt(sql) {
Statement::Update {
table,
assignments,
selection,
} => {
assert_eq!(
TableWithJoins {
relation: TableFactor::Table {
name: ObjectName(vec![Ident::new("users")]),
alias: Some(TableAlias {
name: Ident::new("u"),
columns: vec![]
}),
args: vec![],
with_hints: vec![],
},
joins: vec![]
},
table
);
assert_eq!(
vec![Assignment {
id: vec![Ident::new("u"), Ident::new("username")],
value: Expr::Value(Value::SingleQuotedString("new_user".to_string()))
}],
assignments
);
assert_eq!(
Some(Expr::BinaryOp {
left: Box::new(Expr::CompoundIdentifier(vec![
Ident::new("u"),
Ident::new("username")
])),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(Value::SingleQuotedString(
"old_user".to_string()
)))
}),
selection
);
}
_ => unreachable!(),
}
}
#[test]
fn parse_invalid_table_name() {
let ast = all_dialects()