-
Type:
Improvement
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
-
Query Optimization
-
None
-
None
-
None
-
None
-
None
-
None
-
None
V3 explain emits queryPlanner.rankerChoice with chosenRanker but no reason for multi-planned queries whose winner runs in SBE. SERVER-132033 routed the SBE explainers through the V3 per-plan enumerator, which made appendPlanRankerChoice() reachable on the SBE path for the first time; the reason recorded during plan ranking does not survive the hand-off to the SBE executor.
Two independent gaps produce this:
- crp_sbe::MultiPlanner is constructed without the ranking result's explain data
(get_executor.cpp:866). The classic sibling at get_executor.cpp:740 passes planRankingResult.maybeExplainData, and so does the single-solution branch a few lines below the SBE one, so this looks like an omission rather than a decision. Downstream, crp_sbe::PlannerBase::prepareSbePlanExecutor() then hardcodes
boost::none /* maybeExplainData */ (classic_runtime_planner_for_sbe/planner_interface.cpp:59), so nothing recorded during ranking can reach PlanExplainerClassicRuntimePlannerForSBE.
- MPPlanRankingStrategy deliberately records no reason when
getPlanRankerReasonFromConfig() yields none - which is the case for an SBE-bound query with the internalQueryPlanRanker knob at mixed, since canUseCBR requires the classic engine (mp_plan_ranking.cpp:33). Its comment states the assumption explicitly:
"such plans never reach V3 emission, so nothing is recorded for them". That assumption held until SBE started rendering V3 output.
Repro
Set internalQueryFrameworkControl: trySbeEngine and
featureFlagGetExecutorDeferredEngineChoice: false, then explain a multi-planned find at plannerChoice, plannerStats or execStats. The default (flag on) path goes through get_executor_deferred_engine_choice_planning.cpp, which does record a reason, so this only shows up with the flag off - as configured by the
enterprise-amazon-linux2-arm64-all-feature-flags-sbe-full variant, which runs core_explain_v3_passthrough via its default tag.
Notes for the fix
Threading the explain data through crp_sbe::MultiPlanner addresses gap 1 but not gap 2:
a mixed-knob SBE query still arrives with no reason. Gap 2 needs a reason value for
"CBR requires the classic engine, so the multi-planner was used" - engine provenance in the same family as kCBRFeatureFlagDisabled. No such PlanRankerReason exists today, so this likely means a new enum member plus its mirror in the JS PlanRankerReason in jstests/libs/query/analyze_plan.js (the names must stay byte-equal).
Current behavior
SERVER-132033 relaxed appendPlanRankerChoice() to omit reason instead of tripping tassert 13237700 ("a ranking strategy decided the winning plan but recorded no reason"), which that patch had made reachable. See the comment at explain.cpp:385. Restoring the invariant - a strategy that decided always records why - is the goal of this ticket.
- is related to
-
SERVER-132033 Extend V3 explain with output from the SBE explainer
-
- In Code Review
-