Skip to content

Commit b16de30

Browse files
iffyioVedin
authored andcommitted
Support multiple tables in UPDATE FROM clause (apache#1681)
1 parent 749bac7 commit b16de30

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
@@ -3927,13 +3927,13 @@ impl fmt::Display for Statement {
39273927
}
39283928
write!(f, "{table}")?;
39293929
if let Some(UpdateTableFromKind::BeforeSet(from)) = from {
3930-
write!(f, " FROM {from}")?;
3930+
write!(f, " FROM {}", display_comma_separated(from))?;
39313931
}
39323932
if !assignments.is_empty() {
39333933
write!(f, " SET {}", display_comma_separated(assignments))?;
39343934
}
39353935
if let Some(UpdateTableFromKind::AfterSet(from)) = from {
3936-
write!(f, " FROM {from}")?;
3936+
write!(f, " FROM {}", display_comma_separated(from))?;
39373937
}
39383938
if let Some(selection) = selection {
39393939
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
@@ -2165,10 +2165,11 @@ impl Spanned for SelectInto {
21652165

21662166
impl Spanned for UpdateTableFromKind {
21672167
fn span(&self) -> Span {
2168-
match self {
2169-
UpdateTableFromKind::BeforeSet(from) => from.span(),
2170-
UpdateTableFromKind::AfterSet(from) => from.span(),
2171-
}
2168+
let from = match self {
2169+
UpdateTableFromKind::BeforeSet(from) => from,
2170+
UpdateTableFromKind::AfterSet(from) => from,
2171+
};
2172+
union_spans(from.iter().map(|t| t.span()))
21722173
}
21732174
}
21742175

src/parser/mod.rs

+4-2
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

+7-4
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)