-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
Query Integration
-
ALL
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Summary
When mongos delegates the merging half of a sharded $search query that references $$SEARCH_META to a shard, the metadata $mergeCursors that mongos injected into the $setVariableFromSubPipeline sub-pipeline does not survive serialization to the merging shard. The shard reparses the sub-pipeline as the bare planShardedSearch metaPipeline (e.g. [$group, $facet, $replaceRoot]), whose front stage requires an input source, and the first doGetNext() hits tripwire 6448002 ("Expected to have already attached a cursor source to the pipeline"), failing the query.
Mechanism
* cluster_aggregation_planner.cpp: partitionAndAddMergeCursorsSource() runs before the merge-location decision, injecting the data cursors as a top-level $mergeCursors and the metadata cursors into the $setVariableFromSubPipeline sub-pipeline (injectMetaCursor in sharded_agg_helpers.cpp).
* When the merge is delegated (createCommandForMergingShard), the top-level data $mergeCursors serializes with its remotes, but the sub-pipeline's injected initial source is dropped -- the production-captured command (see AF-18751) shows the bare metaPipeline.
* On the shard, DocumentSourceSetVariableFromSubPipeline::createFromBson reparses the sub-pipeline; nothing reattaches a cursor source; tassert 6448002 fires on first execution.
Reproduction
Deterministic shard-side repro attached (af18751_repro.js): replays the captured merging-command shape directly against an 8.0 shard (internal-client hello; no mongot required). Fails with 6448002 on stock 8.0.27 binaries.
The router-side trigger (what makes mongos choose shard-merge for a SEARCH_META pipeline) was not reproduced locally: after meta-cursor injection the merge pipeline reports required-to-run-on-router in a 2-shard mongotmock fixture, overriding both internalQueryProhibitMergingOnMongoS and $_internalSplitPipeline. The production occurrence (3-shard cluster, single targeted remote, secondaryPreferred, allowDiskUse, metaPipeline containing $facet) evidently reached a delegating dispatch path -- identifying it is part of this ticket.
Fix directions
Either (a) make the setVariable sub-pipeline's cursor source survive the mongos->shard hop (serialize + reattach, as the top-level $mergeCursors does), or (b) make SEARCH_META merge pipelines explicitly router-only in the dispatch decision so delegation cannot occur.
Acceptance criteria
The attached repro shape no longer trips 6448002 (either executes correctly with merged metadata or fails with a clean, non-tripwire error), plus a regression test covering the end-to-end router path once identified.