Django

Code

Changeset 7740

Show
Ignore:
Timestamp:
06/25/08 20:01:21 (3 months ago)
Author:
mtredinnick
Message:

Fixed a problem with values() and values_list() queries and nullable joins.

Previously, if we were querying across a nullable join and then a non-nullable
one, the second join would not be a LEFT OUTER join, which would exclude
certain valid results from the result set.

This is the same problem as [7597] but for values() field specifications, so
this covers the second case where Django adds extra stuff to the select-clause.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/db/models/sql/query.py

    r7597 r7740  
    680680        False, the join is only promoted if it is nullable, otherwise it is 
    681681        always promoted. 
     682 
     683        Returns True if the join was promoted. 
    682684        """ 
    683685        if ((unconditional or self.alias_map[alias][NULLABLE]) and 
     
    686688            data[JOIN_TYPE] = self.LOUTER 
    687689            self.alias_map[alias] = tuple(data) 
     690            return True 
     691        return False 
    688692 
    689693    def change_aliases(self, change_map): 
     
    12951299                        col = join[LHS_JOIN_COL] 
    12961300                        joins = joins[:-1] 
     1301                promote = False 
    12971302                for join in joins[1:]: 
    12981303                    # Only nullable aliases are promoted, so we don't end up 
    12991304                    # doing unnecessary left outer joins here. 
    1300                     self.promote_alias(join) 
     1305                    if self.promote_alias(join, promote): 
     1306                        promote = True 
    13011307                self.select.append((final_alias, col)) 
    13021308                self.select_fields.append(field) 
  • django/trunk/tests/regressiontests/queries/models.py

    r7739 r7740  
    5959class Report(models.Model): 
    6060    name = models.CharField(max_length=10) 
    61     creator = models.ForeignKey(Author, to_field='num'
     61    creator = models.ForeignKey(Author, to_field='num', null=True
    6262 
    6363    def __unicode__(self): 
     
    192192>>> r2 = Report(name='r2', creator=a3) 
    193193>>> r2.save() 
     194>>> r3 = Report(name='r3') 
     195>>> r3.save() 
    194196 
    195197Ordering by 'rank' gives us rank2, rank1, rank3. Ordering by the Meta.ordering 
     
    714716>>> ManagedModel.objects.update(data='mm') 
    715717 
     718A values() or values_list() query across joined models must use outer joins 
     719appropriately. 
     720>>> Report.objects.values_list("creator__extra__info", flat=True).order_by("name") 
     721[u'e1', u'e2', None] 
     722 
    716723"""} 
    717724