summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuslan Abdulkhalikov <ruslan.abdulkhalikov@mongodb.com>2021-10-06 21:53:52 -0700
committerRuslan Abdulkhalikov <ruslan.abdulkhalikov@mongodb.com>2021-10-08 09:12:55 -0700
commit76287d314beec26cfbfa726eff17265d72776bb5 (patch)
tree5a08429b249e29b5b82ea637fe26b41a544205d6
parent8aef619d2368bb802aa5f109bffbbb916c0aa357 (diff)
downloadmongo-SERVER-56932-const-folding-error-code.tar.gz
SERVER-56932 failed optimizer error to have a specific codeSERVER-56932-const-folding-error-code
-rw-r--r--jstests/core/const_folding_failure.js29
-rw-r--r--src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp8
-rw-r--r--src/mongo/db/pipeline/expression.cpp8
-rw-r--r--src/mongo/db/pipeline/pipeline.cpp18
-rw-r--r--src/mongo/db/pipeline/pipeline.h5
5 files changed, 54 insertions, 14 deletions
diff --git a/jstests/core/const_folding_failure.js b/jstests/core/const_folding_failure.js
new file mode 100644
index 00000000000..172eddbafd4
--- /dev/null
+++ b/jstests/core/const_folding_failure.js
@@ -0,0 +1,29 @@
+// Tests that checks if optimization errors raised with a specific code
+// @tags: [
+// requires_fcv_51
+// ]
+
+(function() {
+"use strict";
+
+const coll = db.getCollection(jsTestName());
+
+coll.drop();
+
+// Forcing optimizer only failure (empty collection, $project will never execute)
+assert.throwsWithCode(() => db.nonexistent.aggregate([
+ {$project:
+ {dt1:
+ {$map:
+ {
+ input: "$a",
+ as: "b",
+ in: {
+ $toDate: {
+ $dayOfYear: {
+ date: new Date("2019-04-08T11:48:29.394Z"),
+ timezone: "Australia/Melbourne"
+ }
+ }
+ }}}}}]), 5693200);
+})();
diff --git a/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp b/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp
index 950a6521fd7..20a7af03466 100644
--- a/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp
+++ b/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp
@@ -198,14 +198,6 @@ boost::intrusive_ptr<DocumentSourceSort> createMetadataSortForReorder(
maxMemoryUsageBytes);
}
-// Optimize the section of the pipeline before the $_internalUnpackBucket stage.
-void optimizePrefix(Pipeline::SourceContainer::iterator itr, Pipeline::SourceContainer* container) {
- auto prefix = Pipeline::SourceContainer(container->begin(), itr);
- Pipeline::optimizeContainer(&prefix);
- container->erase(container->begin(), itr);
- container->splice(itr, prefix);
-}
-
// Returns whether 'field' depends on a pushed down $addFields or computed $project.
bool fieldIsComputed(BucketSpec spec, std::string field) {
return std::any_of(
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 8d8c1d27d98..cbbdfc25e0f 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -6463,8 +6463,12 @@ boost::intrusive_ptr<Expression> ExpressionConvert::optimize() {
// and _onNull values could still be legally folded if those values are not needed. Support for
// that case would add more complexity than it's worth, though.
if (ExpressionConstant::allNullOrConstant({_input, _to, _onError, _onNull})) {
- return ExpressionConstant::create(
- getExpressionContext(), evaluate(Document{}, &(getExpressionContext()->variables)));
+ try {
+ return ExpressionConstant::create(
+ getExpressionContext(), evaluate(Document{}, &(getExpressionContext()->variables)));
+ } catch (DBException& ex) {
+ uasserted(5693200, str::stream() << "Failed to optimize pipeline :: " + ex.reason());
+ }
}
return this;
diff --git a/src/mongo/db/pipeline/pipeline.cpp b/src/mongo/db/pipeline/pipeline.cpp
index 486b2e3ac7d..9ef25e6e2f7 100644
--- a/src/mongo/db/pipeline/pipeline.cpp
+++ b/src/mongo/db/pipeline/pipeline.cpp
@@ -26,20 +26,16 @@
* exception statement from all source files in the program, then also delete
* it in the license file.
*/
-
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kDefault
#include "mongo/db/pipeline/pipeline.h"
#include "mongo/logv2/log.h"
-#include <algorithm>
-
#include "mongo/base/error_codes.h"
#include "mongo/db/bson/dotted_path_support.h"
#include "mongo/db/exec/document_value/document.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/operation_context.h"
-#include "mongo/db/pipeline/accumulator.h"
#include "mongo/db/pipeline/document_source.h"
#include "mongo/db/pipeline/document_source_match.h"
#include "mongo/db/pipeline/document_source_merge.h"
@@ -50,6 +46,8 @@
#include "mongo/db/storage/storage_options.h"
#include "mongo/util/fail_point.h"
#include "mongo/util/str.h"
+#include <algorithm>
+
namespace mongo {
@@ -669,6 +667,18 @@ std::unique_ptr<Pipeline, PipelineDeleter> Pipeline::makePipeline(
return pipeline;
}
+std::ostream& operator<<(std::ostream& os, const Pipeline& pipeline) {
+ vector<Value> serializedSources;
+ for (auto&& source : pipeline.getSources()) {
+ source->serializeToArray(serializedSources, explain::VerbosityEnum::kQueryPlanner);
+ }
+
+ for (auto stage : serializedSources) {
+ os << stage << " ";
+ }
+ return os;
+}
+
Pipeline::SourceContainer::iterator Pipeline::optimizeEndOfPipeline(
Pipeline::SourceContainer::iterator itr, Pipeline::SourceContainer* container) {
// We must create a new SourceContainer representing the subsection of the pipeline we wish to
diff --git a/src/mongo/db/pipeline/pipeline.h b/src/mongo/db/pipeline/pipeline.h
index dd52df4ab9e..9b3eb19df1c 100644
--- a/src/mongo/db/pipeline/pipeline.h
+++ b/src/mongo/db/pipeline/pipeline.h
@@ -449,4 +449,9 @@ private:
bool _dismissed = false;
};
+/**
+ * Print operator useful for diagnostics
+ */
+std::ostream& operator<<(std::ostream& os, const Pipeline& pipeline);
+
} // namespace mongo