summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Storch <david.storch@mongodb.com>2020-09-11 09:51:14 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-09-14 21:10:40 +0000
commitfcad026e0d27016c7f79ee70b5a80029e4f2e89f (patch)
tree8514ac2a3dbffb31bce7cbc4267fac8110e2b7ab /src
parent5a407eb9c6c11f6da9778f08d8baf5d485c7d666 (diff)
downloadmongo-fcad026e0d27016c7f79ee70b5a80029e4f2e89f.tar.gz
SERVER-50726 Add unique id to QuerySolutionNode
This will be useful later for implementing explain output for the slot-based execution engine.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/exec/sbe/expression_test_base.h2
-rw-r--r--src/mongo/db/exec/sbe/expressions/expression.h2
-rw-r--r--src/mongo/db/exec/sbe/parser/parser.h2
-rw-r--r--src/mongo/db/exec/sbe/sbe_plan_stage_test.h2
-rw-r--r--src/mongo/db/exec/sbe/values/slot.h8
-rw-r--r--src/mongo/db/query/get_executor.cpp10
-rw-r--r--src/mongo/db/query/plan_cache.h2
-rw-r--r--src/mongo/db/query/plan_cache_test.cpp8
-rw-r--r--src/mongo/db/query/planner_analysis.cpp2
-rw-r--r--src/mongo/db/query/query_planner.cpp2
-rw-r--r--src/mongo/db/query/query_planner_options_test.cpp2
-rw-r--r--src/mongo/db/query/query_planner_test_fixture.cpp3
-rw-r--r--src/mongo/db/query/query_solution.cpp15
-rw-r--r--src/mongo/db/query/query_solution.h91
-rw-r--r--src/mongo/db/query/query_solution_test.cpp26
-rw-r--r--src/mongo/db/query/sbe_stage_builder.h2
-rw-r--r--src/mongo/db/query/sbe_stage_builder_coll_scan.h2
-rw-r--r--src/mongo/db/query/sbe_stage_builder_expression.h2
-rw-r--r--src/mongo/db/query/sbe_stage_builder_filter.h2
-rw-r--r--src/mongo/db/query/sbe_stage_builder_index_scan.h2
-rw-r--r--src/mongo/db/query/sbe_stage_builder_projection.h2
-rw-r--r--src/mongo/db/query/stage_builder_util.cpp8
-rw-r--r--src/mongo/dbtests/plan_ranking.cpp30
-rw-r--r--src/mongo/dbtests/query_stage_multiplan.cpp4
-rw-r--r--src/mongo/s/chunk_manager.cpp2
-rw-r--r--src/mongo/util/id_generator.h (renamed from src/mongo/db/exec/sbe/values/id_generators.h)10
26 files changed, 159 insertions, 84 deletions
diff --git a/src/mongo/db/exec/sbe/expression_test_base.h b/src/mongo/db/exec/sbe/expression_test_base.h
index d09deb4f2a8..9884ebb485b 100644
--- a/src/mongo/db/exec/sbe/expression_test_base.h
+++ b/src/mongo/db/exec/sbe/expression_test_base.h
@@ -32,7 +32,7 @@
#include "mongo/db/exec/sbe/expressions/expression.h"
#include "mongo/db/exec/sbe/stages/co_scan.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
+#include "mongo/db/exec/sbe/values/slot.h"
#include "mongo/db/exec/sbe/vm/vm.h"
namespace mongo::sbe {
diff --git a/src/mongo/db/exec/sbe/expressions/expression.h b/src/mongo/db/exec/sbe/expressions/expression.h
index 91c55ba9c06..c2a308992fe 100644
--- a/src/mongo/db/exec/sbe/expressions/expression.h
+++ b/src/mongo/db/exec/sbe/expressions/expression.h
@@ -34,7 +34,7 @@
#include <vector>
#include "mongo/db/exec/sbe/util/debug_print.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
+#include "mongo/db/exec/sbe/values/slot.h"
#include "mongo/db/exec/sbe/values/value.h"
#include "mongo/db/exec/sbe/vm/vm.h"
#include "mongo/stdx/unordered_map.h"
diff --git a/src/mongo/db/exec/sbe/parser/parser.h b/src/mongo/db/exec/sbe/parser/parser.h
index 87e5b04be7f..8d8819a39c5 100644
--- a/src/mongo/db/exec/sbe/parser/parser.h
+++ b/src/mongo/db/exec/sbe/parser/parser.h
@@ -36,7 +36,7 @@
#include "mongo/db/exec/sbe/stages/ix_scan.h"
#include "mongo/db/exec/sbe/stages/spool.h"
#include "mongo/db/exec/sbe/stages/stages.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
+#include "mongo/db/exec/sbe/values/slot.h"
#include "mongo/db/query/sbe_stage_builder.h"
namespace mongo {
diff --git a/src/mongo/db/exec/sbe/sbe_plan_stage_test.h b/src/mongo/db/exec/sbe/sbe_plan_stage_test.h
index 6fede2f7672..ce636d4f7ad 100644
--- a/src/mongo/db/exec/sbe/sbe_plan_stage_test.h
+++ b/src/mongo/db/exec/sbe/sbe_plan_stage_test.h
@@ -38,7 +38,7 @@
#include "mongo/db/exec/sbe/stages/project.h"
#include "mongo/db/exec/sbe/stages/unwind.h"
#include "mongo/db/exec/sbe/values/bson.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
+#include "mongo/db/exec/sbe/values/slot.h"
#include "mongo/db/exec/sbe/values/value.h"
#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
diff --git a/src/mongo/db/exec/sbe/values/slot.h b/src/mongo/db/exec/sbe/values/slot.h
index a2336250618..be51cff2215 100644
--- a/src/mongo/db/exec/sbe/values/slot.h
+++ b/src/mongo/db/exec/sbe/values/slot.h
@@ -29,9 +29,11 @@
#pragma once
-#include "mongo/db/exec/sbe/values/value.h"
#include <boost/container/small_vector.hpp>
+#include "mongo/db/exec/sbe/values/value.h"
+#include "mongo/util/id_generator.h"
+
namespace mongo {
class BufReader;
class BufBuilder;
@@ -582,4 +584,8 @@ using SlotAccessorMap = SlotMap<SlotAccessor*>;
using FieldAccessorMap = absl::flat_hash_map<std::string, std::unique_ptr<ViewOfValueAccessor>>;
using SlotSet = absl::flat_hash_set<SlotId>;
using SlotVector = std::vector<SlotId>;
+
+using SlotIdGenerator = IdGenerator<value::SlotId>;
+using FrameIdGenerator = IdGenerator<FrameId>;
+using SpoolIdGenerator = IdGenerator<SpoolId>;
} // namespace mongo::sbe::value
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp
index ea3407b8f6a..bdbf08e404f 100644
--- a/src/mongo/db/query/get_executor.cpp
+++ b/src/mongo/db/query/get_executor.cpp
@@ -1535,7 +1535,7 @@ namespace {
* Otherwise, returns 'false'.
*/
bool turnIxscanIntoCount(QuerySolution* soln) {
- QuerySolutionNode* root = soln->root.get();
+ QuerySolutionNode* root = soln->root();
// Root should be an ixscan or fetch w/o any filters.
if (!(STAGE_FETCH == root->getType() || STAGE_IXSCAN == root->getType())) {
@@ -1583,13 +1583,13 @@ bool turnIxscanIntoCount(QuerySolution* soln) {
}
// Make the count node that we replace the fetch + ixscan with.
- CountScanNode* csn = new CountScanNode(isn->index);
+ auto csn = std::make_unique<CountScanNode>(isn->index);
csn->startKey = startKey;
csn->startKeyInclusive = startKeyInclusive;
csn->endKey = endKey;
csn->endKeyInclusive = endKeyInclusive;
// Takes ownership of 'cn' and deletes the old root.
- soln->root.reset(csn);
+ soln->setRoot(std::move(csn));
return true;
}
@@ -1759,7 +1759,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorCoun
bool turnIxscanIntoDistinctIxscan(QuerySolution* soln,
const std::string& field,
bool strictDistinctOnly) {
- QuerySolutionNode* root = soln->root.get();
+ auto root = soln->root();
// We can attempt to convert a plan if it follows one of these patterns (starting from the
// root):
@@ -1898,7 +1898,7 @@ bool turnIxscanIntoDistinctIxscan(QuerySolution* soln,
root->children.clear();
// Make the fetch the new root. This destroys the project stage.
- soln->root.reset(fetchNode);
+ soln->setRoot(std::unique_ptr<QuerySolutionNode>(fetchNode));
}
// Whenver we have a FETCH node, the IXSCAN is its child. We detach the IXSCAN from the
diff --git a/src/mongo/db/query/plan_cache.h b/src/mongo/db/query/plan_cache.h
index 464370cac35..52337bac042 100644
--- a/src/mongo/db/query/plan_cache.h
+++ b/src/mongo/db/query/plan_cache.h
@@ -109,7 +109,7 @@ public:
namespace plan_ranker {
struct PlanRankingDecision;
}
-struct QuerySolution;
+class QuerySolution;
struct QuerySolutionNode;
/**
diff --git a/src/mongo/db/query/plan_cache_test.cpp b/src/mongo/db/query/plan_cache_test.cpp
index fc535b0db54..33381e7788e 100644
--- a/src/mongo/db/query/plan_cache_test.cpp
+++ b/src/mongo/db/query/plan_cache_test.cpp
@@ -1073,8 +1073,7 @@ protected:
BSONObj testSoln = fromjson(solnJson);
size_t matches = 0;
for (auto&& soln : solns) {
- QuerySolutionNode* root = soln->root.get();
- if (QueryPlannerTestLib::solutionMatches(testSoln, root)) {
+ if (QueryPlannerTestLib::solutionMatches(testSoln, soln->root())) {
++matches;
}
}
@@ -1155,8 +1154,7 @@ protected:
QuerySolution* firstMatchingSolution(const string& solnJson) const {
BSONObj testSoln = fromjson(solnJson);
for (auto&& soln : solns) {
- QuerySolutionNode* root = soln->root.get();
- if (QueryPlannerTestLib::solutionMatches(testSoln, root)) {
+ if (QueryPlannerTestLib::solutionMatches(testSoln, soln->root())) {
return soln.get();
}
}
@@ -1178,7 +1176,7 @@ protected:
*/
void assertSolutionMatches(QuerySolution* trueSoln, const string& solnJson) const {
BSONObj testSoln = fromjson(solnJson);
- if (!QueryPlannerTestLib::solutionMatches(testSoln, trueSoln->root.get())) {
+ if (!QueryPlannerTestLib::solutionMatches(testSoln, trueSoln->root())) {
str::stream ss;
ss << "Expected solution " << solnJson
<< " did not match true solution: " << trueSoln->toString() << '\n';
diff --git a/src/mongo/db/query/planner_analysis.cpp b/src/mongo/db/query/planner_analysis.cpp
index 7f446b8c757..e3fe12fad4d 100644
--- a/src/mongo/db/query/planner_analysis.cpp
+++ b/src/mongo/db/query/planner_analysis.cpp
@@ -999,7 +999,7 @@ std::unique_ptr<QuerySolution> QueryPlannerAnalysis::analyzeDataAccess(
solnRoot = tryPushdownProjectBeneathSort(std::move(solnRoot));
- soln->root = std::move(solnRoot);
+ soln->setRoot(std::move(solnRoot));
return soln;
}
diff --git a/src/mongo/db/query/query_planner.cpp b/src/mongo/db/query/query_planner.cpp
index 3f11099d0a4..18d7f3543a7 100644
--- a/src/mongo/db/query/query_planner.cpp
+++ b/src/mongo/db/query/query_planner.cpp
@@ -1063,7 +1063,7 @@ StatusWith<std::vector<std::unique_ptr<QuerySolution>>> QueryPlanner::plan(
QueryPlannerParams paramsForCoveredIxScan;
auto soln = buildWholeIXSoln(index, query, paramsForCoveredIxScan);
- if (soln && !soln->root->fetched()) {
+ if (soln && !soln->root()->fetched()) {
LOGV2_DEBUG(
20983, 5, "Planner: outputting soln that uses index to provide projection");
PlanCacheIndexTree* indexTree = new PlanCacheIndexTree();
diff --git a/src/mongo/db/query/query_planner_options_test.cpp b/src/mongo/db/query/query_planner_options_test.cpp
index 2eb180d2d9a..a82a7f405f9 100644
--- a/src/mongo/db/query/query_planner_options_test.cpp
+++ b/src/mongo/db/query/query_planner_options_test.cpp
@@ -919,7 +919,7 @@ TEST_F(QueryPlannerTest, DollarResumeAfterFieldPropagatedFromQueryRequestToStage
runQueryAsCommand(cmdObj);
assertHasOnlyCollscan();
- const auto* node = solns.front()->root.get();
+ const auto* node = solns.front()->root();
const CollectionScanNode* csn = static_cast<const CollectionScanNode*>(node);
ASSERT_EQUALS(RecordId(42LL), csn->resumeAfterRecordId.get());
}
diff --git a/src/mongo/db/query/query_planner_test_fixture.cpp b/src/mongo/db/query/query_planner_test_fixture.cpp
index 25189abcc81..0bc0a8c8f77 100644
--- a/src/mongo/db/query/query_planner_test_fixture.cpp
+++ b/src/mongo/db/query/query_planner_test_fixture.cpp
@@ -501,8 +501,7 @@ size_t QueryPlannerTest::numSolutionMatches(const std::string& solnJson) const {
BSONObj testSoln = fromjson(solnJson);
size_t matches = 0;
for (auto&& soln : solns) {
- QuerySolutionNode* root = soln->root.get();
- if (QueryPlannerTestLib::solutionMatches(testSoln, root, relaxBoundsCheck)) {
+ if (QueryPlannerTestLib::solutionMatches(testSoln, soln->root(), relaxBoundsCheck)) {
++matches;
}
}
diff --git a/src/mongo/db/query/query_solution.cpp b/src/mongo/db/query/query_solution.cpp
index 9b571f19de3..d45567d7550 100644
--- a/src/mongo/db/query/query_solution.cpp
+++ b/src/mongo/db/query/query_solution.cpp
@@ -127,6 +127,8 @@ void QuerySolutionNode::addIndent(str::stream* ss, int level) {
void QuerySolutionNode::addCommon(str::stream* ss, int indent) const {
addIndent(ss, indent + 1);
+ *ss << "nodeId = " << _nodeId << '\n';
+ addIndent(ss, indent + 1);
*ss << "fetched = " << fetched() << '\n';
addIndent(ss, indent + 1);
*ss << "sortedByDiskLoc = " << sortedByDiskLoc() << '\n';
@@ -148,6 +150,19 @@ bool QuerySolutionNode::hasNode(StageType type) const {
return false;
}
+void QuerySolution::assignNodeIds(QsnIdGenerator& idGenerator, QuerySolutionNode& node) {
+ for (auto&& child : node.children) {
+ assignNodeIds(idGenerator, *child);
+ }
+ node._nodeId = idGenerator.generate();
+}
+
+void QuerySolution::setRoot(std::unique_ptr<QuerySolutionNode> root) {
+ _root = std::move(root);
+ QsnIdGenerator idGenerator;
+ assignNodeIds(idGenerator, *_root);
+}
+
//
// TextNode
//
diff --git a/src/mongo/db/query/query_solution.h b/src/mongo/db/query/query_solution.h
index 0020b6f8442..09a9cf91f4c 100644
--- a/src/mongo/db/query/query_solution.h
+++ b/src/mongo/db/query/query_solution.h
@@ -39,6 +39,7 @@
#include "mongo/db/query/index_bounds.h"
#include "mongo/db/query/plan_cache.h"
#include "mongo/db/query/stage_types.h"
+#include "mongo/util/id_generator.h"
namespace mongo {
@@ -110,7 +111,16 @@ private:
* PlanStages, which can then be handed to a PlanRunner for execution.
*/
struct QuerySolutionNode {
- QuerySolutionNode() {}
+ /**
+ * Each node in a 'QuerySolution' tree is assigned a unique identifier of this type. The
+ * identifiers are unique within the tree, but not across trees.
+ *
+ * Ids are assigned as sequential positive integers starting from 1. An id of 0 means that no id
+ * was explicit assigned during construction of the QuerySolution.
+ */
+ using NodeId = uint32_t;
+
+ QuerySolutionNode() = default;
/**
* Constructs a QuerySolutionNode with a single child.
@@ -238,6 +248,10 @@ struct QuerySolutionNode {
*/
bool hasNode(StageType type) const;
+ NodeId nodeId() const {
+ return _nodeId;
+ }
+
// These are owned here.
//
// TODO SERVER-35512: Make this a vector of unique_ptr.
@@ -260,8 +274,13 @@ protected:
void addCommon(str::stream* ss, int indent) const;
private:
+ // Allows the QuerySolution constructor to set '_nodeId'.
+ friend class QuerySolution;
+
QuerySolutionNode(const QuerySolutionNode&) = delete;
QuerySolutionNode& operator=(const QuerySolutionNode&) = delete;
+
+ NodeId _nodeId{0u};
};
struct QuerySolutionNodeWithSortSet : public QuerySolutionNode {
@@ -291,11 +310,43 @@ struct QuerySolutionNodeWithSortSet : public QuerySolutionNode {
* A tree of stages may be built from a QuerySolution. The QuerySolution must outlive the tree
* of stages.
*/
-struct QuerySolution {
- QuerySolution() : hasBlockingStage(false), indexFilterApplied(false) {}
+class QuerySolution {
+public:
+ QuerySolution() = default;
- // Owned here.
- std::unique_ptr<QuerySolutionNode> root;
+ /**
+ * Return true if this solution tree contains a node of the given 'type'.
+ */
+ bool hasNode(StageType type) const {
+ return _root && _root->hasNode(type);
+ }
+
+ /**
+ * Output a human-readable std::string representing the plan.
+ */
+ std::string toString() {
+ if (!_root) {
+ return "empty query solution";
+ }
+
+ str::stream ss;
+ _root->appendToString(&ss, 0);
+ return ss;
+ }
+
+ const QuerySolutionNode* root() const {
+ return _root.get();
+ }
+ QuerySolutionNode* root() {
+ return _root.get();
+ }
+
+ /**
+ * Assigns the QuerySolutionNode rooted at 'root' to this QuerySolution. Also assigns a unique
+ * identifying integer to each node in the tree, which can subsequently be displayed in debug
+ * output (e.g. explain).
+ */
+ void setRoot(std::unique_ptr<QuerySolutionNode> root);
// Any filters in root or below point into this object. Must be owned.
BSONObj filterData;
@@ -309,38 +360,24 @@ struct QuerySolution {
// Hashed AND stage:
// The hashed AND stage buffers data from multiple index scans and could block. In that case,
// we would want to fall back on an alternate non-blocking solution.
- bool hasBlockingStage;
+ bool hasBlockingStage{false};
// Runner executing this solution might be interested in knowing
// if the planning process for this solution was based on filtered indices.
- bool indexFilterApplied;
+ bool indexFilterApplied{false};
// Owned here. Used by the plan cache.
std::unique_ptr<SolutionCacheData> cacheData;
- /**
- * True, of this solution tree contains a node of the given 'type'.
- */
- bool hasNode(StageType type) const {
- return root && root->hasNode(type);
- }
-
- /**
- * Output a human-readable std::string representing the plan.
- */
- std::string toString() {
- if (nullptr == root) {
- return "empty query solution";
- }
-
- str::stream ss;
- root->appendToString(&ss, 0);
- return ss;
- }
-
private:
+ using QsnIdGenerator = IdGenerator<QuerySolutionNode::NodeId>;
+
QuerySolution(const QuerySolution&) = delete;
QuerySolution& operator=(const QuerySolution&) = delete;
+
+ void assignNodeIds(QsnIdGenerator& idGenerator, QuerySolutionNode& node);
+
+ std::unique_ptr<QuerySolutionNode> _root;
};
struct TextNode : public QuerySolutionNodeWithSortSet {
diff --git a/src/mongo/db/query/query_solution_test.cpp b/src/mongo/db/query/query_solution_test.cpp
index bcb4ea7c725..e7546a854c9 100644
--- a/src/mongo/db/query/query_solution_test.cpp
+++ b/src/mongo/db/query/query_solution_test.cpp
@@ -1045,4 +1045,30 @@ TEST(QuerySolutionTest, SharedPrefixMultikeyNonMinMaxBoundsDoesNotProvideAnySort
ASSERT_EQUALS(node.providedSorts().getIgnoredFields().size(), 0U);
ASSERT_BSONOBJ_EQ(node.providedSorts().getBaseSortPattern(), BSONObj());
}
+
+TEST(QuerySolutionTest, NodeIdsAssignedInPostOrderFashionStartingFromOne) {
+ // Construct a QuerySolution consisting of a root node with two children.
+ std::vector<std::unique_ptr<QuerySolutionNode>> children;
+ children.push_back(std::make_unique<IndexScanNode>(buildSimpleIndexEntry(BSON("a" << 1))));
+ children.push_back(std::make_unique<IndexScanNode>(buildSimpleIndexEntry(BSON("b" << 1))));
+ auto orNode = std::make_unique<OrNode>();
+ orNode->addChildren(std::move(children));
+
+ // Before being added to the QuerySolution, all the nodes should have a nodeId of zero, which
+ // means that an id has not yet been assigned.
+ ASSERT_EQ(orNode->nodeId(), 0u);
+ ASSERT_EQ(orNode->children[0]->nodeId(), 0u);
+ ASSERT_EQ(orNode->children[1]->nodeId(), 0u);
+
+ auto querySolution = std::make_unique<QuerySolution>();
+ querySolution->setRoot(std::move(orNode));
+ auto root = querySolution->root();
+
+ // Since ids are assigned according to a post-order traversal, the root node should have id 3,
+ // the left child should have id 1, and the right child should have id 2.
+ ASSERT_EQ(root->nodeId(), 3);
+ ASSERT_EQ(root->children[0]->nodeId(), 1);
+ ASSERT_EQ(root->children[1]->nodeId(), 2);
+}
+
} // namespace
diff --git a/src/mongo/db/query/sbe_stage_builder.h b/src/mongo/db/query/sbe_stage_builder.h
index 3137d12156d..ad3f26625c9 100644
--- a/src/mongo/db/query/sbe_stage_builder.h
+++ b/src/mongo/db/query/sbe_stage_builder.h
@@ -30,8 +30,8 @@
#pragma once
#include "mongo/db/exec/sbe/expressions/expression.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
#include "mongo/db/exec/sbe/values/slot.h"
+#include "mongo/db/exec/sbe/values/value.h"
#include "mongo/db/exec/trial_period_utils.h"
#include "mongo/db/exec/trial_run_progress_tracker.h"
#include "mongo/db/query/plan_yield_policy_sbe.h"
diff --git a/src/mongo/db/query/sbe_stage_builder_coll_scan.h b/src/mongo/db/query/sbe_stage_builder_coll_scan.h
index f6ed8671739..345f2a411c0 100644
--- a/src/mongo/db/query/sbe_stage_builder_coll_scan.h
+++ b/src/mongo/db/query/sbe_stage_builder_coll_scan.h
@@ -31,7 +31,7 @@
#include "mongo/db/exec/sbe/expressions/expression.h"
#include "mongo/db/exec/sbe/stages/stages.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
+#include "mongo/db/exec/sbe/values/value.h"
#include "mongo/db/exec/trial_run_progress_tracker.h"
#include "mongo/db/query/query_solution.h"
diff --git a/src/mongo/db/query/sbe_stage_builder_expression.h b/src/mongo/db/query/sbe_stage_builder_expression.h
index 4193abfd847..221552b94b0 100644
--- a/src/mongo/db/query/sbe_stage_builder_expression.h
+++ b/src/mongo/db/query/sbe_stage_builder_expression.h
@@ -31,7 +31,7 @@
#include "mongo/db/exec/sbe/expressions/expression.h"
#include "mongo/db/exec/sbe/stages/stages.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
+#include "mongo/db/exec/sbe/values/value.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/pipeline/expression.h"
diff --git a/src/mongo/db/query/sbe_stage_builder_filter.h b/src/mongo/db/query/sbe_stage_builder_filter.h
index 4d1df429a35..5678d31dcf2 100644
--- a/src/mongo/db/query/sbe_stage_builder_filter.h
+++ b/src/mongo/db/query/sbe_stage_builder_filter.h
@@ -30,7 +30,7 @@
#pragma once
#include "mongo/db/exec/sbe/stages/stages.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
+#include "mongo/db/exec/sbe/values/value.h"
#include "mongo/db/matcher/expression.h"
namespace mongo::stage_builder {
diff --git a/src/mongo/db/query/sbe_stage_builder_index_scan.h b/src/mongo/db/query/sbe_stage_builder_index_scan.h
index 63389a33ba6..748e8647439 100644
--- a/src/mongo/db/query/sbe_stage_builder_index_scan.h
+++ b/src/mongo/db/query/sbe_stage_builder_index_scan.h
@@ -30,7 +30,7 @@
#pragma once
#include "mongo/db/exec/sbe/stages/stages.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
+#include "mongo/db/exec/sbe/values/value.h"
#include "mongo/db/exec/trial_run_progress_tracker.h"
#include "mongo/db/query/query_solution.h"
diff --git a/src/mongo/db/query/sbe_stage_builder_projection.h b/src/mongo/db/query/sbe_stage_builder_projection.h
index 00190b4ccd7..dac4c99d7e9 100644
--- a/src/mongo/db/query/sbe_stage_builder_projection.h
+++ b/src/mongo/db/query/sbe_stage_builder_projection.h
@@ -31,7 +31,7 @@
#include "mongo/db/exec/sbe/expressions/expression.h"
#include "mongo/db/exec/sbe/stages/stages.h"
-#include "mongo/db/exec/sbe/values/id_generators.h"
+#include "mongo/db/exec/sbe/values/value.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/query/projection.h"
diff --git a/src/mongo/db/query/stage_builder_util.cpp b/src/mongo/db/query/stage_builder_util.cpp
index 733675aa0b7..9af708df67b 100644
--- a/src/mongo/db/query/stage_builder_util.cpp
+++ b/src/mongo/db/query/stage_builder_util.cpp
@@ -46,10 +46,10 @@ std::unique_ptr<PlanStage> buildClassicExecutableTree(OperationContext* opCtx,
// $text/$where context (and $text/$where are allowed), then no attempt should be made to
// execute the query.
invariant(!cq.canHaveNoopMatchNodes());
- invariant(solution.root);
+ invariant(solution.root());
invariant(ws);
auto builder = std::make_unique<ClassicStageBuilder>(opCtx, collection, cq, solution, ws);
- return builder->build(solution.root.get());
+ return builder->build(solution.root());
}
std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData>
@@ -64,14 +64,14 @@ buildSlotBasedExecutableTree(OperationContext* opCtx,
// $text/$where context (and $text/$where are allowed), then no attempt should be made to
// execute the query.
invariant(!cq.canHaveNoopMatchNodes());
- invariant(solution.root);
+ invariant(solution.root());
auto sbeYieldPolicy = dynamic_cast<PlanYieldPolicySBE*>(yieldPolicy);
invariant(sbeYieldPolicy);
auto builder = std::make_unique<SlotBasedStageBuilder>(
opCtx, collection, cq, solution, sbeYieldPolicy, needsTrialRunProgressTracker);
- auto root = builder->build(solution.root.get());
+ auto root = builder->build(solution.root());
auto data = builder->getPlanStageData();
// Register this plan to yield according to the configured policy.
diff --git a/src/mongo/dbtests/plan_ranking.cpp b/src/mongo/dbtests/plan_ranking.cpp
index 0457a67d829..ddd7a9c51cf 100644
--- a/src/mongo/dbtests/plan_ranking.cpp
+++ b/src/mongo/dbtests/plan_ranking.cpp
@@ -243,7 +243,7 @@ public:
ASSERT(
QueryPlannerTestLib::solutionMatches("{fetch: {filter: {a:1}, node: "
"{ixscan: {filter: null, pattern: {d:1}}}}}",
- soln->root.get()));
+ soln->root()));
AutoGetCollectionForReadCommand ctx(&_opCtx, nss);
const Collection* collection = ctx.getCollection();
@@ -296,7 +296,7 @@ public:
// {a:100} is super selective so choose that.
auto soln = pickBestPlan(cq.get());
ASSERT(QueryPlannerTestLib::solutionMatches(
- "{fetch: {filter: {b:1}, node: {ixscan: {pattern: {a: 1}}}}}", soln->root.get()));
+ "{fetch: {filter: {b:1}, node: {ixscan: {pattern: {a: 1}}}}}", soln->root()));
// Turn on the "force intersect" option.
// This will be reverted by PlanRankingTestBase's destructor when the test completes.
@@ -319,7 +319,7 @@ public:
QueryPlannerTestLib::solutionMatches("{fetch: {node: {andSorted: {nodes: ["
"{ixscan: {filter: null, pattern: {a:1}}},"
"{ixscan: {filter: null, pattern: {b:1}}}]}}}}",
- soln->root.get()));
+ soln->root()));
}
};
@@ -355,7 +355,7 @@ public:
QueryPlannerTestLib::solutionMatches("{fetch: {node: {andHash: {nodes: ["
"{ixscan: {filter: null, pattern: {a:1}}},"
"{ixscan: {filter: null, pattern: {b:1}}}]}}}}",
- soln->root.get()));
+ soln->root()));
// Confirm that a backup plan is available.
ASSERT(hasBackupPlan());
@@ -392,7 +392,7 @@ public:
// Prefer the fully covered plan.
ASSERT(QueryPlannerTestLib::solutionMatches(
"{proj: {spec: {_id:0, a:1, b:1}, node: {ixscan: {pattern: {a: 1, b:1}}}}}",
- soln->root.get()));
+ soln->root()));
}
};
@@ -425,9 +425,9 @@ public:
// Anti-prefer the intersection plan.
bool bestIsScanOverA = QueryPlannerTestLib::solutionMatches(
- "{fetch: {node: {ixscan: {pattern: {a: 1}}}}}", soln->root.get());
+ "{fetch: {node: {ixscan: {pattern: {a: 1}}}}}", soln->root());
bool bestIsScanOverB = QueryPlannerTestLib::solutionMatches(
- "{fetch: {node: {ixscan: {pattern: {b: 1}}}}}", soln->root.get());
+ "{fetch: {node: {ixscan: {pattern: {b: 1}}}}}", soln->root());
ASSERT(bestIsScanOverA || bestIsScanOverB);
}
};
@@ -464,7 +464,7 @@ public:
// Prefer the fully covered plan.
ASSERT(QueryPlannerTestLib::solutionMatches(
"{proj: {spec: {_id:0, a:1, b:1}, node: {ixscan: {pattern: {a: 1, b:1}}}}}",
- soln->root.get()));
+ soln->root()));
}
};
@@ -496,7 +496,7 @@ public:
// {a: 100} is super selective so choose that.
auto soln = pickBestPlan(cq.get());
ASSERT(QueryPlannerTestLib::solutionMatches(
- "{fetch: {filter: {b:1}, node: {ixscan: {pattern: {a: 1}}}}}", soln->root.get()));
+ "{fetch: {filter: {b:1}, node: {ixscan: {pattern: {a: 1}}}}}", soln->root()));
}
};
@@ -532,7 +532,7 @@ public:
// {a: 100} is super selective so choose that.
auto soln = pickBestPlan(cq.get());
ASSERT(QueryPlannerTestLib::solutionMatches(
- "{fetch: {filter: {b:1}, node: {ixscan: {pattern: {a: 1}}}}}", soln->root.get()));
+ "{fetch: {filter: {b:1}, node: {ixscan: {pattern: {a: 1}}}}}", soln->root()));
}
};
@@ -565,7 +565,7 @@ public:
"{sort: {pattern: {c: 1}, limit: 0, type:'simple', node:"
"{fetch: {filter: null, node: "
"{ixscan: {filter: null, pattern: {_id: 1}}}}}}}",
- soln->root.get()));
+ soln->root()));
}
};
@@ -592,7 +592,7 @@ public:
// The best must be a collscan.
ASSERT(QueryPlannerTestLib::solutionMatches("{cscan: {dir: 1, filter: {foo: 2001}}}",
- soln->root.get()));
+ soln->root()));
}
};
@@ -629,7 +629,7 @@ public:
ASSERT(
QueryPlannerTestLib::solutionMatches("{fetch: {filter: {a:1}, node: "
"{ixscan: {filter: null, pattern: {d:1,e:1}}}}}",
- soln->root.get()));
+ soln->root()));
}
};
@@ -662,7 +662,7 @@ public:
// Use index on 'b'.
auto soln = pickBestPlan(cq.get());
ASSERT(QueryPlannerTestLib::solutionMatches("{fetch: {node: {ixscan: {pattern: {b: 1}}}}}",
- soln->root.get()));
+ soln->root()));
}
};
@@ -694,7 +694,7 @@ public:
// Expect to use index {a: 1, b: 1}.
auto soln = pickBestPlan(cq.get());
ASSERT(QueryPlannerTestLib::solutionMatches("{fetch: {node: {ixscan: {pattern: {a: 1}}}}}",
- soln->root.get()));
+ soln->root()));
}
};
diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp
index 4729de695ea..3d77785ac5c 100644
--- a/src/mongo/dbtests/query_stage_multiplan.cpp
+++ b/src/mongo/dbtests/query_stage_multiplan.cpp
@@ -422,7 +422,7 @@ TEST_F(QueryStageMultiPlanTest, MPSBackupPlan) {
"{fetch: {node: {andSorted: {nodes: ["
"{ixscan: {filter: null, pattern: {a:1}}},"
"{ixscan: {filter: null, pattern: {b:1}}}]}}}}}}",
- soln->root.get()));
+ soln->root()));
// Get the resulting document.
PlanStage::StageState state = PlanStage::NEED_TIME;
@@ -446,7 +446,7 @@ TEST_F(QueryStageMultiPlanTest, MPSBackupPlan) {
"{fetch: {node: {andSorted: {nodes: ["
"{ixscan: {filter: null, pattern: {a:1}}},"
"{ixscan: {filter: null, pattern: {b:1}}}]}}}}}}",
- soln->root.get()));
+ soln->root()));
// Restore index intersection force parameter.
internalQueryForceIntersectionPlans.store(forceIxisectOldValue);
diff --git a/src/mongo/s/chunk_manager.cpp b/src/mongo/s/chunk_manager.cpp
index 9ded562066c..24d0fcf715c 100644
--- a/src/mongo/s/chunk_manager.cpp
+++ b/src/mongo/s/chunk_manager.cpp
@@ -576,7 +576,7 @@ IndexBounds ChunkManager::getIndexBoundsForQuery(const BSONObj& key,
// Pick any solution that has non-trivial IndexBounds. bounds.size() == 0 represents a
// trivial IndexBounds where none of the fields' values are bounded.
for (auto&& soln : solutions) {
- IndexBounds bounds = collapseQuerySolution(soln->root.get());
+ IndexBounds bounds = collapseQuerySolution(soln->root());
if (bounds.size() > 0) {
return bounds;
}
diff --git a/src/mongo/db/exec/sbe/values/id_generators.h b/src/mongo/util/id_generator.h
index 4b3fae32cca..6f9dfb2b9ab 100644
--- a/src/mongo/db/exec/sbe/values/id_generators.h
+++ b/src/mongo/util/id_generator.h
@@ -29,9 +29,7 @@
#pragma once
-#include "mongo/db/exec/sbe/values/slot.h"
-
-namespace mongo::sbe::value {
+namespace mongo {
/**
* A reusable id generator suitable for use with integer ids that generates each new id by adding an
* increment to the previously generated id. This generator is not thread safe; calls to
@@ -76,8 +74,4 @@ public:
return idVector;
}
};
-
-using SlotIdGenerator = IdGenerator<value::SlotId>;
-using FrameIdGenerator = IdGenerator<FrameId>;
-using SpoolIdGenerator = IdGenerator<SpoolId>;
-} // namespace mongo::sbe::value
+} // namespace mongo