11from django .db .models .fields import BigAutoField
22from django .db .models .sql import compiler
33
4+ from clickhouse_backend import compat
45from clickhouse_backend .idworker import id_worker
56
7+ if compat .dj_ge42 :
8+ from django .core .exceptions import FullResultSet
9+
610
711class ClickhouseMixin :
8- def as_sql (self , * args , ** kwargs ):
9- sql , params = super ().as_sql (* args , ** kwargs )
12+ def _add_explain_sql (self , sql , params ):
1013 # Backward compatible for django 3.2
1114 explain_info = getattr (self .query , "explain_info" , None )
1215 if explain_info :
@@ -18,6 +21,9 @@ def as_sql(self, *args, **kwargs):
1821 sql = "%s %s" % (prefix , sql .lstrip ())
1922 if suffix :
2023 sql = "%s %s" % (sql , suffix )
24+ return sql , params
25+
26+ def _add_settings_sql (self , sql , params ):
2127 if getattr (self .query , "setting_info" , None ):
2228 setting_sql , setting_params = self .connection .ops .settings_sql (
2329 ** self .query .setting_info
@@ -26,12 +32,30 @@ def as_sql(self, *args, **kwargs):
2632 params = (* params , * setting_params )
2733 return sql , params
2834
35+ def _compile_where (self , table ):
36+ if compat .dj_ge42 :
37+ try :
38+ where , params = self .compile (self .query .where )
39+ except FullResultSet :
40+ where , params = "" , ()
41+ else :
42+ where , params = self .compile (self .query .where )
43+ if where :
44+ where = where .replace (table + "." , "" )
45+ else :
46+ where = "1"
47+ return where , params
48+
2949
3050class SQLCompiler (ClickhouseMixin , compiler .SQLCompiler ):
31- pass
51+ def as_sql (self , * args , ** kwargs ):
52+ sql , params = super ().as_sql (* args , ** kwargs )
53+ sql , params = self ._add_settings_sql (sql , params )
54+ sql , params = self ._add_explain_sql (sql , params )
55+ return sql , params
3256
3357
34- class SQLInsertCompiler (ClickhouseMixin , compiler .SQLInsertCompiler ):
58+ class SQLInsertCompiler (compiler .SQLInsertCompiler ):
3559 def as_sql (self ):
3660 # We don't need quote_name_unless_alias() here, since these are all
3761 # going to be column names (so we can avoid the extra overhead).
@@ -62,11 +86,16 @@ def as_sql(self):
6286 ]
6387
6488 placeholder_rows , param_rows = self .assemble_as_sql (fields , value_rows )
89+ # https://clickhouse.com/docs/en/sql-reference/statements/insert-into
90+ # If you want to specify SETTINGS for INSERT query then you have to do it before FORMAT clause
91+ # since everything after FORMAT format_name is treated as data.
92+ if getattr (self .query , "setting_info" , None ):
93+ setting_sql , setting_params = self .connection .ops .settings_sql (
94+ ** self .query .setting_info
95+ )
96+ result .append (setting_sql % setting_params )
97+
6598 result .append (self .connection .ops .bulk_insert_sql (fields , placeholder_rows ))
66- if hasattr (self .query , "get_settings" ):
67- settings_string = self .query .get_settings ()
68- if settings_string :
69- result .append (settings_string )
7099 return [(" " .join (result ), param_rows )]
71100
72101 def execute_sql (self , returning_fields = None ):
@@ -84,16 +113,14 @@ def _as_sql(self, query):
84113 "table"."column" in WHERE clause.
85114 """
86115 table = self .quote_name_unless_alias (query .base_table )
87- result = [
88- "ALTER TABLE %s DELETE" % table
89- ]
90- where , params = self .compile (query .where )
91- where = where .replace (table + "." , "" )
92- if where :
93- result .append ("WHERE %s" % where )
94- else :
95- result .append ("WHERE 1" )
96- return " " .join (result ), tuple (params )
116+ delete = "ALTER TABLE %s DELETE" % table
117+ where , params = self ._compile_where (table )
118+ return f"{ delete } WHERE { where } " , tuple (params )
119+
120+ def as_sql (self ):
121+ sql , params = super ().as_sql ()
122+ sql , params = self ._add_settings_sql (sql , params )
123+ return sql , params
97124
98125
99126class SQLUpdateCompiler (ClickhouseMixin , compiler .SQLUpdateCompiler ):
@@ -159,23 +186,15 @@ def as_sql(self):
159186 "ALTER TABLE %s UPDATE" % table ,
160187 ", " .join (values ).replace (table + "." , "" ),
161188 ]
162- where , params = self .compile (self .query .where )
163- where = where .replace (table + "." , "" )
164-
165- if where :
166- result .append ("WHERE %s" % where )
167- else :
168- result .append ("WHERE 1" )
169-
189+ where , params = self ._compile_where (table )
190+ result .append (f"WHERE { where } " )
170191 params = (* update_params , * params )
171- if getattr (self .query , "setting_info" , None ):
172- setting_sql , setting_params = self .connection .ops .settings_sql (
173- ** self .query .setting_info
174- )
175- result .append (setting_sql )
176- params = (* params , * setting_params )
177- return " " .join (result ), params
192+ return self ._add_settings_sql (" " .join (result ), params )
178193
179194
180195class SQLAggregateCompiler (ClickhouseMixin , compiler .SQLAggregateCompiler ):
181- pass
196+ def as_sql (self ):
197+ sql , params = super ().as_sql ()
198+ sql , params = self ._add_settings_sql (sql , params )
199+ sql , params = self ._add_explain_sql (sql , params )
200+ return sql , params
0 commit comments