Repository navigation
fix(pretty_print): keep comments before CASE and GRANT keywords in place - #934
Merged
Merged
Conversation
…functions break sensibly
…print-grant-admin-option
…int-long-identifiers
psteinroe
added a commit
that referenced
this pull request
Oct 26, 2026
Stacked on #934. In expanded layout, a CASE nested in the THEN of another CASE moved right by `then ` plus two indent levels per level of nesting. #884 aligns each CASE's branches with the column it starts at, and a nested CASE starts after `then `. With the default indent, twenty levels reached 184 columns at width 100. Finding P16 of the release review. **What changed** A CASE written as the result of a `THEN` or `ELSE` no longer aligns with its own column. It is indented from the line of its keyword: its branches one level in, and `END` under `THEN` or `ELSE`. Each level now costs two indents, the minimum for a WHEN and its THEN: ```sql -- layout: expanded, indentSize: 4 -- before case status when 'A' then case when enabled then 'active' else 'paused' end else 'closed' end -- after case status when 'A' then case when enabled then 'active' else 'paused' end else 'closed' end ``` `else case when ... else case ...` chains read the same way. A CASE anywhere else, after `select` or a leading comma for instance, still aligns with the column it starts at, which is what #884 was about. Fit layout doesn't align, so it is unchanged. This changes the nested layout that #884's `expanded_nested_case_keeps_each_branch_at_its_own_indent` test asserted, and the test now expects the new layout. I preferred this over breaking after `then` for every nested CASE: that would add a line and a level for every nested CASE, also the shallow ones that fit today. The docs section on expanded CASE describes the nested layout. **Tests and snapshot changes** - `case_layout.rs`: the updated nested test, a CASE nested in ELSE, and twenty levels nested in THEN staying within width 100. - The only snapshot change is the nested CASE in `expanded_case_alignment` (added in #912), whose inner branches move left to the new indent. - The option matrix passes over the fixtures and the regression suite.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #917.
Comments written before a keyword that has no AST node of its own (
ELSE,THEN,END, GRANT'sON/TO/FROM) moved past the keyword, sometimes into another branch or clause. The output was stable on reformat, so nothing flagged it, but the comment no longer sat where it was written. Finding P17 of the release review.Why they moved
Comments are attached to AST nodes by source position, and a comment that leads goes to the next node: a block comment, an own-line comment, or a comment after a clause keyword. For
'x' /* inline */ else 'y'the next node is'y', so the comment came out afterelse. A comment right aftercasedidn't count as following a clause keyword, so it trailed the whole CASE and came out after the last branch. A comment beforeendled the next node after the CASE, in the FROM clause.What changed
before_keyword). A parent that writes such a keyword before a child can take the comments written before it, withemit_comments_before_keyword, and emit them before the keyword. They are emitted like the trailing comments of the previous node, so an own-line comment keeps its own line. Only comments recorded for that exact keyword are taken. A parent that doesn't call it keeps today's placement, so nothing else moves.ELSEandTHEN. GRANT/REVOKE takes them beforeONandTO/FROM, and GRANT role beforeTO/FROM.ENDstays with the last branch: it trails the previous node instead of leading the next one, because nothing inside the CASE followsEND.CASEcounts as a clause keyword, so a line comment right after it goes before the firstWHEN.a /* cond */ then.Tests
comment_layout.rscover a comment beforeELSE,THENandEND, afterCASE, and before GRANT'sONandTO, in fit and expanded layout, each formatted twice to check idempotence.comments.rscover the attachment.Not covered
Other keyword-only positions (
ONin a join,ASbefore an alias,FROMin a SELECT, ...) keep the old placement. They can opt in the same way when needed.