Author: ikelly
Date: 2009-02-25 17:56:00 -0600 (Wed, 25 Feb 2009)
New Revision: 9905

Modified:
   django/trunk/django/db/models/sql/query.py
   django/trunk/tests/regressiontests/aggregation_regress/models.py
Log:
Fixed #10290: do not use aliases when adding extra_selects to the GROUP BY 
clause, to generate compliant sql that will be accepted by Oracle.

Modified: django/trunk/django/db/models/sql/query.py
===================================================================
--- django/trunk/django/db/models/sql/query.py  2009-02-24 22:51:14 UTC (rev 
9904)
+++ django/trunk/django/db/models/sql/query.py  2009-02-25 23:56:00 UTC (rev 
9905)
@@ -392,18 +392,21 @@
                 result.append('AND')
             result.append(' AND '.join(self.extra_where))
 
-        grouping = self.get_grouping()
+        grouping, gb_params = self.get_grouping()
         if grouping:
             if ordering:
                 # If the backend can't group by PK (i.e., any database
                 # other than MySQL), then any fields mentioned in the
                 # ordering clause needs to be in the group by clause.
                 if not self.connection.features.allows_group_by_pk:
-                    grouping.extend([str(col) for col in ordering_group_by
-                        if col not in grouping])
+                    for col, col_params in ordering_group_by:
+                        if col not in grouping:
+                            grouping.append(str(col))
+                            gb_params.extend(col_params)
             else:
                 ordering = self.connection.ops.force_no_ordering()
             result.append('GROUP BY %s' % ', '.join(grouping))
+            params.extend(gb_params)
 
         if having:
             result.append('HAVING %s' % having)
@@ -710,17 +713,22 @@
         Returns a tuple representing the SQL elements in the "group by" clause.
         """
         qn = self.quote_name_unless_alias
-        result = []
+        result, params = [], []
         if self.group_by is not None:
             group_by = self.group_by or []
-            for col in group_by + self.related_select_cols + 
self.extra_select.keys():
+            
+            extra_selects = []
+            for extra_select, extra_params in self.extra_select.itervalues():
+                extra_selects.append(extra_select)
+                params.extend(extra_params)
+            for col in group_by + self.related_select_cols + extra_selects:
                 if isinstance(col, (list, tuple)):
                     result.append('%s.%s' % (qn(col[0]), qn(col[1])))
                 elif hasattr(col, 'as_sql'):
                     result.append(col.as_sql(qn))
                 else:
                     result.append(str(col))
-        return result
+        return result, params
 
     def get_ordering(self):
         """
@@ -768,7 +776,7 @@
                 else:
                     order = asc
                 result.append('%s %s' % (field, order))
-                group_by.append(field)
+                group_by.append((field, []))
                 continue
             col, order = get_order_dir(field, asc)
             if col in self.aggregate_select:
@@ -783,7 +791,7 @@
                     processed_pairs.add((table, col))
                     if not distinct or elt in select_aliases:
                         result.append('%s %s' % (elt, order))
-                        group_by.append(elt)
+                        group_by.append((elt, []))
             elif get_order_dir(field)[0] not in self.extra_select:
                 # 'col' is of the form 'field' or 'field1__field2' or
                 # '-field1__field2__field', etc.
@@ -795,13 +803,13 @@
                         if distinct and elt not in select_aliases:
                             ordering_aliases.append(elt)
                         result.append('%s %s' % (elt, order))
-                        group_by.append(elt)
+                        group_by.append((elt, []))
             else:
                 elt = qn2(col)
                 if distinct and col not in select_aliases:
                     ordering_aliases.append(elt)
                 result.append('%s %s' % (elt, order))
-                group_by.append(elt)
+                group_by.append(self.extra_select[col])
         self.ordering_aliases = ordering_aliases
         return result, group_by
 

Modified: django/trunk/tests/regressiontests/aggregation_regress/models.py
===================================================================
--- django/trunk/tests/regressiontests/aggregation_regress/models.py    
2009-02-24 22:51:14 UTC (rev 9904)
+++ django/trunk/tests/regressiontests/aggregation_regress/models.py    
2009-02-25 23:56:00 UTC (rev 9905)
@@ -230,6 +230,12 @@
 >>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors=2).dates('pubdate',
 >>>  'day')
 [datetime.datetime(1995, 1, 15, 0, 0), datetime.datetime(2007, 12, 6, 0, 0)]
 
+# Regression for #10290 - extra selects with parameters can be used for
+# grouping.
+>>> qs = 
Book.objects.all().annotate(mean_auth_age=Avg('authors__age')).extra(select={'sheets'
 : '(pages + %s) / %s'}, select_params=[1, 
2]).order_by('sheets').values('sheets')
+>>> [int(x['sheets']) for x in qs]
+[150, 175, 224, 264, 473, 566]
+
 """
 }
 


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to