Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 27 additions & 58 deletions src/dialect/mssql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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<Result<Statement, ParserError>> {
Expand Down Expand Up @@ -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 }
Expand Down
7 changes: 7 additions & 0 deletions tests/sqlparser_mssql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]");
}
Loading