Skip to content

Commit 4efea04

Browse files
committed
refactored the json_haskey code
1 parent bd008db commit 4efea04

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

mssql/functions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ def json_HasKeyLookup(self, compiler, connection):
249249
"""
250250

251251
def _combine_conditions(conditions):
252+
# Combine multiple conditions with the logical operator if present, else return the first condition
252253
if hasattr(self, 'logical_operator') and self.logical_operator:
253254
logical_op = f" {self.logical_operator} "
254255
return f"({logical_op.join(conditions)})"
@@ -257,10 +258,12 @@ def _combine_conditions(conditions):
257258

258259
# Process JSON path from the left-hand side.
259260
if isinstance(self.lhs, KeyTransform):
261+
# If lhs is a KeyTransform, preprocess to get SQL and JSON path
260262
lhs, _, lhs_key_transforms = self.lhs.preprocess_lhs(compiler, connection)
261263
lhs_json_path = compile_json_path(lhs_key_transforms)
262264
lhs_params = []
263265
else:
266+
# Otherwise, process lhs normally
264267
lhs, lhs_params = self.process_lhs(compiler, connection)
265268
lhs_json_path = '$'
266269

@@ -270,21 +273,26 @@ def _combine_conditions(conditions):
270273
# Process JSON paths from the right-hand side
271274
rhs = self.rhs
272275
if not isinstance(rhs, (list, tuple)):
276+
# Ensure rhs is a list for uniform processing
273277
rhs = [rhs]
274278

275279
rhs_params = []
276280
for key in rhs:
277281
if isinstance(key, KeyTransform):
282+
# If key is a KeyTransform, preprocess to get JSON path
278283
*_, rhs_key_transforms = key.preprocess_lhs(compiler, connection)
279284
else:
285+
# Otherwise, treat key as a single transform
280286
rhs_key_transforms = [key]
281287

282288
if VERSION >= (4, 1):
289+
# For Django 4.1+, split out the final key and compile the path
283290
*rhs_key_transforms, final_key = rhs_key_transforms
284291
rhs_json_path = compile_json_path(rhs_key_transforms, include_root=False)
285292
rhs_json_path += self.compile_json_path_final_key(final_key)
286293
rhs_params.append(lhs_json_path + rhs_json_path)
287294
else:
295+
# For older Django, just compile the path
288296
rhs_params.append(
289297
'%s%s' % (
290298
lhs_json_path,
@@ -297,28 +305,36 @@ def _combine_conditions(conditions):
297305
params = []
298306
conditions = []
299307
if is_cast_expression:
308+
# If lhs is a Cast, get its SQL and params
300309
cast_sql, cast_params = self.lhs.as_sql(compiler, connection)
301310

302311
for path in rhs_params:
312+
# Escape single quotes in the path
303313
path_escaped = path.replace("'", "''")
314+
# Build the JSON_PATH_EXISTS condition
304315
conditions.append(f"JSON_PATH_EXISTS({cast_sql}, '{path_escaped}') > 0")
305316
params.extend(cast_params)
306317

307318
return _combine_conditions(conditions), params
308319
else:
309320
for path in rhs_params:
321+
# Escape single quotes in the path
310322
path_escaped = path.replace("'", "''")
323+
# Build the JSON_PATH_EXISTS condition using lhs
311324
conditions.append("JSON_PATH_EXISTS(%s, '%s') > 0" % (lhs, path_escaped))
312325

313326
return _combine_conditions(conditions), lhs_params
314327

315328
else:
316329
if is_cast_expression:
330+
# If lhs is a Cast and SQL Server is old, just return a dummy condition
317331
return "1=1", []
318332
else:
319333
conditions = []
320334
for path in rhs_params:
335+
# Escape single quotes in the path
321336
path_escaped = path.replace("'", "''")
337+
# Build the JSON_VALUE IS NOT NULL condition
322338
conditions.append("JSON_VALUE(%s, '%s') IS NOT NULL" % (lhs, path_escaped))
323339

324340
return _combine_conditions(conditions), lhs_params

0 commit comments

Comments
 (0)