Skip to content

Commit d443595

Browse files
committed
Apply UPDATE SET FROM statement for some dialects
1 parent 914810d commit d443595

File tree

3 files changed

+91
-81
lines changed

3 files changed

+91
-81
lines changed

src/parser.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5075,7 +5075,9 @@ impl<'a> Parser<'a> {
50755075
let table = self.parse_table_and_joins()?;
50765076
self.expect_keyword(Keyword::SET)?;
50775077
let assignments = self.parse_comma_separated(Parser::parse_assignment)?;
5078-
let from = if self.parse_keyword(Keyword::FROM) && dialect_of!(self is PostgreSqlDialect) {
5078+
let from = if self.parse_keyword(Keyword::FROM)
5079+
&& dialect_of!(self is PostgreSqlDialect | BigQueryDialect | SnowflakeDialect | RedshiftSqlDialect | MsSqlDialect)
5080+
{
50795081
Some(self.parse_table_and_joins()?)
50805082
} else {
50815083
None

tests/sqlparser_common.rs

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use sqlparser::ast::SelectItem::UnnamedExpr;
2626
use sqlparser::ast::*;
2727
use sqlparser::dialect::{
2828
AnsiDialect, BigQueryDialect, ClickHouseDialect, GenericDialect, HiveDialect, MsSqlDialect,
29-
PostgreSqlDialect, SQLiteDialect, SnowflakeDialect,
29+
PostgreSqlDialect, RedshiftSqlDialect, SQLiteDialect, SnowflakeDialect,
3030
};
3131
use sqlparser::keywords::ALL_KEYWORDS;
3232
use sqlparser::parser::{Parser, ParserError};
@@ -186,6 +186,93 @@ fn parse_update() {
186186
);
187187
}
188188

189+
#[test]
190+
fn parse_update_set_from() {
191+
let sql = "UPDATE t1 SET name = t2.name FROM (SELECT name, id FROM t1 GROUP BY id) AS t2 WHERE t1.id = t2.id";
192+
let dialects = TestedDialects {
193+
dialects: vec![
194+
Box::new(PostgreSqlDialect {}),
195+
Box::new(BigQueryDialect {}),
196+
Box::new(RedshiftSqlDialect {}),
197+
Box::new(MsSqlDialect {}),
198+
],
199+
};
200+
let stmt = dialects.verified_stmt(sql);
201+
assert_eq!(
202+
stmt,
203+
Statement::Update {
204+
table: TableWithJoins {
205+
relation: TableFactor::Table {
206+
name: ObjectName(vec![Ident::new("t1")]),
207+
alias: None,
208+
args: None,
209+
with_hints: vec![],
210+
},
211+
joins: vec![],
212+
},
213+
assignments: vec![Assignment {
214+
id: vec![Ident::new("name")],
215+
value: Expr::CompoundIdentifier(vec![Ident::new("t2"), Ident::new("name")])
216+
}],
217+
from: Some(TableWithJoins {
218+
relation: TableFactor::Derived {
219+
lateral: false,
220+
subquery: Box::new(Query {
221+
with: None,
222+
body: Box::new(SetExpr::Select(Box::new(Select {
223+
distinct: false,
224+
top: None,
225+
projection: vec![
226+
SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("name"))),
227+
SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("id"))),
228+
],
229+
into: None,
230+
from: vec![TableWithJoins {
231+
relation: TableFactor::Table {
232+
name: ObjectName(vec![Ident::new("t1")]),
233+
alias: None,
234+
args: None,
235+
with_hints: vec![],
236+
},
237+
joins: vec![],
238+
}],
239+
lateral_views: vec![],
240+
selection: None,
241+
group_by: vec![Expr::Identifier(Ident::new("id"))],
242+
cluster_by: vec![],
243+
distribute_by: vec![],
244+
sort_by: vec![],
245+
having: None,
246+
qualify: None
247+
}))),
248+
order_by: vec![],
249+
limit: None,
250+
offset: None,
251+
fetch: None,
252+
lock: None,
253+
}),
254+
alias: Some(TableAlias {
255+
name: Ident::new("t2"),
256+
columns: vec![],
257+
})
258+
},
259+
joins: vec![],
260+
}),
261+
selection: Some(Expr::BinaryOp {
262+
left: Box::new(Expr::CompoundIdentifier(vec![
263+
Ident::new("t1"),
264+
Ident::new("id")
265+
])),
266+
op: BinaryOperator::Eq,
267+
right: Box::new(Expr::CompoundIdentifier(vec![
268+
Ident::new("t2"),
269+
Ident::new("id")
270+
])),
271+
}),
272+
}
273+
);
274+
}
275+
189276
#[test]
190277
fn parse_update_with_table_alias() {
191278
let sql = "UPDATE users AS u SET u.username = 'new_user' WHERE u.username = 'old_user'";

tests/sqlparser_postgres.rs

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -446,85 +446,6 @@ PHP ₱ USD $
446446
//assert_eq!(sql, ast.to_string());
447447
}
448448

