Ticket #10099: 03-subquery-in-limit.diff

File 03-subquery-in-limit.diff, 3.8 KB (added by lamby, 7 years ago)
  • db/backends/__init__.py

    For-upstream: maybe
    Website: http://code.djangoproject.com/ticket/10099
    
    diff a/db/backends/__init__.py b/db/backends/__init__.py
    a b  
    8181    # If True, don't use integer foreign keys referring to, e.g., positive
    8282    # integer primary keys.
    8383    related_fields_match_type = False
     84    allow_limit_in_in_subquery = True
    8485
    8586class BaseDatabaseOperations(object):
    8687    """
  • db/backends/mysql/base.py

    diff a/db/backends/mysql/base.py b/db/backends/mysql/base.py
    a b  
    112112    update_can_self_select = False
    113113    allows_group_by_pk = True
    114114    related_fields_match_type = True
     115    allow_limit_in_in_subquery = False
    115116
    116117class DatabaseOperations(BaseDatabaseOperations):
    117118    def date_extract_sql(self, lookup_type, field_name):
  • db/models/fields/__init__.py

    diff a/db/models/fields/__init__.py b/db/models/fields/__init__.py
    a b  
    193193
    194194    def get_db_prep_lookup(self, lookup_type, value):
    195195        "Returns field's value prepared for database lookup."
     196        def pk_trace(value):
     197            # Value may be a primary key, or an object held in a relation.
     198            # If it is an object, then we need to get the primary key value for
     199            # that object. In certain conditions (especially one-to-one relations),
     200            # the primary key may itself be an object - so we need to keep drilling
     201            # down until we hit a value that can be used for a comparison.
     202            v, field = value, None
     203            try:
     204                while True:
     205                    v, field = getattr(v, v._meta.pk.name), v._meta.pk
     206            except AttributeError:
     207                pass
     208            if field:
     209                if lookup_type in ('range', 'in'):
     210                    v = [v]
     211                v = field.get_db_prep_lookup(lookup_type, v)
     212                if isinstance(v, list):
     213                    v = v[0]
     214            return v
    196215        if hasattr(value, 'as_sql'):
    197216            # If the value has a relabel_aliases method, it will need to
    198217            # be invoked before the final SQL is evaluated
    199218            if hasattr(value, 'relabel_aliases'):
    200219                return value
     220            if lookup_type == 'in':
     221                query_uses_limit = value.query.high_mark is not None or \
     222                    value.query.low_mark
     223                if query_uses_limit and \
     224                            not connection.features.allow_limit_in_in_subquery:
     225                    ret = map(pk_trace, value)
     226                    value.value_annotation = bool(ret)
     227                    return ret
    201228            sql, params = value.as_sql()
    202229            return QueryWrapper(('(%s)' % sql), params)
    203230
  • db/models/fields/related.py

    diff a/db/models/fields/related.py b/db/models/fields/related.py
    a b  
    145145            # be invoked before the final SQL is evaluated
    146146            if hasattr(value, 'relabel_aliases'):
    147147                return value
     148            if lookup_type == 'in':
     149                query_uses_limit = value.query.high_mark is not None or \
     150                    value.query.low_mark
     151                if query_uses_limit and \
     152                            not connection.features.allow_limit_in_in_subquery:
     153                    ret = map(pk_trace, value)
     154                    value.value_annotation = bool(ret)
     155                    return ret
    148156            sql, params = value.as_sql()
    149157            return QueryWrapper(('(%s)' % sql), params)
    150158
Back to Top