From b209c680a90ec038c66a2e4d9f8dccb8468fe062 Mon Sep 17 00:00:00 2001 From: Andrey Tvorozhkov Date: Thu, 9 Feb 2023 10:13:00 +0600 Subject: [PATCH 1/5] Fix ORM missing attributes --- .../drivers/compilers/sqlcompiler.py | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py b/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py index b38d63ca..8aee4c76 100644 --- a/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py +++ b/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py @@ -3,6 +3,7 @@ WARN_LINTING, crud from sqlalchemy.sql import type_api from sqlalchemy.util import inspect_getfullargspec +import operator from ... import types @@ -11,6 +12,31 @@ class ClickHouseSQLCompiler(compiler.SQLCompiler): def visit_mod_binary(self, binary, operator, **kw): return self.process(binary.left, **kw) + ' %% ' + \ self.process(binary.right, **kw) + + def visit_select( + self, + select_stmt, + **kwargs, + ): + orig_compile_state_factory = select_stmt._compile_state_factory + + def f(self, *args, **kwargs): + tmp = orig_compile_state_factory(self, *args, **kwargs) + + # Fix missed attributes + for attr in ["_with_cube", "_with_rollup", "_with_totals", "_final_clause", "_sample_clause", "_limit_by_clause", "_array_join"]: + val = getattr(tmp.select_statement, attr, None) + + if val: + setattr(tmp.statement, attr, val) + + return tmp + + select_stmt._compile_state_factory = f + tmp_select = super().visit_select(select_stmt=select_stmt, **kwargs) + + return tmp_select + def visit_is_not_distinct_from_binary(self, binary, operator, **kw): """ @@ -482,18 +508,3 @@ def visit_not_regexp_match_op_binary(self, binary, operator, **kw): operator, **kw ) - - def visit_ilike_case_insensitive_operand(self, element, **kw): - return element.element._compiler_dispatch(self, **kw) - - def visit_ilike_op_binary(self, binary, operator, **kw): - return "%s ILIKE %s" % ( - self.process(binary.left, **kw), - self.process(binary.right, **kw) - ) - - def visit_not_ilike_op_binary(self, binary, operator, **kw): - return "%s NOT ILIKE %s" % ( - self.process(binary.left, **kw), - self.process(binary.right, **kw) - ) From 8cbc699596d04ceb7248cd33528e952d24b0f071 Mon Sep 17 00:00:00 2001 From: Andrey Tvorozhkov Date: Thu, 9 Feb 2023 10:15:48 +0600 Subject: [PATCH 2/5] Add "if" in visit_select for protection --- .../drivers/compilers/sqlcompiler.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py b/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py index 8aee4c76..f32ba595 100644 --- a/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py +++ b/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py @@ -23,12 +23,13 @@ def visit_select( def f(self, *args, **kwargs): tmp = orig_compile_state_factory(self, *args, **kwargs) - # Fix missed attributes - for attr in ["_with_cube", "_with_rollup", "_with_totals", "_final_clause", "_sample_clause", "_limit_by_clause", "_array_join"]: - val = getattr(tmp.select_statement, attr, None) + if hasattr(tmp, 'select_statement'): + # Fix missed attributes + for attr in ["_with_cube", "_with_rollup", "_with_totals", "_final_clause", "_sample_clause", "_limit_by_clause", "_array_join"]: + val = getattr(tmp.select_statement, attr, None) - if val: - setattr(tmp.statement, attr, val) + if val: + setattr(tmp.statement, attr, val) return tmp From 27d6125800455670c259d4bec9c2bb20275a59ec Mon Sep 17 00:00:00 2001 From: Andrey Tvorozhkov Date: Thu, 9 Feb 2023 10:22:35 +0600 Subject: [PATCH 3/5] Move back code from master --- .../drivers/compilers/sqlcompiler.py | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py b/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py index f32ba595..e9957f38 100644 --- a/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py +++ b/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py @@ -9,17 +9,13 @@ class ClickHouseSQLCompiler(compiler.SQLCompiler): - def visit_mod_binary(self, binary, operator, **kw): - return self.process(binary.left, **kw) + ' %% ' + \ - self.process(binary.right, **kw) - def visit_select( self, select_stmt, **kwargs, ): orig_compile_state_factory = select_stmt._compile_state_factory - + def f(self, *args, **kwargs): tmp = orig_compile_state_factory(self, *args, **kwargs) @@ -35,9 +31,12 @@ def f(self, *args, **kwargs): select_stmt._compile_state_factory = f tmp_select = super().visit_select(select_stmt=select_stmt, **kwargs) - + return tmp_select - + + def visit_mod_binary(self, binary, operator, **kw): + return self.process(binary.left, **kw) + ' %% ' + \ + self.process(binary.right, **kw) def visit_is_not_distinct_from_binary(self, binary, operator, **kw): """ @@ -509,3 +508,18 @@ def visit_not_regexp_match_op_binary(self, binary, operator, **kw): operator, **kw ) + + def visit_ilike_case_insensitive_operand(self, element, **kw): + return element.element._compiler_dispatch(self, **kw) + + def visit_ilike_op_binary(self, binary, operator, **kw): + return "%s ILIKE %s" % ( + self.process(binary.left, **kw), + self.process(binary.right, **kw) + ) + + def visit_not_ilike_op_binary(self, binary, operator, **kw): + return "%s NOT ILIKE %s" % ( + self.process(binary.left, **kw), + self.process(binary.right, **kw) + ) From 62395588bb13a5d332591b7b24fbab5f0b7663bf Mon Sep 17 00:00:00 2001 From: Andrey Tvorozhkov Date: Thu, 9 Feb 2023 10:32:56 +0600 Subject: [PATCH 4/5] Remove unused import --- clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py b/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py index e9957f38..d1011591 100644 --- a/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py +++ b/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.py @@ -3,7 +3,6 @@ WARN_LINTING, crud from sqlalchemy.sql import type_api from sqlalchemy.util import inspect_getfullargspec -import operator from ... import types From 90800654ffd9438e87d36ba10a4d78613f3242c4 Mon Sep 17 00:00:00 2001 From: Andrey Tvorozhkov Date: Thu, 9 Feb 2023 10:42:21 +0600 Subject: [PATCH 5/5] Add copy of needed flags --- clickhouse_sqlalchemy/orm/query.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/clickhouse_sqlalchemy/orm/query.py b/clickhouse_sqlalchemy/orm/query.py index 3b486e2f..611b4f71 100644 --- a/clickhouse_sqlalchemy/orm/query.py +++ b/clickhouse_sqlalchemy/orm/query.py @@ -19,6 +19,21 @@ class Query(BaseQuery): _limit_by = None _array_join = None + def _statement_20(self, for_statement=False, use_legacy_query_style=True): + orig_smt = super(Query, self)._statement_20(for_statement=for_statement, + use_legacy_query_style=use_legacy_query_style) + + orig_smt._with_cube = self._with_cube + orig_smt._with_rollup = self._with_rollup + orig_smt._with_totals = self._with_totals + orig_smt._final_clause = self._final + orig_smt._sample_clause = sample_clause(self._sample) + orig_smt._limit_by_clause = self._limit_by + orig_smt._array_join = self._array_join + + return orig_smt + + def _compile_context(self, *args, **kwargs): context = super(Query, self)._compile_context(*args, **kwargs) query = context.query