449-
#[test]
450-
fn parse_update_set_from() {
451-
let sql = "UPDATE t1 SET name = t2.name FROM (SELECT name, id FROM t1 GROUP BY id) AS t2 WHERE t1.id = t2.id";
452-
let stmt = pg().verified_stmt(sql);
453-
assert_eq!(
454-
stmt,
455-
Statement::Update {
456-
table: TableWithJoins {
457-
relation: TableFactor::Table {
458-
name: ObjectName(vec![Ident::new("t1")]),
459-
alias: None,
460-
args: None,
461-
with_hints: vec![],
462-
},
463-
joins: vec![],
464-
},
465-
assignments: vec![Assignment {
466-
id: vec![Ident::new("name")],
467-
value: Expr::CompoundIdentifier(vec![Ident::new("t2"), Ident::new("name")])
468-
}],
469-
from: Some(TableWithJoins {
470-
relation: TableFactor::Derived {
471-
lateral: false,
472-
subquery: Box::new(Query {
473-
with: None,
474-
body: Box::new(SetExpr::Select(Box::new(Select {
475-
distinct: false,
476-
top: None,
477-
projection: vec![
478-
SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("name"))),
479-
SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("id"))),
480-
],
481-
into: None,
482-
from: vec![TableWithJoins {
483-
relation: TableFactor::Table {
484-
name: ObjectName(vec![Ident::new("t1")]),
485-
alias: None,
486-
args: None,
487-
with_hints: vec![],
488-
},
489-
joins: vec![],
490-
}],
491-
lateral_views: vec![],
492-
selection: None,
493-
group_by: vec![Expr::Identifier(Ident::new("id"))],
494-
cluster_by: vec![],
495-
distribute_by: vec![],
496-
sort_by: vec![],
497-
having: None,
498-
qualify: None
499-
}))),
500-
order_by: vec![],
501-
limit: None,
502-
offset: None,
503-
fetch: None,
504-
lock: None,
505-
}),
506-
alias: Some(TableAlias {
507-
name: Ident::new("t2"),
508-
columns: vec![],
509-
})
510-
},
511-
joins: vec![],
512-
}),
513-
selection: Some(Expr::BinaryOp {
514-
left: Box::new(Expr::CompoundIdentifier(vec![
515-
Ident::new("t1"),
516-
Ident::new("id")
517-
])),
518-
op: BinaryOperator::Eq,
519-
right: Box::new(Expr::CompoundIdentifier(vec![
520-
Ident::new("t2"),
521-
Ident::new("id")
522-
])),
523-
}),
524-
}
525-
);
526-
}
527-
528449
#[test]
529450
fn test_copy_from() {
530451
let stmt = pg().verified_stmt("COPY users FROM 'data.csv'");

0 commit comments

Comments
 (0)