From 2a038521c4eabdc5f6d5026d3dd6d22868e329cd Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Tue, 18 Feb 2020 11:45:12 +0100 Subject: [PATCH] Fixed #31271 -- Preserved ordering when unifying query parameters on Oracle. This caused misplacing parameters in logged SQL queries. Regression in 79065b55a70cd220820a260a1c54851b7be0615a. Thanks Hans Aarne Liblik for the report. --- django/db/backends/oracle/base.py | 5 ++++- docs/releases/3.0.4.txt | 3 +++ tests/backends/tests.py | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 652e3235217..4d2f5b51f1a 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -500,7 +500,10 @@ class FormatStylePlaceholderCursor: # params_dict = {0.75: ':arg0', 2: ':arg1', 'sth': ':arg2'} # args = [':arg0', ':arg1', ':arg0', ':arg2', ':arg0'] # params = {':arg0': 0.75, ':arg1': 2, ':arg2': 'sth'} - params_dict = {param: ':arg%d' % i for i, param in enumerate(set(params))} + params_dict = { + param: ':arg%d' % i + for i, param in enumerate(dict.fromkeys(params)) + } args = [params_dict[param] for param in params] params = {value: key for key, value in params_dict.items()} query = query % tuple(args) diff --git a/docs/releases/3.0.4.txt b/docs/releases/3.0.4.txt index 7be1ed15cee..216bc29b0e2 100644 --- a/docs/releases/3.0.4.txt +++ b/docs/releases/3.0.4.txt @@ -20,3 +20,6 @@ Bugfixes related fields or parent link fields with :ref:`multi-table-inheritance` in the ``of`` argument, the corresponding models were not locked (:ticket:`31246`). + +* Fixed a regression in Django 3.0 that caused misplacing parameters in logged + SQL queries on Oracle (:ticket:`31271`). diff --git a/tests/backends/tests.py b/tests/backends/tests.py index ce3b863016d..f20d3db5f1d 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -79,6 +79,10 @@ class LastExecutedQueryTest(TestCase): for qs in ( Article.objects.filter(pk=1), Article.objects.filter(pk__in=(1, 2), reporter__pk=3), + Article.objects.filter( + pk=1, + reporter__pk=9, + ).exclude(reporter__pk__in=[2, 1]), ): sql, params = qs.query.sql_with_params() with qs.query.get_compiler(DEFAULT_DB_ALIAS).execute_sql(CURSOR) as cursor: