Skip to content

Commit 4706d8b

Browse files
authored
delete: add using clause, possibility of using aliases (apache#541)
Signed-off-by: Maciej Obuchowski <obuchowski.maciej@gmail.com>
1 parent 93e16e9 commit 4706d8b

File tree

3 files changed

+86
-5
lines changed

3 files changed

+86
-5
lines changed

src/ast/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,9 @@ pub enum Statement {
830830
/// DELETE
831831
Delete {
832832
/// FROM
833-
table_name: ObjectName,
833+
table_name: TableFactor,
834+
/// USING (Snowflake, Postgres)
835+
using: Option<TableFactor>,
834836
/// WHERE
835837
selection: Option<Expr>,
836838
},
@@ -1398,9 +1400,13 @@ impl fmt::Display for Statement {
13981400
}
13991401
Statement::Delete {
14001402
table_name,
1403+
using,
14011404
selection,
14021405
} => {
14031406
write!(f, "DELETE FROM {}", table_name)?;
1407+
if let Some(using) = using {
1408+
write!(f, " USING {}", using)?;
1409+
}
14041410
if let Some(selection) = selection {
14051411
write!(f, " WHERE {}", selection)?;
14061412
}

src/parser.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3141,7 +3141,12 @@ impl<'a> Parser<'a> {
31413141

31423142
pub fn parse_delete(&mut self) -> Result<Statement, ParserError> {
31433143
self.expect_keyword(Keyword::FROM)?;
3144-
let table_name = self.parse_object_name()?;
3144+
let table_name = self.parse_table_factor()?;
3145+
let using = if self.parse_keyword(Keyword::USING) {
3146+
Some(self.parse_table_factor()?)
3147+
} else {
3148+
None
3149+
};
31453150
let selection = if self.parse_keyword(Keyword::WHERE) {
31463151
Some(self.parse_expr()?)
31473152
} else {
@@ -3150,6 +3155,7 @@ impl<'a> Parser<'a> {
31503155

31513156
Ok(Statement::Delete {
31523157
table_name,
3158+
using,
31533159
selection,
31543160
})
31553161
}

tests/sqlparser_common.rs

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,12 @@ fn parse_delete_statement() {
253253
match verified_stmt(sql) {
254254
Statement::Delete { table_name, .. } => {
255255
assert_eq!(
256-
ObjectName(vec![Ident::with_quote('"', "table")]),
256+
TableFactor::Table {
257+
name: ObjectName(vec![Ident::with_quote('"', "table")]),
258+
alias: None,
259+
args: None,
260+
with_hints: vec![]
261+
},
257262
table_name
258263
);
259264
}
@@ -269,11 +274,20 @@ fn parse_where_delete_statement() {
269274
match verified_stmt(sql) {
270275
Statement::Delete {
271276
table_name,
277+
using,
272278
selection,
273-
..
274279
} => {
275-
assert_eq!(ObjectName(vec![Ident::new("foo")]), table_name);
280+
assert_eq!(
281+
TableFactor::Table {
282+
name: ObjectName(vec![Ident::new("foo")]),
283+
alias: None,
284+
args: None,
285+
with_hints: vec![]
286+
},
287+
table_name,
288+
);
276289

290+
assert_eq!(None, using);
277291
assert_eq!(
278292
Expr::BinaryOp {
279293
left: Box::new(Expr::Identifier(Ident::new("name"))),
@@ -287,6 +301,61 @@ fn parse_where_delete_statement() {
287301
}
288302
}
289303

304+
#[test]
305+
fn parse_where_delete_with_alias_statement() {
306+
use self::BinaryOperator::*;
307+
308+
let sql = "DELETE FROM basket AS a USING basket AS b WHERE a.id < b.id";
309+
match verified_stmt(sql) {
310+
Statement::Delete {
311+
table_name,
312+
using,
313+
selection,
314+
} => {
315+
assert_eq!(
316+
TableFactor::Table {
317+
name: ObjectName(vec![Ident::new("basket")]),
318+
alias: Some(TableAlias {
319+
name: Ident::new("a"),
320+
columns: vec![]
321+
}),
322+
args: None,
323+
with_hints: vec![]
324+
},
325+
table_name,
326+
);
327+
328+
assert_eq!(
329+
Some(TableFactor::Table {
330+
name: ObjectName(vec![Ident::new("basket")]),
331+
alias: Some(TableAlias {
332+
name: Ident::new("b"),
333+
columns: vec![]
334+
}),
335+
args: None,
336+
with_hints: vec![]
337+
}),
338+
using
339+
);
340+
assert_eq!(
341+
Expr::BinaryOp {
342+
left: Box::new(Expr::CompoundIdentifier(vec![
343+
Ident::new("a"),
344+
Ident::new("id")
345+
])),
346+
op: Lt,
347+
right: Box::new(Expr::CompoundIdentifier(vec![
348+
Ident::new("b"),
349+
Ident::new("id")
350+
])),
351+
},
352+
selection.unwrap(),
353+
);
354+
}
355+
_ => unreachable!(),
356+
}
357+
}
358+
290359
#[test]
291360
fn parse_top_level() {
292361
verified_stmt("SELECT 1");

0 commit comments

Comments
 (0)