|
24 | 24 | from collections.abc import Iterator |
25 | 25 | from typing import Any, cast, TYPE_CHECKING |
26 | 26 |
|
| 27 | +import sqlglot |
27 | 28 | import sqlparse |
28 | 29 | from flask_babel import gettext as __ |
29 | 30 | from jinja2 import nodes |
30 | 31 | from sqlalchemy import and_ |
31 | 32 | from sqlglot.dialects.dialect import Dialects |
| 33 | +from sqlglot.errors import ParseError |
32 | 34 | from sqlparse import keywords |
33 | 35 | from sqlparse.lexer import Lexer |
34 | 36 | from sqlparse.sql import ( |
|
42 | 44 | Where, |
43 | 45 | ) |
44 | 46 | from sqlparse.tokens import ( |
45 | | - Comment, |
46 | 47 | CTE, |
47 | 48 | DDL, |
48 | 49 | DML, |
@@ -257,6 +258,7 @@ def __init__( |
257 | 258 | sql_statement: str, |
258 | 259 | engine: str = "base", |
259 | 260 | ): |
| 261 | + sql_statement = sqlglot.transpile(sql_statement) |
260 | 262 | self.sql: str = sql_statement |
261 | 263 | self._engine = engine |
262 | 264 | self._dialect = SQLGLOT_DIALECTS.get(engine) if engine else None |
@@ -579,30 +581,35 @@ def set_or_update_query_limit(self, new_limit: int, force: bool = False) -> str: |
579 | 581 |
|
580 | 582 | def sanitize_clause(clause: str) -> str: |
581 | 583 | # clause = sqlparse.format(clause, strip_comments=True) |
582 | | - statements = sqlparse.parse(clause) |
| 584 | + try: |
| 585 | + statements = sqlglot.transpile(clause, pretty=True) |
| 586 | + except Exception as p_err: |
| 587 | + if isinstance(p_err, ParseError): |
| 588 | + raise QueryClauseValidationException(str(p_err)) from p_err |
| 589 | + raise ValueError(str(p_err)) from None |
583 | 590 | if len(statements) != 1: |
584 | 591 | raise QueryClauseValidationException("Clause contains multiple statements") |
585 | | - open_parens = 0 |
586 | | - |
587 | | - previous_token = None |
588 | | - for token in statements[0]: |
589 | | - if token.value == "/" and previous_token and previous_token.value == "*": |
590 | | - raise QueryClauseValidationException("Closing unopened multiline comment") |
591 | | - if token.value == "*" and previous_token and previous_token.value == "/": |
592 | | - raise QueryClauseValidationException("Unclosed multiline comment") |
593 | | - if token.value in (")", "("): |
594 | | - open_parens += 1 if token.value == "(" else -1 |
595 | | - if open_parens < 0: |
596 | | - raise QueryClauseValidationException( |
597 | | - "Closing unclosed parenthesis in filter clause" |
598 | | - ) |
599 | | - previous_token = token |
600 | | - if open_parens > 0: |
601 | | - raise QueryClauseValidationException("Unclosed parenthesis in filter clause") |
602 | | - |
603 | | - if previous_token and previous_token.ttype in Comment: |
604 | | - if previous_token.value[-1] != "\n": |
605 | | - clause = f"{clause}\n" |
| 592 | + # open_parens = 0 |
| 593 | + |
| 594 | + # previous_token = None |
| 595 | + # for token in statements[0]: |
| 596 | + # if token.value == "/" and previous_token and previous_token.value == "*": |
| 597 | + # raise QueryClauseValidationException("Closing unopened multiline comment") |
| 598 | + # if token.value == "*" and previous_token and previous_token.value == "/": |
| 599 | + # raise QueryClauseValidationException("Unclosed multiline comment") |
| 600 | + # if token.value in (")", "("): |
| 601 | + # open_parens += 1 if token.value == "(" else -1 |
| 602 | + # if open_parens < 0: |
| 603 | + # raise QueryClauseValidationException( |
| 604 | + # "Closing unclosed parenthesis in filter clause" |
| 605 | + # ) |
| 606 | + # previous_token = token |
| 607 | + # if open_parens > 0: |
| 608 | + # raise QueryClauseValidationException("Unclosed parenthesis in filter clause") |
| 609 | + |
| 610 | + # if previous_token and previous_token.ttype in Comment: |
| 611 | + # if previous_token.value[-1] != "\n": |
| 612 | + # clause = f"{clause}\n" |
606 | 613 |
|
607 | 614 | return clause |
608 | 615 |
|
|
0 commit comments