From 4ce5ced230481fc93288aeea922398bc36102d1e Mon Sep 17 00:00:00 2001
From: Rajiv Makhijani <rajiv@blue-tech.org>
Date: Fri, 8 Aug 2014 03:08:26 -0700
Subject: [PATCH] [1.7.x] Fixed #23259 -- Corrected insertion order of extra()
 select_params

A regression caused queries to produce incorrect results for cases where
extra(select) is excluded by values() but included by extra(order_by)

The regression was caused by 2f35c6f10fcbae541691207fb0c0560a13b754fc.

Backport of f0b358880a from master
---
 django/db/models/sql/compiler.py |  3 ++-
 tests/queries/tests.py           | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index 6792824ecd3..d8697fa06dd 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -117,7 +117,7 @@ class SQLCompiler(object):
 
         if self.query.distinct:
             result.append(self.connection.ops.distinct_sql(distinct_fields))
-        params.extend(o_params)
+
         result.append(', '.join(out_cols + self.ordering_aliases))
         params.extend(s_params)
         params.extend(self.ordering_params)
@@ -146,6 +146,7 @@ class SQLCompiler(object):
 
         if ordering:
             result.append('ORDER BY %s' % ', '.join(ordering))
+            params.extend(o_params)
 
         if with_limits:
             if self.query.high_mark is not None:
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index 60d1083879a..0fff68b21f5 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -2129,6 +2129,26 @@ class ValuesQuerysetTests(BaseQuerysetTest):
             order_by=['value_minus_one'])
         qs = qs.values('num')
 
+    def test_extra_select_params_values_order_in_extra(self):
+        # testing for 23259 issue
+        qs = Number.objects.extra(
+            select={'value_plus_x': 'num+%s'},
+            select_params=[1],
+            order_by=['value_plus_x'])
+        qs = qs.filter(num=72)
+        qs = qs.values('num')
+        self.assertQuerysetEqual(qs, [{'num': 72}], self.identity)
+
+    def test_extra_multiple_select_params_values_order_by(self):
+        # testing for 23259 issue
+        qs = Number.objects.extra(select=OrderedDict([('value_plus_x', 'num+%s'),
+                                                     ('value_minus_x', 'num-%s')]),
+                                  select_params=(72, 72))
+        qs = qs.order_by('value_minus_x')
+        qs = qs.filter(num=1)
+        qs = qs.values('num')
+        self.assertQuerysetEqual(qs, [], self.identity)
+
     def test_extra_values_list(self):
         # testing for ticket 14930 issues
         qs = Number.objects.extra(select={'value_plus_one': 'num+1'})