Skip to content

Commit f6bcf03

Browse files
authored
feat(binder): support update from (#17464)
* feat(binder): support update from * chore(parser): fix token * chore(test): add sqllogictest * chore(test): update stmt unit-test
1 parent 9e24c38 commit f6bcf03

File tree

10 files changed

+246
-80
lines changed

10 files changed

+246
-80
lines changed

src/query/ast/src/ast/statements/merge_into.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ use crate::ast::TableReference;
3030
use crate::ast::WithOptions;
3131

3232
#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
33-
pub struct MergeUpdateExpr {
33+
pub struct MutationUpdateExpr {
3434
pub table: Option<Identifier>,
3535
pub name: Identifier,
3636
pub expr: Expr,
3737
}
3838

39-
impl Display for MergeUpdateExpr {
39+
impl Display for MutationUpdateExpr {
4040
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
4141
if self.table.is_some() {
4242
write!(f, "{}.", self.table.clone().unwrap())?;
@@ -49,7 +49,7 @@ impl Display for MergeUpdateExpr {
4949
#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
5050
pub enum MatchOperation {
5151
Update {
52-
update_list: Vec<MergeUpdateExpr>,
52+
update_list: Vec<MutationUpdateExpr>,
5353
is_star: bool,
5454
},
5555
Delete,
@@ -86,7 +86,7 @@ pub struct MergeIntoStmt {
8686
pub catalog: Option<Identifier>,
8787
pub database: Option<Identifier>,
8888
pub table_ident: Identifier,
89-
pub source: MergeSource,
89+
pub source: MutationSource,
9090
// target_alias is belong to target
9191
pub target_alias: Option<TableAlias>,
9292
pub join_expr: Expr,
@@ -167,7 +167,7 @@ impl Display for MergeIntoStmt {
167167
}
168168

169169
#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
170-
pub enum MergeSource {
170+
pub enum MutationSource {
171171
StreamingV2 {
172172
settings: FileFormatOptions,
173173
on_error_mode: Option<String>,
@@ -187,7 +187,7 @@ pub enum MergeSource {
187187
},
188188
}
189189

190-
impl MergeSource {
190+
impl MutationSource {
191191
pub fn transform_table_reference(&self) -> TableReference {
192192
match self {
193193
Self::StreamingV2 {
@@ -229,10 +229,10 @@ impl MergeSource {
229229
}
230230
}
231231

232-
impl Display for MergeSource {
232+
impl Display for MutationSource {
233233
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
234234
match self {
235-
MergeSource::StreamingV2 {
235+
MutationSource::StreamingV2 {
236236
settings,
237237
on_error_mode,
238238
start: _,
@@ -245,12 +245,12 @@ impl Display for MergeSource {
245245
)
246246
}
247247

248-
MergeSource::Select {
248+
MutationSource::Select {
249249
query,
250250
source_alias,
251251
} => write!(f, "({query}) AS {source_alias}"),
252252

253-
MergeSource::Table {
253+
MutationSource::Table {
254254
catalog,
255255
database,
256256
table,

src/query/ast/src/ast/statements/update.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,24 @@ use derive_visitor::Drive;
1919
use derive_visitor::DriveMut;
2020

2121
use crate::ast::write_comma_separated_list;
22+
use crate::ast::write_dot_separated_list;
2223
use crate::ast::Expr;
2324
use crate::ast::Hint;
2425
use crate::ast::Identifier;
25-
use crate::ast::TableReference;
26+
use crate::ast::MutationSource;
27+
use crate::ast::MutationUpdateExpr;
28+
use crate::ast::TableAlias;
2629
use crate::ast::With;
2730

2831
#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
2932
pub struct UpdateStmt {
3033
pub hints: Option<Hint>,
31-
pub table: TableReference,
32-
pub update_list: Vec<UpdateExpr>,
34+
pub catalog: Option<Identifier>,
35+
pub database: Option<Identifier>,
36+
pub table: Identifier,
37+
pub table_alias: Option<TableAlias>,
38+
pub update_list: Vec<MutationUpdateExpr>,
39+
pub from: Option<MutationSource>,
3340
pub selection: Option<Expr>,
3441
// With clause, common table expression
3542
pub with: Option<With>,
@@ -44,8 +51,21 @@ impl Display for UpdateStmt {
4451
if let Some(hints) = &self.hints {
4552
write!(f, "{} ", hints)?;
4653
}
47-
write!(f, "{} SET ", self.table)?;
54+
write_dot_separated_list(
55+
f,
56+
self.catalog
57+
.iter()
58+
.chain(&self.database)
59+
.chain(Some(&self.table)),
60+
)?;
61+
if let Some(alias) = &self.table_alias {
62+
write!(f, " AS {}", alias.name)?;
63+
}
64+
write!(f, " SET ")?;
4865
write_comma_separated_list(f, &self.update_list)?;
66+
if let Some(from) = &self.from {
67+
write!(f, " FROM {} ", from)?;
68+
}
4969
if let Some(conditions) = &self.selection {
5070
write!(f, " WHERE {conditions}")?;
5171
}

src/query/ast/src/parser/statement.rs

+26-11
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub fn statement_body(i: Input) -> IResult<Statement> {
227227
rule! {
228228
MERGE ~ #hint?
229229
~ INTO ~ #dot_separated_idents_1_to_3 ~ #table_alias?
230-
~ USING ~ #merge_source
230+
~ USING ~ #mutation_source
231231
~ ON ~ #expr ~ (#match_clause | #unmatch_clause)*
232232
},
233233
|(
@@ -271,15 +271,30 @@ pub fn statement_body(i: Input) -> IResult<Statement> {
271271

272272
let update = map(
273273
rule! {
274-
#with? ~ UPDATE ~ #hint? ~ #table_reference_only
275-
~ SET ~ ^#comma_separated_list1(update_expr)
274+
#with? ~ UPDATE ~ #hint? ~ #dot_separated_idents_1_to_3 ~ #table_alias?
275+
~ SET ~ ^#comma_separated_list1(mutation_update_expr)
276+
~ ( FROM ~ #mutation_source )?
276277
~ ( WHERE ~ ^#expr )?
277278
},
278-
|(with, _, hints, table, _, update_list, opt_selection)| {
279+
|(
280+
with,
281+
_,
282+
hints,
283+
(catalog, database, table),
284+
table_alias,
285+
_,
286+
update_list,
287+
from,
288+
opt_selection,
289+
)| {
279290
Statement::Update(UpdateStmt {
280291
hints,
292+
catalog,
293+
database,
281294
table,
295+
table_alias,
282296
update_list,
297+
from: from.map(|(_, table)| table),
283298
selection: opt_selection.map(|(_, selection)| selection),
284299
with,
285300
})
@@ -2899,28 +2914,28 @@ pub fn raw_insert_source(i: Input) -> IResult<InsertSource> {
28992914
)(i)
29002915
}
29012916

2902-
pub fn merge_source(i: Input) -> IResult<MergeSource> {
2917+
pub fn mutation_source(i: Input) -> IResult<MutationSource> {
29032918
let streaming_v2 = map(
29042919
rule! {
29052920
#file_format_clause ~ (ON_ERROR ~ ^"=" ~ ^#ident)? ~ #rest_str
29062921
},
2907-
|(options, on_error_opt, (_, start))| MergeSource::StreamingV2 {
2922+
|(options, on_error_opt, (_, start))| MutationSource::StreamingV2 {
29082923
settings: options,
29092924
on_error_mode: on_error_opt.map(|v| v.2.to_string()),
29102925
start,
29112926
},
29122927
);
29132928

29142929
let query = map(rule! {#query ~ #table_alias}, |(query, source_alias)| {
2915-
MergeSource::Select {
2930+
MutationSource::Select {
29162931
query: Box::new(query),
29172932
source_alias,
29182933
}
29192934
});
29202935

29212936
let source_table = map(
29222937
rule!(#dot_separated_idents_1_to_3 ~ #with_options? ~ #table_alias?),
2923-
|((catalog, database, table), with_options, alias)| MergeSource::Table {
2938+
|((catalog, database, table), with_options, alias)| MutationSource::Table {
29242939
catalog,
29252940
database,
29262941
table,
@@ -3813,7 +3828,7 @@ fn match_operation(i: Input) -> IResult<MatchOperation> {
38133828
value(MatchOperation::Delete, rule! { DELETE }),
38143829
map(
38153830
rule! {
3816-
UPDATE ~ SET ~ ^#comma_separated_list1(merge_update_expr)
3831+
UPDATE ~ SET ~ ^#comma_separated_list1(mutation_update_expr)
38173832
},
38183833
|(_, _, update_list)| MatchOperation::Update {
38193834
update_list,
@@ -4640,10 +4655,10 @@ pub fn udf_definition(i: Input) -> IResult<UDFDefinition> {
46404655
)(i)
46414656
}
46424657

4643-
pub fn merge_update_expr(i: Input) -> IResult<MergeUpdateExpr> {
4658+
pub fn mutation_update_expr(i: Input) -> IResult<MutationUpdateExpr> {
46444659
map(
46454660
rule! { #dot_separated_idents_1_to_2 ~ "=" ~ ^#expr },
4646-
|((table, name), _, expr)| MergeUpdateExpr { table, name, expr },
4661+
|((table, name), _, expr)| MutationUpdateExpr { table, name, expr },
46474662
)(i)
46484663
}
46494664

src/query/ast/src/parser/token.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1711,6 +1711,7 @@ impl TokenKind {
17111711
// | TokenKind::SIMILAR
17121712
| TokenKind::SOME
17131713
| TokenKind::SEMI
1714+
| TokenKind::SET
17141715
| TokenKind::SAMPLE
17151716
// | TokenKind::SYMMETRIC
17161717
// | TokenKind::TABLESAMPLE

src/query/ast/tests/it/testdata/stmt.txt

+19-26
Original file line numberDiff line numberDiff line change
@@ -16489,38 +16489,29 @@ UPDATE db1.tb1 SET a = a + 1, b = 2 WHERE c > 3
1648916489
Update(
1649016490
UpdateStmt {
1649116491
hints: None,
16492-
table: Table {
16493-
span: Some(
16494-
7..14,
16495-
),
16496-
catalog: None,
16497-
database: Some(
16498-
Identifier {
16499-
span: Some(
16500-
7..10,
16501-
),
16502-
name: "db1",
16503-
quote: None,
16504-
ident_type: None,
16505-
},
16506-
),
16507-
table: Identifier {
16492+
catalog: None,
16493+
database: Some(
16494+
Identifier {
1650816495
span: Some(
16509-
11..14,
16496+
7..10,
1651016497
),
16511-
name: "tb1",
16498+
name: "db1",
1651216499
quote: None,
1651316500
ident_type: None,
1651416501
},
16515-
alias: None,
16516-
temporal: None,
16517-
with_options: None,
16518-
pivot: None,
16519-
unpivot: None,
16520-
sample: None,
16502+
),
16503+
table: Identifier {
16504+
span: Some(
16505+
11..14,
16506+
),
16507+
name: "tb1",
16508+
quote: None,
16509+
ident_type: None,
1652116510
},
16511+
table_alias: None,
1652216512
update_list: [
16523-
UpdateExpr {
16513+
MutationUpdateExpr {
16514+
table: None,
1652416515
name: Identifier {
1652516516
span: Some(
1652616517
19..20,
@@ -16563,7 +16554,8 @@ Update(
1656316554
},
1656416555
},
1656516556
},
16566-
UpdateExpr {
16557+
MutationUpdateExpr {
16558+
table: None,
1656716559
name: Identifier {
1656816560
span: Some(
1656916561
30..31,
@@ -16582,6 +16574,7 @@ Update(
1658216574
},
1658316575
},
1658416576
],
16577+
from: None,
1658516578
selection: Some(
1658616579
BinaryOp {
1658716580
span: Some(

src/query/sql/src/planner/binder/bind_mutation/delete.rs

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ impl Binder {
6868
target_table_identifier,
6969
expression: MutationExpression::Delete {
7070
target: table.clone(),
71+
from: None,
7172
filter: selection.clone(),
7273
},
7374
strategy: MutationStrategy::MatchedOnly,

0 commit comments

Comments
 (0)