summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew Paroski <drew.paroski@mongodb.com>2020-04-28 18:36:49 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-06-02 14:24:40 +0000
commit7e28f4296a04d858a2e3dd84a1e79c9ba59a9568 (patch)
treea6e6f9fdfffe9f7e0be7d37269c853a0baf82c96
parent3a737b6beefe346060bbfd64b5c97790d4fd86ad (diff)
downloadmongo-7e28f4296a04d858a2e3dd84a1e79c9ba59a9568.tar.gz
SERVER-47773 Error consistently when tailable cursors and $near are used togetherr4.0.19-rc0r4.0.19
(cherry picked from commit c8ced6df8f620daaa2e539f192f2eef356c63e9c) (cherry picked from commit e9c31e791b2e056c016c048d7e21c59e0e2452ea) (cherry picked from commit 444dab325b5351ddd566da1d5365ec8728a06634)
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml3
-rw-r--r--jstests/core/geo_near_tailable.js25
-rw-r--r--src/mongo/db/query/canonical_query.cpp6
-rw-r--r--src/mongo/db/query/query_planner.cpp2
4 files changed, 35 insertions, 1 deletions
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml
index 7a3f0037aa4..5d66eb6200d 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml
@@ -274,6 +274,9 @@ selector:
- jstests/core/cursora.js
- jstests/core/bench_test1.js
+ # It is illegal to open a tailable cursor in a transaction
+ - jstests/core/geo_near_tailable.js
+
exclude_with_any_tags:
# "Cowardly refusing to override read concern of command: ..."
- assumes_read_concern_unchanged
diff --git a/jstests/core/geo_near_tailable.js b/jstests/core/geo_near_tailable.js
new file mode 100644
index 00000000000..fd7b077f110
--- /dev/null
+++ b/jstests/core/geo_near_tailable.js
@@ -0,0 +1,25 @@
+// @tags: [requires_capped]
+//
+// Tests that combine $geoNear and tailable cursors.
+//
+(function() {
+ "use strict";
+
+ let cmdRes;
+ const collName = 'geo_near_tailable';
+ const cappedCollName = 'geo_near_tailable_capped';
+
+ // Avoid using the drop() shell helper here in order to avoid "implicit collection recreation"
+ // which can happen when this test runs in certain passthroughs. For details, see
+ // "jstests/libs/override_methods/implicitly_shard_accessed_collections.js".
+ db.runCommand({drop: collName});
+ db.runCommand({drop: cappedCollName});
+ assert.commandWorked(db.createCollection(collName));
+ assert.commandWorked(db.createCollection(cappedCollName, {capped: true, size: 10000}));
+
+ // Error when tailable option is used with NEAR.
+ cmdRes = db.runCommand({find: collName, filter: {a: {$geoNear: [1, 2]}}, tailable: true});
+ assert.commandFailedWithCode(cmdRes, ErrorCodes.BadValue);
+ cmdRes = db.runCommand({find: cappedCollName, filter: {a: {$geoNear: [1, 2]}}, tailable: true});
+ assert.commandFailedWithCode(cmdRes, ErrorCodes.BadValue);
+})();
diff --git a/src/mongo/db/query/canonical_query.cpp b/src/mongo/db/query/canonical_query.cpp
index 6d2337d92ef..3d15afafe6c 100644
--- a/src/mongo/db/query/canonical_query.cpp
+++ b/src/mongo/db/query/canonical_query.cpp
@@ -404,6 +404,12 @@ Status CanonicalQuery::isValid(MatchExpression* root, const QueryRequest& parsed
return Status(ErrorCodes::BadValue, "text and tailable cursor not allowed in same query");
}
+ // NEAR and tailable are incompatible.
+ if (numGeoNear > 0 && parsed.isTailable()) {
+ return Status(ErrorCodes::BadValue,
+ "Tailable cursors and geo $near cannot be used together");
+ }
+
// $natural sort order must agree with hint.
if (sortNaturalElt) {
if (!hintObj.isEmpty() && !hintNaturalElt) {
diff --git a/src/mongo/db/query/query_planner.cpp b/src/mongo/db/query/query_planner.cpp
index d91e92a6449..9236c52d206 100644
--- a/src/mongo/db/query/query_planner.cpp
+++ b/src/mongo/db/query/query_planner.cpp
@@ -544,7 +544,7 @@ StatusWith<std::vector<std::unique_ptr<QuerySolution>>> QueryPlanner::plan(
// If the query requests a tailable cursor, the only solution is a collscan + filter with
// tailable set on the collscan.
if (isTailable) {
- if (!QueryPlannerCommon::hasNode(query.root(), MatchExpression::GEO_NEAR) && canTableScan) {
+ if (canTableScan) {
auto soln = buildCollscanSoln(query, isTailable, params);
if (soln) {
out.push_back(std::move(soln));