summaryrefslogtreecommitdiff
path: root/src/mongo/s/query
diff options
context:
space:
mode:
authorRuoxin Xu <ruoxin.xu@mongodb.com>2021-02-02 21:03:25 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-02-17 11:23:05 +0000
commit5ada96cbe318734f9c7dfa26dea3f28dbe4627bf (patch)
tree5a63211f065b1e40e5eeeb239d241355e1720ffa /src/mongo/s/query
parentd4ff82a11019aef87701db9053499461601e75d6 (diff)
downloadmongo-5ada96cbe318734f9c7dfa26dea3f28dbe4627bf.tar.gz
SERVER-53060 Remove QueryRequest class
Diffstat (limited to 'src/mongo/s/query')
-rw-r--r--src/mongo/s/query/async_results_merger_test.cpp2
-rw-r--r--src/mongo/s/query/cluster_find.cpp110
-rw-r--r--src/mongo/s/query/results_merger_test_fixture.h18
3 files changed, 68 insertions, 62 deletions
diff --git a/src/mongo/s/query/async_results_merger_test.cpp b/src/mongo/s/query/async_results_merger_test.cpp
index 00112add13b..fd156343e2a 100644
--- a/src/mongo/s/query/async_results_merger_test.cpp
+++ b/src/mongo/s/query/async_results_merger_test.cpp
@@ -38,7 +38,7 @@
#include "mongo/db/pipeline/resume_token.h"
#include "mongo/db/query/cursor_response.h"
#include "mongo/db/query/getmore_request.h"
-#include "mongo/db/query/query_request.h"
+#include "mongo/db/query/query_request_helper.h"
#include "mongo/executor/task_executor.h"
#include "mongo/s/catalog/type_shard.h"
#include "mongo/s/client/shard_registry.h"
diff --git a/src/mongo/s/query/cluster_find.cpp b/src/mongo/s/query/cluster_find.cpp
index 7fac4105e93..02c4b570ac9 100644
--- a/src/mongo/s/query/cluster_find.cpp
+++ b/src/mongo/s/query/cluster_find.cpp
@@ -84,86 +84,94 @@ static const int kPerDocumentOverheadBytesUpperBound = 10;
const char kFindCmdName[] = "find";
/**
- * Given the QueryRequest 'qr' being executed by mongos, returns a copy of the query which is
- * suitable for forwarding to the targeted hosts.
+ * Given the FindCommand 'findCommand' being executed by mongos, returns a copy of the query which
+ * is suitable for forwarding to the targeted hosts.
*/
-StatusWith<std::unique_ptr<QueryRequest>> transformQueryForShards(
- const QueryRequest& qr, bool appendGeoNearDistanceProjection) {
+StatusWith<std::unique_ptr<FindCommand>> transformQueryForShards(
+ const FindCommand& findCommand, bool appendGeoNearDistanceProjection) {
// If there is a limit, we forward the sum of the limit and the skip.
boost::optional<int64_t> newLimit;
- if (qr.getLimit()) {
+ if (findCommand.getLimit()) {
long long newLimitValue;
- if (overflow::add(*qr.getLimit(), qr.getSkip().value_or(0), &newLimitValue)) {
+ if (overflow::add(
+ *findCommand.getLimit(), findCommand.getSkip().value_or(0), &newLimitValue)) {
return Status(
ErrorCodes::Overflow,
str::stream()
<< "sum of limit and skip cannot be represented as a 64-bit integer, limit: "
- << *qr.getLimit() << ", skip: " << qr.getSkip().value_or(0));
+ << *findCommand.getLimit() << ", skip: " << findCommand.getSkip().value_or(0));
}
newLimit = newLimitValue;
}
// Similarly, if nToReturn is set, we forward the sum of nToReturn and the skip.
boost::optional<int64_t> newNToReturn;
- if (qr.getNToReturn()) {
+ if (findCommand.getNtoreturn()) {
// 'singleBatch' and ntoreturn mean the same as 'singleBatch' and limit, so perform the
// conversion.
- if (qr.isSingleBatch()) {
+ if (findCommand.getSingleBatch()) {
int64_t newLimitValue;
- if (overflow::add(*qr.getNToReturn(), qr.getSkip().value_or(0), &newLimitValue)) {
+ if (overflow::add(*findCommand.getNtoreturn(),
+ findCommand.getSkip().value_or(0),
+ &newLimitValue)) {
return Status(ErrorCodes::Overflow,
str::stream()
<< "sum of ntoreturn and skip cannot be represented as a 64-bit "
"integer, ntoreturn: "
- << *qr.getNToReturn() << ", skip: " << qr.getSkip().value_or(0));
+ << *findCommand.getNtoreturn()
+ << ", skip: " << findCommand.getSkip().value_or(0));
}
newLimit = newLimitValue;
} else {
int64_t newNToReturnValue;
- if (overflow::add(*qr.getNToReturn(), qr.getSkip().value_or(0), &newNToReturnValue)) {
+ if (overflow::add(*findCommand.getNtoreturn(),
+ findCommand.getSkip().value_or(0),
+ &newNToReturnValue)) {
return Status(ErrorCodes::Overflow,
str::stream()
<< "sum of ntoreturn and skip cannot be represented as a 64-bit "
"integer, ntoreturn: "
- << *qr.getNToReturn() << ", skip: " << qr.getSkip().value_or(0));
+ << *findCommand.getNtoreturn()
+ << ", skip: " << findCommand.getSkip().value_or(0));
}
newNToReturn = newNToReturnValue;
}
}
// If there is a sort other than $natural, we send a sortKey meta-projection to the remote node.
- BSONObj newProjection = qr.getProj();
- if (!qr.getSort().isEmpty() && !qr.getSort()[QueryRequest::kNaturalSortField]) {
+ BSONObj newProjection = findCommand.getProjection();
+ if (!findCommand.getSort().isEmpty() &&
+ !findCommand.getSort()[query_request_helper::kNaturalSortField]) {
BSONObjBuilder projectionBuilder;
- projectionBuilder.appendElements(qr.getProj());
+ projectionBuilder.appendElements(findCommand.getProjection());
projectionBuilder.append(AsyncResultsMerger::kSortKeyField, kSortKeyMetaProjection);
newProjection = projectionBuilder.obj();
}
if (appendGeoNearDistanceProjection) {
- invariant(qr.getSort().isEmpty());
+ invariant(findCommand.getSort().isEmpty());
BSONObjBuilder projectionBuilder;
- projectionBuilder.appendElements(qr.getProj());
+ projectionBuilder.appendElements(findCommand.getProjection());
projectionBuilder.append(AsyncResultsMerger::kSortKeyField, kGeoNearDistanceMetaProjection);
newProjection = projectionBuilder.obj();
}
- auto newQR = std::make_unique<QueryRequest>(qr);
- newQR->setProj(newProjection);
+ auto newQR = std::make_unique<FindCommand>(findCommand);
+ newQR->setProjection(newProjection);
newQR->setSkip(boost::none);
newQR->setLimit(newLimit);
- newQR->setNToReturn(newNToReturn);
+ newQR->setNtoreturn(newNToReturn);
// Even if the client sends us singleBatch=true, we may need to retrieve
// multiple batches from a shard in order to return the single requested batch to the client.
// Therefore, we must always send singleBatch=false to the shards.
- newQR->setSingleBatchField(false);
+ newQR->setSingleBatch(false);
// Any expansion of the 'showRecordId' flag should have already happened on mongos.
- if (newQR->showRecordId())
+ if (newQR->getShowRecordId())
newQR->setShowRecordId(false);
- invariant(newQR->validate());
+ uassertStatusOK(query_request_helper::validateFindCommand(*newQR));
return std::move(newQR);
}
@@ -178,20 +186,20 @@ std::vector<std::pair<ShardId, BSONObj>> constructRequestsForShards(
const CanonicalQuery& query,
bool appendGeoNearDistanceProjection) {
- std::unique_ptr<QueryRequest> qrToForward;
+ std::unique_ptr<FindCommand> findCommandToForward;
if (shardIds.size() > 1) {
- qrToForward = uassertStatusOK(
- transformQueryForShards(query.getQueryRequest(), appendGeoNearDistanceProjection));
+ findCommandToForward = uassertStatusOK(
+ transformQueryForShards(query.getFindCommand(), appendGeoNearDistanceProjection));
} else {
- // Forwards the QueryRequest as is to a single shard so that limit and skip can
+ // Forwards the FindCommand as is to a single shard so that limit and skip can
// be applied on mongod.
- qrToForward = std::make_unique<QueryRequest>(query.getQueryRequest());
+ findCommandToForward = std::make_unique<FindCommand>(query.getFindCommand());
}
auto& readConcernArgs = repl::ReadConcernArgs::get(opCtx);
if (readConcernArgs.wasAtClusterTimeSelected()) {
// If mongos selected atClusterTime or received it from client, transmit it to shard.
- qrToForward->setReadConcern(readConcernArgs.toBSONInner());
+ findCommandToForward->setReadConcern(readConcernArgs.toBSONInner());
}
auto shardRegistry = Grid::get(opCtx)->shardRegistry();
@@ -201,7 +209,7 @@ std::vector<std::pair<ShardId, BSONObj>> constructRequestsForShards(
invariant(!shard->isConfig() || shard->getConnString());
BSONObjBuilder cmdBuilder;
- qrToForward->asFindCommand(&cmdBuilder);
+ findCommandToForward->serialize(BSONObj(), &cmdBuilder);
if (cm.isSharded()) {
cm.getVersion(shardId).appendToCommand(&cmdBuilder);
@@ -240,20 +248,20 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
const ChunkManager& cm,
std::vector<BSONObj>* results,
bool* partialResultsReturned) {
+ auto findCommand = query.getFindCommand();
// Get the set of shards on which we will run the query.
- auto shardIds = getTargetedShardsForQuery(query.getExpCtx(),
- cm,
- query.getQueryRequest().getFilter(),
- query.getQueryRequest().getCollation());
+ auto shardIds = getTargetedShardsForQuery(
+ query.getExpCtx(), cm, findCommand.getFilter(), findCommand.getCollation());
// Construct the query and parameters. Defer setting skip and limit here until
// we determine if the query is targeting multi-shards or a single shard below.
ClusterClientCursorParams params(
query.nss(), APIParameters::get(opCtx), readPref, ReadConcernArgs::get(opCtx));
params.originatingCommandObj = CurOp::get(opCtx)->opDescription().getOwned();
- params.batchSize = query.getQueryRequest().getEffectiveBatchSize();
- params.tailableMode = query.getQueryRequest().getTailableMode();
- params.isAllowPartialResults = query.getQueryRequest().isAllowPartialResults();
+ params.batchSize =
+ findCommand.getBatchSize() ? findCommand.getBatchSize() : findCommand.getNtoreturn();
+ params.tailableMode = query_request_helper::getTailableMode(findCommand);
+ params.isAllowPartialResults = findCommand.getAllowPartialResults();
params.lsid = opCtx->getLogicalSessionId();
params.txnNumber = opCtx->getTxnNumber();
params.originatingPrivileges = {
@@ -274,8 +282,7 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
// 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.
BSONObj sortComparatorObj;
- if (query.getSortPattern() &&
- !query.getQueryRequest().getSort()[QueryRequest::kNaturalSortField]) {
+ if (query.getSortPattern() && !findCommand.getSort()[query_request_helper::kNaturalSortField]) {
// We have already validated the input sort object. Serialize the raw sort spec into one
// suitable for use as the ordering specification in BSONObj::woCompare(). In particular, we
// want to eliminate sorts using expressions (like $meta) and replace them with a
@@ -303,7 +310,7 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
// Tailable cursors can't have a sort, which should have already been validated.
tassert(4457013,
"tailable cursor unexpectedly has a sort",
- sortComparatorObj.isEmpty() || !query.getQueryRequest().isTailable());
+ sortComparatorObj.isEmpty() || !findCommand.getTailable());
// Construct the requests that we will use to establish cursors on the targeted shards,
// attaching the shardVersion and txnNumber, if necessary.
@@ -317,7 +324,7 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
query.nss(),
readPref,
requests,
- query.getQueryRequest().isAllowPartialResults());
+ findCommand.getAllowPartialResults());
// Determine whether the cursor we may eventually register will be single- or multi-target.
@@ -328,9 +335,8 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
// Only set skip, limit and sort to be applied to on the router for the multi-shard case. For
// the single-shard case skip/limit as well as sorts are appled on mongod.
if (cursorType == ClusterCursorManager::CursorType::MultiTarget) {
- const auto qr = query.getQueryRequest();
- params.skipToApplyOnRouter = qr.getSkip();
- params.limit = qr.getLimit();
+ params.skipToApplyOnRouter = findCommand.getSkip();
+ params.limit = findCommand.getLimit();
params.sortToApplyOnRouter = sortComparatorObj;
params.compareWholeSortKeyOnRouter = compareWholeSortKeyOnRouter;
}
@@ -350,7 +356,7 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
// This loop will not result in actually calling getMore against shards, but just loading
// results from the initial batches (that were obtained while establishing cursors) into
// 'results'.
- while (!FindCommon::enoughForFirstBatch(query.getQueryRequest(), results->size())) {
+ while (!FindCommon::enoughForFirstBatch(findCommand, results->size())) {
auto next = uassertStatusOK(ccc->next(RouterExecStage::ExecContext::kInitialFind));
if (next.isEOF()) {
@@ -381,7 +387,7 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
ccc->detachFromOperationContext();
- if (query.getQueryRequest().isSingleBatch() && !ccc->isTailable()) {
+ if (findCommand.getSingleBatch() && !ccc->isTailable()) {
cursorState = ClusterCursorManager::CursorState::Exhausted;
}
@@ -408,7 +414,7 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
// Register the cursor with the cursor manager for subsequent getMore's.
auto cursorManager = Grid::get(opCtx)->getCursorManager();
- const auto cursorLifetime = query.getQueryRequest().isNoCursorTimeout()
+ const auto cursorLifetime = findCommand.getNoCursorTimeout()
? ClusterCursorManager::CursorLifetime::Immortal
: ClusterCursorManager::CursorLifetime::Mortal;
auto authUsers = AuthorizationSession::get(opCtx->getClient())->getAuthenticatedUserNames();
@@ -488,19 +494,19 @@ CursorId ClusterFind::runQuery(OperationContext* opCtx,
// We must always have a BSONObj vector into which to output our results.
invariant(results);
+ auto findCommand = query.getFindCommand();
// Projection on the reserved sort key field is illegal in mongos.
- if (query.getQueryRequest().getProj().hasField(AsyncResultsMerger::kSortKeyField)) {
+ if (findCommand.getProjection().hasField(AsyncResultsMerger::kSortKeyField)) {
uasserted(ErrorCodes::BadValue,
str::stream() << "Projection contains illegal field '"
<< AsyncResultsMerger::kSortKeyField
- << "': " << query.getQueryRequest().getProj());
+ << "': " << findCommand.getProjection());
}
// Attempting to establish a resumable query through mongoS is illegal.
uassert(ErrorCodes::BadValue,
"Queries on mongoS may not request or provide a resume token",
- !query.getQueryRequest().getRequestResumeToken() &&
- query.getQueryRequest().getResumeAfter().isEmpty());
+ !findCommand.getRequestResumeToken() && findCommand.getResumeAfter().isEmpty());
auto const catalogCache = Grid::get(opCtx)->catalogCache();
diff --git a/src/mongo/s/query/results_merger_test_fixture.h b/src/mongo/s/query/results_merger_test_fixture.h
index d653bfe0bfa..10978c11cb7 100644
--- a/src/mongo/s/query/results_merger_test_fixture.h
+++ b/src/mongo/s/query/results_merger_test_fixture.h
@@ -72,22 +72,22 @@ protected:
if (findCmd) {
// If there is no '$db', append it.
auto cmd = OpMsgRequest::fromDBAndBody(kTestNss.db(), *findCmd).body;
- const auto qr =
- QueryRequest::makeFromFindCommandForTests(cmd, false /* isExplain */, kTestNss);
- if (!qr->getSort().isEmpty()) {
- params.setSort(qr->getSort().getOwned());
+ const auto findCommand =
+ query_request_helper::makeFromFindCommandForTests(cmd, kTestNss);
+ if (!findCommand->getSort().isEmpty()) {
+ params.setSort(findCommand->getSort().getOwned());
}
if (getMoreBatchSize) {
params.setBatchSize(getMoreBatchSize);
} else {
- params.setBatchSize(qr->getBatchSize()
- ? boost::optional<std::int64_t>(
- static_cast<std::int64_t>(*qr->getBatchSize()))
+ params.setBatchSize(findCommand->getBatchSize()
+ ? boost::optional<std::int64_t>(static_cast<std::int64_t>(
+ *findCommand->getBatchSize()))
: boost::none);
}
- params.setTailableMode(qr->getTailableMode());
- params.setAllowPartialResults(qr->isAllowPartialResults());
+ params.setTailableMode(query_request_helper::getTailableMode(*findCommand));
+ params.setAllowPartialResults(findCommand->getAllowPartialResults());
}
OperationSessionInfoFromClient sessionInfo;