diff --git a/CHANGELOG b/CHANGELOG index 44d5938e..c3353bec 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,8 @@ Development Version ------------------- -Nothing yet. +* Fix statement splitting after compound blocks whose closing keywords + contain multiple spaces, tabs, or newlines. Release 0.6.0 (Aug 13, 2026) diff --git a/sqlparse/engine/statement_splitter.py b/sqlparse/engine/statement_splitter.py index bc57d170..07b19d4d 100644 --- a/sqlparse/engine/statement_splitter.py +++ b/sqlparse/engine/statement_splitter.py @@ -102,7 +102,7 @@ def _change_splitlevel(self, ttype, value): return 0 # Everything after here is ttype = T.Keyword - unified = value.upper() + unified = ' '.join(value.upper().split()) # DDL Create though can contain more words such as "or replace" if ttype is T.Keyword.DDL and unified.startswith('CREATE'): diff --git a/tests/test_split.py b/tests/test_split.py index 92c3fefe..b41399bc 100644 --- a/tests/test_split.py +++ b/tests/test_split.py @@ -374,3 +374,26 @@ def test_split_standalone_for_update(): assert stmts[1] == "SELECT 3;" +@pytest.mark.parametrize('prefix', ['', 'CREATE PROCEDURE p() ']) +@pytest.mark.parametrize('separator', [' ', ' ', '\t', '\n']) +@pytest.mark.parametrize('opening, closing', [ + ('IF 1 THEN', 'IF'), + ('FOR r DO', 'FOR'), + ('WHILE 1 DO', 'WHILE'), + ('LOOP', 'LOOP'), + ('CASE 1 WHEN 1 THEN', 'CASE'), +]) +def test_split_compound_closing_keyword_whitespace(prefix, separator, + opening, closing): + block = (f'{prefix}BEGIN\n' + f' {opening}\n' + " SELECT 'END IF';\n" + f' END{separator}{closing};\n' + 'END;') + text = block + '\nSELECT 2;\nSELECT 3;' + expected = [block, 'SELECT 2;', 'SELECT 3;'] + + assert sqlparse.split(text) == expected + assert [str(stmt).strip() for stmt in sqlparse.parse(text)] == expected + +