summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/planner_access.h
diff options
context:
space:
mode:
authorHari Khalsa <hkhalsa@10gen.com>2013-11-20 16:33:07 -0500
committerHari Khalsa <hkhalsa@10gen.com>2013-11-21 10:22:12 -0500
commitb5aad6eccd3b934b6109be9091b23c4d64034c33 (patch)
treea37a29eeec89a5486fc31e98156ce0c2ac094618 /src/mongo/db/query/planner_access.h
parent2cd39093e92fa7b4779beb68073f949c0880fd30 (diff)
downloadmongo-b5aad6eccd3b934b6109be9091b23c4d64034c33.tar.gz
SERVER-10026 break planner into four pieces
Diffstat (limited to 'src/mongo/db/query/planner_access.h')
-rw-r--r--src/mongo/db/query/planner_access.h159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/mongo/db/query/planner_access.h b/src/mongo/db/query/planner_access.h
new file mode 100644
index 00000000000..ce3cb10d73a
--- /dev/null
+++ b/src/mongo/db/query/planner_access.h
@@ -0,0 +1,159 @@
+/**
+ * Copyright (C) 2013 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+#include "mongo/db/query/canonical_query.h"
+#include "mongo/db/query/query_planner_params.h"
+#include "mongo/db/query/query_solution.h"
+
+namespace mongo {
+
+ /**
+ * Methods for creating a QuerySolutionNode tree that accesses the data required by the query.
+ */
+ class QueryPlannerAccess {
+ public:
+ /**
+ * Return a CollectionScanNode that scans as requested in 'query'.
+ */
+ static QuerySolutionNode* makeCollectionScan(const CanonicalQuery& query,
+ bool tailable,
+ const QueryPlannerParams& params);
+
+ /**
+ * Return a plan that uses the provided index as a proxy for a collection scan.
+ */
+ static QuerySolutionNode* scanWholeIndex(const IndexEntry& index,
+ const CanonicalQuery& query,
+ const QueryPlannerParams& params,
+ int direction = 1);
+
+ //
+ // Indexed Data Access methods.
+ //
+ // The inArrayOperator flag deserves some attention. It is set when we're processing a child of
+ // a MatchExpression::ALL or MatchExpression::ELEM_MATCH_OBJECT.
+ //
+ // When true, the following behavior changes for all methods below that take it as an argument:
+ // 0. No deletion of MatchExpression(s). In fact,
+ // 1. No mutation of the MatchExpression at all. We need the tree as-is in order to perform
+ // a filter on the entire tree.
+ // 2. No fetches performed. There will be a final fetch by the caller of buildIndexedDataAccess
+ // who set the value of inArrayOperator to true.
+ // 3. No compound indices are used and no bounds are combined. These are incorrect in the context
+ // of these operators.
+ //
+
+ /**
+ * If 'inArrayOperator' is false, takes ownership of 'root'.
+ */
+ static QuerySolutionNode* buildIndexedDataAccess(const CanonicalQuery& query,
+ MatchExpression* root,
+ bool inArrayOperator,
+ const vector<IndexEntry>& indices);
+
+ /**
+ * Takes ownership of 'root'.
+ */
+ static QuerySolutionNode* buildIndexedAnd(const CanonicalQuery& query,
+ MatchExpression* root,
+ bool inArrayOperator,
+ const vector<IndexEntry>& indices);
+
+ /**
+ * Takes ownership of 'root'.
+ */
+ static QuerySolutionNode* buildIndexedOr(const CanonicalQuery& query,
+ MatchExpression* root,
+ bool inArrayOperator,
+ const vector<IndexEntry>& indices);
+
+ /**
+ * Helper used by buildIndexedAnd and buildIndexedOr.
+ *
+ * The children of AND and OR nodes are sorted by the index that the subtree rooted at
+ * that node uses. Child nodes that use the same index are adjacent to one another to
+ * facilitate grouping of index scans. As such, the processing for AND and OR is
+ * almost identical.
+ *
+ * See tagForSort and sortUsingTags in index_tag.h for details on ordering the children
+ * of OR and AND.
+ *
+ * Does not take ownership of 'root' but may remove children from it.
+ */
+ static bool processIndexScans(const CanonicalQuery& query,
+ MatchExpression* root,
+ bool inArrayOperator,
+ const vector<IndexEntry>& indices,
+ vector<QuerySolutionNode*>* out);
+
+ //
+ // Helpers for creating an index scan.
+ //
+
+ /**
+ * Create a new data access node.
+ *
+ * If the node is an index scan, the bounds for 'expr' are computed and placed into the
+ * first field's OIL position. The rest of the OILs are allocated but uninitialized.
+ *
+ * If the node is a geo node, grab the geo data from 'expr' and stuff it into the
+ * geo solution node of the appropriate type.
+ */
+ static QuerySolutionNode* makeLeafNode(const IndexEntry& index,
+ MatchExpression* expr,
+ bool* exact);
+
+ /**
+ * Merge the predicate 'expr' with the leaf node 'node'.
+ */
+ static void mergeWithLeafNode(MatchExpression* expr,
+ const IndexEntry& index,
+ size_t pos,
+ bool* exactOut,
+ QuerySolutionNode* node,
+ MatchExpression::MatchType mergeType);
+
+ /**
+ * If index scan (regular or expression index), fill in any bounds that are missing in
+ * 'node' with the "all values for this field" interval.
+ *
+ * If geo, do nothing.
+ */
+ static void finishLeafNode(QuerySolutionNode* node, const IndexEntry& index);
+
+ /**
+ * Assumes each OIL in bounds is increasing.
+ *
+ * Aligns OILs (and bounds) according to the kp direction * the scanDir.
+ */
+ static void alignBounds(IndexBounds* bounds, const BSONObj& kp, int scanDir = 1);
+ };
+
+} // namespace mongo