Fixed #17877 -- Ensured that extra WHERE clauses get correctly ANDed when they contain OR operations. Thanks to Marek Brzóska for the report, to eleather for the test case and to Adrien Lemaire for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17880 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5c53e30607
commit
93d1fdb130
1
AUTHORS
1
AUTHORS
|
@ -326,6 +326,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
lcordier@point45.com
|
lcordier@point45.com
|
||||||
Jeong-Min Lee <falsetru@gmail.com>
|
Jeong-Min Lee <falsetru@gmail.com>
|
||||||
Tai Lee <real.human@mrmachine.net>
|
Tai Lee <real.human@mrmachine.net>
|
||||||
|
Adrien Lemaire <lemaire.adrien@gmail.com>
|
||||||
Christopher Lenz <http://www.cmlenz.net/>
|
Christopher Lenz <http://www.cmlenz.net/>
|
||||||
lerouxb@gmail.com
|
lerouxb@gmail.com
|
||||||
Piotr Lewandowski <piotr.lewandowski@gmail.com>
|
Piotr Lewandowski <piotr.lewandowski@gmail.com>
|
||||||
|
|
|
@ -281,7 +281,8 @@ class ExtraWhere(object):
|
||||||
self.params = params
|
self.params = params
|
||||||
|
|
||||||
def as_sql(self, qn=None, connection=None):
|
def as_sql(self, qn=None, connection=None):
|
||||||
return " AND ".join(self.sqls), tuple(self.params or ())
|
sqls = ["(%s)" % sql for sql in self.sqls]
|
||||||
|
return " AND ".join(sqls), tuple(self.params or ())
|
||||||
|
|
||||||
class Constraint(object):
|
class Constraint(object):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -968,11 +968,11 @@ of the arguments is required, but you should use at least one of them.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
Entry.objects.extra(where=['id IN (3, 4, 5, 20)'])
|
Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
|
||||||
|
|
||||||
...translates (roughly) into the following SQL::
|
...translates (roughly) into the following SQL::
|
||||||
|
|
||||||
SELECT * FROM blog_entry WHERE id IN (3, 4, 5, 20);
|
SELECT * FROM blog_entry WHERE (foo='a' OR bar='a') AND (baz='a')
|
||||||
|
|
||||||
Be careful when using the ``tables`` parameter if you're specifying
|
Be careful when using the ``tables`` parameter if you're specifying
|
||||||
tables that are already used in the query. When you add extra tables
|
tables that are already used in the query. When you add extra tables
|
||||||
|
|
|
@ -313,3 +313,34 @@ class ExtraRegressTests(TestCase):
|
||||||
TestObject.objects.extra(where=["id > %s"], params=[obj.pk]),
|
TestObject.objects.extra(where=["id > %s"], params=[obj.pk]),
|
||||||
['<TestObject: TestObject: first,second,third>']
|
['<TestObject: TestObject: first,second,third>']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_regression_17877(self):
|
||||||
|
"""
|
||||||
|
Ensure that extra WHERE clauses get correctly ANDed, even when they
|
||||||
|
contain OR operations.
|
||||||
|
"""
|
||||||
|
# Test Case 1: should appear in queryset.
|
||||||
|
t = TestObject(first='a', second='a', third='a')
|
||||||
|
t.save()
|
||||||
|
# Test Case 2: should appear in queryset.
|
||||||
|
t = TestObject(first='b', second='a', third='a')
|
||||||
|
t.save()
|
||||||
|
# Test Case 3: should not appear in queryset, bug case.
|
||||||
|
t = TestObject(first='a', second='a', third='b')
|
||||||
|
t.save()
|
||||||
|
# Test Case 4: should not appear in queryset.
|
||||||
|
t = TestObject(first='b', second='a', third='b')
|
||||||
|
t.save()
|
||||||
|
# Test Case 5: should not appear in queryset.
|
||||||
|
t = TestObject(first='b', second='b', third='a')
|
||||||
|
t.save()
|
||||||
|
# Test Case 6: should not appear in queryset, bug case.
|
||||||
|
t = TestObject(first='a', second='b', third='b')
|
||||||
|
t.save()
|
||||||
|
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
TestObject.objects.extra(
|
||||||
|
where=["first = 'a' OR second = 'a'", "third = 'a'"],
|
||||||
|
),
|
||||||
|
['<TestObject: TestObject: a,a,a>', '<TestObject: TestObject: b,a,a>']
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue