Skip to content

Commit

Permalink
Fixed #34103 -- Fixed logging SQL queries with duplicate parameters o…
Browse files Browse the repository at this point in the history
…n Oracle.
  • Loading branch information
shangxiao authored and felixxm committed Nov 25, 2022
1 parent 80c66e4 commit 64b3c41
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
16 changes: 8 additions & 8 deletions django/db/backends/oracle/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,16 +323,16 @@ def last_executed_query(self, cursor, sql, params):
# Unlike Psycopg's `query` and MySQLdb`'s `_executed`, cx_Oracle's
# `statement` doesn't contain the query parameters. Substitute
# parameters manually.
if isinstance(params, (tuple, list)):
for i, param in enumerate(reversed(params), start=1):
param_num = len(params) - i
statement = statement.replace(
":arg%d" % param_num, force_str(param, errors="replace")
)
elif isinstance(params, dict):
if params:
if isinstance(params, (tuple, list)):
params = {
f":arg{i}": param for i, param in enumerate(dict.fromkeys(params))
}
elif isinstance(params, dict):
params = {f":{key}": val for (key, val) in params.items()}
for key in sorted(params, key=len, reverse=True):
statement = statement.replace(
":%s" % key, force_str(params[key], errors="replace")
key, force_str(params[key], errors="replace")
)
return statement

Expand Down
17 changes: 17 additions & 0 deletions tests/backends/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,23 @@ def test_last_executed_query_dict_overlap_keys(self):
sql % params,
)

def test_last_executed_query_with_duplicate_params(self):
square_opts = Square._meta
table = connection.introspection.identifier_converter(square_opts.db_table)
id_column = connection.ops.quote_name(square_opts.get_field("id").column)
root_column = connection.ops.quote_name(square_opts.get_field("root").column)
sql = f"UPDATE {table} SET {root_column} = %s + %s WHERE {id_column} = %s"
with connection.cursor() as cursor:
params = [42, 42, 1]
cursor.execute(sql, params)
last_executed_query = connection.ops.last_executed_query(
cursor, sql, params
)
self.assertEqual(
last_executed_query,
f"UPDATE {table} SET {root_column} = 42 + 42 WHERE {id_column} = 1",
)


class ParameterHandlingTest(TestCase):
def test_bad_parameter_count(self):
Expand Down

0 comments on commit 64b3c41

Please sign in to comment.