Skip to content

Commit fdbe864

Browse files
authored
Support multiple tables in UPDATE FROM clause (#1681)
1 parent 74163b1 commit fdbe864

File tree

5 files changed

+20
-14
lines changed

5 files changed

+20
-14
lines changed

src/ast/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3872,13 +3872,13 @@ impl fmt::Display for Statement {
38723872
}
38733873
write!(f, "{table}")?;
38743874
if let Some(UpdateTableFromKind::BeforeSet(from)) = from {
3875-
write!(f, " FROM {from}")?;
3875+
write!(f, " FROM {}", display_comma_separated(from))?;
38763876
}
38773877
if !assignments.is_empty() {
38783878
write!(f, " SET {}", display_comma_separated(assignments))?;
38793879
}
38803880
if let Some(UpdateTableFromKind::AfterSet(from)) = from {
3881-
write!(f, " FROM {from}")?;
3881+
write!(f, " FROM {}", display_comma_separated(from))?;
38823882
}
38833883
if let Some(selection) = selection {
38843884
write!(f, " WHERE {selection}")?;

src/ast/query.rs

Lines changed: 2 additions & 2 deletions
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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,10 +2138,11 @@ impl Spanned for SelectInto {
21382138

21392139
impl Spanned for UpdateTableFromKind {
21402140
fn span(&self) -> Span {
2141-
match self {
2142-
UpdateTableFromKind::BeforeSet(from) => from.span(),
2143-
UpdateTableFromKind::AfterSet(from) => from.span(),
2144-
}
2141+
let from = match self {
2142+
UpdateTableFromKind::BeforeSet(from) => from,
2143+
UpdateTableFromKind::AfterSet(from) => from,
2144+
};
2145+
union_spans(from.iter().map(|t| t.span()))
21452146
}
21462147
}
21472148

src/parser/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12617,15 +12617,17 @@ impl<'a> Parser<'a> {
1261712617
let table = self.parse_table_and_joins()?;
1261812618
let from_before_set = if self.parse_keyword(Keyword::FROM) {
1261912619
Some(UpdateTableFromKind::BeforeSet(
12620-
self.parse_table_and_joins()?,
12620+
self.parse_table_with_joins()?,
1262112621
))
1262212622
} else {
1262312623
None
1262412624
};
1262512625
self.expect_keyword(Keyword::SET)?;
1262612626
let assignments = self.parse_comma_separated(Parser::parse_assignment)?;
1262712627
let from = if from_before_set.is_none() && self.parse_keyword(Keyword::FROM) {
12628-
Some(UpdateTableFromKind::AfterSet(self.parse_table_and_joins()?))
12628+
Some(UpdateTableFromKind::AfterSet(
12629+
self.parse_table_with_joins()?,
12630+
))
1262912631
} else {
1263012632
from_before_set
1263112633
};

tests/sqlparser_common.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ fn parse_update_set_from() {
403403
target: AssignmentTarget::ColumnName(ObjectName::from(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]
@@ -13051,8 +13054,8 @@ fn parse_select_without_projection() {
1305113054

1305213055
#[test]
1305313056
fn parse_update_from_before_select() {
13054-
all_dialects()
13055-
.verified_stmt("UPDATE t1 FROM (SELECT name, id FROM t1 GROUP BY id) AS t2 SET name = t2.name WHERE t1.id = t2.id");
13057+
verified_stmt("UPDATE t1 FROM (SELECT name, id FROM t1 GROUP BY id) AS t2 SET name = t2.name WHERE t1.id = t2.id");
13058+
verified_stmt("UPDATE t1 FROM U, (SELECT id FROM V) AS W SET a = b WHERE 1 = 1");
1305613059

1305713060
let query =
1305813061
"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)