From 3e0bae24890fcec3e99f0991017a04a1377e3513 Mon Sep 17 00:00:00 2001 From: LucaCappelletti94 Date: Sun, 25 Oct 2026 18:40:48 +0100 Subject: [PATCH] MSSQL: Share alias keyword exclusions --- src/dialect/mssql.rs | 85 +++++++++++++--------------------------- tests/sqlparser_mssql.rs | 7 ++++ 2 files changed, 34 insertions(+), 58 deletions(-) diff --git a/src/dialect/mssql.rs b/src/dialect/mssql.rs index 9808eec0fd..98f660d7e2 100644 --- a/src/dialect/mssql.rs +++ b/src/dialect/mssql.rs @@ -138,33 +138,7 @@ impl Dialect for MsSqlDialect { } fn is_select_item_alias(&self, explicit: bool, kw: &Keyword, parser: &mut Parser) -> bool { - match kw { - // List of keywords that cannot be used as select item (column) aliases in MSSQL - // regardless of whether the alias is explicit or implicit. - // - // These are T-SQL statement-starting keywords; allowing them as implicit aliases - // causes the parser to consume the keyword as an alias for the previous expression, - // then fail on the token that follows (e.g. `TABLE`, `@var`, `sp_name`, …). - Keyword::IF - | Keyword::ELSE - | Keyword::DECLARE - | Keyword::EXEC - | Keyword::EXECUTE - | Keyword::INSERT - | Keyword::UPDATE - | Keyword::DELETE - | Keyword::DROP - | Keyword::CREATE - | Keyword::ALTER - | Keyword::TRUNCATE - | Keyword::PRINT - | Keyword::WHILE - | Keyword::RETURN - | Keyword::THROW - | Keyword::RAISERROR - | Keyword::MERGE => false, - _ => explicit || self.is_column_alias(kw, parser), - } + !Self::is_reserved_for_alias(kw) && (explicit || self.is_column_alias(kw, parser)) } /// LIMIT is not a reserved word in Transact-SQL. @@ -174,37 +148,7 @@ impl Dialect for MsSqlDialect { } fn is_table_factor_alias(&self, explicit: bool, kw: &Keyword, parser: &mut Parser) -> bool { - match kw { - // List of keywords that cannot be used as table aliases in MSSQL - // regardless of whether the alias is explicit or implicit. - // - // These are T-SQL statement-starting keywords. Without blocking them here, - // a bare `SELECT * FROM t` followed by a newline and one of these keywords - // would cause the parser to consume the keyword as a table alias for `t`, - // then fail on the token that follows (e.g. `@var`, `sp_name`, `TABLE`, …). - // - // `SET` is already covered by the global `RESERVED_FOR_TABLE_ALIAS` list; - // the keywords below are MSSQL-specific additions. - Keyword::IF - | Keyword::ELSE - | Keyword::DECLARE - | Keyword::EXEC - | Keyword::EXECUTE - | Keyword::INSERT - | Keyword::UPDATE - | Keyword::DELETE - | Keyword::DROP - | Keyword::CREATE - | Keyword::ALTER - | Keyword::TRUNCATE - | Keyword::PRINT - | Keyword::WHILE - | Keyword::RETURN - | Keyword::THROW - | Keyword::RAISERROR - | Keyword::MERGE => false, - _ => explicit || self.is_table_alias(kw, parser), - } + !Self::is_reserved_for_alias(kw) && (explicit || self.is_table_alias(kw, parser)) } fn parse_statement(&self, parser: &mut Parser) -> Option> { @@ -261,6 +205,31 @@ impl Dialect for MsSqlDialect { } impl MsSqlDialect { + /// Keywords excluded from explicit and implicit aliases. + fn is_reserved_for_alias(kw: &Keyword) -> bool { + matches!( + kw, + Keyword::IF + | Keyword::ELSE + | Keyword::DECLARE + | Keyword::EXEC + | Keyword::EXECUTE + | Keyword::INSERT + | Keyword::UPDATE + | Keyword::DELETE + | Keyword::DROP + | Keyword::CREATE + | Keyword::ALTER + | Keyword::TRUNCATE + | Keyword::PRINT + | Keyword::WHILE + | Keyword::RETURN + | Keyword::THROW + | Keyword::RAISERROR + | Keyword::MERGE + ) + } + /// ```sql /// IF boolean_expression /// { sql_statement | statement_block } diff --git a/tests/sqlparser_mssql.rs b/tests/sqlparser_mssql.rs index 62f3a53efd..23388bd15a 100644 --- a/tests/sqlparser_mssql.rs +++ b/tests/sqlparser_mssql.rs @@ -3019,3 +3019,10 @@ fn parse_mssql_declare_comma_list_display() { ms().verified_stmt("DECLARE @a INT = 1, @b TEXT = 'x'"); ms().verified_stmt("DECLARE @foo CURSOR, @bar INT"); } + +#[test] +fn parse_quoted_statement_keyword_aliases() { + ms().one_statement_parses_to("SELECT 1 [PRINT]", "SELECT 1 AS [PRINT]"); + ms().verified_stmt("SELECT * FROM t [PRINT]"); + ms().verified_stmt("SELECT * FROM t AS [PRINT]"); +}