Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ install_requires =
pydantic[dotenv]>=1.8.2,<3.0.0
python-dateutil>=2.8.2
readerwriterlock>=1.0.9
sqlparse@git+https://github.com/lorenzhs/sqlparse.git@8d379386c1c3e103ee67ef6582ea1b7c2296aa5b
sqlparse>=0.5.5
Comment thread
lorenzhs marked this conversation as resolved.
Outdated
trio>=0.22.0
truststore>=0.10;python_version>="3.10"
python_requires = >=3.9
Expand Down
76 changes: 76 additions & 0 deletions src/firebolt/common/statement_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
from typing import Dict, List, Optional, Sequence, Union

from sqlparse import parse as parse_sql # type: ignore
from sqlparse import tokens as _T
from sqlparse.engine.statement_splitter import (
StatementSplitter as _StatementSplitter,
)
from sqlparse.sql import ( # type: ignore
Comment,
Comparison,
Expand All @@ -22,6 +26,78 @@
NotSupportedError,
)


def _patched_change_splitlevel(self, ttype, value): # type: ignore[no-untyped-def]

Check failure on line 30 in src/firebolt/common/statement_formatter.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 23 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=firebolt-db_firebolt-python-sdk&issues=AZ0baxlfyHdV9D4UJdMc&open=AZ0baxlfyHdV9D4UJdMc&pullRequest=494
"""Patched version of StatementSplitter._change_splitlevel.

Fixes CASE...END level tracking outside of CREATE blocks.
See: https://github.com/andialbrecht/sqlparse/pull/839
"""
if ttype is _T.Punctuation and value == "(":
return 1
elif ttype is _T.Punctuation and value == ")":
return -1
elif ttype not in _T.Keyword:
return 0

unified = value.upper()

if ttype is _T.Keyword.DDL and unified.startswith("CREATE"):
self._is_create = True
return 0

if unified == "DECLARE" and self._is_create and self._begin_depth == 0:
self._in_declare = True
return 1

if unified == "BEGIN":
self._begin_depth += 1
self._seen_begin = True
if self._is_create:
return 1
return 0

if (
self._seen_begin
and (ttype is _T.Keyword or ttype is _T.Name)
and unified
in (
"TRANSACTION",
"WORK",
"TRAN",
"DISTRIBUTED",
"DEFERRED",
"IMMEDIATE",
"EXCLUSIVE",
)
):
self._begin_depth = max(0, self._begin_depth - 1)
self._seen_begin = False
return 0

if unified == "END":
if not self._in_case:
self._begin_depth = max(0, self._begin_depth - 1)
else:
self._in_case = False
return -1

if unified == "CASE":
self._in_case = True
return 1

if unified in ("IF", "FOR", "WHILE") and self._is_create and self._begin_depth > 0:
return 1

if unified in ("END IF", "END FOR", "END WHILE"):
return -1

return 0


setattr(_StatementSplitter, "_change_splitlevel", _patched_change_splitlevel)


escape_chars_v2 = {
"\0": "\\0",
"'": "''",
Expand Down
Loading