summaryrefslogtreecommitdiff
path: root/django/db/models/sql
diff options
context:
space:
mode:
authorIan Kelly <ian.g.kelly@gmail.com>2010-09-16 19:53:41 +0000
committerIan Kelly <ian.g.kelly@gmail.com>2010-09-16 19:53:41 +0000
commit320c46999c44efdc31be9cc80d3a2d1bf5186f18 (patch)
tree77c242a2be11e589678485456c60a7657e12f599 /django/db/models/sql
parent763bcf8472e61ba09cc739086bb181822501efa4 (diff)
Fixed #14244: Allow lists of more than 1000 items to be used with the 'in' lookup in Oracle, by breaking them up into groups of 1000 items and ORing them together. Thanks to rlynch for the report and initial patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@13859 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/db/models/sql')
-rw-r--r--django/db/models/sql/where.py21
1 files changed, 19 insertions, 2 deletions
diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
index 72b2d4cc82..2427a528fb 100644
--- a/django/db/models/sql/where.py
+++ b/django/db/models/sql/where.py
@@ -2,6 +2,7 @@
Code to manage the creation and SQL rendering of 'where' constraints.
"""
import datetime
+from itertools import repeat
from django.utils import tree
from django.db.models.fields import Field
@@ -178,8 +179,24 @@ class WhereNode(tree.Node):
raise EmptyResultSet
if extra:
return ('%s IN %s' % (field_sql, extra), params)
- return ('%s IN (%s)' % (field_sql, ', '.join(['%s'] * len(params))),
- params)
+ max_in_list_size = connection.ops.max_in_list_size()
+ if max_in_list_size and len(params) > max_in_list_size:
+ # Break up the params list into an OR of manageable chunks.
+ in_clause_elements = ['(']
+ for offset in xrange(0, len(params), max_in_list_size):
+ if offset > 0:
+ in_clause_elements.append(' OR ')
+ in_clause_elements.append('%s IN (' % field_sql)
+ group_size = min(len(params) - offset, max_in_list_size)
+ param_group = ', '.join(repeat('%s', group_size))
+ in_clause_elements.append(param_group)
+ in_clause_elements.append(')')
+ in_clause_elements.append(')')
+ return ''.join(in_clause_elements), params
+ else:
+ return ('%s IN (%s)' % (field_sql,
+ ', '.join(repeat('%s', len(params)))),
+ params)
elif lookup_type in ('range', 'year'):
return ('%s BETWEEN %%s and %%s' % field_sql, params)
elif lookup_type in ('month', 'day', 'week_day'):