Ticket #12807: 12807.patch

File 12807.patch, 3.9 KB (added by Samuel Cormier-Iijima, 15 years ago)
  • django/db/models/sql/query.py

    diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
    index d92d2f6..f3646c0 100644
    a b from django.db.models.sql import aggregates as base_aggregates_module  
    2020from django.db.models.sql.expressions import SQLEvaluator
    2121from django.db.models.sql.where import WhereNode, Constraint, EverythingNode, AND, OR
    2222from django.core.exceptions import FieldError
    23 from datastructures import EmptyResultSet, Empty, MultiJoin
     23from datastructures import EmptyResultSet, FullResultSet, Empty, MultiJoin
    2424from constants import *
    2525
    2626try:
    class BaseQuery(object):  
    400400        from_, f_params = self.get_from_clause()
    401401
    402402        qn = self.quote_name_unless_alias
    403         where, w_params = self.where.as_sql(qn=qn)
     403        try:
     404            where, w_params = self.where.as_sql(qn=qn)
     405        except FullResultSet:
     406            where, w_params = '', []
    404407        having, h_params = self.having.as_sql(qn=qn)
    405408        params = []
    406409        for val in self.extra_select.itervalues():
  • django/db/models/sql/where.py

    diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
    index ec0545c..42f317c 100644
    a b class WhereNode(tree.Node):  
    9494        result = []
    9595        result_params = []
    9696        empty = True
     97        full = True
    9798        for child in self.children:
    9899            try:
    99100                if hasattr(child, 'as_sql'):
    class WhereNode(tree.Node):  
    103104                    sql, params = self.make_atom(child, qn)
    104105
    105106            except EmptyResultSet:
    106                 if self.connector == AND and not self.negated:
    107                     # We can bail out early in this particular case (only).
    108                     raise
    109                 elif self.negated:
    110                     empty = False
    111                 continue
     107                if self.connector == AND:
     108                    # Ignoring negation, the result is empty
     109                    empty, full = True, False
     110                    break
     111                else:
     112                    # Definitely not full, but maybe still empty
     113                    full = False
     114                    continue
    112115            except FullResultSet:
    113116                if self.connector == OR:
    114                     if self.negated:
    115                         empty = True
    116                         break
    117                     # We match everything. No need for any constraints.
    118                     return '', []
    119                 if self.negated:
    120                     empty = True
    121                 continue
     117                    # Ignoring negation, the result is full
     118                    empty, full = False, True
     119                    break
     120                else:
     121                    # Definitely not empty, but maybe still full
     122                    empty = False
     123                    continue
    122124
    123125            empty = False
     126            full = False
    124127            if sql:
    125128                result.append(sql)
    126129                result_params.extend(params)
    127         if empty:
     130
     131        # Take negation into account here and raise the appropriate indicator
     132        if empty and self.negated or full and not self.negated:
     133            raise FullResultSet
     134        if empty and not self.negated or full and self.negated:
    128135            raise EmptyResultSet
    129136
    130137        conn = ' %s ' % self.connector
  • tests/modeltests/or_lookups/models.py

    diff --git a/tests/modeltests/or_lookups/models.py b/tests/modeltests/or_lookups/models.py
    index 60b40d0..aca2823 100644
    a b __test__ = {'API_TESTS':"""  
    133133[<Article: Hello>]
    134134>>> Article.objects.complex_filter(Q(pk=1) | Q(pk=2))
    135135[<Article: Hello>, <Article: Goodbye>]
     136
     137# Empty or full result sets bubble correctly
     138>>> Article.objects.filter((Q(pk=1) | ~Q(pk__in=[])) & Q(pk=3))
     139[<Article: Hello and goodbye>]
    136140"""}
Back to Top