summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2022-07-05 05:53:49 +0200
committerGitHub <noreply@github.com>2022-07-05 05:53:49 +0200
commit249ecc437f79c08b087d0daa0ec8b41f9b25a238 (patch)
tree78860d6090c7e655a7df00455682d11c367ecc60
parentd12d7c4c42814736c24731a6a300a79526fc2ef6 (diff)
Fixed #33815 -- Fixed last_executed_query() on Oracle when parameter names overlap.
-rw-r--r--django/db/backends/oracle/operations.py9
-rw-r--r--tests/backends/tests.py17
2 files changed, 22 insertions, 4 deletions
diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py
index 672a02d664..b044adadda 100644
--- a/django/db/backends/oracle/operations.py
+++ b/django/db/backends/oracle/operations.py
@@ -309,14 +309,15 @@ END;
# `statement` doesn't contain the query parameters. Substitute
# parameters manually.
if isinstance(params, (tuple, list)):
- for i, param in enumerate(params):
+ for i, param in enumerate(reversed(params), start=1):
+ param_num = len(params) - i
statement = statement.replace(
- ":arg%d" % i, force_str(param, errors="replace")
+ ":arg%d" % param_num, force_str(param, errors="replace")
)
elif isinstance(params, dict):
- for key, param in params.items():
+ for key in sorted(params, key=len, reverse=True):
statement = statement.replace(
- ":%s" % key, force_str(param, errors="replace")
+ ":%s" % key, force_str(params[key], errors="replace")
)
return statement
diff --git a/tests/backends/tests.py b/tests/backends/tests.py
index 9303089b51..c6980058ca 100644
--- a/tests/backends/tests.py
+++ b/tests/backends/tests.py
@@ -101,6 +101,7 @@ class LastExecutedQueryTest(TestCase):
pk=1,
reporter__pk=9,
).exclude(reporter__pk__in=[2, 1]),
+ Article.objects.filter(pk__in=list(range(20, 31))),
):
sql, params = qs.query.sql_with_params()
with qs.query.get_compiler(DEFAULT_DB_ALIAS).execute_sql(CURSOR) as cursor:
@@ -125,6 +126,22 @@ class LastExecutedQueryTest(TestCase):
sql % params,
)
+ @skipUnlessDBFeature("supports_paramstyle_pyformat")
+ def test_last_executed_query_dict_overlap_keys(self):
+ square_opts = Square._meta
+ sql = "INSERT INTO %s (%s, %s) VALUES (%%(root)s, %%(root2)s)" % (
+ connection.introspection.identifier_converter(square_opts.db_table),
+ connection.ops.quote_name(square_opts.get_field("root").column),
+ connection.ops.quote_name(square_opts.get_field("square").column),
+ )
+ with connection.cursor() as cursor:
+ params = {"root": 2, "root2": 4}
+ cursor.execute(sql, params)
+ self.assertEqual(
+ cursor.db.ops.last_executed_query(cursor, sql, params),
+ sql % params,
+ )
+
class ParameterHandlingTest(TestCase):
def test_bad_parameter_count(self):