Skip to content

Commit d023b08

Browse files
committed
Include UPDATE keyword in statement span
1 parent a00d5cd commit d023b08

File tree

6 files changed

+65
-13
lines changed

6 files changed

+65
-13
lines changed

src/ast/dml.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ use sqlparser_derive::{Visit, VisitMut};
2727
use crate::display_utils::{indented_list, Indent, SpaceOrNewline};
2828

2929
use super::{
30-
display_comma_separated, query::InputFormatClause, Assignment, Expr, FromTable, Ident,
31-
InsertAliases, MysqlInsertPriority, ObjectName, OnInsert, OrderByExpr, Query, SelectItem,
32-
Setting, SqliteOnConflict, TableObject, TableWithJoins, UpdateTableFromKind,
30+
display_comma_separated, helpers::attached_token::AttachedToken, query::InputFormatClause,
31+
Assignment, Expr, FromTable, Ident, InsertAliases, MysqlInsertPriority, ObjectName, OnInsert,
32+
OrderByExpr, Query, SelectItem, Setting, SqliteOnConflict, TableObject, TableWithJoins,
33+
UpdateTableFromKind,
3334
};
3435

3536
/// INSERT statement.
@@ -246,6 +247,8 @@ impl Display for Delete {
246247
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
247248
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
248249
pub struct Update {
250+
/// Token for the `UPDATE` keyword
251+
pub update_token: AttachedToken,
249252
/// TABLE
250253
pub table: TableWithJoins,
251254
/// Column assignments

src/ast/spans.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,7 @@ impl Spanned for Delete {
869869
impl Spanned for Update {
870870
fn span(&self) -> Span {
871871
let Update {
872+
update_token,
872873
table,
873874
assignments,
874875
from,
@@ -880,6 +881,7 @@ impl Spanned for Update {
880881

881882
union_spans(
882883
core::iter::once(table.span())
884+
.chain(core::iter::once(update_token.0.span))
883885
.chain(assignments.iter().map(|i| i.span()))
884886
.chain(from.iter().map(|i| i.span()))
885887
.chain(selection.iter().map(|i| i.span()))
@@ -2540,4 +2542,22 @@ ALTER TABLE users
25402542
assert_eq!(stmt_span.start, (2, 13).into());
25412543
assert_eq!(stmt_span.end, (4, 11).into());
25422544
}
2545+
2546+
#[test]
2547+
fn test_update_statement_span() {
2548+
let sql = r#"-- foo
2549+
UPDATE foo
2550+
/* bar */
2551+
SET bar = 3
2552+
WHERE quux > 42 ;
2553+
"#;
2554+
2555+
let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2556+
assert_eq!(1, r.len());
2557+
2558+
let stmt_span = r[0].span();
2559+
2560+
assert_eq!(stmt_span.start, (2, 7).into());
2561+
assert_eq!(stmt_span.end, (5, 17).into());
2562+
}
25432563
}

src/parser/mod.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ impl<'a> Parser<'a> {
590590
Keyword::INSERT => self.parse_insert(),
591591
Keyword::REPLACE => self.parse_replace(),
592592
Keyword::UNCACHE => self.parse_uncache_table(),
593-
Keyword::UPDATE => self.parse_update(),
593+
Keyword::UPDATE => self.parse_update(next_token),
594594
Keyword::ALTER => self.parse_alter(),
595595
Keyword::CALL => self.parse_call(),
596596
Keyword::COPY => self.parse_copy(),
@@ -12014,7 +12014,7 @@ impl<'a> Parser<'a> {
1201412014
} else if self.parse_keyword(Keyword::UPDATE) {
1201512015
Ok(Query {
1201612016
with,
12017-
body: self.parse_update_setexpr_boxed()?,
12017+
body: self.parse_update_setexpr_boxed(self.get_current_token().clone())?,
1201812018
order_by: None,
1201912019
limit_clause: None,
1202012020
fetch: None,
@@ -15754,11 +15754,14 @@ impl<'a> Parser<'a> {
1575415754
/// Parse an UPDATE statement, returning a `Box`ed SetExpr
1575515755
///
1575615756
/// This is used to reduce the size of the stack frames in debug builds
15757-
fn parse_update_setexpr_boxed(&mut self) -> Result<Box<SetExpr>, ParserError> {
15758-
Ok(Box::new(SetExpr::Update(self.parse_update()?)))
15757+
fn parse_update_setexpr_boxed(
15758+
&mut self,
15759+
update_token: TokenWithSpan,
15760+
) -> Result<Box<SetExpr>, ParserError> {
15761+
Ok(Box::new(SetExpr::Update(self.parse_update(update_token)?)))
1575915762
}
1576015763

15761-
pub fn parse_update(&mut self) -> Result<Statement, ParserError> {
15764+
pub fn parse_update(&mut self, update_token: TokenWithSpan) -> Result<Statement, ParserError> {
1576215765
let or = self.parse_conflict_clause();
1576315766
let table = self.parse_table_and_joins()?;
1576415767
let from_before_set = if self.parse_keyword(Keyword::FROM) {
@@ -15793,6 +15796,7 @@ impl<'a> Parser<'a> {
1579315796
None
1579415797
};
1579515798
Ok(Update {
15799+
update_token: update_token.into(),
1579615800
table,
1579715801
assignments,
1579815802
from,

tests/sqlparser_common.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ use sqlparser::dialect::{
3939
};
4040
use sqlparser::keywords::{Keyword, ALL_KEYWORDS};
4141
use sqlparser::parser::{Parser, ParserError, ParserOptions};
42-
use sqlparser::tokenizer::Tokenizer;
43-
use sqlparser::tokenizer::{Location, Span};
42+
use sqlparser::tokenizer::{Location, Span, TokenWithSpan};
43+
use sqlparser::tokenizer::{Token, Tokenizer};
4444
use test_utils::{
4545
all_dialects, all_dialects_where, all_dialects_with_options, alter_table_op, assert_eq_vec,
4646
call, expr_from_projection, join, number, only, table, table_alias, table_from_name,
@@ -456,6 +456,10 @@ fn parse_update_set_from() {
456456
assert_eq!(
457457
stmt,
458458
Statement::Update(Update {
459+
update_token: AttachedToken(TokenWithSpan {
460+
token: Token::make_keyword("UPDATE"),
461+
span: Span::new((1, 1).into(), (1, 7).into()),
462+
}),
459463
table: TableWithJoins {
460464
relation: table_from_name(ObjectName::from(vec![Ident::new("t1")])),
461465
joins: vec![],
@@ -551,6 +555,7 @@ fn parse_update_with_table_alias() {
551555
returning,
552556
or: None,
553557
limit: None,
558+
update_token,
554559
}) => {
555560
assert_eq!(
556561
TableWithJoins {
@@ -599,6 +604,13 @@ fn parse_update_with_table_alias() {
599604
selection
600605
);
601606
assert_eq!(None, returning);
607+
assert_eq!(
608+
AttachedToken(TokenWithSpan {
609+
token: Token::make_keyword("UPDATE"),
610+
span: Span::new((1, 1).into(), (1, 7).into()),
611+
}),
612+
update_token
613+
);
602614
}
603615
_ => unreachable!(),
604616
}

tests/sqlparser_mysql.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use sqlparser::ast::MysqlInsertPriority::{Delayed, HighPriority, LowPriority};
2626
use sqlparser::ast::*;
2727
use sqlparser::dialect::{GenericDialect, MySqlDialect};
2828
use sqlparser::parser::{ParserError, ParserOptions};
29-
use sqlparser::tokenizer::Span;
3029
use sqlparser::tokenizer::Token;
30+
use sqlparser::tokenizer::{Span, TokenWithSpan};
3131
use test_utils::*;
3232

3333
#[macro_use]
@@ -2632,6 +2632,7 @@ fn parse_update_with_joins() {
26322632
returning,
26332633
or: None,
26342634
limit: None,
2635+
update_token,
26352636
}) => {
26362637
assert_eq!(
26372638
TableWithJoins {
@@ -2706,6 +2707,13 @@ fn parse_update_with_joins() {
27062707
selection
27072708
);
27082709
assert_eq!(None, returning);
2710+
assert_eq!(
2711+
AttachedToken(TokenWithSpan {
2712+
token: Token::make_keyword("UPDATE"),
2713+
span: Span::new((1, 1).into(), (1, 7).into()),
2714+
}),
2715+
update_token
2716+
);
27092717
}
27102718
_ => unreachable!(),
27112719
}

tests/sqlparser_sqlite.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#[macro_use]
2323
mod test_utils;
2424

25+
use sqlparser::ast::helpers::attached_token::AttachedToken;
2526
use sqlparser::keywords::Keyword;
2627
use test_utils::*;
2728

@@ -30,7 +31,7 @@ use sqlparser::ast::Value::Placeholder;
3031
use sqlparser::ast::*;
3132
use sqlparser::dialect::{GenericDialect, SQLiteDialect};
3233
use sqlparser::parser::{ParserError, ParserOptions};
33-
use sqlparser::tokenizer::Token;
34+
use sqlparser::tokenizer::{Span, Token, TokenWithSpan};
3435

3536
#[test]
3637
fn pragma_no_value() {
@@ -494,7 +495,11 @@ fn parse_update_tuple_row_values() {
494495
},
495496
from: None,
496497
returning: None,
497-
limit: None
498+
limit: None,
499+
update_token: AttachedToken(TokenWithSpan {
500+
token: Token::make_keyword("UPDATE"),
501+
span: Span::new((1, 1).into(), (1, 7).into())
502+
})
498503
})
499504
);
500505
}

0 commit comments

Comments
 (0)