@@ -193,20 +193,18 @@ def compile_json_path_final_key(self, key_transform):
193
193
# Compile the final key without interpreting ints as array elements.
194
194
return ".%s" % json.dumps(key_transform)
195
195
196
-
def as_sql(self, compiler, connection, template=None):
196
+
def _as_sql_parts(self, compiler, connection):
197
197
# Process JSON path from the left-hand side.
198
198
if isinstance(self.lhs, KeyTransform):
199
-
lhs, lhs_params, lhs_key_transforms = self.lhs.preprocess_lhs(
199
+
lhs_sql, lhs_params, lhs_key_transforms = self.lhs.preprocess_lhs(
200
200
compiler, connection
201
201
)
202
202
lhs_json_path = compile_json_path(lhs_key_transforms)
203
203
else:
204
-
lhs, lhs_params = self.process_lhs(compiler, connection)
204
+
lhs_sql, lhs_params = self.process_lhs(compiler, connection)
205
205
lhs_json_path = "$"
206
-
sql = template % lhs
207
206
# Process JSON path from the right-hand side.
208
207
rhs = self.rhs
209
-
rhs_params = []
210
208
if not isinstance(rhs, (list, tuple)):
211
209
rhs = [rhs]
212
210
for key in rhs:
@@ -217,24 +215,43 @@ def as_sql(self, compiler, connection, template=None):
217
215
*rhs_key_transforms, final_key = rhs_key_transforms
218
216
rhs_json_path = compile_json_path(rhs_key_transforms, include_root=False)
219
217
rhs_json_path += self.compile_json_path_final_key(final_key)
220
-
rhs_params.append(lhs_json_path + rhs_json_path)
218
+
yield lhs_sql, lhs_params, lhs_json_path + rhs_json_path
219
+
220
+
def _combine_sql_parts(self, parts):
221
221
# Add condition for each key.
222
222
if self.logical_operator:
223
-
sql = "(%s)" % self.logical_operator.join([sql] * len(rhs_params))
224
-
return sql, tuple(lhs_params) + tuple(rhs_params)
223
+
return "(%s)" % self.logical_operator.join(parts)
224
+
return "".join(parts)
225
+
226
+
def as_sql(self, compiler, connection, template=None):
227
+
sql_parts = []
228
+
params = []
229
+
for lhs_sql, lhs_params, rhs_json_path in self._as_sql_parts(
230
+
compiler, connection
231
+
):
232
+
sql_parts.append(template % (lhs_sql, "%s"))
233
+
params.extend(lhs_params + [rhs_json_path])
234
+
return self._combine_sql_parts(sql_parts), tuple(params)
225
235
226
236
def as_mysql(self, compiler, connection):
227
237
return self.as_sql(
228
-
compiler, connection, template="JSON_CONTAINS_PATH(%s, 'one', %%s)"
238
+
compiler, connection, template="JSON_CONTAINS_PATH(%s, 'one', %s)"
229
239
)
230
240
231
241
def as_oracle(self, compiler, connection):
232
-
sql, params = self.as_sql(
233
-
compiler, connection, template="JSON_EXISTS(%s, '%%s')"
234
-
)
235
-
# Add paths directly into SQL because path expressions cannot be passed
236
-
# as bind variables on Oracle.
237
-
return sql % tuple(params), []
242
+
template = "JSON_EXISTS(%s, '%s')"
243
+
sql_parts = []
244
+
params = []
245
+
for lhs_sql, lhs_params, rhs_json_path in self._as_sql_parts(
246
+
compiler, connection
247
+
):
248
+
# Add right-hand-side directly into SQL because it cannot be passed
249
+
# as bind variables to JSON_EXISTS. It might result in invalid
250
+
# queries but it is assumed that it cannot be evaded because the
251
+
# path is JSON serialized.
252
+
sql_parts.append(template % (lhs_sql, rhs_json_path))
253
+
params.extend(lhs_params)
254
+
return self._combine_sql_parts(sql_parts), tuple(params)
238
255
239
256
def as_postgresql(self, compiler, connection):
240
257
if isinstance(self.rhs, KeyTransform):
@@ -246,7 +263,7 @@ def as_postgresql(self, compiler, connection):
246
263
247
264
def as_sqlite(self, compiler, connection):
248
265
return self.as_sql(
249
-
compiler, connection, template="JSON_TYPE(%s, %%s) IS NOT NULL"
266
+
compiler, connection, template="JSON_TYPE(%s, %s) IS NOT NULL"
250
267
)
251
268
252
269
@@ -455,9 +472,9 @@ def as_oracle(self, compiler, connection):
455
472
return "(NOT %s OR %s IS NULL)" % (sql, lhs), tuple(params) + tuple(lhs_params)
456
473
457
474
def as_sqlite(self, compiler, connection):
458
-
template = "JSON_TYPE(%s, %%s) IS NULL"
475
+
template = "JSON_TYPE(%s, %s) IS NULL"
459
476
if not self.rhs:
460
-
template = "JSON_TYPE(%s, %%s) IS NOT NULL"
477
+
template = "JSON_TYPE(%s, %s) IS NOT NULL"
461
478
return HasKeyOrArrayIndex(self.lhs.lhs, self.lhs.key_name).as_sql(
462
479
compiler,
463
480
connection,
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4