Skip to content

Commit aadda6b

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 897eb2d commit aadda6b

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

sqlparse/engine/statement_splitter.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ def _change_splitlevel(self, ttype, value):
6767
(ttype is T.Keyword or ttype is T.Name) and \
6868
unified in ('TRANSACTION', 'WORK', 'TRAN',
6969
'DISTRIBUTED', 'DEFERRED',
70-
'IMMEDIATE', 'EXCLUSIVE'):
70+
'IMMEDIATE', 'EXCLUSIVE',
71+
'ISOLATION', 'READ'):
7172
self._begin_depth = max(0, self._begin_depth - 1)
7273
self._seen_begin = False
7374
return 0

tests/test_split.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,31 @@ def test_split_begin_transaction_formatted(): # issue826
284284
assert stmts[1].startswith('DELETE')
285285
assert stmts[2].startswith('INSERT')
286286
assert stmts[3] == 'END\nTRANSACTION;'
287+
288+
289+
# https://github.com/andialbrecht/sqlparse/issues/843
290+
def test_split_begin_read_write():
291+
# Redshift BEGIN READ WRITE should not be treated as a block start
292+
sql = """BEGIN READ WRITE;
293+
DELETE FROM schema.table_a USING table_a_temp
294+
WHERE schema.table_a.id = table_a_temp.id;
295+
INSERT INTO schema.table_a SELECT * FROM table_a_temp;
296+
END TRANSACTION;"""
297+
stmts = sqlparse.split(sql)
298+
assert len(stmts) == 4
299+
assert stmts[0] == 'BEGIN READ WRITE;'
300+
assert stmts[1].startswith('DELETE')
301+
assert stmts[2].startswith('INSERT')
302+
assert stmts[3] == 'END TRANSACTION;'
303+
304+
305+
# https://github.com/andialbrecht/sqlparse/issues/843
306+
def test_split_begin_isolation_level_read_only():
307+
sql = """BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY;
308+
SELECT 1;
309+
END TRANSACTION;"""
310+
stmts = sqlparse.split(sql)
311+
assert len(stmts) == 3
312+
assert stmts[0] == 'BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY;'
313+
assert stmts[1] == 'SELECT 1;'
314+
assert stmts[2] == 'END TRANSACTION;'

0 commit comments

Comments
 (0)