Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Regression for READ WRITE syntax in Redshift starting from 0.5.4 version #843

Copy link
Copy link

Description

@divaltor
Issue body actions

Describe the bug

sqlparse.split() does not correctly split Redshift transaction blocks that use BEGIN READ WRITE

This is still reproducible in sqlparse==0.5.5. It looks similar to the BEGIN TRANSACTION regression fixed after 0.5.4 in #826, but BEGIN READ WRITE remains affected

Appreciate for help

To Reproduce

import sqlparse

sql = """
BEGIN READ WRITE;
DELETE FROM schema.table_a USING table_a_temp
WHERE schema.table_a.id = table_a_temp.id;
INSERT INTO schema.table_a SELECT * FROM table_a_temp;
END TRANSACTION;
"""

statements = sqlparse.split(sql)

print(f'Statements found: {len(statements)}')
for idx, stmt in enumerate(statements, 1):
    print(f'{idx}: {stmt}')

Output from 0.5.3 version:

❯ uv run --with sqlparse==0.5.3 python
Python 3.12.8 (main, Jan  5 2025, 06:55:30) [Clang 19.1.6 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlparse
>>>
>>> sql = """
... BEGIN READ WRITE;
... DELETE FROM schema.table_a USING table_a_temp
... WHERE schema.table_a.id = table_a_temp.id;
... INSERT INTO schema.table_a SELECT * FROM table_a_temp;
... END TRANSACTION;
... """
>>>
>>> statements = sqlparse.split(sql)
>>>
>>> print(f'Statements found: {len(statements)}')
Statements found: 4
>>> for idx, stmt in enumerate(statements, 1):
...     print(f'{idx}: {stmt}')
...
1: BEGIN READ WRITE;
2: DELETE FROM schema.table_a USING table_a_temp
WHERE schema.table_a.id = table_a_temp.id;
3: INSERT INTO schema.table_a SELECT * FROM table_a_temp;
4: END TRANSACTION;
>>>

Output from 0.5.4 and 0.5.5 version:

❯ uv run --with sqlparse==0.5.4 python
Python 3.12.8 (main, Jan  5 2025, 06:55:30) [Clang 19.1.6 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlparse
>>>
>>> sql = """
... BEGIN READ WRITE;
... DELETE FROM schema.table_a USING table_a_temp
... WHERE schema.table_a.id = table_a_temp.id;
... INSERT INTO schema.table_a SELECT * FROM table_a_temp;
... END TRANSACTION;
... """
>>>
>>> statements = sqlparse.split(sql)
>>>
>>> print(f'Statements found: {len(statements)}')
Statements found: 1
>>> for idx, stmt in enumerate(statements, 1):
...     print(f'{idx}: {stmt}')
...
1: BEGIN READ WRITE;
DELETE FROM schema.table_a USING table_a_temp
WHERE schema.table_a.id = table_a_temp.id;
INSERT INTO schema.table_a SELECT * FROM table_a_temp;
END TRANSACTION;
>>>

Expected behavior

With sqlparse==0.5.5, this returns 1 statement containing the whole block.

Related variants:

BEGIN READ WRITE;
SELECT 1;
END;

also returns 1 statement in 0.5.5.

Expected behavior sqlparse.split() should split the block into individual statements:

1. BEGIN READ WRITE;
2. DELETE ...
3. INSERT ...
4. END TRANSACTION;

Additional context

According to Redshift documentation it's valid syntax, but it's broken since 0.5.4 version - https://docs.aws.amazon.com/redshift/latest/dg/r_BEGIN.html

Version BEGIN TRANSACTION BEGIN READ WRITE
0.5.1 OK OK
0.5.2 OK OK
0.5.3 OK OK
0.5.4 broken broken
0.5.5 fixed still broken
Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.