1 | Index: 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)
|
---|
39 | Index: tests/modeltests/where/__init__.py
|
---|
40 | ===================================================================
|
---|
41 | Index: 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()
|
---|
50 | Index: 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)
|
---|