Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions sqlparse/filters/aligned_indent.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,23 +68,36 @@ def _process_identifierlist(self, tlist):
def _process_case(self, tlist):
offset_ = len('case ') + len('when ')
cases = tlist.get_cases(skip_ws=True)
# align the end as well
# align the end as well (skip when END is missing or nested)
end_token = tlist.token_next_by(m=(T.Keyword, 'END'))[1]
# END is missing on malformed input, e.g. when an inner BEGIN ... END
# block closed the CASE.
if end_token is not None:
cases.append((None, [end_token]))
if not cases:
return

condition_width = [len(' '.join(map(str, cond))) if cond else 0
for cond, _ in cases]
max_cond_width = max(condition_width, default=0)

for i, (cond, value) in enumerate(cases):
# cond is None when 'else or end'
stmt = cond[0] if cond else value[0]
if cond:
stmt = cond[0]
elif value:
stmt = value[0]
else:
continue
if stmt is None:
continue

if i > 0:
tlist.insert_before(stmt, self.nl(offset_ - len(str(stmt))))
try:
tlist.insert_before(stmt, self.nl(offset_ - len(str(stmt))))
except ValueError:
# Token is not a direct child (malformed CASE) — leave as-is.
continue
if cond:
ws = sql.Token(T.Whitespace, self.char * (
max_cond_width - condition_width[i]))
Expand Down
6 changes: 6 additions & 0 deletions tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,12 @@ def test_window_functions(self):
' from table'])



def test_malformed_case_does_not_raise(self):
# issue #886
sql = "CASE 'a' := WHERE END SELECT GO # ->>"
assert isinstance(self.formatter(sql), str)

class TestSpacesAroundOperators:
@staticmethod
def formatter(sql):
Expand Down
9 changes: 9 additions & 0 deletions tests/test_regressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,12 @@ def test_max_recursion(limit_recursion):
])
def test_format_malformed_input_does_not_crash(sql, options):
assert isinstance(sqlparse.format(sql, **options), str)


def test_reindent_aligned_malformed_case_no_valueerror_issue886():
# Malformed CASE where END is nested inside an assignment group used to
# raise ValueError from token_index(None) inside AlignedIndentFilter.
sql = "CASE 'a' := WHERE END SELECT GO # ->>"
out = sqlparse.format(sql, reindent_aligned=True)
assert isinstance(out, str)
assert 'CASE' in out