Skip to content

Commit 9a42c3f

Browse files
committed
feat: include end token in ALTER TABLE statement for accurate span calculation
1 parent c1648e7 commit 9a42c3f

File tree

6 files changed

+51
-1
lines changed

6 files changed

+51
-1
lines changed

src/ast/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3382,6 +3382,9 @@ pub enum Statement {
33823382
/// Snowflake "ICEBERG" clause for Iceberg tables
33833383
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-iceberg-table>
33843384
iceberg: bool,
3385+
/// Token that represents the end of the statement (semicolon or EOF)
3386+
/// Used for accurate span calculation
3387+
end_token: AttachedToken,
33853388
},
33863389
/// ```sql
33873390
/// ALTER INDEX
@@ -5419,6 +5422,7 @@ impl fmt::Display for Statement {
54195422
location,
54205423
on_cluster,
54215424
iceberg,
5425+
end_token: _,
54225426
} => {
54235427
if *iceberg {
54245428
write!(f, "ALTER ICEBERG TABLE ")?;

src/ast/spans.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,10 +434,12 @@ impl Spanned for Statement {
434434
location: _,
435435
on_cluster,
436436
iceberg: _,
437+
end_token,
437438
} => union_spans(
438439
core::iter::once(name.span())
439440
.chain(operations.iter().map(|i| i.span()))
440-
.chain(on_cluster.iter().map(|i| i.span)),
441+
.chain(on_cluster.iter().map(|i| i.span))
442+
.chain(core::iter::once(end_token.0.span)),
441443
),
442444
Statement::AlterIndex { name, operation } => name.span().union(&operation.span()),
443445
Statement::AlterView {
@@ -2548,4 +2550,20 @@ pub mod tests {
25482550
stmt => panic!("expected query; got {stmt:?}"),
25492551
}
25502552
}
2553+
2554+
#[test]
2555+
fn test_alter_table_multiline_span() {
2556+
let sql = r#"-- foo
2557+
ALTER TABLE users
2558+
ADD COLUMN foo
2559+
varchar; -- hi there"#;
2560+
2561+
let r = Parser::parse_sql(&crate::dialect::PostgreSqlDialect {}, sql).unwrap();
2562+
assert_eq!(1, r.len());
2563+
2564+
let stmt_span = r[0].span();
2565+
2566+
assert_eq!(stmt_span.start, (2, 13).into());
2567+
assert_eq!(stmt_span.end, (4, 11).into());
2568+
}
25512569
}

src/parser/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9227,6 +9227,12 @@ impl<'a> Parser<'a> {
92279227
});
92289228
}
92299229

9230+
let end_token = if self.peek_token_ref().token == Token::SemiColon {
9231+
self.peek_token_ref().clone()
9232+
} else {
9233+
self.get_current_token().clone()
9234+
};
9235+
92309236
Ok(Statement::AlterTable {
92319237
name: table_name,
92329238
if_exists,
@@ -9235,6 +9241,7 @@ impl<'a> Parser<'a> {
92359241
location,
92369242
on_cluster,
92379243
iceberg,
9244+
end_token: AttachedToken(end_token),
92389245
})
92399246
}
92409247

src/test_utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ pub fn alter_table_op_with_name(stmt: Statement, expected_name: &str) -> AlterTa
351351
on_cluster: _,
352352
location: _,
353353
iceberg,
354+
end_token: _,
354355
} => {
355356
assert_eq!(name.to_string(), expected_name);
356357
assert!(!if_exists);

tests/sqlparser_common.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4758,6 +4758,25 @@ fn parse_alter_table() {
47584758
}
47594759
}
47604760

4761+
#[test]
4762+
fn alter_table_span_includes_semicolon() {
4763+
use sqlparser::ast::Spanned;
4764+
use sqlparser::dialect::PostgreSqlDialect;
4765+
use sqlparser::parser::Parser;
4766+
4767+
let sql = r#"-- foo
4768+
ALTER TABLE users
4769+
ADD COLUMN foo
4770+
varchar; -- hi there"#;
4771+
let dialect = PostgreSqlDialect {};
4772+
let ast = Parser::parse_sql(&dialect, sql).unwrap();
4773+
let stmt = &ast[0];
4774+
let span = stmt.span();
4775+
4776+
assert_eq!(span.end.line, 4);
4777+
assert_eq!(span.end.column, 11);
4778+
}
4779+
47614780
#[test]
47624781
fn parse_rename_table() {
47634782
match verified_stmt("RENAME TABLE test.test1 TO test_db.test2") {

tests/sqlparser_mysql.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,6 +2635,7 @@ fn parse_alter_table_add_column() {
26352635
iceberg,
26362636
location: _,
26372637
on_cluster: _,
2638+
end_token: _,
26382639
} => {
26392640
assert_eq!(name.to_string(), "tab");
26402641
assert!(!if_exists);

0 commit comments

Comments
 (0)