Skip to content

Commit bbad59e

Browse files
committed
Add unit test.
1 parent 73bfed5 commit bbad59e

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

tests/queries_/test_mql.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,3 +1079,122 @@ def test_self_join_tag_three_levels_pushable(self):
10791079
{"$match": {"$and": [{"name": "T1"}, {"T2.name": "T2"}, {"T3.name": "T3"}]}},
10801080
],
10811081
)
1082+
1083+
def test_partial_and_pushdown(self):
1084+
a1 = Author.objects.create(name="Alice")
1085+
a2 = Author.objects.create(name="Bob")
1086+
b1 = Book.objects.create(title="B1", author=a1, isbn="111")
1087+
Book.objects.create(title="B2", author=a2, isbn="222")
1088+
cond = models.Q(author__name="Alice") & models.Q(title__contains="B")
1089+
expected = [b1]
1090+
with self.assertNumQueries(1) as ctx:
1091+
self.assertSequenceEqual(Book.objects.filter(cond), expected)
1092+
self.assertAggregateQuery(
1093+
ctx.captured_queries[0]["sql"],
1094+
"queries__book",
1095+
[
1096+
{
1097+
"$lookup": {
1098+
"from": "queries__author",
1099+
"let": {"parent__field__0": "$author_id"},
1100+
"pipeline": [
1101+
{
1102+
"$match": {
1103+
"$and": [
1104+
{
1105+
"$expr": {
1106+
"$and": [{"$eq": ["$$parent__field__0", "$_id"]}]
1107+
}
1108+
},
1109+
{"name": "Alice"},
1110+
]
1111+
}
1112+
}
1113+
],
1114+
"as": "queries__author",
1115+
}
1116+
},
1117+
{"$unwind": "$queries__author"},
1118+
{
1119+
"$match": {
1120+
"$and": [
1121+
{"queries__author.name": "Alice"},
1122+
{"title": {"$regex": "B", "$options": ""}},
1123+
]
1124+
}
1125+
},
1126+
],
1127+
)
1128+
1129+
def test_not_or_demorgan_pushdown(self):
1130+
a1 = Author.objects.create(name="Alice")
1131+
a2 = Author.objects.create(name="Bob")
1132+
b1 = Book.objects.create(title="B1", author=a1, isbn="111")
1133+
Book.objects.create(title="B2", author=a2, isbn="222")
1134+
expected = [b1]
1135+
with self.assertNumQueries(1) as ctx:
1136+
self.assertSequenceEqual(
1137+
Book.objects.filter(~(models.Q(author__name="Bob") | models.Q(isbn="222"))),
1138+
expected,
1139+
)
1140+
self.assertAggregateQuery(
1141+
ctx.captured_queries[0]["sql"],
1142+
"queries__book",
1143+
[
1144+
{
1145+
"$lookup": {
1146+
"from": "queries__author",
1147+
"let": {"parent__field__0": "$author_id"},
1148+
"pipeline": [
1149+
{
1150+
"$match": {
1151+
"$and": [
1152+
{
1153+
"$expr": {
1154+
"$and": [{"$eq": ["$$parent__field__0", "$_id"]}]
1155+
}
1156+
},
1157+
{"$nor": [{"name": "Bob"}]},
1158+
]
1159+
}
1160+
}
1161+
],
1162+
"as": "queries__author",
1163+
}
1164+
},
1165+
{"$unwind": "$queries__author"},
1166+
{"$match": {"$nor": [{"$or": [{"queries__author.name": "Bob"}, {"isbn": "222"}]}]}},
1167+
],
1168+
)
1169+
1170+
def test_or_mixed_local_remote_pushdown(self):
1171+
a1 = Author.objects.create(name="Alice")
1172+
a2 = Author.objects.create(name="Bob")
1173+
b1 = Book.objects.create(title="B1", author=a1, isbn="111")
1174+
b2 = Book.objects.create(title="B2", author=a2, isbn="222")
1175+
cond = models.Q(title="B1") | models.Q(author__name="Bob")
1176+
expected = [b1, b2]
1177+
with self.assertNumQueries(1) as ctx:
1178+
self.assertSequenceEqual(Book.objects.filter(cond), expected)
1179+
self.assertAggregateQuery(
1180+
ctx.captured_queries[0]["sql"],
1181+
"queries__book",
1182+
[
1183+
{
1184+
"$lookup": {
1185+
"from": "queries__author",
1186+
"let": {"parent__field__0": "$author_id"},
1187+
"pipeline": [
1188+
{
1189+
"$match": {
1190+
"$expr": {"$and": [{"$eq": ["$$parent__field__0", "$_id"]}]}
1191+
}
1192+
}
1193+
],
1194+
"as": "queries__author",
1195+
}
1196+
},
1197+
{"$unwind": "$queries__author"},
1198+
{"$match": {"$or": [{"title": "B1"}, {"queries__author.name": "Bob"}]}},
1199+
],
1200+
)

0 commit comments

Comments
 (0)