summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew Paroski <drew.paroski@mongodb.com>2020-05-07 01:18:25 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-05-13 00:35:44 +0000
commit6ed3c7611c6fdf992360c12765773f94fd903297 (patch)
tree83f21c3cbf2dfaf5cfaf655d4b2b68fbc3a2faa6
parentcb3f49285f8a5663244f94d89e56c2f28f7ae685 (diff)
downloadmongo-6ed3c7611c6fdf992360c12765773f94fd903297.tar.gz
SERVER-47596 Add a common parent class for QuerySolutionNodes with a ProvidedSortSet field
-rw-r--r--src/mongo/db/query/query_solution.cpp27
-rw-r--r--src/mongo/db/query/query_solution.h120
2 files changed, 40 insertions, 107 deletions
diff --git a/src/mongo/db/query/query_solution.cpp b/src/mongo/db/query/query_solution.cpp
index 18d05847bb5..1d51d66022b 100644
--- a/src/mongo/db/query/query_solution.cpp
+++ b/src/mongo/db/query/query_solution.cpp
@@ -166,7 +166,6 @@ QuerySolutionNode* TextNode::clone() const {
TextNode* copy = new TextNode(this->index);
cloneBaseData(copy);
- copy->_sort = this->_sort;
copy->ftsQuery = this->ftsQuery->clone();
copy->indexPrefix = this->indexPrefix;
@@ -195,7 +194,6 @@ QuerySolutionNode* CollectionScanNode::clone() const {
CollectionScanNode* copy = new CollectionScanNode();
cloneBaseData(copy);
- copy->_sort = this->_sort;
copy->name = this->name;
copy->tailable = this->tailable;
copy->direction = this->direction;
@@ -251,9 +249,6 @@ FieldAvailability AndHashNode::getFieldAvailability(const string& field) const {
QuerySolutionNode* AndHashNode::clone() const {
AndHashNode* copy = new AndHashNode();
cloneBaseData(copy);
-
- copy->_sort = this->_sort;
-
return copy;
}
@@ -299,9 +294,6 @@ FieldAvailability AndSortedNode::getFieldAvailability(const string& field) const
QuerySolutionNode* AndSortedNode::clone() const {
AndSortedNode* copy = new AndSortedNode();
cloneBaseData(copy);
-
- copy->_sort = this->_sort;
-
return copy;
}
@@ -358,7 +350,6 @@ QuerySolutionNode* OrNode::clone() const {
OrNode* copy = new OrNode();
cloneBaseData(copy);
- copy->_sort = this->_sort;
copy->dedup = this->dedup;
return copy;
@@ -417,7 +408,6 @@ QuerySolutionNode* MergeSortNode::clone() const {
MergeSortNode* copy = new MergeSortNode();
cloneBaseData(copy);
- copy->_sorts = this->_sorts;
copy->dedup = this->dedup;
copy->sort = this->sort;
@@ -449,9 +439,6 @@ void FetchNode::appendToString(str::stream* ss, int indent) const {
QuerySolutionNode* FetchNode::clone() const {
FetchNode* copy = new FetchNode();
cloneBaseData(copy);
-
- copy->_sorts = this->_sorts;
-
return copy;
}
@@ -886,7 +873,7 @@ std::pair<ProvidedSortSet, std::set<StringData>> computeSortsAndMultikeyPathsFor
} // namespace
void IndexScanNode::computeProperties() {
- std::tie(_sorts, multikeyFields) =
+ std::tie(sortSet, multikeyFields) =
computeSortsAndMultikeyPathsForScan(index, direction, bounds, queryCollator);
}
@@ -894,7 +881,6 @@ QuerySolutionNode* IndexScanNode::clone() const {
IndexScanNode* copy = new IndexScanNode(this->index);
cloneBaseData(copy);
- copy->_sorts = this->_sorts;
copy->direction = this->direction;
copy->addKeyMetadata = this->addKeyMetadata;
copy->bounds = this->bounds;
@@ -981,7 +967,7 @@ void ProjectionNode::computeProperties() {
}
prefixBob.append(key);
}
- _sorts = ProvidedSortSet(prefixBob.obj(), inputSorts.getIgnoredFields());
+ sortSet = ProvidedSortSet(prefixBob.obj(), inputSorts.getIgnoredFields());
}
void ProjectionNode::cloneProjectionData(ProjectionNode* copy) const {
@@ -989,7 +975,7 @@ void ProjectionNode::cloneProjectionData(ProjectionNode* copy) const {
if (this->filter)
copy->filter = this->filter->shallowClone();
- copy->_sorts = this->_sorts;
+ copy->sortSet = this->sortSet;
}
ProjectionNode* ProjectionNodeDefault::clone() const {
@@ -1060,7 +1046,6 @@ void SortNode::appendToString(str::stream* ss, int indent) const {
void SortNode::cloneSortData(SortNode* copy) const {
cloneBaseData(copy);
- copy->_sorts = this->_sorts;
copy->pattern = this->pattern;
copy->limit = this->limit;
copy->addSortKeyMetadata = this->addSortKeyMetadata;
@@ -1151,7 +1136,6 @@ QuerySolutionNode* GeoNear2DNode::clone() const {
GeoNear2DNode* copy = new GeoNear2DNode(this->index);
cloneBaseData(copy);
- copy->_sorts = this->_sorts;
copy->nq = this->nq;
copy->baseBounds = this->baseBounds;
copy->addPointMeta = this->addPointMeta;
@@ -1185,7 +1169,6 @@ QuerySolutionNode* GeoNear2DSphereNode::clone() const {
GeoNear2DSphereNode* copy = new GeoNear2DSphereNode(this->index);
cloneBaseData(copy);
- copy->_sorts = this->_sorts;
copy->nq = this->nq;
copy->baseBounds = this->baseBounds;
copy->addPointMeta = this->addPointMeta;
@@ -1241,7 +1224,6 @@ QuerySolutionNode* DistinctNode::clone() const {
DistinctNode* copy = new DistinctNode(this->index);
cloneBaseData(copy);
- copy->sorts = this->sorts;
copy->direction = this->direction;
copy->bounds = this->bounds;
copy->queryCollator = this->queryCollator;
@@ -1253,7 +1235,7 @@ QuerySolutionNode* DistinctNode::clone() const {
void DistinctNode::computeProperties() {
// Note that we don't need to save the returned multikey fields for a DISTINCT_SCAN. They are
// only needed for explodeForSort(), which works on IXSCAN but not DISTINCT_SCAN.
- sorts = computeSortsAndMultikeyPathsForScan(index, direction, bounds, queryCollator).first;
+ sortSet = computeSortsAndMultikeyPathsForScan(index, direction, bounds, queryCollator).first;
}
//
@@ -1277,7 +1259,6 @@ QuerySolutionNode* CountScanNode::clone() const {
CountScanNode* copy = new CountScanNode(this->index);
cloneBaseData(copy);
- copy->sorts = this->sorts;
copy->startKey = this->startKey;
copy->startKeyInclusive = this->startKeyInclusive;
copy->endKey = this->endKey;
diff --git a/src/mongo/db/query/query_solution.h b/src/mongo/db/query/query_solution.h
index ba0f06d5fca..4d8e5c06ee7 100644
--- a/src/mongo/db/query/query_solution.h
+++ b/src/mongo/db/query/query_solution.h
@@ -259,6 +259,27 @@ private:
QuerySolutionNode& operator=(const QuerySolutionNode&) = delete;
};
+struct QuerySolutionNodeWithSortSet : public QuerySolutionNode {
+ QuerySolutionNodeWithSortSet() = default;
+
+ /**
+ * This constructor is only useful for QuerySolutionNodes with a single child.
+ */
+ explicit QuerySolutionNodeWithSortSet(std::unique_ptr<QuerySolutionNode> child)
+ : QuerySolutionNode(std::move(child)) {}
+
+ const ProvidedSortSet& providedSorts() const final {
+ return sortSet;
+ }
+
+ void cloneBaseData(QuerySolutionNodeWithSortSet* other) const {
+ QuerySolutionNode::cloneBaseData(other);
+ other->sortSet = sortSet;
+ }
+
+ ProvidedSortSet sortSet;
+};
+
/**
* A QuerySolution must be entirely self-contained and own everything inside of it.
*
@@ -310,7 +331,7 @@ private:
QuerySolution& operator=(const QuerySolution&) = delete;
};
-struct TextNode : public QuerySolutionNode {
+struct TextNode : public QuerySolutionNodeWithSortSet {
TextNode(IndexEntry index) : index(std::move(index)) {}
virtual ~TextNode() {}
@@ -331,14 +352,9 @@ struct TextNode : public QuerySolutionNode {
bool sortedByDiskLoc() const {
return false;
}
- const ProvidedSortSet& providedSorts() const {
- return _sort;
- }
QuerySolutionNode* clone() const;
- ProvidedSortSet _sort;
-
IndexEntry index;
std::unique_ptr<fts::FTSQuery> ftsQuery;
@@ -355,7 +371,7 @@ struct TextNode : public QuerySolutionNode {
BSONObj indexPrefix;
};
-struct CollectionScanNode : public QuerySolutionNode {
+struct CollectionScanNode : public QuerySolutionNodeWithSortSet {
CollectionScanNode();
virtual ~CollectionScanNode() {}
@@ -374,14 +390,9 @@ struct CollectionScanNode : public QuerySolutionNode {
bool sortedByDiskLoc() const {
return false;
}
- const ProvidedSortSet& providedSorts() const {
- return _sort;
- }
QuerySolutionNode* clone() const;
- ProvidedSortSet _sort;
-
// Name of the namespace.
std::string name;
@@ -441,11 +452,9 @@ struct AndHashNode : public QuerySolutionNode {
}
QuerySolutionNode* clone() const;
-
- ProvidedSortSet _sort;
};
-struct AndSortedNode : public QuerySolutionNode {
+struct AndSortedNode : public QuerySolutionNodeWithSortSet {
AndSortedNode();
virtual ~AndSortedNode();
@@ -460,16 +469,11 @@ struct AndSortedNode : public QuerySolutionNode {
bool sortedByDiskLoc() const {
return true;
}
- const ProvidedSortSet& providedSorts() const {
- return _sort;
- }
QuerySolutionNode* clone() const;
-
- ProvidedSortSet _sort;
};
-struct OrNode : public QuerySolutionNode {
+struct OrNode : public QuerySolutionNodeWithSortSet {
OrNode();
virtual ~OrNode();
@@ -486,18 +490,13 @@ struct OrNode : public QuerySolutionNode {
// any order on the output.
return false;
}
- const ProvidedSortSet& providedSorts() const {
- return _sort;
- }
QuerySolutionNode* clone() const;
- ProvidedSortSet _sort;
-
bool dedup;
};
-struct MergeSortNode : public QuerySolutionNode {
+struct MergeSortNode : public QuerySolutionNodeWithSortSet {
MergeSortNode();
virtual ~MergeSortNode();
@@ -513,21 +512,15 @@ struct MergeSortNode : public QuerySolutionNode {
return false;
}
- const ProvidedSortSet& providedSorts() const {
- return _sorts;
- }
-
QuerySolutionNode* clone() const;
virtual void computeProperties() {
for (size_t i = 0; i < children.size(); ++i) {
children[i]->computeProperties();
}
- _sorts = ProvidedSortSet(sort, std::set<std::string>());
+ sortSet = ProvidedSortSet(sort, std::set<std::string>());
}
- ProvidedSortSet _sorts;
-
BSONObj sort;
bool dedup;
};
@@ -556,11 +549,9 @@ struct FetchNode : public QuerySolutionNode {
}
QuerySolutionNode* clone() const;
-
- ProvidedSortSet _sorts;
};
-struct IndexScanNode : public QuerySolutionNode {
+struct IndexScanNode : public QuerySolutionNodeWithSortSet {
IndexScanNode(IndexEntry index);
virtual ~IndexScanNode() {}
@@ -577,9 +568,6 @@ struct IndexScanNode : public QuerySolutionNode {
}
FieldAvailability getFieldAvailability(const std::string& field) const;
bool sortedByDiskLoc() const;
- const ProvidedSortSet& providedSorts() const {
- return _sorts;
- }
QuerySolutionNode* clone() const;
@@ -593,8 +581,6 @@ struct IndexScanNode : public QuerySolutionNode {
static std::set<StringData> getFieldsWithStringBounds(const IndexBounds& bounds,
const BSONObj& indexKeyPattern);
- ProvidedSortSet _sorts;
-
IndexEntry index;
int direction;
@@ -650,11 +636,11 @@ struct ReturnKeyNode : public QuerySolutionNode {
* is much slower than the fast-path implementations. We only really have all the information
* available to choose a projection implementation at planning time.
*/
-struct ProjectionNode : QuerySolutionNode {
+struct ProjectionNode : public QuerySolutionNodeWithSortSet {
ProjectionNode(std::unique_ptr<QuerySolutionNode> child,
const MatchExpression& fullExpression,
projection_ast::Projection proj)
- : QuerySolutionNode(std::move(child)),
+ : QuerySolutionNodeWithSortSet(std::move(child)),
fullExpression(fullExpression),
proj(std::move(proj)) {}
@@ -688,10 +674,6 @@ struct ProjectionNode : QuerySolutionNode {
return children[0]->sortedByDiskLoc();
}
- const ProvidedSortSet& providedSorts() const {
- return _sorts;
- }
-
protected:
void cloneProjectionData(ProjectionNode* copy) const;
@@ -701,8 +683,6 @@ public:
*/
virtual StringData projectionImplementationTypeToString() const = 0;
- ProvidedSortSet _sorts;
-
// The full query tree. Needed when we have positional operators.
// Owned in the CanonicalQuery, not here.
const MatchExpression& fullExpression;
@@ -799,7 +779,7 @@ struct SortKeyGeneratorNode : public QuerySolutionNode {
BSONObj sortSpec;
};
-struct SortNode : public QuerySolutionNode {
+struct SortNode : public QuerySolutionNodeWithSortSet {
SortNode() : limit(0) {}
virtual ~SortNode() {}
@@ -816,19 +796,13 @@ struct SortNode : public QuerySolutionNode {
return false;
}
- const ProvidedSortSet& providedSorts() const {
- return _sorts;
- }
-
virtual void computeProperties() {
for (size_t i = 0; i < children.size(); ++i) {
children[i]->computeProperties();
}
- _sorts = ProvidedSortSet(pattern, std::set<std::string>());
+ sortSet = ProvidedSortSet(pattern, std::set<std::string>());
}
- ProvidedSortSet _sorts;
-
BSONObj pattern;
// Sum of both limit and skip count in the parsed query.
@@ -931,8 +905,7 @@ struct SkipNode : public QuerySolutionNode {
long long skip;
};
-// This is a standalone stage.
-struct GeoNear2DNode : public QuerySolutionNode {
+struct GeoNear2DNode : public QuerySolutionNodeWithSortSet {
GeoNear2DNode(IndexEntry index)
: index(std::move(index)), addPointMeta(false), addDistMeta(false) {}
@@ -952,14 +925,9 @@ struct GeoNear2DNode : public QuerySolutionNode {
bool sortedByDiskLoc() const {
return false;
}
- const ProvidedSortSet& providedSorts() const {
- return _sorts;
- }
QuerySolutionNode* clone() const;
- ProvidedSortSet _sorts;
-
// Not owned here
const GeoNearExpression* nq;
IndexBounds baseBounds;
@@ -969,8 +937,7 @@ struct GeoNear2DNode : public QuerySolutionNode {
bool addDistMeta;
};
-// This is actually its own standalone stage.
-struct GeoNear2DSphereNode : public QuerySolutionNode {
+struct GeoNear2DSphereNode : public QuerySolutionNodeWithSortSet {
GeoNear2DSphereNode(IndexEntry index)
: index(std::move(index)), addPointMeta(false), addDistMeta(false) {}
@@ -990,14 +957,9 @@ struct GeoNear2DSphereNode : public QuerySolutionNode {
bool sortedByDiskLoc() const {
return false;
}
- const ProvidedSortSet& providedSorts() const {
- return _sorts;
- }
QuerySolutionNode* clone() const;
- ProvidedSortSet _sorts;
-
// Not owned here
const GeoNearExpression* nq;
IndexBounds baseBounds;
@@ -1046,7 +1008,7 @@ struct ShardingFilterNode : public QuerySolutionNode {
* Distinct queries only want one value for a given field. We run an index scan but
* *always* skip over the current key to the next key.
*/
-struct DistinctNode : public QuerySolutionNode {
+struct DistinctNode : public QuerySolutionNodeWithSortSet {
DistinctNode(IndexEntry index) : index(std::move(index)) {}
virtual ~DistinctNode() {}
@@ -1072,16 +1034,11 @@ struct DistinctNode : public QuerySolutionNode {
bool sortedByDiskLoc() const {
return false;
}
- const ProvidedSortSet& providedSorts() const {
- return sorts;
- }
QuerySolutionNode* clone() const;
virtual void computeProperties();
- ProvidedSortSet sorts;
-
IndexEntry index;
IndexBounds bounds;
@@ -1096,7 +1053,7 @@ struct DistinctNode : public QuerySolutionNode {
* Some count queries reduce to counting how many keys are between two entries in a
* Btree.
*/
-struct CountScanNode : public QuerySolutionNode {
+struct CountScanNode : public QuerySolutionNodeWithSortSet {
CountScanNode(IndexEntry index) : index(std::move(index)) {}
virtual ~CountScanNode() {}
@@ -1115,14 +1072,9 @@ struct CountScanNode : public QuerySolutionNode {
bool sortedByDiskLoc() const {
return false;
}
- const ProvidedSortSet& providedSorts() const {
- return sorts;
- }
QuerySolutionNode* clone() const;
- ProvidedSortSet sorts;
-
IndexEntry index;
BSONObj startKey;