-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
-
Query Optimization
-
Fully Compatible
-
ALL
-
200
-
None
-
None
-
None
-
None
-
None
-
None
-
None
[
{ $set: { "a.b.c": 1 } },
{ $project: {
"a.str": "value",
"a.b.c": 1
}}
]
When including a path like "a.b.c", we have a tassert saying that if the base "a" is already present in the scope, it must have been modified in the current stage, and not trivially included / referenced from earlier stage.
This guards "including" / adding a reference to a prior field into a base field which was itself only referenced in the current scope. This expectation is broken when processing the subpath "b.c".
{ $project: {
"a.str": "value",
"a.b.c": 1
}}
In conjunction with a modification, the sequence the graph sees when processing the above is:
1. Modify "a.str"
1.a Declare modified "a" with references to all fields from before (including referencing "a.b")
1.b Declare subfield "a.str"
2. Include "a.b.c"
2.a Include "a" (remainder "b.c") no-op - "a" modified cannot include it - tassert passes ("a" exists in this scope already but is modified - "a.str" redeclared "a')
2.b Include "b" (remainder "c") into the scope for the embedded "a" document - tassert FAILS - "b" already present in this scope, but it is just a reference to prior "b".
2.c (if tassert is removed) Include "c" inside "b" would alter the previous instance of "b" declared in the previous stage.
However, the issue is not the assert, but the fact that we included 'b' in the first place. This was caused by SERVER-128465 - it needed the prior value of a modified path's prefix inside an exhaustive stage, so that in
{ $project: { "a.b": "$x" } }
the base "a" keeps the arrayness it had before the projection (the modification array-traverses the previous value), but it accidentally preserved the subfields too.
- is related to
-
SERVER-128465 Fix dependency graph arrayness for dotted path modifications that array-traverse their prefix
-
- Closed
-