Skip to content

Commit 0bb6ae8

Browse files
committed
Fix BEGIN READ WRITE regression for Redshift syntax
Redshift allows BEGIN with transaction mode modifiers such as READ WRITE or ISOLATION LEVEL. Treat those tokens like transaction starters so split() does not mistake BEGIN for a procedural block.
1 parent c923da9 commit 0bb6ae8

2 files changed

Lines changed: 29 additions & 3 deletions

File tree

sqlparse/engine/statement_splitter.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ def _change_splitlevel(self, ttype, value):
132132
(ttype is T.Keyword or ttype is T.Name) and \
133133
unified in ('TRANSACTION', 'WORK', 'TRAN',
134134
'DISTRIBUTED', 'DEFERRED',
135-
'IMMEDIATE', 'EXCLUSIVE'):
135+
'IMMEDIATE', 'EXCLUSIVE',
136+
'ISOLATION', 'READ'):
136137
self._seen_begin = False
137138
if self._block_stack and self._block_stack[-1] == 'BEGIN':
138139
self._block_stack.pop()

tests/test_split.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,33 @@ def test_split_begin_transaction_formatted(): # issue826
285285
assert stmts[2].startswith('INSERT')
286286
assert stmts[3] == 'END\nTRANSACTION;'
287287

288+
# https://github.com/andialbrecht/sqlparse/issues/843
289+
def test_split_begin_read_write():
290+
# Redshift BEGIN READ WRITE should not be treated as a block start
291+
sql = """BEGIN READ WRITE;
292+
DELETE FROM schema.table_a USING table_a_temp
293+
WHERE schema.table_a.id = table_a_temp.id;
294+
INSERT INTO schema.table_a SELECT * FROM table_a_temp;
295+
END TRANSACTION;"""
296+
stmts = sqlparse.split(sql)
297+
assert len(stmts) == 4
298+
assert stmts[0] == 'BEGIN READ WRITE;'
299+
assert stmts[1].startswith('DELETE')
300+
assert stmts[2].startswith('INSERT')
301+
assert stmts[3] == 'END TRANSACTION;'
302+
303+
304+
# https://github.com/andialbrecht/sqlparse/issues/843
305+
def test_split_begin_isolation_level_read_only():
306+
sql = """BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY;
307+
SELECT 1;
308+
END TRANSACTION;"""
309+
stmts = sqlparse.split(sql)
310+
assert len(stmts) == 3
311+
assert stmts[0] == 'BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY;'
312+
assert stmts[1] == 'SELECT 1;'
313+
assert stmts[2] == 'END TRANSACTION;'
314+
288315

289316
def test_split_anonymous_begin_end_for(): # issue845 Case 1
290317
sql = """
@@ -372,5 +399,3 @@ def test_split_standalone_for_update():
372399
assert len(stmts) == 2
373400
assert stmts[0] == "SELECT * FROM foo FOR UPDATE;"
374401
assert stmts[1] == "SELECT 3;"
375-
376-

0 commit comments

Comments
 (0)