New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed #24705 -- Fixed negated Q objects in expressions. #4677
Conversation
Unfortunately both new tests fail on Oracle with "ORA-00932: inconsistent datatypes: expected - got BLOB". Other cosmetic edits: diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 0be2c56..e66695b 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1258,8 +1258,8 @@ class Query(object):
else:
child_clause, needed_inner = self.build_filter(
child, can_reuse=used_aliases, branch_negated=branch_negated,
- current_negated=current_negated, connector=connector, allow_joins=allow_joins,
- split_subq=split_subq
+ current_negated=current_negated, connector=connector,
+ allow_joins=allow_joins, split_subq=split_subq,
)
joinpromoter.add_votes(needed_inner)
if child_clause:
diff --git a/docs/releases/1.8.2.txt b/docs/releases/1.8.2.txt
index 2b11d08..c835435 100644
--- a/docs/releases/1.8.2.txt
+++ b/docs/releases/1.8.2.txt
@@ -18,10 +18,9 @@ Bugfixes
query with a ``Case`` expression could unexpectedly filter out results
(:ticket:`24766`).
-* Fixed negated Q-objects as expressions. Negated Q-objects tried to generate
- a subquery when the Q-object was used as an expression (for example
- `Case(When(~Q(friends__age__lte=30)))`). This resulted in crash
- (:ticket:`24705`).
+* Fixed negated ``Q`` objects in expressions. Cases like
+ ``Case(When(~Q(friends__age__lte=30)))`` tried to generate a subquery which
+ resulted in a crash (:ticket:`24705`).
* Fixed incorrect GROUP BY clause generation on MySQL when the query's model
has a self-referential foreign key (:ticket:`24748`).
diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py
index a40e937..e19ee80 100644
--- a/tests/expressions_case/tests.py
+++ b/tests/expressions_case/tests.py
@@ -1052,15 +1052,16 @@ class CaseExpressionTests(TestCase):
CaseTestModel.objects.create(integer=10, integer2=1, string='1')
qs = CaseTestModel.objects.annotate(
cnt=models.Sum(
- Case(When(~Q(fk_rel__integer=1), then=1),
- default=2),
- output_field=models.IntegerField())).order_by('integer')
- # The first o has 2 as result as its fk_rel__integer=1, thus it hits
- # the default=2 case. Other ones have 2 as result as they have 2
+ Case(When(~Q(fk_rel__integer=1), then=1), default=2),
+ output_field=models.IntegerField()
+ ),
+ ).order_by('integer')
+ # The first o has 2 as its fk_rel__integer=1, thus it hits the
+ # default=2 case. The other ones have 2 as the result as they have 2
# fk_rel objects, except for integer=4 and integer=10 (created above).
- # The integer=4 case has one integer, thus result is 1, and integer=10
- # doesn't have any, and this too generates 1 (instead of 0) as ~Q()
- # matches also nulls.
+ # The integer=4 case has one integer, thus the result is 1, and
+ # integer=10 doesn't have any and this too generates 1 (instead of 0)
+ # as ~Q() also matches nulls.
self.assertQuerysetEqual(
qs,
[(1, 2), (2, 2), (2, 2), (3, 2), (3, 2), (3, 2), (4, 1), (10, 1)],
@@ -1071,14 +1072,14 @@ class CaseExpressionTests(TestCase):
CaseTestModel.objects.create(integer=10, integer2=1, string='1')
qs = CaseTestModel.objects.annotate(
cnt=models.Sum(
- Case(When(~Q(fk_rel__integer=1), then=1),
- default=2),
- output_field=models.IntegerField())
+ Case(When(~Q(fk_rel__integer=1), then=1), default=2),
+ output_field=models.IntegerField()
+ ),
).annotate(
cnt2=models.Sum(
- Case(When(~Q(fk_rel__integer=1), then=1),
- default=2),
- output_field=models.IntegerField())
+ Case(When(~Q(fk_rel__integer=1), then=1), default=2),
+ output_field=models.IntegerField()
+ ),
).order_by('integer')
self.assertEqual(str(qs.query).count(' JOIN '), 1)
self.assertQuerysetEqual( |
I believe this is caused by the group by clause. The problem is that we try to group by some field that doesn't work on Oracle. Fix is to add values() to the queries so that only pk and the integer field is in the group by, or just skip the test. I can't do this tonight, will try to check this tomorrow morning. |
Lets see if the added commit is OK for Oracle. @timgraham I don't have Oracle setup available just now, can you test this on Oracle? |
buildbot, test on oracle. |
merged in bc87061, thanks! |
Avoided split_exclude() for Q when used as an expression.