-
Notifications
You must be signed in to change notification settings - Fork 125
FEAT:Support 5.1-Modified JSON_Haskey_Lookup #459
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
base: dev
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors json_HasKeyLookup
in mssql/functions.py
to streamline parameter initialization and SQL generation for JSON key lookups, and updates _get_check_sql
for Django 5.1+ compatibility.
- Initialized
lhs_params
andconditions
lists for more consistent handling. - Simplified JSON path checks using
JSON_VALUE
and unified logic across SQL Server versions. - Updated
_get_check_sql
to useself.condition
for Django 5.1+ while preserving backwards compatibility.
Comments suppressed due to low confidence (1)
mssql/functions.py:284
- The variable
cast_sql
is assigned but never used: the subsequentconditions
uselhs
instead ofcast_sql
, andcast_params
are not applied. You should usecast_sql
in theJSON_VALUE
expression and includecast_params
(or merge them withlhs_params
) in the returned params.
cast_sql, cast_params = self.lhs.as_sql(compiler, connection)
mssql/functions.py
Outdated
@@ -297,10 +296,8 @@ def json_HasKeyLookup(self, compiler, connection): | |||
else: | |||
# if no operators are specified | |||
sql = conditions[0] | |||
|
|||
return sql, cast_params | |||
return sql, lhs_params |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning only lhs_params
here discards the cast_params
needed for the CAST expression. Consider returning cast_params + lhs_params
(or vice versa) to include all required parameters.
return sql, lhs_params | |
return sql, cast_params + lhs_params |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check this comment & resolve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
mssql/functions.py
Outdated
logical_op = " " + self.logical_operator + " " | ||
sql = "(" + logical_op.join(conditions) + ")" | ||
path_escaped = path.replace("'", "''") | ||
conditions.append("JSON_VALUE(%s, '%s') IS NOT NULL" % (lhs, path_escaped)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This inlines both lhs
and path_escaped
into the SQL string, leaving no placeholders; passing lhs_params
to the caller may introduce extraneous parameters. Either switch to placeholders with a params list or return an empty list when there are none.
conditions.append("JSON_VALUE(%s, '%s') IS NOT NULL" % (lhs, path_escaped)) | |
conditions.append("JSON_VALUE(%s, %s) IS NOT NULL") | |
lhs_params.append(path_escaped) |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider parameterizing the SQL instead of injecting path_escaped directly—this will improve security and prevent bugs with unusual key names. Also, the code for building conditions is duplicated across multiple branches; factoring it out into a helper (e.g. _build_json_condition
) could make future changes easier and less error prone. Finally, double-check that all return statements yield consistent parameter lists, not just empty ones in some cases.
e.g.
Instead of
conditions.append("JSON_VALUE(%s, '%s') IS NOT NULL" % (lhs, path_escaped))
Can change to
conditions.append("JSON_VALUE(%s, %s) IS NOT NULL")
lhs_params.extend([lhs, path])
Why: This uses SQL parameters (%s placeholders) for both the column and the path. The path is passed as a parameter, avoiding SQL injection and escaping bugs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made the suggested changes
mssql/functions.py
Outdated
logical_op = " " + self.logical_operator + " " | ||
sql = "(" + logical_op.join(conditions) + ")" | ||
path_escaped = path.replace("'", "''") | ||
conditions.append("JSON_VALUE(%s, '%s') IS NOT NULL" % (lhs, path_escaped)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider parameterizing the SQL instead of injecting path_escaped directly—this will improve security and prevent bugs with unusual key names. Also, the code for building conditions is duplicated across multiple branches; factoring it out into a helper (e.g. _build_json_condition
) could make future changes easier and less error prone. Finally, double-check that all return statements yield consistent parameter lists, not just empty ones in some cases.
e.g.
Instead of
conditions.append("JSON_VALUE(%s, '%s') IS NOT NULL" % (lhs, path_escaped))
Can change to
conditions.append("JSON_VALUE(%s, %s) IS NOT NULL")
lhs_params.extend([lhs, path])
Why: This uses SQL parameters (%s placeholders) for both the column and the path. The path is passed as a parameter, avoiding SQL injection and escaping bugs.
mssql/functions.py
Outdated
@@ -297,10 +296,8 @@ def json_HasKeyLookup(self, compiler, connection): | |||
else: | |||
# if no operators are specified | |||
sql = conditions[0] | |||
|
|||
return sql, cast_params | |||
return sql, lhs_params |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check this comment & resolve.
This pull request refactors and enhances JSON handling for SQL Server in
mssql/functions.py
, focusing on improving readability, modularity, and support for logical operators in JSON conditions. The most important changes include introducing a helper function for condition building, updating thejson_HasKeyLookup
method for better SQL generation, and improving compatibility with different SQL Server versions.Refactoring and Modularity:
_build_json_conditions
helper function to centralize and simplify the logic for combining SQL conditions with logical operators (e.g., AND/OR). This reduces code duplication and improves maintainability.Enhancements to
json_HasKeyLookup
:JSON_PATH_EXISTS
with better escaping and condition building. For older SQL Server versions, fallback logic now usesJSON_VALUE
with enhanced parameter handling.These changes make the codebase cleaner, easier to extend, and more robust in handling various SQL Server versions and JSON query scenarios.