Repository navigation
fix(format): stop rewriting SQL and only break lines that do not fit - #849
Merged
Merged
Conversation
The formatter rewrote what was written: it dropped pg_catalog qualifiers, replaced dollar-quote tags, dropped argument names from signatures, uppercased some function and privilege names, and broke lines that fit. - Function calls keep their name as qualified, SQL-standard syntax is only used for calls the parser flagged as written in it - Function and DO bodies keep their source quoting byte for byte - Signatures are printed from objfuncargs, with names and modes - Every keyword, privilege and option name follows keywordCase - Constraint, index and other names lose redundant quotes - A group stays on one line whenever it fits, broken column definitions and constraints continue one level deeper, and parenthesized lists break inside their parentheses - CREATE INDEX keeps its head, opclasses and short predicate together - End-of-line comments after a comma stay on their line - Blank lines between statements are normalized to at most one The semantic check no longer normalizes away qualifiers, argument names, function name case, SET values or function bodies, and the regression suite now also checks that formatting is idempotent.
format --stdin-file-path=<path> reads SQL from stdin, applies the configuration for <path> and prints only the formatted SQL. Check mode now also fails for files whose only change is between statements.
Workspace.format, Workspace.formatSql and a top-level format() take the options of the format section of the configuration file.
- Merge emit_word into emit_keyword, which now spells any word in the keyword case - Measure a group's single-line form only until the line is full - Merge the emit_parenthesized_list imports into the existing ones - Print OVERLAPS operands as parenthesized lists, so they break inside the parentheses - Drop the stdin ignore check the workspace already performs
…matting Collapse blank lines with one pass over the gap and trim the start and end of the file at the call site, instead of a position-aware state machine. The layout of a reformatted SQL function body now lives in set_formatted_sql_fn_body.
- Import emit_parenthesized_list the way each file already imported node_list helpers, inline where it used full paths - Reuse emit_keywords for privilege names and emit_parenthesized_list for exclusion constraint elements - Reuse the self-contained expression check of casts for the operands of SQL-standard syntax - Spell EXTRACT fields with emit_keyword - Drop an unreachable branch for time zone types - Build the one-off WASM format workspace with createWorkspace
Instead of keeping each body's original quoting, quote every function and DO body the same way: $$, or $body$ when the body contains $$. The body itself is still written byte for byte. Without the original quoting to recover, the emitter no longer needs the statement source.
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.
The formatter rewrote SQL instead of only laying it out. It dropped
pg_catalog.qualifiers, replaced$$with$function$and trimmed function bodies, removed argument names fromALTER FUNCTION/GRANT/REVOKEsignatures, and printed some keywords and function names in uppercase underkeywordCase: lower. It also broke short column definitions and constraint lists across lines. With this PR it changes only whitespace, line breaks, keyword case and redundant quotes.Source fidelity
EXTRACT,TRIM,AT TIME ZONE,COLLATION FOR, ...) is only used when the parser flagged the call as written that way (funcformat), and those calls are now printed in that syntax instead of astimezone(...)/btrim(...).pg_catalognames the grammar creates itself, sopg_catalog.textandint4stay as written.DObodies are kept byte for byte (they were trimmed before) and always dollar-quoted with$$, or$body$when the body contains$$, instead of a tag picked per statement kind ($function$,$do$, ...).objfuncargs, which keeps argument names and modes.Stricter verification
normalize_astno longer hides the differences above. It used to strippg_catalog, lowercase function names, clear argument names andobjfuncargs, lowercaseSETvalues (SET datestyle = 'German'was printed asgerman) and trim function bodies. The Postgres regression suite test now also requiresformat(format(x)) == format(x). Every accepted statement for 15–17 passes both checks.Layout
,orover ().CREATE INDEXkeeps its head, opclasses and a shortWHEREon one line.This changes most pretty-print snapshots, mostly lines that now stay joined and function names that are no longer uppercased.
New entry points
format --stdin-file-path=<path>prints only the formatted SQL. Check mode (formatwithout--write) already exited non-zero with a diff. It now also does so when only blank lines change. Both are documented.format(sql, options)andWorkspace.format/formatSql, with options mirroring theformatconfig section.Not included: an
identifierQuoting: "preserve"option, and a configurable maximum number of blank lines (fixed at one).