Skip to content

Commit 9a4d235

Browse files
Moved the Update struct out of the Statement enum
1 parent 4862b28 commit 9a4d235

File tree

8 files changed

+117
-99
lines changed

8 files changed

+117
-99
lines changed

src/ast/dml.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::display_utils::{indented_list, Indent, SpaceOrNewline};
2929
use super::{
3030
display_comma_separated, query::InputFormatClause, Assignment, Expr, FromTable, Ident,
3131
InsertAliases, MysqlInsertPriority, ObjectName, OnInsert, OrderByExpr, Query, SelectItem,
32-
Setting, SqliteOnConflict, TableObject, TableWithJoins,
32+
Setting, SqliteOnConflict, TableObject, TableWithJoins, UpdateTableFromKind,
3333
};
3434

3535
/// INSERT statement.
@@ -240,3 +240,66 @@ impl Display for Delete {
240240
Ok(())
241241
}
242242
}
243+
244+
/// UPDATE statement.
245+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
246+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
247+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
248+
pub struct Update {
249+
/// TABLE
250+
pub table: TableWithJoins,
251+
/// Column assignments
252+
pub assignments: Vec<Assignment>,
253+
/// Table which provide value to be set
254+
pub from: Option<UpdateTableFromKind>,
255+
/// WHERE
256+
pub selection: Option<Expr>,
257+
/// RETURNING
258+
pub returning: Option<Vec<SelectItem>>,
259+
/// SQLite-specific conflict resolution clause
260+
pub or: Option<SqliteOnConflict>,
261+
/// LIMIT
262+
pub limit: Option<Expr>,
263+
}
264+
265+
impl Display for Update {
266+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
267+
f.write_str("UPDATE ")?;
268+
if let Some(or) = &self.or {
269+
or.fmt(f)?;
270+
f.write_str(" ")?;
271+
}
272+
self.table.fmt(f)?;
273+
if let Some(UpdateTableFromKind::BeforeSet(from)) = &self.from {
274+
SpaceOrNewline.fmt(f)?;
275+
f.write_str("FROM")?;
276+
indented_list(f, from)?;
277+
}
278+
if !self.assignments.is_empty() {
279+
SpaceOrNewline.fmt(f)?;
280+
f.write_str("SET")?;
281+
indented_list(f, &self.assignments)?;
282+
}
283+
if let Some(UpdateTableFromKind::AfterSet(from)) = &self.from {
284+
SpaceOrNewline.fmt(f)?;
285+
f.write_str("FROM")?;
286+
indented_list(f, from)?;
287+
}
288+
if let Some(selection) = &self.selection {
289+
SpaceOrNewline.fmt(f)?;
290+
f.write_str("WHERE")?;
291+
SpaceOrNewline.fmt(f)?;
292+
Indent(selection).fmt(f)?;
293+
}
294+
if let Some(returning) = &self.returning {
295+
SpaceOrNewline.fmt(f)?;
296+
f.write_str("RETURNING")?;
297+
indented_list(f, returning)?;
298+
}
299+
if let Some(limit) = &self.limit {
300+
SpaceOrNewline.fmt(f)?;
301+
write!(f, "LIMIT {limit}")?;
302+
}
303+
Ok(())
304+
}
305+
}

src/ast/mod.rs

Lines changed: 10 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use serde::{Deserialize, Serialize};
4343
use sqlparser_derive::{Visit, VisitMut};
4444

