summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCharlie Swanson <charlie.swanson@mongodb.com>2015-05-12 12:59:23 -0400
committerCharlie Swanson <charlie.swanson@mongodb.com>2015-05-12 16:42:45 -0400
commitb94f71a5dfa687aef2aa1af83e797683f9ad7476 (patch)
treec219f9bde1d327989d593e210261f187576ffcce /src
parent3341d6407fb8ba147303432027db0ed006a85c46 (diff)
downloadmongo-b94f71a5dfa687aef2aa1af83e797683f9ad7476.tar.gz
SERVER-14608 Optimize out empty match stage in aggregation pipeline
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/pipeline/document_source.h1
-rw-r--r--src/mongo/db/pipeline/document_source_match.cpp4
-rw-r--r--src/mongo/dbtests/pipelinetests.cpp31
3 files changed, 32 insertions, 4 deletions
diff --git a/src/mongo/db/pipeline/document_source.h b/src/mongo/db/pipeline/document_source.h
index bbbe429e1bd..a2b6c2225da 100644
--- a/src/mongo/db/pipeline/document_source.h
+++ b/src/mongo/db/pipeline/document_source.h
@@ -567,6 +567,7 @@ namespace mongo {
virtual const char *getSourceName() const;
virtual bool coalesce(const boost::intrusive_ptr<DocumentSource>& nextSource);
virtual Value serialize(bool explain = false) const;
+ virtual boost::intrusive_ptr<DocumentSource> optimize();
virtual void setSource(DocumentSource* Source);
/**
diff --git a/src/mongo/db/pipeline/document_source_match.cpp b/src/mongo/db/pipeline/document_source_match.cpp
index ab2784acb97..b6c6e005446 100644
--- a/src/mongo/db/pipeline/document_source_match.cpp
+++ b/src/mongo/db/pipeline/document_source_match.cpp
@@ -53,6 +53,10 @@ namespace mongo {
return Value(DOC(getSourceName() << Document(getQuery())));
}
+ intrusive_ptr<DocumentSource> DocumentSourceMatch::optimize() {
+ return getQuery().isEmpty() ? nullptr : this;
+ }
+
boost::optional<Document> DocumentSourceMatch::getNext() {
pExpCtx->checkForInterrupt();
diff --git a/src/mongo/dbtests/pipelinetests.cpp b/src/mongo/dbtests/pipelinetests.cpp
index ef3d24dd546..11f9230e5b7 100644
--- a/src/mongo/dbtests/pipelinetests.cpp
+++ b/src/mongo/dbtests/pipelinetests.cpp
@@ -97,13 +97,34 @@ namespace PipelineTests {
}
};
- class RemoveSkipZeroKeepProject : public Base {
+ class RemoveEmptyMatch : public Base {
string inputPipeJson() override {
- return "[{$skip: 0}, {$project: {i: true}}]";
+ return "[{$match: {}}]";
}
string outputPipeJson() override {
- return "[{$project: {i: true}}]";
+ return "[]";
+ }
+ };
+
+ class RemoveMultipleEmptyMatches : public Base {
+ string inputPipeJson() override {
+ return "[{$match: {}}, {$match: {}}]";
+ }
+
+ string outputPipeJson() override {
+ // TODO: The desired behavior here is to end up with an empty array.
+ return "[{$match: {$and: [{}, {}]}}]";
+ }
+ };
+
+ class DoNotRemoveNonEmptyMatch : public Base {
+ string inputPipeJson() override {
+ return "[{$match: {_id: 1}}]";
+ }
+
+ string outputPipeJson() override {
+ return "[{$match: {_id: 1}}]";
}
};
@@ -278,7 +299,9 @@ namespace PipelineTests {
void setupTests() {
add<Optimizations::Local::RemoveSkipZero>();
add<Optimizations::Local::DoNotRemoveSkipOne>();
- add<Optimizations::Local::RemoveSkipZeroKeepProject>();
+ add<Optimizations::Local::RemoveEmptyMatch>();
+ add<Optimizations::Local::RemoveMultipleEmptyMatches>();
+ add<Optimizations::Local::DoNotRemoveNonEmptyMatch>();
add<Optimizations::Sharded::Empty>();
add<Optimizations::Sharded::moveFinalUnwindFromShardsToMerger::OneUnwind>();
add<Optimizations::Sharded::moveFinalUnwindFromShardsToMerger::TwoUnwind>();