Skip to content

Commit 5464656

Browse files
committed
Support multiple tables in UPDATE FROM clause
Adds support for multiple tables in the `FROM` clause of an update statement. ```sql UPDATE A SET .. FROM T, U, V ```
1 parent 4f71542 commit 5464656

File tree

5 files changed

+20
-14
lines changed

5 files changed

+20
-14
lines changed

src/ast/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3842,13 +3842,13 @@ impl fmt::Display for Statement {
38423842
}
38433843
write!(f, "{table}")?;
38443844
if let Some(UpdateTableFromKind::BeforeSet(from)) = from {
3845-
write!(f, " FROM {from}")?;
3845+
write!(f, " FROM {}", display_comma_separated(from))?;
38463846
}
38473847
if !assignments.is_empty() {
38483848
write!(f, " SET {}", display_comma_separated(assignments))?;
38493849
}
38503850
if let Some(UpdateTableFromKind::AfterSet(from)) = from {
3851-
write!(f, " FROM {from}")?;
3851+
write!(f, " FROM {}", display_comma_separated(from))?;
38523852
}
38533853
if let Some(selection) = selection {
38543854
write!(f, " WHERE {selection}")?;

src/ast/query.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2829,8 +2829,8 @@ impl fmt::Display for ValueTableMode {
28292829
pub enum UpdateTableFromKind {
28302830
/// Update Statement where the 'FROM' clause is before the 'SET' keyword (Supported by Snowflake)
28312831
/// For Example: `UPDATE FROM t1 SET t1.name='aaa'`
2832-
BeforeSet(TableWithJoins),
2832+
BeforeSet(Vec<TableWithJoins>),
28332833
/// Update Statement where the 'FROM' clause is after the 'SET' keyword (Which is the standard way)
28342834
/// For Example: `UPDATE SET t1.name='aaa' FROM t1`
2835-
AfterSet(TableWithJoins),
2835+
AfterSet(Vec<TableWithJoins>),
28362836
}

src/ast/spans.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -2130,10 +2130,11 @@ impl Spanned for SelectInto {
21302130

21312131
impl Spanned for UpdateTableFromKind {
21322132
fn span(&self) -> Span {
2133-
match self {
2134-
UpdateTableFromKind::BeforeSet(from) => from.span(),
2135-
UpdateTableFromKind::AfterSet(from) => from.span(),
2136-
}
2133+
let from = match self {
2134+
UpdateTableFromKind::BeforeSet(from) => from,
2135+
UpdateTableFromKind::AfterSet(from) => from,
2136+
};
2137+
union_spans(from.iter().map(|t| t.span()))
21372138
}
21382139
}
21392140

src/parser/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -12585,15 +12585,17 @@ impl<'a> Parser<'a> {
1258512585
let table = self.parse_table_and_joins()?;
1258612586
let from_before_set = if self.parse_keyword(Keyword::FROM) {
1258712587
Some(UpdateTableFromKind::BeforeSet(
12588-
self.parse_table_and_joins()?,
12588+
self.parse_table_with_joins()?,
1258912589
))
1259012590
} else {
1259112591
None
1259212592
};
1259312593
self.expect_keyword(Keyword::SET)?;
1259412594
let assignments = self.parse_comma_separated(Parser::parse_assignment)?;
1259512595
let from = if from_before_set.is_none() && self.parse_keyword(Keyword::FROM) {
12596-
Some(UpdateTableFromKind::AfterSet(self.parse_table_and_joins()?))
12596+
Some(UpdateTableFromKind::AfterSet(
12597+
self.parse_table_with_joins()?,
12598+
))
1259712599
} else {
1259812600
from_before_set
1259912601
};

tests/sqlparser_common.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ fn parse_update_set_from() {
403403
target: AssignmentTarget::ColumnName(ObjectName(vec![Ident::new("name")])),
404404
value: Expr::CompoundIdentifier(vec![Ident::new("t2"), Ident::new("name")])
405405
}],
406-
from: Some(UpdateTableFromKind::AfterSet(TableWithJoins {
406+
from: Some(UpdateTableFromKind::AfterSet(vec![TableWithJoins {
407407
relation: TableFactor::Derived {
408408
lateral: false,
409409
subquery: Box::new(Query {
@@ -455,7 +455,7 @@ fn parse_update_set_from() {
455455
})
456456
},
457457
joins: vec![]
458-
})),
458+
}])),
459459
selection: Some(Expr::BinaryOp {
460460
left: Box::new(Expr::CompoundIdentifier(vec![
461461
Ident::new("t1"),
@@ -471,6 +471,9 @@ fn parse_update_set_from() {
471471
or: None,
472472
}
473473
);
474+
475+
let sql = "UPDATE T SET a = b FROM U, (SELECT foo FROM V) AS W WHERE 1 = 1";
476+
dialects.verified_stmt(sql);
474477
}
475478

476479
#[test]
@@ -13046,8 +13049,8 @@ fn parse_select_without_projection() {
1304613049

1304713050
#[test]
1304813051
fn parse_update_from_before_select() {
13049-
all_dialects()
13050-
.verified_stmt("UPDATE t1 FROM (SELECT name, id FROM t1 GROUP BY id) AS t2 SET name = t2.name WHERE t1.id = t2.id");
13052+
verified_stmt("UPDATE t1 FROM (SELECT name, id FROM t1 GROUP BY id) AS t2 SET name = t2.name WHERE t1.id = t2.id");
13053+
verified_stmt("UPDATE t1 FROM U, (SELECT id FROM V) AS W SET a = b WHERE 1 = 1");
1305113054

1305213055
let query =
1305313056
"UPDATE t1 FROM (SELECT name, id FROM t1 GROUP BY id) AS t2 SET name = t2.name FROM (SELECT name from t2) AS t2";

0 commit comments

Comments
 (0)