4545
use crate::{
46-
display_utils::{indented_list, SpaceOrNewline},
46+
display_utils::SpaceOrNewline,
4747
tokenizer::{Span, Token},
4848
};
4949
use crate::{
@@ -72,7 +72,7 @@ pub use self::ddl::{
7272
TableConstraint, TagsColumnOption, Truncate, UserDefinedTypeCompositeAttributeDef,
7373
UserDefinedTypeRepresentation, ViewColumnDef,
7474
};
75-
pub use self::dml::{Delete, Insert};
75+
pub use self::dml::{Delete, Insert, Update};
7676
pub use self::operator::{BinaryOperator, UnaryOperator};
7777
pub use self::query::{
7878
AfterMatchSkip, ConnectBy, Cte, CteAsMaterialized, Distinct, EmptyMatchesMode,
@@ -3241,22 +3241,7 @@ pub enum Statement {
32413241
/// ```sql
32423242
/// UPDATE
32433243
/// ```
3244-
Update {
3245-
/// TABLE
3246-
table: TableWithJoins,
3247-
/// Column assignments
3248-
assignments: Vec<Assignment>,
3249-
/// Table which provide value to be set
3250-
from: Option<UpdateTableFromKind>,
3251-
/// WHERE
3252-
selection: Option<Expr>,
3253-
/// RETURNING
3254-
returning: Option<Vec<SelectItem>>,
3255-
/// SQLite-specific conflict resolution clause
3256-
or: Option<SqliteOnConflict>,
3257-
/// LIMIT
3258-
limit: Option<Expr>,
3259-
},
3244+
Update(Update),
32603245
/// ```sql
32613246
/// DELETE
32623247
/// ```
@@ -4676,53 +4661,7 @@ impl fmt::Display for Statement {
46764661
}
46774662
Ok(())
46784663
}
4679-
Statement::Update {
4680-
table,
4681-
assignments,
4682-
from,
4683-
selection,
4684-
returning,
4685-
or,
4686-
limit,
4687-
} => {
4688-
f.write_str("UPDATE ")?;
4689-
if let Some(or) = or {
4690-
or.fmt(f)?;
4691-
f.write_str(" ")?;
4692-
}
4693-
table.fmt(f)?;
4694-
if let Some(UpdateTableFromKind::BeforeSet(from)) = from {
4695-
SpaceOrNewline.fmt(f)?;
4696-
f.write_str("FROM")?;
4697-
indented_list(f, from)?;
4698-
}
4699-
if !assignments.is_empty() {
4700-
SpaceOrNewline.fmt(f)?;
4701-
f.write_str("SET")?;
4702-
indented_list(f, assignments)?;
4703-
}
4704-
if let Some(UpdateTableFromKind::AfterSet(from)) = from {
4705-
SpaceOrNewline.fmt(f)?;
4706-
f.write_str("FROM")?;
4707-
indented_list(f, from)?;
4708-
}
4709-
if let Some(selection) = selection {
4710-
SpaceOrNewline.fmt(f)?;
4711-
f.write_str("WHERE")?;
4712-
SpaceOrNewline.fmt(f)?;
4713-
Indent(selection).fmt(f)?;
4714-
}
4715-
if let Some(returning) = returning {
4716-
SpaceOrNewline.fmt(f)?;
4717-
f.write_str("RETURNING")?;
4718-
indented_list(f, returning)?;
4719-
}
4720-
if let Some(limit) = limit {
4721-
SpaceOrNewline.fmt(f)?;
4722-
write!(f, "LIMIT {limit}")?;
4723-
}
4724-
Ok(())
4725-
}
4664+
Statement::Update(update) => update.fmt(f),
47264665
Statement::Delete(delete) => delete.fmt(f),
47274666
Statement::Open(open) => open.fmt(f),
47284667
Statement::Close { cursor } => {
@@ -10891,6 +10830,12 @@ impl From<Insert> for Statement {
1089110830
}
1089210831
}
1089310832

10833+
impl From<Update> for Statement {
10834+
fn from(u: Update) -> Self {
10835+
Self::Update(u)
10836+
}
10837+
}
10838+
1089410839
impl From<CaseStatement> for Statement {
1089510840
fn from(c: CaseStatement) -> Self {
1089610841
Self::Case(c)

src/ast/spans.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ use super::{
4040
RaiseStatementValue, ReferentialAction, RenameSelectItem, ReplaceSelectElement,
4141
ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SqlOption, Statement, Subscript,
4242
SymbolDefinition, TableAlias, TableAliasColumnDef, TableConstraint, TableFactor, TableObject,
43-
TableOptionsClustered, TableWithJoins, UpdateTableFromKind, Use, Value, Values, ViewColumnDef,
44-
WhileStatement, WildcardAdditionalOptions, With, WithFill,
43+
TableOptionsClustered, TableWithJoins, Update, UpdateTableFromKind, Use, Value, Values,
44+
ViewColumnDef, WhileStatement, WildcardAdditionalOptions, With, WithFill,
4545
};
4646

4747
/// Given an iterator of spans, return the [Span::union] of all spans.
@@ -346,21 +346,7 @@ impl Spanned for Statement {
346346
CloseCursor::All => Span::empty(),
347347
CloseCursor::Specific { name } => name.span,
348348
},
349-
Statement::Update {
350-
table,
351-
assignments,
352-
from,
353-
selection,
354-
returning,
355-
or: _,
356-
limit: _,
357-
} => union_spans(
358-
core::iter::once(table.span())
359-
.chain(assignments.iter().map(|i| i.span()))
360-
.chain(from.iter().map(|i| i.span()))
361-
.chain(selection.iter().map(|i| i.span()))
362-
.chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span()))),
363-
),
349+
Statement::Update(update) => update.span(),
364350
Statement::Delete(delete) => delete.span(),
365351
Statement::CreateView {
366352
or_alter: _,
@@ -997,6 +983,29 @@ impl Spanned for Delete {
997983
}
998984
}
999985

986+
impl Spanned for Update {
987+
fn span(&self) -> Span {
988+
let Update {
989+
table,
990+
assignments,
991+
from,
992+
selection,
993+
returning,
994+
or: _,
995+
limit,
996+
} = self;
997+
998+
union_spans(
999+
core::iter::once(table.span())
1000+
.chain(assignments.iter().map(|i| i.span()))
1001+
.chain(from.iter().map(|i| i.span()))
1002+
.chain(selection.iter().map(|i| i.span()))
1003+
.chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span())))
1004+
.chain(limit.iter().map(|i| i.span())),
1005+
)
1006+
}
1007+
}
1008+
10001009
impl Spanned for FromTable {
10011010
fn span(&self) -> Span {
10021011
match self {

src/parser/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15640,15 +15640,16 @@ impl<'a> Parser<'a> {
1564015640
} else {
1564115641
None
1564215642
};
15643-
Ok(Statement::Update {
15643+
Ok(Update {
1564415644
table,
1564515645
assignments,
1564615646
from,
1564715647
selection,
1564815648
returning,
1564915649
or,
1565015650
limit,
15651-
})
15651+
}
15652+
.into())
1565215653
}
1565315654

1565415655
/// Parse a `var = expr` assignment, used in an UPDATE statement

tests/sqlparser_common.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -377,12 +377,12 @@ fn parse_insert_sqlite() {
377377
fn parse_update() {
378378
let sql = "UPDATE t SET a = 1, b = 2, c = 3 WHERE d";
379379
match verified_stmt(sql) {
380-
Statement::Update {
380+
Statement::Update(Update {
381381
table,
382382
assignments,
383383
selection,
384384
..
385-
} => {
385+
}) => {
386386
assert_eq!(table.to_string(), "t".to_string());
387387
assert_eq!(
388388
assignments,
@@ -439,7 +439,7 @@ fn parse_update_set_from() {
439439
let stmt = dialects.verified_stmt(sql);
440440
assert_eq!(
441441
stmt,
442-
Statement::Update {
442+
Statement::Update(Update {
443443
table: TableWithJoins {
444444
relation: table_from_name(ObjectName::from(vec![Ident::new("t1")])),
445445
joins: vec![],
@@ -516,7 +516,7 @@ fn parse_update_set_from() {
516516
returning: None,
517517
or: None,
518518
limit: None
519-
}
519+
})
520520
);
521521

522522
let sql = "UPDATE T SET a = b FROM U, (SELECT foo FROM V) AS W WHERE 1 = 1";
@@ -527,15 +527,15 @@ fn parse_update_set_from() {
527527
fn parse_update_with_table_alias() {
528528
let sql = "UPDATE users AS u SET u.username = 'new_user' WHERE u.username = 'old_user'";
529529
match verified_stmt(sql) {
530-
Statement::Update {
530+
Statement::Update(Update {
531531
table,
532532
assignments,
533533
from: _from,
534534
selection,
535535
returning,
536536
or: None,
537537
limit: None,
538-
} => {
538+
}) => {
539539
assert_eq!(
540540
TableWithJoins {
541541
relation: TableFactor::Table {
@@ -591,7 +591,7 @@ fn parse_update_with_table_alias() {
591591
#[test]
592592
fn parse_update_or() {
593593
let expect_or_clause = |sql: &str, expected_action: SqliteOnConflict| match verified_stmt(sql) {
594-
Statement::Update { or, .. } => assert_eq!(or, Some(expected_action)),
594+
Statement::Update(Update { or, .. }) => assert_eq!(or, Some(expected_action)),
595595
other => unreachable!("Expected update with or, got {:?}", other),
596596
};
597597
expect_or_clause(

tests/sqlparser_mysql.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,15 +2601,15 @@ fn parse_insert_with_numeric_prefix_column_name() {
26012601
fn parse_update_with_joins() {
26022602
let sql = "UPDATE orders AS o JOIN customers AS c ON o.customer_id = c.id SET o.completed = true WHERE c.firstname = 'Peter'";
26032603
match mysql().verified_stmt(sql) {
2604-
Statement::Update {
2604+
Statement::Update(Update {
26052605
table,
26062606
assignments,
26072607
from: _from,
26082608
selection,
26092609
returning,
26102610
or: None,
26112611
limit: None,
2612-
} => {
2612+
}) => {
26132613
assert_eq!(
26142614
TableWithJoins {
26152615
relation: TableFactor::Table {
@@ -4177,7 +4177,7 @@ fn test_variable_assignment_using_colon_equal() {
41774177
let stmt = mysql().verified_stmt(sql_update);
41784178

41794179
match stmt {
4180-
Statement::Update { assignments, .. } => {
4180+
Statement::Update(Update { assignments, .. }) => {
41814181
assert_eq!(
41824182
assignments,
41834183
vec![Assignment {

tests/sqlparser_postgres.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2008,7 +2008,7 @@ fn parse_pg_returning() {
20082008
RETURNING temp_lo AS lo, temp_hi AS hi, prcp",
20092009
);
20102010
match stmt {
2011-
Statement::Update { returning, .. } => {
2011+
Statement::Update(Update { returning, .. }) => {
20122012
assert_eq!(
20132013
Some(vec![
20142014
SelectItem::ExprWithAlias {

tests/sqlparser_sqlite.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ fn parse_update_tuple_row_values() {
467467
// See https://github.com/sqlparser-rs/sqlparser-rs/issues/1311
468468
assert_eq!(
469469
sqlite().verified_stmt("UPDATE x SET (a, b) = (1, 2)"),
470-
Statement::Update {
470+
Statement::Update(Update {
471471
or: None,
472472
assignments: vec![Assignment {
473473
target: AssignmentTarget::Tuple(vec![
@@ -487,7 +487,7 @@ fn parse_update_tuple_row_values() {
487487
from: None,
488488
returning: None,
489489
limit: None
490-
}
490+
})
491491
);
492492
}
493493

@@ -596,7 +596,7 @@ fn test_regexp_operator() {
596596
#[test]
597597
fn test_update_delete_limit() {
598598
match sqlite().verified_stmt("UPDATE foo SET bar = 1 LIMIT 99") {
599-
Statement::Update { limit, .. } => {
599+
Statement::Update(Update { limit, .. }) => {
600600
assert_eq!(limit, Some(Expr::value(number("99"))));
601601
}
602602
_ => unreachable!(),

0 commit comments

Comments
 (0)