Skip to content

Separate statements in reindent_aligned output (issue673) - #907

Open
adarshsm wants to merge 1 commit into
andialbrecht:masterfrom
adarshsm:fix/673-aligned-indent-statement-separator
Open

adarshsm wants to merge 1 commit into
andialbrecht:masterfrom
adarshsm:fix/673-aligned-indent-statement-separator

Conversation

@adarshsm

Copy link
Copy Markdown

Fixes #673.

The bug

sqlformat -a (format(sql, reindent_aligned=True)) runs consecutive
statements together, so the second statement starts in the middle of the last
line of the first:

>>> sqlparse.format('select * from a;\nselect * from b;\n', reindent_aligned=True)
'select *\n  from a;select *\n  from b;'

Printed:

select *
  from a;select *
  from b;

reindent=True on the same input does the right thing:

>>> sqlparse.format('select * from a;\nselect * from b;\n', reindent=True)
'select *\nfrom a;\n\n\nselect *\nfrom b;'

Root cause

reindent_aligned turns on strip_whitespace (formatter.py), so by the time
AlignedIndentFilter runs, the whitespace that separated one statement from
the next has already been removed — and AlignedIndentFilter._process_statement
pops any remaining leading whitespace as well.

ReindentFilter.process() already compensates for exactly this, re-inserting a
newline before every statement after the first:

if self._last_stmt is not None:
    nl = '\n' if str(self._last_stmt).endswith('\n') else '\n\n'
    stmt.tokens.insert(0, sql.Token(T.Whitespace, nl))
self._last_stmt = stmt

AlignedIndentFilter.process() had no such step, so nothing put a separator
back.

The fix

Apply the same separator logic in AlignedIndentFilter.process(), reusing
ReindentFilter's rule so the two reindent modes agree. The filter is
constructed per format() call, so _last_stmt doesn't leak between calls —
same as in ReindentFilter.

After:

>>> sqlparse.format('select * from a;\nselect * from b;\n', reindent_aligned=True)
'select *\n  from a;\n\nselect *\n  from b;'

Single-statement output is unchanged.

Testing

  • New TestFormatReindentAligned::test_multiple_statements_are_separated;
    verified it fails on master (from t1;select b on one line) and passes
    with the fix.
  • Full suite: 507 passed, 2 xfailed, 1 xpassed. ruff check sqlparse/ clean.

reindent_aligned sets strip_whitespace, so the whitespace that separated
one statement from the next is removed before AlignedIndentFilter runs.
ReindentFilter.process() compensates by inserting a newline ahead of every
statement after the first; AlignedIndentFilter.process() did not, so
formatting a file of statements produced "... from a;select * ..." with
the second statement starting mid-line.

Insert the same separator in AlignedIndentFilter, using the rule
ReindentFilter already uses.
@adarshsm
adarshsm marked this pull request as ready for review September 22, 2026 12:11
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.

sqlformat concatenates statements together

1 participant