Conversation
f964516 to
bbed5cc
Compare
|
Thanks for the pull request. I have to take some time to digest it, as it's quite a mouthful. I totally understand why this change might be quite a large one. Well.. I personally had put that one aside as an unfixable one with the current architecture. An initial glance at the code tells me that it contains lots of code to tackle various specific cases. That in turn leads me to the initial conclusion that this whole thing is likely very fragile. That is, it's not some sort of generic fix for this whole problem, but rather it's a set of patches for the problem in various scenarios that occurred to the author, with lots of other scenarios to be patched up in the future. In general I'm reluctant to take aboard such a large piece of code which in its essence is one big hack. Don't take this personally, I very much believe that it might not really be possible to fix it in any non-hack way. I'm OK with small hacks to correct some shortcomings in this fundamentally flawed SQL Formatter library. But I'd like to avoid big hacks that can become a burden to maintain. Instead I like directing people into using prettier-plugin-sql-cst, which is built on top of a proper SQL parser, or to use conditional comments to disable the formatter for parts of code it can't handle. Anyway, these are just my very initial thoughts. I'm planning to have a more proper look at this, and then give my full verdict. |
|
Yeah, that's a fair read. It is a pile of positional special cases, and each new One thing on the size: an If you want it smaller I'll cut it to |
|
Hey, that sounds like a great plan. I think fixing the |
Some dialects allow reserved words as aliases, as in `SELECT id AS set FROM tbl`. The word is tokenized as a RESERVED_* token and the parser then reads it as the start of a clause, so the formatter breaks the line and reindents. Directly after AS a reserved word can only be an alias name, so convert it to IDENTIFIER there. Only the token types that cannot legitimately follow AS are converted, leaving `CREATE TABLE t AS SELECT ...` and `PREPARE foo AS UPDATE ...` working. The bare alias form, as in `FROM pg_settings set`, needs statement position tracking and is not covered here. Refs sql-formatter-org#801
bbed5cc to
bcd3a42
Compare
|
Cut down, pushed as bcd3a42. The PR is now 82 added lines across 3 files, down from 275, and the The positional tracking is gone entirely. What is left is const keywordAliasAfterAs = (token: Token, i: number, tokens: Token[]): Token => {
if (canBeAliasAfterAs(token)) {
const prevToken = prevNonCommentToken(tokens, i);
if (prevToken && isAsKeyword(prevToken)) {
return { ...token, type: TokenType.IDENTIFIER, text: token.raw };
}
}
return token;
};No paren stack, no clause tracking, no new helpers. The rest of the 45 source lines is The bare alias form is not covered, as agreed. Full suite is green, 5866 passing, plus eslint and prettier. New tests are the Happy to drop the |
Cut down to the
AS-only rule, per the discussion below. The previous version tracked statementposition to also fix the bare alias form; that machinery is gone.
A reserved word used as an alias breaks the formatter. In
SELECT id AS set FROM tblthesettoken is classified as the start of a
SETclause, so a clause appears where the parser does notexpect one.
Directly after
AS, a reserved word can only be an alias name.keywordAliasAfterAsconverts it toIDENTIFIER, and joins the existingdisambiguateTokenspipeline alongside the five neighbour-localpasses, which are unchanged.
Only the token types that cannot legitimately follow
ASare converted.RESERVED_CLAUSEisexcluded apart from
SET, soCREATE TABLE t AS SELECT ...,... AS VALUES (...)andPREPARE foo AS UPDATE ...keep working. Data types are excluded for the same reason.Not covered: the bare alias form, as in
LEFT JOIN pg_settings set ON set.name = $9. A bare aliasneeds to know where it sits in the statement, which is the positional tracking this version drops.
Anyone hitting that case can add
AS.Tests: the
ASalias in the shared suite, the two PostgreSQL forms from the issue, and a regressioncheck that
SETstill starts a clause after an alias, as inUPDATE tbl AS set SET x = 1.Refs #801