parent
457c16d0d6
commit
a9f1711518
|
@ -1,4 +1,5 @@
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
from itertools import repeat
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -77,8 +78,8 @@ class Lookup(RegisterLookupMixin):
|
||||||
lhs = lhs or self.lhs
|
lhs = lhs or self.lhs
|
||||||
return qn.compile(lhs)
|
return qn.compile(lhs)
|
||||||
|
|
||||||
def process_rhs(self, qn, connection, rhs=None):
|
def process_rhs(self, qn, connection):
|
||||||
value = rhs or self.rhs
|
value = self.rhs
|
||||||
# Due to historical reasons there are a couple of different
|
# Due to historical reasons there are a couple of different
|
||||||
# ways to produce sql here. get_compiler is likely a Query
|
# ways to produce sql here. get_compiler is likely a Query
|
||||||
# instance, _as_sql QuerySet and as_sql just something with
|
# instance, _as_sql QuerySet and as_sql just something with
|
||||||
|
@ -95,6 +96,12 @@ class Lookup(RegisterLookupMixin):
|
||||||
else:
|
else:
|
||||||
return self.get_db_prep_lookup(value, connection)
|
return self.get_db_prep_lookup(value, connection)
|
||||||
|
|
||||||
|
def rhs_is_direct_value(self):
|
||||||
|
return not(
|
||||||
|
hasattr(self.rhs, 'as_sql') or
|
||||||
|
hasattr(self.rhs, '_as_sql') or
|
||||||
|
hasattr(self.rhs, 'get_compiler'))
|
||||||
|
|
||||||
def relabeled_clone(self, relabels):
|
def relabeled_clone(self, relabels):
|
||||||
new = copy(self)
|
new = copy(self)
|
||||||
new.lhs = new.lhs.relabeled_clone(relabels)
|
new.lhs = new.lhs.relabeled_clone(relabels)
|
||||||
|
@ -186,6 +193,31 @@ class In(BuiltinLookup):
|
||||||
|
|
||||||
def get_rhs_op(self, connection, rhs):
|
def get_rhs_op(self, connection, rhs):
|
||||||
return 'IN %s' % rhs
|
return 'IN %s' % rhs
|
||||||
|
|
||||||
|
def as_sql(self, qn, connection):
|
||||||
|
max_in_list_size = connection.ops.max_in_list_size()
|
||||||
|
if self.rhs_is_direct_value() and (max_in_list_size and
|
||||||
|
len(self.rhs) > max_in_list_size):
|
||||||
|
rhs, rhs_params = self.process_rhs(qn, connection)
|
||||||
|
lhs, lhs_params = self.process_lhs(qn, connection)
|
||||||
|
in_clause_elements = ['(']
|
||||||
|
params = []
|
||||||
|
for offset in xrange(0, len(rhs_params), max_in_list_size):
|
||||||
|
if offset > 0:
|
||||||
|
in_clause_elements.append(' OR ')
|
||||||
|
in_clause_elements.append('%s IN (' % lhs)
|
||||||
|
params.extend(lhs_params)
|
||||||
|
group_size = min(len(rhs_params) - offset, max_in_list_size)
|
||||||
|
param_group = ', '.join(repeat('%s', group_size))
|
||||||
|
in_clause_elements.append(param_group)
|
||||||
|
in_clause_elements.append(')')
|
||||||
|
params.extend(rhs_params[offset: offset + max_in_list_size])
|
||||||
|
in_clause_elements.append(')')
|
||||||
|
return ''.join(in_clause_elements), params
|
||||||
|
else:
|
||||||
|
return super(In, self).as_sql(qn, connection)
|
||||||
|
|
||||||
|
|
||||||
default_lookups['in'] = In
|
default_lookups['in'] = In
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue