diff options
Diffstat (limited to 'src/mongo/db/pipeline/expression_context.h')
| -rw-r--r-- | src/mongo/db/pipeline/expression_context.h | 53 |
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; }; |
