diff options
author | Jonathan Reams <jbreams@mongodb.com> | 2015-08-27 19:43:23 -0400 |
---|---|---|
committer | Jonathan Reams <jbreams@mongodb.com> | 2015-08-27 19:43:23 -0400 |
commit | f51b43f0fbabe121c18387d8bfbb187a2c6efdee (patch) | |
tree | 3c5a0ef9a49220dbbfee75e43f9d7d3eb56d873a /src | |
parent | 022cc024da1e4ff5664742befed0059c1ddfa255 (diff) | |
download | mongo-f51b43f0fbabe121c18387d8bfbb187a2c6efdee.tar.gz |
Revert "SERVER-19355 mongos issues sortKey meta-projection in order to perform sorted merge"
This reverts commit eed4c7978289968e54ff4510c5bbfab808a21fb0.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/s/query/SConscript | 3 | ||||
-rw-r--r-- | src/mongo/s/query/async_results_merger.cpp | 15 | ||||
-rw-r--r-- | src/mongo/s/query/async_results_merger_test.cpp | 118 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor_impl.cpp | 5 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor_params.cpp | 37 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor_params.h | 5 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_find.cpp | 24 | ||||
-rw-r--r-- | src/mongo/s/query/router_stage_remove_sortkey.cpp | 64 | ||||
-rw-r--r-- | src/mongo/s/query/router_stage_remove_sortkey.h | 49 | ||||
-rw-r--r-- | src/mongo/s/query/router_stage_remove_sortkey_test.cpp | 127 |
10 files changed, 27 insertions, 420 deletions
diff --git a/src/mongo/s/query/SConscript b/src/mongo/s/query/SConscript index 13e67f7fd35..317dcdf2942 100644 --- a/src/mongo/s/query/SConscript +++ b/src/mongo/s/query/SConscript @@ -31,7 +31,6 @@ env.Library( "router_stage_limit.cpp", "router_stage_merge.cpp", "router_stage_mock.cpp", - "router_stage_remove_sortkey.cpp", "router_stage_skip.cpp", ], LIBDEPS=[ @@ -43,7 +42,6 @@ env.CppUnitTest( target="router_exec_stage_test", source=[ "router_stage_limit_test.cpp", - "router_stage_remove_sortkey_test.cpp", "router_stage_skip_test.cpp", ], LIBDEPS=[ @@ -55,7 +53,6 @@ env.Library( target="async_results_merger", source=[ "async_results_merger.cpp", - "cluster_client_cursor_params.cpp", ], LIBDEPS=[ "$BUILD_DIR/mongo/db/query/command_request_response", diff --git a/src/mongo/s/query/async_results_merger.cpp b/src/mongo/s/query/async_results_merger.cpp index 57441815d92..73f67095547 100644 --- a/src/mongo/s/query/async_results_merger.cpp +++ b/src/mongo/s/query/async_results_merger.cpp @@ -357,16 +357,6 @@ void AsyncResultsMerger::handleBatchResponse( remote.cursorId = getMoreResponse.cursorId; for (const auto& obj : getMoreResponse.batch) { - // If there's a sort, we're expecting the remote node to give us back a sort key. - if (!_params.sort.isEmpty() && - obj[ClusterClientCursorParams::kSortKeyField].type() != BSONType::Object) { - remote.status = Status(ErrorCodes::InternalError, - str::stream() << "Missing field '" - << ClusterClientCursorParams::kSortKeyField - << "' in document: " << obj); - return; - } - remote.docBuffer.push(obj); ++remote.fetchedCount; } @@ -511,10 +501,7 @@ bool AsyncResultsMerger::MergingComparator::operator()(const size_t& lhs, const const BSONObj& leftDoc = _remotes[lhs].docBuffer.front(); const BSONObj& rightDoc = _remotes[rhs].docBuffer.front(); - BSONObj leftDocKey = leftDoc[ClusterClientCursorParams::kSortKeyField].Obj(); - BSONObj rightDocKey = rightDoc[ClusterClientCursorParams::kSortKeyField].Obj(); - - return leftDocKey.woCompare(rightDocKey, _sort, false /*considerFieldName*/) > 0; + return leftDoc.woSortOrder(rightDoc, _sort, true /*useDotted*/) > 0; } } // namespace mongo diff --git a/src/mongo/s/query/async_results_merger_test.cpp b/src/mongo/s/query/async_results_merger_test.cpp index c02db414282..7542d182f66 100644 --- a/src/mongo/s/query/async_results_merger_test.cpp +++ b/src/mongo/s/query/async_results_merger_test.cpp @@ -291,30 +291,27 @@ TEST_F(AsyncResultsMergerTest, ClusterFindSorted) { ASSERT_FALSE(arm->ready()); std::vector<GetMoreResponse> responses; - std::vector<BSONObj> batch1 = {fromjson("{_id: 5, $sortKey: {'': 5}}"), - fromjson("{_id: 6, $sortKey: {'': 6}}")}; + std::vector<BSONObj> batch1 = {fromjson("{_id: 5}"), fromjson("{_id: 6}")}; responses.emplace_back(_nss, CursorId(0), batch1); - std::vector<BSONObj> batch2 = {fromjson("{_id: 3, $sortKey: {'': 3}}"), - fromjson("{_id: 9, $sortKey: {'': 9}}")}; + std::vector<BSONObj> batch2 = {fromjson("{_id: 3}"), fromjson("{_id: 9}")}; responses.emplace_back(_nss, CursorId(0), batch2); - std::vector<BSONObj> batch3 = {fromjson("{_id: 4, $sortKey: {'': 4}}"), - fromjson("{_id: 8, $sortKey: {'': 8}}")}; + std::vector<BSONObj> batch3 = {fromjson("{_id: 4}"), fromjson("{_id: 8}")}; responses.emplace_back(_nss, CursorId(0), batch3); scheduleNetworkResponses(responses); executor->waitForEvent(readyEvent); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{_id: 3, $sortKey: {'': 3}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 3}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{_id: 4, $sortKey: {'': 4}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 4}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{_id: 5, $sortKey: {'': 5}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 5}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{_id: 6, $sortKey: {'': 6}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 6}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{_id: 8, $sortKey: {'': 8}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 8}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{_id: 9, $sortKey: {'': 9}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 9}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); ASSERT(!unittest::assertGet(arm->nextReady())); } @@ -328,128 +325,61 @@ TEST_F(AsyncResultsMergerTest, ClusterFindAndGetMoreSorted) { ASSERT_FALSE(arm->ready()); std::vector<GetMoreResponse> responses; - std::vector<BSONObj> batch1 = {fromjson("{$sortKey: {'': 5}}"), - fromjson("{$sortKey: {'': 6}}")}; + std::vector<BSONObj> batch1 = {fromjson("{_id: 5}"), fromjson("{_id: 6}")}; responses.emplace_back(_nss, CursorId(1), batch1); - std::vector<BSONObj> batch2 = {fromjson("{$sortKey: {'': 3}}"), - fromjson("{$sortKey: {'': 4}}")}; + std::vector<BSONObj> batch2 = {fromjson("{_id: 3}"), fromjson("{_id: 4}")}; responses.emplace_back(_nss, CursorId(0), batch2); - std::vector<BSONObj> batch3 = {fromjson("{$sortKey: {'': 7}}"), - fromjson("{$sortKey: {'': 8}}")}; + std::vector<BSONObj> batch3 = {fromjson("{_id: 7}"), fromjson("{_id: 8}")}; responses.emplace_back(_nss, CursorId(2), batch3); scheduleNetworkResponses(responses); executor->waitForEvent(readyEvent); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 3}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 3}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 4}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 4}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 5}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 5}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 6}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 6}"), *unittest::assertGet(arm->nextReady())); ASSERT_FALSE(arm->ready()); readyEvent = unittest::assertGet(arm->nextEvent()); ASSERT_FALSE(arm->ready()); responses.clear(); - std::vector<BSONObj> batch4 = {fromjson("{$sortKey: {'': 7}}"), - fromjson("{$sortKey: {'': 10}}")}; + std::vector<BSONObj> batch4 = {fromjson("{_id: 7}"), fromjson("{_id: 10}")}; responses.emplace_back(_nss, CursorId(0), batch4); scheduleNetworkResponses(responses); executor->waitForEvent(readyEvent); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 7}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 7}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 7}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 7}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 8}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 8}"), *unittest::assertGet(arm->nextReady())); ASSERT_FALSE(arm->ready()); readyEvent = unittest::assertGet(arm->nextEvent()); ASSERT_FALSE(arm->ready()); responses.clear(); - std::vector<BSONObj> batch5 = {fromjson("{$sortKey: {'': 9}}"), - fromjson("{$sortKey: {'': 10}}")}; + std::vector<BSONObj> batch5 = {fromjson("{_id: 9}"), fromjson("{_id: 10}")}; responses.emplace_back(_nss, CursorId(0), batch5); scheduleNetworkResponses(responses); executor->waitForEvent(readyEvent); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 9}}"), *unittest::assertGet(arm->nextReady())); - ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 10}}"), *unittest::assertGet(arm->nextReady())); - ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 10}}"), *unittest::assertGet(arm->nextReady())); - ASSERT_TRUE(arm->ready()); - ASSERT(!unittest::assertGet(arm->nextReady())); -} - -TEST_F(AsyncResultsMergerTest, ClusterFindCompoundSortKey) { - BSONObj findCmd = fromjson("{find: 'testcoll', sort: {a: -1, b: 1}, batchSize: 2}"); - makeCursorFromFindCmd(findCmd, _remotes); - - ASSERT_FALSE(arm->ready()); - auto readyEvent = unittest::assertGet(arm->nextEvent()); - ASSERT_FALSE(arm->ready()); - - std::vector<GetMoreResponse> responses; - std::vector<BSONObj> batch1 = {fromjson("{$sortKey: {'': 5, '': 9}}"), - fromjson("{$sortKey: {'': 4, '': 20}}")}; - responses.emplace_back(_nss, CursorId(0), batch1); - std::vector<BSONObj> batch2 = {fromjson("{$sortKey: {'': 10, '': 11}}"), - fromjson("{$sortKey: {'': 4, '': 4}}")}; - responses.emplace_back(_nss, CursorId(0), batch2); - std::vector<BSONObj> batch3 = {fromjson("{$sortKey: {'': 10, '': 12}}"), - fromjson("{$sortKey: {'': 5, '': 9}}")}; - responses.emplace_back(_nss, CursorId(0), batch3); - scheduleNetworkResponses(responses); - executor->waitForEvent(readyEvent); - - ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 10, '': 11}}"), *unittest::assertGet(arm->nextReady())); - ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 10, '': 12}}"), *unittest::assertGet(arm->nextReady())); - ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 5, '': 9}}"), *unittest::assertGet(arm->nextReady())); - ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 5, '': 9}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 9}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 4, '': 4}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 10}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); - ASSERT_EQ(fromjson("{$sortKey: {'': 4, '': 20}}"), *unittest::assertGet(arm->nextReady())); + ASSERT_EQ(fromjson("{_id: 10}"), *unittest::assertGet(arm->nextReady())); ASSERT_TRUE(arm->ready()); ASSERT(!unittest::assertGet(arm->nextReady())); } -TEST_F(AsyncResultsMergerTest, ClusterFindSortedButNoSortKey) { - BSONObj findCmd = fromjson("{find: 'testcoll', sort: {a: -1, b: 1}, batchSize: 2}"); - makeCursorFromFindCmd(findCmd, {_remotes[0]}); - - ASSERT_FALSE(arm->ready()); - auto readyEvent = unittest::assertGet(arm->nextEvent()); - ASSERT_FALSE(arm->ready()); - - // Parsing the batch results in an error because the sort key is missing. - std::vector<GetMoreResponse> responses; - std::vector<BSONObj> batch1 = {fromjson("{a: 2, b: 1}"), fromjson("{a: 1, b: 2}")}; - responses.emplace_back(_nss, CursorId(1), batch1); - scheduleNetworkResponses(responses); - executor->waitForEvent(readyEvent); - - ASSERT_TRUE(arm->ready()); - auto statusWithNext = arm->nextReady(); - ASSERT(!statusWithNext.isOK()); - ASSERT_EQ(statusWithNext.getStatus().code(), ErrorCodes::InternalError); - - // Required to kill the 'arm' on error before destruction. - auto killEvent = arm->kill(); - executor->waitForEvent(killEvent); -} - TEST_F(AsyncResultsMergerTest, ClusterFindInitialBatchSizeIsZero) { // Initial batchSize sent with the find command is zero; batchSize sent with each getMore // command is one. diff --git a/src/mongo/s/query/cluster_client_cursor_impl.cpp b/src/mongo/s/query/cluster_client_cursor_impl.cpp index b371b858338..2662eb1a405 100644 --- a/src/mongo/s/query/cluster_client_cursor_impl.cpp +++ b/src/mongo/s/query/cluster_client_cursor_impl.cpp @@ -35,7 +35,6 @@ #include "mongo/s/query/router_stage_limit.h" #include "mongo/s/query/router_stage_merge.h" #include "mongo/s/query/router_stage_mock.h" -#include "mongo/s/query/router_stage_remove_sortkey.h" #include "mongo/s/query/router_stage_skip.h" #include "mongo/stdx/memory.h" @@ -82,10 +81,6 @@ std::unique_ptr<RouterExecStage> ClusterClientCursorImpl::buildMergerPlan( root = stdx::make_unique<RouterStageLimit>(std::move(root), *params.limit); } - if (!params.sort.isEmpty()) { - root = stdx::make_unique<RouterStageRemoveSortKey>(std::move(root)); - } - return root; } diff --git a/src/mongo/s/query/cluster_client_cursor_params.cpp b/src/mongo/s/query/cluster_client_cursor_params.cpp deleted file mode 100644 index a9c583e80ef..00000000000 --- a/src/mongo/s/query/cluster_client_cursor_params.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (C) 2015 MongoDB Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/s/query/cluster_client_cursor_params.h" - -namespace mongo { - -const char ClusterClientCursorParams::kSortKeyField[] = "$sortKey"; - -} // namespace mongo diff --git a/src/mongo/s/query/cluster_client_cursor_params.h b/src/mongo/s/query/cluster_client_cursor_params.h index 0efec32f93a..e73a6d5d9ab 100644 --- a/src/mongo/s/query/cluster_client_cursor_params.h +++ b/src/mongo/s/query/cluster_client_cursor_params.h @@ -33,15 +33,10 @@ #include "mongo/bson/bsonobj.h" #include "mongo/db/namespace_string.h" -#include "mongo/util/net/hostandport.h" namespace mongo { struct ClusterClientCursorParams { - // When mongos has to do a merge in order to return results to the client in the correct sort - // order, it requests a sortKey meta-projection using this field name. - static const char kSortKeyField[]; - /** * Contains any CCC parameters that are specified per-remote node. */ diff --git a/src/mongo/s/query/cluster_find.cpp b/src/mongo/s/query/cluster_find.cpp index b47c04b5453..73d41cfc3be 100644 --- a/src/mongo/s/query/cluster_find.cpp +++ b/src/mongo/s/query/cluster_find.cpp @@ -55,9 +55,6 @@ namespace mongo { namespace { -static const BSONObj kSortKeyMetaProjection = BSON("$meta" - << "sortKey"); - /** * Given the LiteParsedQuery 'lpq' being executed by mongos, returns a copy of the query which is * suitable for forwarding to the targeted hosts. @@ -75,18 +72,9 @@ std::unique_ptr<LiteParsedQuery> transformQueryForShards(const LiteParsedQuery& newNToReturn = *lpq.getNToReturn() + lpq.getSkip().value_or(0); } - // If there is a sort, we send a sortKey meta-projection to the remote node. - BSONObj newProjection = lpq.getProj(); - if (!lpq.getSort().isEmpty()) { - BSONObjBuilder projectionBuilder; - projectionBuilder.appendElements(lpq.getProj()); - projectionBuilder.append(ClusterClientCursorParams::kSortKeyField, kSortKeyMetaProjection); - newProjection = projectionBuilder.obj(); - } - return LiteParsedQuery::makeAsFindCmd(lpq.nss(), lpq.getFilter(), - newProjection, + lpq.getProj(), lpq.getSort(), lpq.getHint(), boost::none, // Don't forward skip. @@ -145,7 +133,7 @@ StatusWith<CursorId> runQueryWithoutRetrying(OperationContext* txn, // sort on mongos. Including a $natural anywhere in the sort spec results in the whole sort // being considered a hint to use a collection scan. if (!query.getParsed().getSort().hasField("$natural")) { - params.sort = FindCommon::transformSortSpec(query.getParsed().getSort()); + params.sort = query.getParsed().getSort(); } // Tailable cursors can't have a sort, which should have already been validated. @@ -239,14 +227,6 @@ StatusWith<CursorId> ClusterFind::runQuery(OperationContext* txn, std::vector<BSONObj>* results) { invariant(results); - // Projection on the reserved sort key field is illegal in mongos. - if (query.getParsed().getProj().hasField(ClusterClientCursorParams::kSortKeyField)) { - return {ErrorCodes::BadValue, - str::stream() << "Projection contains illegal field '" - << ClusterClientCursorParams::kSortKeyField - << "': " << query.getParsed().getProj()}; - } - auto dbConfig = grid.catalogCache()->getDatabase(txn, query.nss().db().toString()); if (dbConfig.getStatus() == ErrorCodes::DatabaseNotFound) { // If the database doesn't exist, we successfully return an empty result set without diff --git a/src/mongo/s/query/router_stage_remove_sortkey.cpp b/src/mongo/s/query/router_stage_remove_sortkey.cpp deleted file mode 100644 index 7fa343f44c1..00000000000 --- a/src/mongo/s/query/router_stage_remove_sortkey.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (C) 2015 MongoDB Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kQuery - -#include "mongo/platform/basic.h" - -#include "mongo/s/query/router_stage_remove_sortkey.h" - -#include "mongo/bson/bsonobjbuilder.h" -#include "mongo/s/query/cluster_client_cursor_params.h" -#include "mongo/util/mongoutils/str.h" - -namespace mongo { - -RouterStageRemoveSortKey::RouterStageRemoveSortKey(std::unique_ptr<RouterExecStage> child) - : RouterExecStage(std::move(child)) {} - -StatusWith<boost::optional<BSONObj>> RouterStageRemoveSortKey::next() { - auto childResult = getChildStage()->next(); - if (!childResult.isOK() || !childResult.getValue()) { - return childResult; - } - - BSONObjBuilder builder; - for (BSONElement elt : *childResult.getValue()) { - if (!str::equals(elt.fieldName(), ClusterClientCursorParams::kSortKeyField)) { - builder.append(elt); - } - } - - return {builder.obj()}; -} - -void RouterStageRemoveSortKey::kill() { - getChildStage()->kill(); -} - -} // namespace mongo diff --git a/src/mongo/s/query/router_stage_remove_sortkey.h b/src/mongo/s/query/router_stage_remove_sortkey.h deleted file mode 100644 index c376226f23f..00000000000 --- a/src/mongo/s/query/router_stage_remove_sortkey.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (C) 2015 MongoDB Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/s/query/router_exec_stage.h" - -namespace mongo { - -/** - * Removes the sort key added to each document by mongod's sortKey meta-projection. - * - * Only needed if the query specifies a sort. - */ -class RouterStageRemoveSortKey final : public RouterExecStage { -public: - RouterStageRemoveSortKey(std::unique_ptr<RouterExecStage> child); - - StatusWith<boost::optional<BSONObj>> next() final; - - void kill() final; -}; - -} // namespace mongo diff --git a/src/mongo/s/query/router_stage_remove_sortkey_test.cpp b/src/mongo/s/query/router_stage_remove_sortkey_test.cpp deleted file mode 100644 index 90a7a555b07..00000000000 --- a/src/mongo/s/query/router_stage_remove_sortkey_test.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright 2015 MongoDB Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/s/query/router_stage_remove_sortkey.h" - -#include "mongo/bson/bsonobj.h" -#include "mongo/bson/bsonobjbuilder.h" -#include "mongo/s/query/router_stage_mock.h" -#include "mongo/stdx/memory.h" -#include "mongo/unittest/unittest.h" - -namespace mongo { - -namespace { - -TEST(RouterStageRemoveSortKeyTest, RemovesSortKey) { - auto mockStage = stdx::make_unique<RouterStageMock>(); - mockStage->queueResult(BSON("a" << 4 << "$sortKey" << 1 << "b" << 3)); - mockStage->queueResult(BSON("$sortKey" << BSON("" << 3) << "c" << BSON("d" - << "foo"))); - mockStage->queueResult(BSON("a" << 3)); - mockStage->queueResult(BSONObj()); - - auto sortKeyStage = stdx::make_unique<RouterStageRemoveSortKey>(std::move(mockStage)); - - auto firstResult = sortKeyStage->next(); - ASSERT_OK(firstResult.getStatus()); - ASSERT(firstResult.getValue()); - ASSERT_EQ(*firstResult.getValue(), BSON("a" << 4 << "b" << 3)); - - auto secondResult = sortKeyStage->next(); - ASSERT_OK(secondResult.getStatus()); - ASSERT(secondResult.getValue()); - ASSERT_EQ(*secondResult.getValue(), - BSON("c" << BSON("d" - << "foo"))); - - auto thirdResult = sortKeyStage->next(); - ASSERT_OK(thirdResult.getStatus()); - ASSERT(thirdResult.getValue()); - ASSERT_EQ(*thirdResult.getValue(), BSON("a" << 3)); - - auto fourthResult = sortKeyStage->next(); - ASSERT_OK(fourthResult.getStatus()); - ASSERT(fourthResult.getValue()); - ASSERT_EQ(*fourthResult.getValue(), BSONObj()); - - auto fifthResult = sortKeyStage->next(); - ASSERT_OK(fifthResult.getStatus()); - ASSERT(!fifthResult.getValue()); -} - -TEST(RouterStageRemoveSortKeyTest, PropagatesError) { - auto mockStage = stdx::make_unique<RouterStageMock>(); - mockStage->queueResult(BSON("$sortKey" << 1)); - mockStage->queueError(Status(ErrorCodes::BadValue, "bad thing happened")); - - auto sortKeyStage = stdx::make_unique<RouterStageRemoveSortKey>(std::move(mockStage)); - - auto firstResult = sortKeyStage->next(); - ASSERT_OK(firstResult.getStatus()); - ASSERT(firstResult.getValue()); - ASSERT_EQ(*firstResult.getValue(), BSONObj()); - - auto secondResult = sortKeyStage->next(); - ASSERT_NOT_OK(secondResult.getStatus()); - ASSERT_EQ(secondResult.getStatus(), ErrorCodes::BadValue); - ASSERT_EQ(secondResult.getStatus().reason(), "bad thing happened"); -} - -TEST(RouterStageRemoveSortKeyTest, ToleratesMidStreamEOF) { - auto mockStage = stdx::make_unique<RouterStageMock>(); - mockStage->queueResult(BSON("a" << 1 << "$sortKey" << 1 << "b" << 1)); - mockStage->queueEOF(); - mockStage->queueResult(BSON("a" << 2 << "$sortKey" << 1 << "b" << 2)); - - auto sortKeyStage = stdx::make_unique<RouterStageRemoveSortKey>(std::move(mockStage)); - - auto firstResult = sortKeyStage->next(); - ASSERT_OK(firstResult.getStatus()); - ASSERT(firstResult.getValue()); - ASSERT_EQ(*firstResult.getValue(), BSON("a" << 1 << "b" << 1)); - - auto secondResult = sortKeyStage->next(); - ASSERT_OK(secondResult.getStatus()); - ASSERT(!secondResult.getValue()); - - auto thirdResult = sortKeyStage->next(); - ASSERT_OK(thirdResult.getStatus()); - ASSERT(thirdResult.getValue()); - ASSERT_EQ(*thirdResult.getValue(), BSON("a" << 2 << "b" << 2)); - - auto fourthResult = sortKeyStage->next(); - ASSERT_OK(fourthResult.getStatus()); - ASSERT(!fourthResult.getValue()); -} - -} // namespace - -} // namespace mongo |