Django

Code

Changeset 6515

Show
Ignore:
Timestamp:
10/14/07 20:20:10 (11 months ago)
Author:
mtredinnick
Message:

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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/django/db/models/sql/query.py

    r6512 r6515  
    343343        qn = self.quote_name_unless_alias 
    344344        result = [] 
     345        aliases = [] 
    345346        if self.select: 
    346347            for col in self.select: 
    347348                if isinstance(col, (list, tuple)): 
    348                     result.append('%s.%s' % (qn(col[0]), qn(col[1]))) 
     349                    r = '%s.%s' % (qn(col[0]), qn(col[1])) 
     350                    result.append(r) 
     351                    aliases.append(r) 
    349352                else: 
    350353                    result.append(col.as_sql(quote_func=qn)) 
     354                    if hasattr(col, 'alias'): 
     355                        aliases.append(col.alias) 
    351356        else: 
    352357            table_alias = self.tables[0] 
    353358            result = ['%s.%s' % (qn(table_alias), qn(f.column)) 
    354359                    for f in self.model._meta.fields] 
     360            aliases = result[:] 
    355361 
    356362        # We sort extra_select so that the result columns are in a well-defined 
     
    360366        result.extend(['(%s) AS %s' % (col, alias) 
    361367                for alias, col in extra_select]) 
     368        aliases.extend(self.extra_select.keys()) 
     369 
     370        self._select_aliases = dict.fromkeys(aliases) 
    362371        return result 
    363372 
     
    436445            ordering = self.order_by or self.model._meta.ordering 
    437446        qn = self.quote_name_unless_alias 
     447        distinct = self.distinct 
     448        select_aliases = self._select_aliases 
    438449        result = [] 
    439450        for field in ordering: 
     
    455466                col, order = get_order_dir(field) 
    456467                table, col = col.split('.', 1) 
    457                 result.append('%s.%s %s' % (qn(self.table_alias(table)[0]), col, 
    458                         order)) 
     468                elt = '%s.%s' % (qn(self.table_alias(table)[0]), col) 
     469                if not distinct or elt in select_aliases: 
     470                    result.append('%s %s' % (elt, order)) 
    459471            elif get_order_dir(field)[0] not in self.extra_select: 
    460472                # 'col' is of the form 'field' or 'field1__field2' or 
     
    462474                for table, col, order in self.find_ordering_name(field, 
    463475                        self.model._meta): 
    464                     result.append('%s.%s %s' % (qn(table), qn(col), order)) 
     476                    elt = '%s.%s' % (qn(table), qn(col)) 
     477                    if not distinct or elt in select_aliases: 
     478                        result.append('%s %s' % (elt, order)) 
    465479            else: 
    466480                col, order = get_order_dir(field) 
    467                 result.append('%s %s' % (qn(col), order)) 
     481                elt = qn(col) 
     482                if not distinct or elt in select_aliases: 
     483                    result.append('%s %s' % (elt, order)) 
    468484        return result 
    469485 
  • django/branches/queryset-refactor/tests/regressiontests/queries/models.py

    r6514 r6515  
    1515class Note(models.Model): 
    1616    note = models.CharField(maxlength=100) 
     17    misc = models.CharField(maxlength=10) 
    1718 
    1819    class Meta: 
     
    9293>>> t5.save() 
    9394 
    94 >>> n1 = Note(note='n1'
     95>>> n1 = Note(note='n1', misc='foo'
    9596>>> n1.save() 
    96 >>> n2 = Note(note='n2'
     97>>> n2 = Note(note='n2', misc='bar'
    9798>>> n2.save() 
    98 >>> n3 = Note(note='n3'
     99>>> n3 = Note(note='n3', misc='foo'
    99100>>> n3.save() 
    100101 
     
    330331>>> Item.objects.filter(Q(creator__name='a3', name='two')|Q(creator__name='a4', name='four')) 
    331332[<Item: four>] 
     333 
     334Bug #5321 
     335>>> Note.objects.values('misc').distinct().order_by('note', '-misc') 
     336[{'misc': u'foo'}, {'misc': u'bar'}] 
    332337"""} 
    333338