Author: mtredinnick
Date: 2007-10-14 20:20:10 -0500 (Sun, 14 Oct 2007)
New Revision: 6515

Modified:
   django/branches/queryset-refactor/django/db/models/sql/query.py
   django/branches/queryset-refactor/tests/regressiontests/queries/models.py
Log:
queryset-refactor: Made sure the ordering columns in a distinct() query only
include the columns we are selecting on. This avoids some PostgreSQL problems
and leads to more efficient queries to boot. Refs #5321.


Modified: django/branches/queryset-refactor/django/db/models/sql/query.py
===================================================================
--- django/branches/queryset-refactor/django/db/models/sql/query.py     
2007-10-15 00:48:40 UTC (rev 6514)
+++ django/branches/queryset-refactor/django/db/models/sql/query.py     
2007-10-15 01:20:10 UTC (rev 6515)
@@ -342,16 +342,22 @@
         """
         qn = self.quote_name_unless_alias
         result = []
+        aliases = []
         if self.select:
             for col in self.select:
                 if isinstance(col, (list, tuple)):
-                    result.append('%s.%s' % (qn(col[0]), qn(col[1])))
+                    r = '%s.%s' % (qn(col[0]), qn(col[1]))
+                    result.append(r)
+                    aliases.append(r)
                 else:
                     result.append(col.as_sql(quote_func=qn))
+                    if hasattr(col, 'alias'):
+                        aliases.append(col.alias)
         else:
             table_alias = self.tables[0]
             result = ['%s.%s' % (qn(table_alias), qn(f.column))
                     for f in self.model._meta.fields]
+            aliases = result[:]
 
         # We sort extra_select so that the result columns are in a well-defined
         # order (and thus QuerySet.iterator can extract them correctly).
@@ -359,6 +365,9 @@
         extra_select.sort()
         result.extend(['(%s) AS %s' % (col, alias)
                 for alias, col in extra_select])
+        aliases.extend(self.extra_select.keys())
+
+        self._select_aliases = dict.fromkeys(aliases)
         return result
 
     def get_from_clause(self):
@@ -435,6 +444,8 @@
             # is handled in the previous test.
             ordering = self.order_by or self.model._meta.ordering
         qn = self.quote_name_unless_alias
+        distinct = self.distinct
+        select_aliases = self._select_aliases
         result = []
         for field in ordering:
             if field == '?':
@@ -454,17 +465,22 @@
                 # necessary.
                 col, order = get_order_dir(field)
                 table, col = col.split('.', 1)
-                result.append('%s.%s %s' % (qn(self.table_alias(table)[0]), 
col,
-                        order))
+                elt = '%s.%s' % (qn(self.table_alias(table)[0]), col)
+                if not distinct or elt in select_aliases:
+                    result.append('%s %s' % (elt, order))
             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.
                 for table, col, order in self.find_ordering_name(field,
                         self.model._meta):
-                    result.append('%s.%s %s' % (qn(table), qn(col), order))
+                    elt = '%s.%s' % (qn(table), qn(col))
+                    if not distinct or elt in select_aliases:
+                        result.append('%s %s' % (elt, order))
             else:
                 col, order = get_order_dir(field)
-                result.append('%s %s' % (qn(col), order))
+                elt = qn(col)
+                if not distinct or elt in select_aliases:
+                    result.append('%s %s' % (elt, order))
         return result
 
     def find_ordering_name(self, name, opts, alias=None, default_order='ASC'):

Modified: 
django/branches/queryset-refactor/tests/regressiontests/queries/models.py
===================================================================
--- django/branches/queryset-refactor/tests/regressiontests/queries/models.py   
2007-10-15 00:48:40 UTC (rev 6514)
+++ django/branches/queryset-refactor/tests/regressiontests/queries/models.py   
2007-10-15 01:20:10 UTC (rev 6515)
@@ -14,6 +14,7 @@
 
 class Note(models.Model):
     note = models.CharField(maxlength=100)
+    misc = models.CharField(maxlength=10)
 
     class Meta:
         ordering = ['note']
@@ -91,11 +92,11 @@
 >>> t5 = Tag(name='t5', parent=t3)
 >>> t5.save()
 
->>> n1 = Note(note='n1')
+>>> n1 = Note(note='n1', misc='foo')
 >>> n1.save()
->>> n2 = Note(note='n2')
+>>> n2 = Note(note='n2', misc='bar')
 >>> n2.save()
->>> n3 = Note(note='n3')
+>>> n3 = Note(note='n3', misc='foo')
 >>> n3.save()
 
 Create these out of order so that sorting by 'id' will be different to sorting
@@ -329,5 +330,9 @@
 Bug #3037
 >>> Item.objects.filter(Q(creator__name='a3', 
 >>> name='two')|Q(creator__name='a4', name='four'))
 [<Item: four>]
+
+Bug #5321
+>>> Note.objects.values('misc').distinct().order_by('note', '-misc')
+[{'misc': u'foo'}, {'misc': u'bar'}]
 """}
 


--~--~---------~--~----~------------~-------~--~----~
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