feat: Include end token in ALTER TABLE statement (#1999)

Co-authored-by: Ifeanyi Ubah <ify1992@yahoo.com>
This commit is contained in:
Tyler White 2025-08-09 02:31:58 -04:00 committed by GitHub
parent 27544f9343
commit 356308b348
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 31 additions and 1 deletions

View file

@ -3384,6 +3384,8 @@ pub enum Statement {
/// Snowflake "ICEBERG" clause for Iceberg tables /// Snowflake "ICEBERG" clause for Iceberg tables
/// <https://docs.snowflake.com/en/sql-reference/sql/alter-iceberg-table> /// <https://docs.snowflake.com/en/sql-reference/sql/alter-iceberg-table>
iceberg: bool, iceberg: bool,
/// Token that represents the end of the statement (semicolon or EOF)
end_token: AttachedToken,
}, },
/// ```sql /// ```sql
/// ALTER INDEX /// ALTER INDEX
@ -5442,6 +5444,7 @@ impl fmt::Display for Statement {
location, location,
on_cluster, on_cluster,
iceberg, iceberg,
end_token: _,
} => { } => {
if *iceberg { if *iceberg {
write!(f, "ALTER ICEBERG TABLE ")?; write!(f, "ALTER ICEBERG TABLE ")?;

View file

@ -435,10 +435,12 @@ impl Spanned for Statement {
location: _, location: _,
on_cluster, on_cluster,
iceberg: _, iceberg: _,
end_token,
} => union_spans( } => union_spans(
core::iter::once(name.span()) core::iter::once(name.span())
.chain(operations.iter().map(|i| i.span())) .chain(operations.iter().map(|i| i.span()))
.chain(on_cluster.iter().map(|i| i.span)), .chain(on_cluster.iter().map(|i| i.span))
.chain(core::iter::once(end_token.0.span)),
), ),
Statement::AlterIndex { name, operation } => name.span().union(&operation.span()), Statement::AlterIndex { name, operation } => name.span().union(&operation.span()),
Statement::AlterView { Statement::AlterView {
@ -2553,4 +2555,20 @@ pub mod tests {
stmt => panic!("expected query; got {stmt:?}"), stmt => panic!("expected query; got {stmt:?}"),
} }
} }
#[test]
fn test_alter_table_multiline_span() {
let sql = r#"-- foo
ALTER TABLE users
ADD COLUMN foo
varchar; -- hi there"#;
let r = Parser::parse_sql(&crate::dialect::PostgreSqlDialect {}, sql).unwrap();
assert_eq!(1, r.len());
let stmt_span = r[0].span();
assert_eq!(stmt_span.start, (2, 13).into());
assert_eq!(stmt_span.end, (4, 11).into());
}
} }

View file

@ -9263,6 +9263,12 @@ impl<'a> Parser<'a> {
}); });
} }
let end_token = if self.peek_token_ref().token == Token::SemiColon {
self.peek_token_ref().clone()
} else {
self.get_current_token().clone()
};
Ok(Statement::AlterTable { Ok(Statement::AlterTable {
name: table_name, name: table_name,
if_exists, if_exists,
@ -9271,6 +9277,7 @@ impl<'a> Parser<'a> {
location, location,
on_cluster, on_cluster,
iceberg, iceberg,
end_token: AttachedToken(end_token),
}) })
} }

View file

@ -351,6 +351,7 @@ pub fn alter_table_op_with_name(stmt: Statement, expected_name: &str) -> AlterTa
on_cluster: _, on_cluster: _,
location: _, location: _,
iceberg, iceberg,
end_token: _,
} => { } => {
assert_eq!(name.to_string(), expected_name); assert_eq!(name.to_string(), expected_name);
assert!(!if_exists); assert!(!if_exists);

View file

@ -2643,6 +2643,7 @@ fn parse_alter_table_add_column() {
iceberg, iceberg,
location: _, location: _,
on_cluster: _, on_cluster: _,
end_token: _,
} => { } => {
assert_eq!(name.to_string(), "tab"); assert_eq!(name.to_string(), "tab");
assert!(!if_exists); assert!(!if_exists);