From 76287d314beec26cfbfa726eff17265d72776bb5 Mon Sep 17 00:00:00 2001 From: Ruslan Abdulkhalikov Date: Wed, 6 Oct 2021 21:53:52 -0700 Subject: SERVER-56932 failed optimizer error to have a specific code --- jstests/core/const_folding_failure.js | 29 ++++++++++++++++++++++ .../document_source_internal_unpack_bucket.cpp | 8 ------ src/mongo/db/pipeline/expression.cpp | 8 ++++-- src/mongo/db/pipeline/pipeline.cpp | 18 +++++++++++--- src/mongo/db/pipeline/pipeline.h | 5 ++++ 5 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 jstests/core/const_folding_failure.js 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 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 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 - #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 + namespace mongo { @@ -669,6 +667,18 @@ std::unique_ptr Pipeline::makePipeline( return pipeline; } +std::ostream& operator<<(std::ostream& os, const Pipeline& pipeline) { + vector 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 -- cgit v1.2.1