Skip to content

Commit c49e345

Browse files
WaVEVtimgraham
authored andcommitted
fix queries when subquery has a union
1 parent b730288 commit c49e345

File tree

3 files changed

+47
-38
lines changed

3 files changed

+47
-38
lines changed

django_mongodb/compiler.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,13 +434,16 @@ def project_field(column):
434434
)
435435

436436
@cached_property
437-
def collection_name(self):
438-
base_table = next(
437+
def base_table(self):
438+
return next(
439439
v
440440
for k, v in self.query.alias_map.items()
441441
if isinstance(v, BaseTable) and self.query.alias_refcount[k]
442442
)
443-
return base_table.table_alias or base_table.table_name
443+
444+
@cached_property
445+
def collection_name(self):
446+
return self.base_table.table_alias or self.base_table.table_name
444447

445448
@cached_property
446449
def collection(self):
@@ -469,6 +472,7 @@ def get_combinator_queries(self):
469472
)
470473
)
471474
compiler_.pre_sql_setup()
475+
compiler_.column_indices = self.column_indices
472476
columns = compiler_.get_columns()
473477
parts.append((compiler_.build_query(columns), compiler_, columns))
474478
except EmptyResultSet:
@@ -496,7 +500,12 @@ def get_combinator_queries(self):
496500
# Combine query with the current combinator pipeline.
497501
if combinator_pipeline:
498502
combinator_pipeline.append(
499-
{"$unionWith": {"coll": compiler_.collection_name, "pipeline": inner_pipeline}}
503+
{
504+
"$unionWith": {
505+
"coll": compiler_.base_table.table_name,
506+
"pipeline": inner_pipeline,
507+
}
508+
}
500509
)
501510
else:
502511
combinator_pipeline = inner_pipeline

django_mongodb/expressions.py

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -122,39 +122,44 @@ def query(self, compiler, connection, lookup_name=None):
122122
if lookup_name in ("in", "range"):
123123
if subquery.aggregation_pipeline is None:
124124
subquery.aggregation_pipeline = []
125-
subquery.aggregation_pipeline.extend(
126-
[
127-
{
128-
"$facet": {
129-
"group": [
125+
wrapping_result_pipeline = [
126+
{
127+
"$facet": {
128+
"group": [
129+
{
130+
"$group": {
131+
"_id": None,
132+
"tmp_name": {
133+
"$addToSet": expr.as_mql(subquery_compiler, connection)
134+
},
135+
}
136+
}
137+
]
138+
}
139+
},
140+
{
141+
"$project": {
142+
field_name: {
143+
"$ifNull": [
130144
{
131-
"$group": {
132-
"_id": None,
133-
"tmp_name": {
134-
"$addToSet": expr.as_mql(subquery_compiler, connection)
135-
},
145+
"$getField": {
146+
"input": {"$arrayElemAt": ["$group", 0]},
147+
"field": "tmp_name",
136148
}
137-
}
149+
},
150+
[],
138151
]
139152
}
140-
},
141-
{
142-
"$project": {
143-
field_name: {
144-
"$ifNull": [
145-
{
146-
"$getField": {
147-
"input": {"$arrayElemAt": ["$group", 0]},
148-
"field": "tmp_name",
149-
}
150-
},
151-
[],
152-
]
153-
}
154-
}
155-
},
156-
]
157-
)
153+
}
154+
},
155+
]
156+
# If the subquery is a combinator, wrap the result at the end of the
157+
# combinator pipeline...
158+
if subquery.query.combinator:
159+
subquery.combinator_pipeline.extend(wrapping_result_pipeline)
160+
# ... otherwise put at the end of subquery's pipeline.
161+
else:
162+
subquery.aggregation_pipeline.extend(wrapping_result_pipeline)
158163
# Erase project_fields since the required value is projected above.
159164
subquery.project_fields = None
160165
compiler.subqueries.append(subquery)

django_mongodb/features.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
7373
# Connection creation doesn't follow the usual Django API.
7474
"backends.tests.ThreadTests.test_pass_connection_between_threads",
7575
"backends.tests.ThreadTests.test_default_connection_thread_local",
76-
# Union as subquery is not mapping the parent parameter and collections:
77-
# https://github.com/mongodb-labs/django-mongodb/issues/156
78-
"queries.test_qs_combinators.QuerySetSetOperationTests.test_union_in_subquery_related_outerref",
79-
"queries.test_qs_combinators.QuerySetSetOperationTests.test_union_in_subquery",
80-
"queries.test_qs_combinators.QuerySetSetOperationTests.test_union_in_with_ordering",
8176
# ObjectId type mismatch in a subquery:
8277
# https://github.com/mongodb-labs/django-mongodb/issues/161
8378
"queries.tests.RelatedLookupTypeTests.test_values_queryset_lookup",

0 commit comments

Comments
 (0)