-
Notifications
You must be signed in to change notification settings - Fork 28
INTPYTHON-749: Fix bug in null matching on queryoptimizer #401
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
Changes from 2 commits
6f2052a
139d0b4
fafe479
50177bc
e8011b9
0ca2a5e
4af823a
0161dfb
0b29263
7802896
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from django.db import models | ||
|
||
|
||
class NullableJSONModel(models.Model): | ||
value = models.JSONField(blank=True, null=True) | ||
|
||
class Meta: | ||
required_db_features = {"supports_json_field"} | ||
|
||
|
||
class Tag(models.Model): | ||
name = models.CharField(max_length=10) | ||
|
||
def __str__(self): | ||
return self.name | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
from django.test import TestCase | ||
|
||
from django_mongodb_backend.test import MongoTestCaseMixin | ||
|
||
from .models import NullableJSONModel, Tag | ||
|
||
|
||
class MQLTests(MongoTestCaseMixin, TestCase): | ||
def test_none_filter_nullable_json(self): | ||
with self.assertNumQueries(1) as ctx: | ||
list(NullableJSONModel.objects.filter(value=None)) | ||
|
||
self.assertAggregateQuery( | ||
ctx.captured_queries[0]["sql"], | ||
"queries__nullablejsonmodel", | ||
[{"$match": {"$and": [{"$exists": False}, {"value": None}]}}], | ||
) | ||
|
||
def test_none_filter(self): | ||
with self.assertNumQueries(1) as ctx: | ||
list(Tag.objects.filter(name=None)) | ||
self.assertAggregateQuery( | ||
ctx.captured_queries[0]["sql"], | ||
"queries__nullablejsonmodel", | ||
[ | ||
{ | ||
"$match": { | ||
"$or": [ | ||
{"$and": [{"name": {"$exists": True}}, {"name": None}]}, | ||
{"$expr": {"$eq": [{"$type": "$name"}, "missing"]}}, | ||
] | ||
} | ||
} | ||
], | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please try to use existing test apps and existing tests. The
expression_converter_
app will be removed when query generation is refactored. In the case of JSONField, since Django'stests/model_fields/test_jsonfield.py
doesn't seem to catch the issue, we can add a file of the same name to this project'stests/model_fields_
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My pushback here is that it they're placed here since we're testing a direct consequence of the
QueryOptimizer
and a bugfix to the QueryOptimizer; the original code has no bug. From my perspective the query refactor is larger lift and it makes more sense there to then fold in models -- especially if this will be temporary.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests are organized by behavior, not by what part of the code caused the problem. Presumably we want any future query generation algorithm to generate the same query, or at least a query that behaves the same. From my perspective, there is no advantage to regression tests like this in
expression_converter_
, as it creates more work down the line to move them elsewhere. Looking at this again,tests/lookup_
might be more appropriate thanmodel_fields_
.InConverter
is also modified but I don't see a regression test for that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I'll also include a test for
$in
as well since it doesn't behave the same way and also move them tolookup_
.