1
1
from django .db .models .fields import BigAutoField
2
2
from django .db .models .sql import compiler
3
3
4
+ from clickhouse_backend import compat
4
5
from clickhouse_backend .idworker import id_worker
5
6
7
+ if compat .dj_ge42 :
8
+ from django .core .exceptions import FullResultSet
9
+
6
10
7
11
class ClickhouseMixin :
8
- def as_sql (self , * args , ** kwargs ):
9
- sql , params = super ().as_sql (* args , ** kwargs )
12
+ def _add_explain_sql (self , sql , params ):
10
13
# Backward compatible for django 3.2
11
14
explain_info = getattr (self .query , "explain_info" , None )
12
15
if explain_info :
@@ -18,6 +21,9 @@ def as_sql(self, *args, **kwargs):
18
21
sql = "%s %s" % (prefix , sql .lstrip ())
19
22
if suffix :
20
23
sql = "%s %s" % (sql , suffix )
24
+ return sql , params
25
+
26
+ def _add_settings_sql (self , sql , params ):
21
27
if getattr (self .query , "setting_info" , None ):
22
28
setting_sql , setting_params = self .connection .ops .settings_sql (
23
29
** self .query .setting_info
@@ -26,12 +32,30 @@ def as_sql(self, *args, **kwargs):
26
32
params = (* params , * setting_params )
27
33
return sql , params
28
34
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
+
29
49
30
50
class 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
32
56
33
57
34
- class SQLInsertCompiler (ClickhouseMixin , compiler .SQLInsertCompiler ):
58
+ class SQLInsertCompiler (compiler .SQLInsertCompiler ):
35
59
def as_sql (self ):
36
60
# We don't need quote_name_unless_alias() here, since these are all
37
61
# going to be column names (so we can avoid the extra overhead).
@@ -62,11 +86,16 @@ def as_sql(self):
62
86
]
63
87
64
88
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
+
65
98
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 )
70
99
return [(" " .join (result ), param_rows )]
71
100
72
101
def execute_sql (self , returning_fields = None ):
@@ -84,16 +113,14 @@ def _as_sql(self, query):
84
113
"table"."column" in WHERE clause.
85
114
"""
86
115
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
97
124
98
125
99
126
class SQLUpdateCompiler (ClickhouseMixin , compiler .SQLUpdateCompiler ):
@@ -159,23 +186,15 @@ def as_sql(self):
159
186
"ALTER TABLE %s UPDATE" % table ,
160
187
", " .join (values ).replace (table + "." , "" ),
161
188
]
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 } " )
170
191
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 )
178
193
179
194
180
195
class 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