Skip to content

Commit 27544f9

Browse files
authored
Add support for UPDATE ... LIMIT ... (#1991)
1 parent 67fca82 commit 27544f9

File tree

6 files changed

+36
-1
lines changed

6 files changed

+36
-1
lines changed

src/ast/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3238,6 +3238,8 @@ pub enum Statement {
32383238
returning: Option<Vec<SelectItem>>,
32393239
/// SQLite-specific conflict resolution clause
32403240
or: Option<SqliteOnConflict>,
3241+
/// LIMIT
3242+
limit: Option<Expr>,
32413243
},
32423244
/// ```sql
32433245
/// DELETE
@@ -4810,6 +4812,7 @@ impl fmt::Display for Statement {
48104812
selection,
48114813
returning,
48124814
or,
4815+
limit,
48134816
} => {
48144817
f.write_str("UPDATE ")?;
48154818
if let Some(or) = or {
@@ -4843,6 +4846,10 @@ impl fmt::Display for Statement {
48434846
f.write_str("RETURNING")?;
48444847
indented_list(f, returning)?;
48454848
}
4849+
if let Some(limit) = limit {
4850+
SpaceOrNewline.fmt(f)?;
4851+
write!(f, "LIMIT {limit}")?;
4852+
}
48464853
Ok(())
48474854
}
48484855
Statement::Delete(delete) => delete.fmt(f),

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ impl Spanned for Statement {
378378
selection,
379379
returning,
380380
or: _,
381+
limit: _,
381382
} => union_spans(
382383
core::iter::once(table.span())
383384
.chain(assignments.iter().map(|i| i.span()))

src/parser/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15152,13 +15152,19 @@ impl<'a> Parser<'a> {
1515215152
} else {
1515315153
None
1515415154
};
15155+
let limit = if self.parse_keyword(Keyword::LIMIT) {
15156+
Some(self.parse_expr()?)
15157+
} else {
15158+
None
15159+
};
1515515160
Ok(Statement::Update {
1515615161
table,
1515715162
assignments,
1515815163
from,
1515915164
selection,
1516015165
returning,
1516115166
or,
15167+
limit,
1516215168
})
1516315169
}
1516415170

tests/sqlparser_common.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ fn parse_update_set_from() {
515515
}),
516516
returning: None,
517517
or: None,
518+
limit: None
518519
}
519520
);
520521

@@ -533,6 +534,7 @@ fn parse_update_with_table_alias() {
533534
selection,
534535
returning,
535536
or: None,
537+
limit: None,
536538
} => {
537539
assert_eq!(
538540
TableWithJoins {

tests/sqlparser_mysql.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,6 +2516,7 @@ fn parse_update_with_joins() {
25162516
selection,
25172517
returning,
25182518
or: None,
2519+
limit: None,
25192520
} => {
25202521
assert_eq!(
25212522
TableWithJoins {

tests/sqlparser_sqlite.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,8 @@ fn parse_update_tuple_row_values() {
485485
joins: vec![],
486486
},
487487
from: None,
488-
returning: None
488+
returning: None,
489+
limit: None
489490
}
490491
);
491492
}
@@ -592,6 +593,23 @@ fn test_regexp_operator() {
592593
sqlite().verified_only_select(r#"SELECT count(*) FROM messages WHERE msg_text REGEXP '\d+'"#);
593594
}
594595

596+
#[test]
597+
fn test_update_delete_limit() {
598+
match sqlite().verified_stmt("UPDATE foo SET bar = 1 LIMIT 99") {
599+
Statement::Update { limit, .. } => {
600+
assert_eq!(limit, Some(Expr::value(number("99"))));
601+
}
602+
_ => unreachable!(),
603+
}
604+
605+
match sqlite().verified_stmt("DELETE FROM foo LIMIT 99") {
606+
Statement::Delete(Delete { limit, .. }) => {
607+
assert_eq!(limit, Some(Expr::value(number("99"))));
608+
}
609+
_ => unreachable!(),
610+
}
611+
}
612+
595613
fn sqlite() -> TestedDialects {
596614
TestedDialects::new(vec![Box::new(SQLiteDialect {})])
597615
}

0 commit comments

Comments
 (0)