summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/expression_context.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/expression_context.h')
-rw-r--r--src/mongo/db/pipeline/expression_context.h53
1 files changed, 47 insertions, 6 deletions
diff --git a/src/mongo/db/pipeline/expression_context.h b/src/mongo/db/pipeline/expression_context.h
index c5ce9b74f27..aa2d212f53d 100644
--- a/src/mongo/db/pipeline/expression_context.h
+++ b/src/mongo/db/pipeline/expression_context.h
@@ -114,6 +114,16 @@ public:
};
/**
+ * Constructs an ExpressionContext to be used for find command parsing and evaluation.
+ */
+ ExpressionContext(OperationContext* opCtx,
+ const FindCommandRequest& findCmd,
+ std::unique_ptr<CollatorInterface> collator,
+ bool mayDbProfile,
+ boost::optional<ExplainOptions::Verbosity> verbosity = boost::none,
+ bool allowDiskUseByDefault = false);
+
+ /**
* Constructs an ExpressionContext to be used for Pipeline parsing and evaluation.
* 'resolvedNamespaces' maps collection names (not full namespaces) to ResolvedNamespaces.
*/
@@ -161,6 +171,22 @@ public:
boost::optional<ExplainOptions::Verbosity> explain = boost::none);
/**
+ * Constructs a blank ExpressionContext suitable for creating Query Shapes, but it could be
+ * applied to other use cases as well.
+ *
+ * The process for creating a Query Shape sometimes requires re-parsing the BSON into a proper
+ * AST, and for that you need an ExpressionContext.
+ *
+ * Note: this is meant for introspection and is not suitable for using to execute queries -
+ * since it does not contain for example a collation argument or a real MongoProcessInterface
+ * for execution.
+ */
+ static boost::intrusive_ptr<ExpressionContext> makeBlankExpressionContext(
+ OperationContext* opCtx,
+ const NamespaceStringOrUUID& nssOrUUID,
+ boost::optional<BSONObj> shapifiedLet = boost::none);
+
+ /**
* Used by a pipeline to check for interrupts so that killOp() works. Throws a UserAssertion if
* this aggregation pipeline has been interrupted.
*/
@@ -278,7 +304,8 @@ public:
*/
const ResolvedNamespace& getResolvedNamespace(const NamespaceString& nss) const {
auto it = _resolvedNamespaces.find(nss.coll());
- invariant(it != _resolvedNamespaces.end());
+ invariant(it != _resolvedNamespaces.end(),
+ str::stream() << "No resolved namespace provided for " << nss.toString());
return it->second;
};
@@ -323,10 +350,8 @@ public:
* created yet. Initializes the Scope with the 'jsScope' variables from the runtimeConstants.
* Loads the Scope with the functions stored in system.js if the expression isn't executed on
* mongos and is called from a MapReduce command or `forceLoadOfStoredProcedures` is true.
- *
- * Returns a JsExec and a boolean indicating whether the Scope was created as part of this call.
*/
- auto getJsExecWithScope(bool forceLoadOfStoredProcedures = false) const {
+ JsExecution* getJsExecWithScope(bool forceLoadOfStoredProcedures = false) const {
uassert(31264,
"Cannot run server-side javascript without the javascript engine enabled",
getGlobalScriptEngine());
@@ -348,9 +373,17 @@ public:
"$where.");
}
- auto scopeObj = BSONObj();
+ // If there is a cached JsExecution object, return it. This is a performance optimization
+ // that avoids potentially copying the scope object, which is not needed if a cached exec
+ // object already exists.
+ JsExecution* jsExec = JsExecution::getCached(opCtx, loadStoredProcedures);
+ if (jsExec) {
+ return jsExec;
+ }
+
+ BSONObj scopeObj = BSONObj();
if (variables.hasValue(Variables::kJsScopeId)) {
- auto scopeVar = variables.getValue(Variables::kJsScopeId);
+ Value scopeVar = variables.getValue(Variables::kJsScopeId);
invariant(scopeVar.isObject());
scopeObj = scopeVar.getDocument().toBson();
}
@@ -558,6 +591,14 @@ protected:
bool _requiresTimeseriesExtendedRangeSupport = false;
private:
+ // Instantiates an ExpressionContext which does not increment expression counters and does not
+ // enforce FCV restrictions. It is used for implementing the `makeBlankExpressionContext()`
+ // factory method. Please also note that the runtime constants are not given real/accurate
+ // values of '$$NOW' and '$$CLUSTER_TIME', in the name of efficiency.
+ ExpressionContext(OperationContext* opCtx,
+ const NamespaceString& ns,
+ const boost::optional<BSONObj>& letParameters = boost::none);
+
boost::optional<ExpressionCounters> _expressionCounters = boost::none;
};