summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/query_solution.h
diff options
context:
space:
mode:
authorHari Khalsa <hkhalsa@10gen.com>2013-09-18 11:57:21 -0400
committerHari Khalsa <hkhalsa@10gen.com>2013-09-18 16:42:20 -0400
commit311ebc33f399b555309ee6eba04af8c605108529 (patch)
treebe50e3cfea0c124759ded943a5d1c7cc5a79910b /src/mongo/db/query/query_solution.h
parentde25d5b966fae434669df47b41c076445d2303f6 (diff)
downloadmongo-311ebc33f399b555309ee6eba04af8c605108529.tar.gz
SERVER-10026 enumeration as strategies, bug fixes galore, build plans
Diffstat (limited to 'src/mongo/db/query/query_solution.h')
-rw-r--r--src/mongo/db/query/query_solution.h189
1 files changed, 180 insertions, 9 deletions
diff --git a/src/mongo/db/query/query_solution.h b/src/mongo/db/query/query_solution.h
index 24b36fadf7d..d5333ec68bb 100644
--- a/src/mongo/db/query/query_solution.h
+++ b/src/mongo/db/query/query_solution.h
@@ -49,8 +49,18 @@ namespace mongo {
/**
* Internal function called by toString()
+ *
+ * TODO: Consider outputting into a BSONObj or builder thereof.
*/
- virtual void appendToString(stringstream* ss) const = 0;
+ virtual void appendToString(stringstream* ss, int indent) const = 0;
+
+ protected:
+ static void addIndent(stringstream* ss, int level) {
+ for (int i = 0; i < level; ++i) {
+ *ss << "---";
+ }
+ }
+
private:
MONGO_DISALLOW_COPYING(QuerySolutionNode);
};
@@ -73,6 +83,8 @@ namespace mongo {
// Any filters in root or below point into this. Must be owned.
BSONObj filterData;
+ string ns;
+
/**
* Output a human-readable string representing the plan.
*/
@@ -82,7 +94,7 @@ namespace mongo {
}
stringstream ss;
- root->appendToString(&ss);
+ root->appendToString(&ss, 0);
return ss.str();
}
private:
@@ -94,8 +106,15 @@ namespace mongo {
virtual StageType getType() const { return STAGE_COLLSCAN; }
- virtual void appendToString(stringstream* ss) const {
- *ss << "COLLSCAN ns=" << name << " filter= " << filter->toString() << endl;
+ virtual void appendToString(stringstream* ss, int indent) const {
+ addIndent(ss, indent);
+ *ss << "COLLSCAN";
+ addIndent(ss, indent + 1);
+ *ss << "ns = " << name;
+ if (NULL != filter) {
+ addIndent(ss, indent + 1);
+ *ss << " filter = " << filter->toString() << endl;
+ }
}
// Name of the namespace.
@@ -112,18 +131,96 @@ namespace mongo {
MatchExpression* filter;
};
+ struct AndHashNode : public QuerySolutionNode {
+ AndHashNode() : filter(NULL) { }
+ ~AndHashNode() {
+ for (size_t i = 0; i < children.size(); ++i) {
+ delete children[i];
+ }
+ }
+ virtual StageType getType() const { return STAGE_AND_HASH; }
+ virtual void appendToString(stringstream* ss, int indent) const {
+ addIndent(ss, indent);
+ *ss << "AND_HASH";
+ if (NULL != filter) {
+ addIndent(ss, indent + 1);
+ *ss << " filter = " << filter->toString() << endl;
+ }
+ for (size_t i = 0; i < children.size(); ++i) {
+ *ss << "Child " << i << ": ";
+ children[i]->appendToString(ss, indent + 1);
+ }
+ }
+ MatchExpression* filter;
+ vector<QuerySolutionNode*> children;
+ };
+
+ struct OrNode : public QuerySolutionNode {
+ OrNode() : dedup(true), filter(NULL) { }
+ ~OrNode() {
+ for (size_t i = 0; i < children.size(); ++i) {
+ delete children[i];
+ }
+ }
+ virtual StageType getType() const { return STAGE_OR; }
+ virtual void appendToString(stringstream* ss, int indent) const {
+ addIndent(ss, indent);
+ *ss << "OR\n";
+ if (NULL != filter) {
+ addIndent(ss, indent + 1);
+ *ss << " filter = " << filter->toString() << endl;
+ }
+ for (size_t i = 0; i < children.size(); ++i) {
+ addIndent(ss, indent + 1);
+ *ss << "Child " << i << ":\n";
+ children[i]->appendToString(ss, indent + 2);
+ *ss << endl;
+ }
+ }
+ bool dedup;
+ MatchExpression* filter;
+ vector<QuerySolutionNode*> children;
+ };
+
+ struct FetchNode : public QuerySolutionNode {
+ FetchNode() : filter(NULL) { }
+ virtual StageType getType() const { return STAGE_FETCH; }
+ virtual void appendToString(stringstream* ss, int indent) const {
+ addIndent(ss, indent);
+ *ss << "FETCH\n";
+ if (NULL != filter) {
+ addIndent(ss, indent + 1);
+ StringBuilder sb;
+ *ss << "filter:\n";
+ filter->debugString(sb, indent + 2);
+ *ss << sb.str();
+ }
+ addIndent(ss, indent + 1);
+ *ss << "Child:" << endl;
+ child->appendToString(ss, indent + 2);
+ }
+ MatchExpression* filter;
+ scoped_ptr<QuerySolutionNode> child;
+ };
+
struct IndexScanNode : public QuerySolutionNode {
IndexScanNode() : filter(NULL), limit(0), direction(1) { }
virtual StageType getType() const { return STAGE_IXSCAN; }
- virtual void appendToString(stringstream* ss) const {
- *ss << "IXSCAN kp=" << indexKeyPattern;
+ virtual void appendToString(stringstream* ss, int indent) const {
+ addIndent(ss, indent);
+ *ss << "IXSCAN\n";
+ addIndent(ss, indent + 1);
+ *ss << "keyPattern = " << indexKeyPattern << endl;
if (NULL != filter) {
- *ss << " filter= " << filter->toString();
+ addIndent(ss, indent + 1);
+ *ss << " filter= " << filter->toString() << endl;
}
- *ss << " dir = " << direction;
- *ss << " bounds = " << bounds.toString();
+ addIndent(ss, indent + 1);
+ *ss << "dir = " << direction << endl;
+ addIndent(ss, indent + 1);
+ *ss << "bounds = " << bounds.toString();
}
BSONObj indexKeyPattern;
@@ -141,4 +238,78 @@ namespace mongo {
IndexBounds bounds;
};
+ struct ProjectionNode : public QuerySolutionNode {
+ ProjectionNode() { }
+ virtual StageType getType() const { return STAGE_PROJECTION; }
+
+ virtual void appendToString(stringstream* ss, int indent) const {
+ addIndent(ss, indent);
+ *ss << "PROJ\n";
+ addIndent(ss, indent + 1);
+ *ss << "proj = " << projection.toString() << endl;
+ addIndent(ss, indent + 1);
+ *ss << "Child:" << endl;
+ child->appendToString(ss, indent + 2);
+ }
+
+ BSONObj projection;
+ scoped_ptr<QuerySolutionNode> child;
+ // TODO: Filter
+ };
+
+ struct SortNode : public QuerySolutionNode {
+ SortNode() { }
+ virtual StageType getType() const { return STAGE_SORT; }
+
+ virtual void appendToString(stringstream* ss, int indent) const {
+ addIndent(ss, indent);
+ *ss << "SORT\n";
+ addIndent(ss, indent + 1);
+ *ss << "pattern = " << pattern.toString() << endl;
+ addIndent(ss, indent + 1);
+ *ss << "Child:" << endl;
+ child->appendToString(ss, indent + 2);
+ }
+
+ BSONObj pattern;
+ scoped_ptr<QuerySolutionNode> child;
+ // TODO: Filter
+ };
+
+ struct LimitNode : public QuerySolutionNode {
+ LimitNode() { }
+ virtual StageType getType() const { return STAGE_LIMIT; }
+
+ virtual void appendToString(stringstream* ss, int indent) const {
+ addIndent(ss, indent);
+ *ss << "LIMIT\n";
+ addIndent(ss, indent + 1);
+ *ss << "limit = " << limit << endl;
+ addIndent(ss, indent + 1);
+ *ss << "Child:" << endl;
+ child->appendToString(ss, indent + 2);
+ }
+
+ int limit;
+ scoped_ptr<QuerySolutionNode> child;
+ };
+
+ struct SkipNode : public QuerySolutionNode {
+ SkipNode() { }
+ virtual StageType getType() const { return STAGE_SKIP; }
+
+ virtual void appendToString(stringstream* ss, int indent) const {
+ addIndent(ss, indent);
+ *ss << "SKIP\n";
+ addIndent(ss, indent + 1);
+ *ss << "skip= " << skip << endl;
+ addIndent(ss, indent + 1);
+ *ss << "Child:" << endl;
+ child->appendToString(ss, indent + 2);
+ }
+
+ int skip;
+ scoped_ptr<QuerySolutionNode> child;
+ };
+
} // namespace mongo