summaryrefslogtreecommitdiffstats
path: root/contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/sql
diff options
context:
space:
mode:
authorrobot-piglet <[email protected]>2025-10-01 22:13:48 +0300
committerrobot-piglet <[email protected]>2025-10-01 22:25:48 +0300
commit35a79522aadb9689d3f4f0309c0a4b95415c56b5 (patch)
tree8ea4480fce239a8712b30a84c4e7a39e342a62c3 /contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/sql
parentf3f7b33a285e94cb3e27aaa4d9b23b543ece4106 (diff)
Intermediate changes
commit_hash:2a2a4a29a447b6b9c8f7d148b02f33aa5942f64e
Diffstat (limited to 'contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/sql')
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/sql/compiler.py74
1 files changed, 74 insertions, 0 deletions
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/sql/compiler.py b/contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/sql/compiler.py
new file mode 100644
index 00000000000..dab2099ef24
--- /dev/null
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/sql/compiler.py
@@ -0,0 +1,74 @@
+from sqlalchemy.exc import CompileError
+from sqlalchemy.sql.compiler import SQLCompiler
+
+from clickhouse_connect.cc_sqlalchemy.sql import format_table
+
+
+# pylint: disable=arguments-differ
+class ChStatementCompiler(SQLCompiler):
+
+ # pylint: disable=attribute-defined-outside-init
+ def visit_delete(self, delete_stmt, visiting_cte=None, **kw):
+ table = delete_stmt.table
+ text = f"DELETE FROM {format_table(table)}"
+
+ if delete_stmt.whereclause is not None:
+ self._in_delete_where = True
+ try:
+ text += " WHERE " + self.process(delete_stmt.whereclause, **kw)
+ finally:
+ self._in_delete_where = False
+ else:
+ raise CompileError("ClickHouse DELETE statements require a WHERE clause. To delete all rows, use 'TRUNCATE TABLE' instead.")
+
+ return text
+
+ def visit_select(self, select_stmt, **kw):
+ return super().visit_select(select_stmt, **kw)
+
+ def visit_join(self, join, **kw):
+ left = self.process(join.left, **kw)
+ right = self.process(join.right, **kw)
+ onclause = join.onclause
+
+ if getattr(join, "full", False):
+ join_kw = " FULL OUTER JOIN "
+ elif onclause is None:
+ join_kw = " CROSS JOIN "
+ elif join.isouter:
+ join_kw = " LEFT OUTER JOIN "
+ else:
+ join_kw = " INNER JOIN "
+
+ text = left + join_kw + right
+
+ if onclause is not None:
+ text += " ON " + self.process(onclause, **kw)
+
+ return text
+
+ def visit_column(self, column, add_to_result_map=None, include_table=True, result_map_targets=(), ambiguous_table_name_map=None, **kw):
+ if getattr(self, "_in_delete_where", False):
+ return self.preparer.quote(column.name)
+
+ return super().visit_column(
+ column,
+ add_to_result_map=add_to_result_map,
+ include_table=include_table,
+ result_map_targets=result_map_targets,
+ **kw,
+ )
+
+ # Abstract methods required by SQLCompiler
+ def delete_extra_from_clause(self, delete_stmt, from_table, extra_froms, from_hints, **kw):
+ raise NotImplementedError("ClickHouse doesn't support DELETE with extra FROM clause")
+
+ def update_from_clause(self, update_stmt, from_table, extra_froms, from_hints, **kw):
+ raise NotImplementedError("ClickHouse doesn't support UPDATE with FROM clause")
+
+ # pylint: disable=unused-argument
+ def visit_empty_set_expr(self, element_types, **kw):
+ return "SELECT 1 WHERE 1=0"
+
+ def visit_sequence(self, sequence, **kw):
+ raise NotImplementedError("ClickHouse doesn't support sequences")