Skip to content

Keep SET/VALUES clauses after reserved-word aliases - #972

Open
cpruijsen wants to merge 2 commits into
sql-formatter-org:masterfrom
cpruijsen:fix/issue-801
Open

cpruijsen wants to merge 2 commits into
sql-formatter-org:masterfrom
cpruijsen:fix/issue-801

Conversation

@cpruijsen

Copy link
Copy Markdown

A reserved word used as an alias crashes the formatter. SELECT a AS set FROM t and the same with
values are the reported cases: the token is classified as the start of a SET or VALUES clause, a
clause appears where the parser does not expect one, and formatting throws.

disambiguateTokens in src/lexer/disambiguateTokens.ts reclassified keywords by looking at
immediate neighbours, one token either side. That is enough for the cases it already handled, a
property name after a dot or a function name before a paren, and not enough here: whether SET starts
a clause depends on where you are in the statement, not on what is next to it.

The new pass tracks that context. It follows the last clause-starting token, knows when an
UPDATE/INSERT/REPLACE/ALTER is still expecting its target object name, which is the position
where a following SET or VALUES genuinely starts a clause, and treats a reserved word after AS
as an alias. Paren depth is tracked separately, so WITH x AS (UPDATE t SET y = 1) SELECT ... keeps
the inner context distinct from the outer one.

That is why the diff is larger than the bug suggests: the existing passes are neighbour-local by
construction, so there was nowhere to add a positional rule without introducing the notion of
position. The five existing passes are unchanged and still run.

Tests cover both reported words as aliases, the clause forms that must keep working, and the nested
case.

Fixes #801

Some dialects like PostgreSQL and DB2 allow reserved words to be used
as aliases. This crashed the parser, as reserved words were not valid
identifier names in the grammar.

Fixes sql-formatter-org#801
Look behind at already-rewritten tokens so UPDATE set SET and
INSERT INTO set VALUES still start a clause. Only treat SET as an
alias after AS, so CREATE TABLE AS WITH and PREPARE AS UPDATE keep
working.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reserved words used as aliases cause a crash

1 participant