Ticket #14244: patch.txt

File patch.txt, 3.3 KB (added by rlynch, 14 years ago)

Patch of proposed fix

Line 
1Index: django/db/models/sql/where.py
2===================================================================
3--- django/db/models/sql/where.py (revision 13680)
4+++ django/db/models/sql/where.py (working copy)
5@@ -178,7 +178,32 @@
6 raise EmptyResultSet
7 if extra:
8 return ('%s IN %s' % (field_sql, extra), params)
9- return ('%s IN (%s)' % (field_sql, ', '.join(['%s'] * len(params))),
10+ #break up in clauses over 1000 itens. This is to specifially support an Oracle limit of 1000 items in an in clause
11+ MAX_IN_PARAMS = 1000
12+ if len(params) > MAX_IN_PARAMS:
13+ in_clause_elements = [] #used to concatinate elements later
14+ is_first = True #avoid putting ' OR ' in front of first in clause group
15+ cur_min = 0 #starting point of current parameter elements
16+ in_clause_elements.append('(')
17+ while cur_min <= len(params):
18+ if not is_first:
19+ in_clause_elements.append(' OR ')
20+ else:
21+ is_first = False
22+ num_params = 0
23+ if cur_min + MAX_IN_PARAMS > len(params):
24+ #we are at the end so only use the remaining parameters
25+ num_params = len(params) - cur_min
26+ else:
27+ #use full 1000 paramaters
28+ num_params = MAX_IN_PARAMS
29+ in_clause_elements.append('(%s IN (%s))' % (field_sql, ', '.join(['%s'] * num_params)))
30+ cur_min += MAX_IN_PARAMS
31+
32+ in_clause_elements.append(')')
33+ return ''.join(in_clause_elements), params
34+ else:
35+ return ('%s IN (%s)' % (field_sql, ', '.join(['%s'] * len(params))),
36 params)
37 elif lookup_type in ('range', 'year'):
38 return ('%s BETWEEN %%s and %%s' % field_sql, params)
39Index: tests/modeltests/where/__init__.py
40===================================================================
41Index: tests/modeltests/where/models.py
42===================================================================
43--- tests/modeltests/where/models.py (revision 0)
44+++ tests/modeltests/where/models.py (revision 0)
45@@ -0,0 +1,4 @@
46+from django.db import models
47+
48+class A(models.Model):
49+ x = models.IntegerField()
50Index: tests/modeltests/where/tests.py
51===================================================================
52--- tests/modeltests/where/tests.py (revision 0)
53+++ tests/modeltests/where/tests.py (revision 0)
54@@ -0,0 +1,20 @@
55+from django.test import TestCase
56+
57+from models import A
58+
59+class WhereTest(TestCase):
60+ '''
61+ Unfortunately this test does not work because SQLite3 has a predefined limit of 1000 parameters in a query.
62+ SQLite3 does expose a setting to increase this but it is only exposed in the C or Python APSW libraries.
63+ http://www.sqlite.org/capi3ref.html#SQLITE_LIMIT_ATTACHED
64+ '''
65+
66+ def testSimple(self):
67+ xs = []
68+ #create 1001 A types
69+ for i in range(1001):
70+ A.objects.create(x=i)
71+ xs.append(i)
72+
73+ queried = A.objects.filter(x__in=xs)
74+ self.assertEquals(len(queried), 1001)
Back to Top