summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_kill_primary_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_kill_primary_jscore_passthrough.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_stepdown_jscore_passthrough.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_terminate_primary_jscore_passthrough.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_stepdown_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_reconfig_kill_primary_jscore_passthrough.yml2
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_terminate_primary_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/retryable_writes_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/retryable_writes_jscore_stepdown_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/session_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/sharded_multi_stmt_txn_jscore_passthrough.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/tenant_migration_causally_consistent_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/tenant_migration_kill_primary_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/tenant_migration_multi_stmt_txn_jscore_passthrough.yml5
-rw-r--r--buildscripts/resmokeconfig/suites/tenant_migration_stepdown_jscore_passthrough.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/tenant_migration_terminate_primary_jscore_passthrough.yml1
-rw-r--r--jstests/core/exists7.js2
-rw-r--r--jstests/core/validate_cmd_ns.js24
-rw-r--r--jstests/noPassthrough/exhaust_option_disallowed_in_session.js32
-rw-r--r--jstests/noPassthrough/max_time_ms.js15
-rw-r--r--jstests/sharding/query_sharded.js25
-rw-r--r--src/mongo/client/dbclient_cursor.cpp255
-rw-r--r--src/mongo/client/dbclient_cursor.h2
-rw-r--r--src/mongo/client/query.cpp3
-rw-r--r--src/mongo/client/query.h1
-rw-r--r--src/mongo/client/query_spec.h124
-rw-r--r--src/mongo/db/query/query_request_helper.cpp35
-rw-r--r--src/mongo/db/query/query_request_helper.h10
-rw-r--r--src/mongo/db/query/query_request_test.cpp38
-rw-r--r--src/mongo/s/commands/cluster_explain_cmd.cpp9
-rw-r--r--src/mongo/shell/explain_query.js119
-rw-r--r--src/mongo/shell/mongo.js5
-rw-r--r--src/mongo/transport/service_state_machine.cpp49
40 files changed, 144 insertions, 653 deletions
diff --git a/buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml
index e830c47cd85..aa9e84dbc1b 100644
--- a/buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/multi_shard_local_read_write_multi_stmt_txn_jscore_passthrough.yml
@@ -134,7 +134,7 @@ selector:
## Some aggregation stages aren't allowed in a transaction.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/collation.js
- jstests/core/explain_shell_helpers.js
@@ -178,7 +178,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed in a transaction.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml
index fead8bf2e92..a2d14686ceb 100644
--- a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_jscore_passthrough.yml
@@ -136,7 +136,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -200,7 +200,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml
index 5b68cfbb2b7..b61aed35737 100644
--- a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_kill_primary_jscore_passthrough.yml
@@ -131,7 +131,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -188,7 +188,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml
index f3cc72c5a3c..4fe4a9b5343 100644
--- a/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/multi_shard_multi_stmt_txn_stepdown_primary_jscore_passthrough.yml
@@ -132,7 +132,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -189,7 +189,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml b/buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml
index 108a850e49d..1cb8898a421 100644
--- a/buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml
+++ b/buildscripts/resmokeconfig/suites/multi_stmt_txn_jscore_passthrough_with_migration.yml
@@ -144,7 +144,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -208,7 +208,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_kill_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_kill_primary_jscore_passthrough.yml
index 2784b7ee3e6..4d7ac98666e 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_kill_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_kill_primary_jscore_passthrough.yml
@@ -47,7 +47,6 @@ selector:
- jstests/core/insert2.js # Creates new mongo connection.
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/startup_log.js # Checks pid, which is different on each server.
- - jstests/core/validate_cmd_ns.js # Calls _exec() directly, not retryable.
# Creates new mongo connection but won't retry connecting.
- jstests/core/shell_connection_strings.js
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 b941a428ed3..f6e153321c3 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
@@ -78,7 +78,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -148,7 +148,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_kill_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_kill_primary_jscore_passthrough.yml
index 2d8f1367138..658df1cca30 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_kill_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_kill_primary_jscore_passthrough.yml
@@ -73,7 +73,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -136,7 +136,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_stepdown_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_stepdown_jscore_passthrough.yml
index b75d012a07f..13227f2f413 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_stepdown_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_stepdown_jscore_passthrough.yml
@@ -72,7 +72,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -135,7 +135,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_terminate_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_terminate_primary_jscore_passthrough.yml
index c4f70cafc08..a0a30f7a18b 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_terminate_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_terminate_primary_jscore_passthrough.yml
@@ -70,7 +70,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -133,7 +133,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_passthrough.yml
index e6318e6bd0a..a12f9273ee6 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_passthrough.yml
@@ -19,7 +19,6 @@ selector:
# These test run commands using legacy queries, which are not supported on sessions.
- jstests/core/comment_field.js
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# Unacknowledged writes prohibited in an explicit session.
- jstests/core/batch_write_command_w0.js
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_stepdown_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_stepdown_passthrough.yml
index b2f526f9170..f0187167f88 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_stepdown_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_reconfig_jscore_stepdown_passthrough.yml
@@ -34,7 +34,6 @@ selector:
# These test run commands using legacy queries, which are not supported on sessions.
- jstests/core/comment_field.js
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# Stepdown commands during fsync lock will fail.
- jstests/core/currentop.js
@@ -62,7 +61,6 @@ selector:
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/top.js # Tests read commands (including getMore) against the secondary
- jstests/core/drop3.js # getMore is not causally consistent if collection is dropped
- - jstests/core/validate_cmd_ns.js # Calls _exec() directly, not retryable.
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/explain_large_bounds.js # Stepdown can timeout waiting for global lock.
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_reconfig_kill_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_reconfig_kill_primary_jscore_passthrough.yml
index 92db4edf639..7462c89afb2 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_reconfig_kill_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_reconfig_kill_primary_jscore_passthrough.yml
@@ -35,7 +35,6 @@ selector:
# These test run commands using legacy queries, which are not supported on sessions.
- jstests/core/comment_field.js
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# Stepdown commands during fsync lock will fail.
- jstests/core/currentop.js
@@ -63,7 +62,6 @@ selector:
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/top.js # Tests read commands (including getMore) against the secondary
- jstests/core/drop3.js # getMore is not causally consistent if collection is dropped
- - jstests/core/validate_cmd_ns.js # Calls _exec() directly, not retryable.
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/explain_large_bounds.js # Stepdown can timeout waiting for global lock.
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_terminate_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_terminate_primary_jscore_passthrough.yml
index 0decf8530d8..22e53534b16 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_terminate_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_terminate_primary_jscore_passthrough.yml
@@ -47,7 +47,6 @@ selector:
- jstests/core/insert2.js # Creates new mongo connection.
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/startup_log.js # Checks pid, which is different on each server.
- - jstests/core/validate_cmd_ns.js # Calls _exec() directly, not retryable.
# Creates new mongo connection but won't retry connecting.
- jstests/core/shell_connection_strings.js
diff --git a/buildscripts/resmokeconfig/suites/retryable_writes_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/retryable_writes_jscore_passthrough.yml
index 101b4295dfa..6a16af8357c 100644
--- a/buildscripts/resmokeconfig/suites/retryable_writes_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/retryable_writes_jscore_passthrough.yml
@@ -19,7 +19,6 @@ selector:
# These test run commands using legacy queries, which are not supported on sessions.
- jstests/core/comment_field.js
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# TODO SERVER-31242: findAndModify no-op retry should respect the fields option.
- jstests/core/crud_api.js
diff --git a/buildscripts/resmokeconfig/suites/retryable_writes_jscore_stepdown_passthrough.yml b/buildscripts/resmokeconfig/suites/retryable_writes_jscore_stepdown_passthrough.yml
index f81f81d153f..fd1a3c2963a 100644
--- a/buildscripts/resmokeconfig/suites/retryable_writes_jscore_stepdown_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/retryable_writes_jscore_stepdown_passthrough.yml
@@ -51,7 +51,6 @@ selector:
- jstests/core/insert2.js # Creates new mongo connection.
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/startup_log.js # Checks pid, which is different on each server.
- - jstests/core/validate_cmd_ns.js # Calls _exec() directly, not retryable.
exclude_with_any_tags:
- assumes_standalone_mongod
diff --git a/buildscripts/resmokeconfig/suites/session_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/session_jscore_passthrough.yml
index 2bb5fdfb37d..9a44de18f12 100644
--- a/buildscripts/resmokeconfig/suites/session_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/session_jscore_passthrough.yml
@@ -10,7 +10,6 @@ selector:
# These test run commands using legacy queries, which are not supported on sessions.
- jstests/core/comment_field.js
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# Unacknowledged writes prohibited in an explicit session.
- jstests/core/crud_api.js
diff --git a/buildscripts/resmokeconfig/suites/sharded_multi_stmt_txn_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/sharded_multi_stmt_txn_jscore_passthrough.yml
index f38fc8934f6..a631b980d9f 100644
--- a/buildscripts/resmokeconfig/suites/sharded_multi_stmt_txn_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/sharded_multi_stmt_txn_jscore_passthrough.yml
@@ -104,7 +104,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -172,7 +172,6 @@ selector:
# SERVER-34868 Cannot run a legacy query on a session.
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
diff --git a/buildscripts/resmokeconfig/suites/tenant_migration_causally_consistent_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/tenant_migration_causally_consistent_jscore_passthrough.yml
index cc0c454e223..f5aaf2f72b5 100644
--- a/buildscripts/resmokeconfig/suites/tenant_migration_causally_consistent_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/tenant_migration_causally_consistent_jscore_passthrough.yml
@@ -144,7 +144,6 @@ selector:
# These test run commands using legacy queries, which are not supported on sessions.
- jstests/core/comment_field.js
- jstests/core/exhaust.js
- - jstests/core/validate_cmd_ns.js
# Unacknowledged writes prohibited in an explicit session.
- jstests/core/crud_api.js
diff --git a/buildscripts/resmokeconfig/suites/tenant_migration_kill_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/tenant_migration_kill_primary_jscore_passthrough.yml
index afa3606c245..3b00933e879 100644
--- a/buildscripts/resmokeconfig/suites/tenant_migration_kill_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/tenant_migration_kill_primary_jscore_passthrough.yml
@@ -144,7 +144,6 @@ selector:
- jstests/core/insert2.js # Creates new mongo connection.
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/startup_log.js # Checks pid, which is different on each server.
- - jstests/core/validate_cmd_ns.js # Calls _exec() directly, not retryable.
#
# Denylists specific to this suite
diff --git a/buildscripts/resmokeconfig/suites/tenant_migration_multi_stmt_txn_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/tenant_migration_multi_stmt_txn_jscore_passthrough.yml
index d0555fc4e6d..5c813fd7a53 100644
--- a/buildscripts/resmokeconfig/suites/tenant_migration_multi_stmt_txn_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/tenant_migration_multi_stmt_txn_jscore_passthrough.yml
@@ -193,7 +193,7 @@ selector:
## Some aggregation stages don't support snapshot readconcern.
##
- # $explain (requires read concern local)
+ # explain (requires read concern local)
- jstests/core/agg_hint.js
- jstests/core/and.js
- jstests/core/collation.js
@@ -253,9 +253,6 @@ selector:
## Misc. reasons.
##
- # SERVER-34868 Cannot run a legacy query on a session.
- - jstests/core/validate_cmd_ns.js
-
# SERVER-34772 Tailable Cursors are not allowed with snapshot readconcern.
- jstests/core/awaitdata_getmore_cmd.js
- jstests/core/getmore_cmd_maxtimems.js
diff --git a/buildscripts/resmokeconfig/suites/tenant_migration_stepdown_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/tenant_migration_stepdown_jscore_passthrough.yml
index 8be100ca0f6..be354b863c4 100644
--- a/buildscripts/resmokeconfig/suites/tenant_migration_stepdown_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/tenant_migration_stepdown_jscore_passthrough.yml
@@ -144,7 +144,6 @@ selector:
- jstests/core/insert2.js # Creates new mongo connection.
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/startup_log.js # Checks pid, which is different on each server.
- - jstests/core/validate_cmd_ns.js # Calls _exec() directly, not retryable.
#
# Denylists specific to this suite
diff --git a/buildscripts/resmokeconfig/suites/tenant_migration_terminate_primary_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/tenant_migration_terminate_primary_jscore_passthrough.yml
index 87679d6a701..dc26c216799 100644
--- a/buildscripts/resmokeconfig/suites/tenant_migration_terminate_primary_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/tenant_migration_terminate_primary_jscore_passthrough.yml
@@ -144,7 +144,6 @@ selector:
- jstests/core/insert2.js # Creates new mongo connection.
- jstests/core/list_collections_filter.js # Temporary collections are dropped on failover.
- jstests/core/startup_log.js # Checks pid, which is different on each server.
- - jstests/core/validate_cmd_ns.js # Calls _exec() directly, not retryable.
#
# Denylists specific to this suite
diff --git a/jstests/core/exists7.js b/jstests/core/exists7.js
index 6ca55a42286..285559e82f8 100644
--- a/jstests/core/exists7.js
+++ b/jstests/core/exists7.js
@@ -1,6 +1,6 @@
// @tags: [requires_non_retryable_writes]
-// Test that non boolean value types are allowed with $explain spec. SERVER-2322
+// Test that non boolean value types are allowed with $exists spec. SERVER-2322
t = db.jstests_exists7;
t.drop();
diff --git a/jstests/core/validate_cmd_ns.js b/jstests/core/validate_cmd_ns.js
deleted file mode 100644
index f5f706335ad..00000000000
--- a/jstests/core/validate_cmd_ns.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Tests that query against the $cmd namespace will error out when the request has
- * a number to return value other than 1 or -1. Note that users cannot have
- * collections named $cmd since $ is an illegal character.
- */
-
-// Note: _exec gives you the raw response from the server.
-var res = db.$cmd.find({whatsmyuri: 1})._exec().next();
-assert.commandFailed(res);
-assert(res.errmsg.indexOf('Bad numberToReturn') > -1);
-
-res = db.$cmd.find({whatsmyuri: 1}).limit(0)._exec().next();
-assert.commandFailed(res);
-assert(res.errmsg.indexOf('Bad numberToReturn') > -1);
-
-res = db.$cmd.find({whatsmyuri: 1}).limit(-2)._exec().next();
-assert.commandFailed(res);
-assert(res.errmsg.indexOf('Bad numberToReturn') > -1);
-
-res = db.$cmd.find({whatsmyuri: 1}).limit(1).next();
-assert.commandWorked(res);
-
-res = db.$cmd.find({whatsmyuri: 1}).limit(-1).next();
-assert.commandWorked(res);
diff --git a/jstests/noPassthrough/exhaust_option_disallowed_in_session.js b/jstests/noPassthrough/exhaust_option_disallowed_in_session.js
deleted file mode 100644
index 1ba1014dc2f..00000000000
--- a/jstests/noPassthrough/exhaust_option_disallowed_in_session.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Make sure the 'exhaust' query option is not able to be used in a session.
- */
-(function() {
-"use strict";
-
-let conn = MongoRunner.runMongod();
-
-const dbName = 'test';
-const collName = 'coll';
-
-const session = conn.startSession();
-const sessionColl = session.getDatabase(dbName).getCollection(collName);
-const testColl = conn.getDB(dbName).getCollection(collName);
-
-testColl.drop();
-
-// Create a collection to query.
-assert.commandWorked(testColl.insert({_id: 1}));
-
-// Exhaust outside of session should work.
-let docs = testColl.find().addOption(DBQuery.Option.exhaust).toArray();
-assert.docEq([{_id: 1}], docs);
-
-// Exhaust in session should fail.
-assert.throws(() => {
- sessionColl.find().addOption(DBQuery.Option.exhaust).toArray();
-});
-
-session.endSession();
-MongoRunner.stopMongod(conn);
-}());
diff --git a/jstests/noPassthrough/max_time_ms.js b/jstests/noPassthrough/max_time_ms.js
index 050b85ac648..a780b21cbbb 100644
--- a/jstests/noPassthrough/max_time_ms.js
+++ b/jstests/noPassthrough/max_time_ms.js
@@ -320,20 +320,9 @@ function executeTest(db, isMongos) {
ErrorCodes.BadValue);
assert.commandFailedWithCode(db.runCommand({ping: 1, maxTimeMS: {}}), ErrorCodes.BadValue);
- // Verify that the maxTimeMS command argument can be sent with $query-wrapped commands.
- cursor = t.getDB().$cmd.find({ping: 1, maxTimeMS: 0}).limit(-1);
- cursor._ensureSpecial();
- assert.eq(1, cursor.next().ok);
-
// Verify that the server rejects invalid command argument $maxTimeMS.
- cursor = t.getDB().$cmd.find({ping: 1, $maxTimeMS: 0}).limit(-1);
- cursor._ensureSpecial();
- assert.commandFailed(cursor.next());
-
- // Verify that the $maxTimeMS query option can't be sent with $query-wrapped commands.
- cursor = t.getDB().$cmd.find({ping: 1}).limit(-1).maxTimeMS(0);
- cursor._ensureSpecial();
- assert.commandFailed(cursor.next());
+ assert.commandFailed(t.getDB().runCommand({ping: 1, $maxTimeMS: 0}),
+ [ErrorCodes.InvalidOptions, 40415]);
})();
//
diff --git a/jstests/sharding/query_sharded.js b/jstests/sharding/query_sharded.js
deleted file mode 100644
index a043f257d6c..00000000000
--- a/jstests/sharding/query_sharded.js
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Tests mongos-only query behavior
-//
-
-var st = new ShardingTest({shards: 1, mongos: 1, verbose: 0});
-
-var mongos = st.s0;
-var coll = mongos.getCollection("foo.bar");
-
-//
-//
-// Ensure we can't trick mongos by inserting exhaust option on a command through mongos
-coll.remove({});
-assert.commandWorked(coll.insert({a: 'b'}));
-var cmdColl = mongos.getCollection(coll.getDB().toString() + ".$cmd");
-var cmdQuery = cmdColl.find({ping: 1}).limit(1);
-assert.commandWorked(cmdQuery.next());
-cmdQuery = cmdColl.find({ping: 1}).limit(1).addOption(DBQuery.Option.exhaust);
-assert.throws(function() {
- assert.commandWorked(cmdQuery.next());
-});
-
-jsTest.log("DONE!");
-
-st.stop();
diff --git a/src/mongo/client/dbclient_cursor.cpp b/src/mongo/client/dbclient_cursor.cpp
index db9cc55d6f3..96a509da122 100644
--- a/src/mongo/client/dbclient_cursor.cpp
+++ b/src/mongo/client/dbclient_cursor.cpp
@@ -103,106 +103,72 @@ Message DBClientCursor::_assembleInit() {
}
// If we haven't gotten a cursorId yet, we need to issue a new query or command.
- if (_isCommand) {
- // HACK:
- // Unfortunately, this code is used by the shell to run commands,
- // so we need to allow the shell to send invalid options so that we can
- // test that the server rejects them. Thus, to allow generating commands with
- // invalid options, we validate them here, and fall back to generating an OP_QUERY
- // through makeDeprecatedQueryMessage() if the options are invalid.
- bool hasValidNToReturnForCommand = (nToReturn == 1 || nToReturn == -1);
- bool hasValidFlagsForCommand = !(opts & mongo::QueryOption_Exhaust);
- bool hasInvalidMaxTimeMs = query.hasField("$maxTimeMS");
-
- if (hasValidNToReturnForCommand && hasValidFlagsForCommand && !hasInvalidMaxTimeMs) {
- return assembleCommandRequest(_client, ns.db(), opts, query);
- }
- } else if (_useFindCommand) {
- // The caller supplies a 'query' object which may have $-prefixed directives in the format
- // expected for a legacy OP_QUERY. Therefore, we use the legacy parsing code supplied by
- // query_request_helper. When actually issuing the request to the remote node, we will
- // assemble a find command.
- bool explain = false;
- auto findCommand =
- query_request_helper::fromLegacyQuery(_nsOrUuid,
- query,
- fieldsToReturn ? *fieldsToReturn : BSONObj(),
- nToSkip,
- nextBatchSize(),
- opts,
- &explain);
- if (findCommand.isOK() && !explain) {
- if (query.getBoolField("$readOnce")) {
- // Legacy queries don't handle readOnce.
- findCommand.getValue()->setReadOnce(true);
- }
- if (query.getBoolField(FindCommandRequest::kRequestResumeTokenFieldName)) {
- // Legacy queries don't handle requestResumeToken.
- findCommand.getValue()->setRequestResumeToken(true);
- }
- if (query.hasField(FindCommandRequest::kResumeAfterFieldName)) {
- // Legacy queries don't handle resumeAfter.
- findCommand.getValue()->setResumeAfter(
- query.getObjectField(FindCommandRequest::kResumeAfterFieldName));
- }
- if (auto replTerm = query[FindCommandRequest::kTermFieldName]) {
- // Legacy queries don't handle term.
- findCommand.getValue()->setTerm(replTerm.numberLong());
- }
- // Legacy queries don't handle readConcern.
- // We prioritize the readConcern parsed from the query object over '_readConcernObj'.
- if (auto readConcern = query[repl::ReadConcernArgs::kReadConcernFieldName]) {
- findCommand.getValue()->setReadConcern(readConcern.Obj());
- } else if (_readConcernObj) {
- findCommand.getValue()->setReadConcern(_readConcernObj);
- }
- BSONObj cmd = findCommand.getValue()->toBSON(BSONObj());
-
- if (auto readPref = query["$readPreference"]) {
- // FindCommandRequest doesn't handle $readPreference.
- cmd = BSONObjBuilder(std::move(cmd)).append(readPref).obj();
- }
- return assembleCommandRequest(_client, ns.db(), opts, std::move(cmd));
- }
- // else use legacy OP_QUERY request.
- // Legacy OP_QUERY request does not support UUIDs.
- if (_nsOrUuid.uuid()) {
- // If there was a problem building the query request, report that.
- uassertStatusOK(findCommand.getStatus());
- // Otherwise it must have been explain.
- uasserted(50937, "Query by UUID is not supported for explain queries.");
- }
+ // The caller supplies a 'query' object which may have $-prefixed directives in the format
+ // expected for a legacy OP_QUERY. Therefore, we use the legacy parsing code supplied by
+ // query_request_helper. When actually issuing the request to the remote node, we will
+ // assemble a find command.
+ auto findCommand =
+ query_request_helper::fromLegacyQuery(_nsOrUuid,
+ query,
+ fieldsToReturn ? *fieldsToReturn : BSONObj(),
+ nToSkip,
+ nextBatchSize(),
+ opts);
+ // If there was a problem building the query request, report that.
+ uassertStatusOK(findCommand.getStatus());
+
+ if (query.getBoolField("$readOnce")) {
+ // Legacy queries don't handle readOnce.
+ findCommand.getValue()->setReadOnce(true);
+ }
+ if (query.getBoolField(FindCommandRequest::kRequestResumeTokenFieldName)) {
+ // Legacy queries don't handle requestResumeToken.
+ findCommand.getValue()->setRequestResumeToken(true);
+ }
+ if (query.hasField(FindCommandRequest::kResumeAfterFieldName)) {
+ // Legacy queries don't handle resumeAfter.
+ findCommand.getValue()->setResumeAfter(
+ query.getObjectField(FindCommandRequest::kResumeAfterFieldName));
+ }
+ if (auto replTerm = query[FindCommandRequest::kTermFieldName]) {
+ // Legacy queries don't handle term.
+ findCommand.getValue()->setTerm(replTerm.numberLong());
+ }
+ // Legacy queries don't handle readConcern.
+ // We prioritize the readConcern parsed from the query object over '_readConcernObj'.
+ if (auto readConcern = query[repl::ReadConcernArgs::kReadConcernFieldName]) {
+ findCommand.getValue()->setReadConcern(readConcern.Obj());
+ } else if (_readConcernObj) {
+ findCommand.getValue()->setReadConcern(_readConcernObj);
+ }
+ BSONObj cmd = findCommand.getValue()->toBSON(BSONObj());
+ if (auto readPref = query["$readPreference"]) {
+ // FindCommandRequest doesn't handle $readPreference.
+ cmd = BSONObjBuilder(std::move(cmd)).append(readPref).obj();
}
- _useFindCommand = false; // Make sure we handle the reply correctly.
- return makeDeprecatedQueryMessage(
- ns.ns(), query, nextBatchSize(), nToSkip, fieldsToReturn, opts);
+ return assembleCommandRequest(_client, ns.db(), opts, std::move(cmd));
}
Message DBClientCursor::_assembleGetMore() {
invariant(cursorId);
- if (_useFindCommand) {
- std::int64_t batchSize = nextBatchSize();
- auto getMoreRequest = GetMoreCommandRequest(cursorId, ns.coll().toString());
- getMoreRequest.setBatchSize(boost::make_optional(batchSize != 0, batchSize));
- getMoreRequest.setMaxTimeMS(boost::make_optional(
- tailableAwaitData(),
- static_cast<std::int64_t>(durationCount<Milliseconds>(_awaitDataTimeout))));
- if (_term) {
- getMoreRequest.setTerm(static_cast<std::int64_t>(*_term));
- }
- getMoreRequest.setLastKnownCommittedOpTime(_lastKnownCommittedOpTime);
- auto msg = assembleCommandRequest(_client, ns.db(), opts, getMoreRequest.toBSON({}));
+ std::int64_t batchSize = nextBatchSize();
+ auto getMoreRequest = GetMoreCommandRequest(cursorId, ns.coll().toString());
+ getMoreRequest.setBatchSize(boost::make_optional(batchSize != 0, batchSize));
+ getMoreRequest.setMaxTimeMS(boost::make_optional(
+ tailableAwaitData(),
+ static_cast<std::int64_t>(durationCount<Milliseconds>(_awaitDataTimeout))));
+ if (_term) {
+ getMoreRequest.setTerm(static_cast<std::int64_t>(*_term));
+ }
+ getMoreRequest.setLastKnownCommittedOpTime(_lastKnownCommittedOpTime);
+ auto msg = assembleCommandRequest(_client, ns.db(), opts, getMoreRequest.toBSON({}));
- // Set the exhaust flag if needed.
- if (opts & QueryOption_Exhaust && msg.operation() == dbMsg) {
- OpMsg::setFlag(&msg, OpMsg::kExhaustSupported);
- }
- return msg;
- } else {
- // Assemble a legacy getMore request.
- return makeDeprecatedGetMoreMessage(ns.ns(), cursorId, nextBatchSize(), opts);
+ // Set the exhaust flag if needed.
+ if (opts & QueryOption_Exhaust && msg.operation() == dbMsg) {
+ OpMsg::setFlag(&msg, OpMsg::kExhaustSupported);
}
+ return msg;
}
bool DBClientCursor::init() {
@@ -339,87 +305,22 @@ void DBClientCursor::dataReceived(const Message& reply, bool& retry, string& hos
batch.objs.clear();
batch.pos = 0;
- // If this is a reply to our initial command request.
- if (_isCommand && cursorId == 0) {
- batch.objs.push_back(commandDataReceived(reply));
- return;
- }
-
- if (_useFindCommand) {
- const auto replyObj = commandDataReceived(reply);
- cursorId = 0; // Don't try to kill cursor if we get back an error.
- auto cr = uassertStatusOK(CursorResponse::parseFromBSON(replyObj));
- cursorId = cr.getCursorId();
- uassert(50935,
- "Received a getMore response with a cursor id of 0 and the moreToCome flag set.",
- !(_connectionHasPendingReplies && cursorId == 0));
-
- ns = cr.getNSS(); // Unlike OP_REPLY, find command can change the ns to use for getMores.
- // Store the resume token, if we got one.
- _postBatchResumeToken = cr.getPostBatchResumeToken();
- batch.objs = cr.releaseBatch();
-
- if (replyObj.hasField(LogicalTime::kOperationTimeFieldName)) {
- _operationTime = LogicalTime::fromOperationTime(replyObj).asTimestamp();
- }
- return;
- }
-
- QueryResult::View qr = reply.singleData().view2ptr();
- resultFlags = qr.getResultFlags();
-
- if (resultFlags & ResultFlag_ErrSet) {
- wasError = true;
- }
-
- if (resultFlags & ResultFlag_CursorNotFound) {
- // cursor id no longer valid at the server.
- invariant(qr.getCursorId() == 0);
-
- // 0 indicates no longer valid (dead).
- cursorId = 0;
-
- uasserted(ErrorCodes::CursorNotFound,
- str::stream() << "cursor id " << cursorId << " didn't exist on server.");
- }
-
- if (cursorId == 0 || !(opts & QueryOption_CursorTailable)) {
- // only set initially: we don't want to kill it on end of data
- // if it's a tailable cursor
- cursorId = qr.getCursorId();
+ const auto replyObj = commandDataReceived(reply);
+ cursorId = 0; // Don't try to kill cursor if we get back an error.
+ auto cr = uassertStatusOK(CursorResponse::parseFromBSON(replyObj));
+ cursorId = cr.getCursorId();
+ uassert(50935,
+ "Received a getMore response with a cursor id of 0 and the moreToCome flag set.",
+ !(_connectionHasPendingReplies && cursorId == 0));
+
+ ns = cr.getNSS(); // find command can change the ns to use for getMores.
+ // Store the resume token, if we got one.
+ _postBatchResumeToken = cr.getPostBatchResumeToken();
+ batch.objs = cr.releaseBatch();
+
+ if (replyObj.hasField(LogicalTime::kOperationTimeFieldName)) {
+ _operationTime = LogicalTime::fromOperationTime(replyObj).asTimestamp();
}
-
- if (opts & QueryOption_Exhaust) {
- // With exhaust mode, each reply after the first claims to be a reply to the previous one
- // rather than the initial request.
- _connectionHasPendingReplies = (cursorId != 0);
- _lastRequestId = reply.header().getId();
- }
-
- batch.objs.reserve(qr.getNReturned());
-
- BufReader data(qr.data(), qr.dataLen());
- while (static_cast<int>(batch.objs.size()) < qr.getNReturned()) {
- if (serverGlobalParams.objcheck) {
- batch.objs.push_back(data.read<Validated<BSONObj>>());
- } else {
- batch.objs.push_back(data.read<BSONObj>());
- }
- batch.objs.back().shareOwnershipWith(reply.sharedBuffer());
- }
- uassert(ErrorCodes::InvalidBSON,
- "Got invalid reply from external server while reading from cursor",
- data.atEof());
-
- _client->checkResponse(batch.objs, false, &retry, &host); // watches for "not primary"
-
- tassert(5262101,
- "Deprecated ShardConfigStale flag encountered in query result",
- !(resultFlags & ResultFlag_ShardConfigStaleDeprecated));
-
- /* this assert would fire the way we currently work:
- verify( nReturned || cursorId == 0 );
- */
}
/** If true, safe to call next(). Requests more from server if necessary. */
@@ -583,7 +484,6 @@ DBClientCursor::DBClientCursor(DBClientBase* client,
_originalHost(_client->getServerAddress()),
_nsOrUuid(nsOrUuid),
ns(nsOrUuid.nss() ? *nsOrUuid.nss() : NamespaceString(nsOrUuid.dbname())),
- _isCommand(ns.isCommand()),
query(query),
nToReturn(nToReturn),
haveLimit(nToReturn > 0 && !(queryOptions & QueryOption_CursorTailable)),
@@ -639,14 +539,7 @@ DBClientCursor::~DBClientCursor() {
void DBClientCursor::kill() {
DESTRUCTOR_GUARD({
if (cursorId && _ownCursor && !globalInShutdownDeprecated()) {
- auto killCursor = [&](auto&& conn) {
- if (_useFindCommand) {
- conn->killCursor(ns, cursorId);
- } else {
- auto toSend = makeDeprecatedKillCursorsMessage(cursorId);
- conn->say(toSend);
- }
- };
+ auto killCursor = [&](auto&& conn) { conn->killCursor(ns, cursorId); };
// We only need to kill the cursor if there aren't pending replies. Pending replies
// indicates that this is an exhaust cursor, so the connection must be closed and the
diff --git a/src/mongo/client/dbclient_cursor.h b/src/mongo/client/dbclient_cursor.h
index 9fd0139254c..c3555a698e6 100644
--- a/src/mongo/client/dbclient_cursor.h
+++ b/src/mongo/client/dbclient_cursor.h
@@ -299,7 +299,6 @@ private:
// After a successful 'find' command, 'ns' is updated to contain the namespace returned by that
// command.
NamespaceString ns;
- const bool _isCommand;
BSONObj query;
int nToReturn;
bool haveLimit;
@@ -314,7 +313,6 @@ private:
std::string _scopedHost;
std::string _lazyHost;
bool wasError;
- bool _useFindCommand = true;
bool _connectionHasPendingReplies = false;
int _lastRequestId = 0;
Milliseconds _awaitDataTimeout = Milliseconds{0};
diff --git a/src/mongo/client/query.cpp b/src/mongo/client/query.cpp
index 6f8ae2e3615..9aa28e92711 100644
--- a/src/mongo/client/query.cpp
+++ b/src/mongo/client/query.cpp
@@ -146,9 +146,6 @@ BSONObj Query::getHint() const {
return BSONObj();
return obj.getObjectField("$hint");
}
-bool Query::isExplain() const {
- return isComplex() && obj.getBoolField("$explain");
-}
string Query::toString() const {
return obj.toString();
diff --git a/src/mongo/client/query.h b/src/mongo/client/query.h
index f295873d98e..6ef2b2531c0 100644
--- a/src/mongo/client/query.h
+++ b/src/mongo/client/query.h
@@ -131,7 +131,6 @@ public:
BSONObj getFilter() const;
BSONObj getSort() const;
BSONObj getHint() const;
- bool isExplain() const;
/**
* @return true if the query object contains a read preference specification object.
diff --git a/src/mongo/client/query_spec.h b/src/mongo/client/query_spec.h
deleted file mode 100644
index 534a841842f..00000000000
--- a/src/mongo/client/query_spec.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Copyright (C) 2018-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * 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
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * 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 Server Side 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/bson/bsonobj.h"
-#include "mongo/client/query.h"
-#include "mongo/util/str.h"
-
-namespace mongo {
-/**
- * Represents a full query description, including all options required for the query to be passed on
- * to other hosts
- */
-class QuerySpec {
- std::string _ns;
- int _ntoskip;
- int _ntoreturn;
- int _options;
- BSONObj _query;
- BSONObj _fields;
- Query _queryObj;
-
-public:
- QuerySpec(const std::string& ns,
- const BSONObj& query,
- const BSONObj& fields,
- int ntoskip,
- int ntoreturn,
- int options)
- : _ns(ns),
- _ntoskip(ntoskip),
- _ntoreturn(ntoreturn),
- _options(options),
- _query(query.getOwned()),
- _fields(fields.getOwned()),
- _queryObj(_query) {}
-
- QuerySpec() {}
-
- bool isEmpty() const {
- return _ns.size() == 0;
- }
-
- bool isExplain() const {
- return _queryObj.isExplain();
- }
- BSONObj filter() const {
- return _queryObj.getFilter();
- }
-
- BSONObj hint() const {
- return _queryObj.getHint();
- }
- BSONObj sort() const {
- return _queryObj.getSort();
- }
- BSONObj query() const {
- return _query;
- }
- BSONObj fields() const {
- return _fields;
- }
- BSONObj* fieldsData() {
- return &_fields;
- }
-
- // don't love this, but needed downstrem
- const BSONObj* fieldsPtr() const {
- return &_fields;
- }
-
- std::string ns() const {
- return _ns;
- }
- int ntoskip() const {
- return _ntoskip;
- }
- int ntoreturn() const {
- return _ntoreturn;
- }
- int options() const {
- return _options;
- }
-
- void setFields(BSONObj& o) {
- _fields = o.getOwned();
- }
-
- std::string toString() const {
- return str::stream() << "QSpec "
- << BSON("ns" << _ns << "n2skip" << _ntoskip << "n2return" << _ntoreturn
- << "options" << _options << "query" << _query << "fields"
- << _fields);
- }
-};
-
-} // namespace mongo
diff --git a/src/mongo/db/query/query_request_helper.cpp b/src/mongo/db/query/query_request_helper.cpp
index b466781d5a3..5f5ce186be8 100644
--- a/src/mongo/db/query/query_request_helper.cpp
+++ b/src/mongo/db/query/query_request_helper.cpp
@@ -92,7 +92,7 @@ void addMetaProjection(FindCommandRequest* findCommand) {
}
}
-Status initFullQuery(const BSONObj& top, FindCommandRequest* findCommand, bool* explain) {
+Status initFullQuery(const BSONObj& top, FindCommandRequest* findCommand) {
BSONObjIterator i(top);
while (i.more()) {
@@ -140,8 +140,8 @@ Status initFullQuery(const BSONObj& top, FindCommandRequest* findCommand, bool*
} else if (name.startsWith("$")) {
name = name.substr(1); // chop first char
if (name == "explain") {
- // Won't throw.
- *explain = e.trueValue();
+ return Status(ErrorCodes::Error(5856600),
+ "the $explain OP_QUERY flag is no longer supported");
} else if (name == "min") {
if (!e.isABSONObj()) {
return Status(ErrorCodes::BadValue, "$min must be a BSONObj");
@@ -191,8 +191,7 @@ Status initFindCommandRequest(int ntoskip,
const BSONObj& queryObj,
const BSONObj& proj,
bool fromQueryMessage,
- FindCommandRequest* findCommand,
- bool* explain) {
+ FindCommandRequest* findCommand) {
if (!proj.isEmpty()) {
findCommand->setProjection(proj.getOwned());
}
@@ -228,7 +227,7 @@ Status initFindCommandRequest(int ntoskip,
}
if (queryField.isABSONObj()) {
findCommand->setFilter(queryField.embeddedObject().getOwned());
- Status status = initFullQuery(queryObj, findCommand, explain);
+ Status status = initFullQuery(queryObj, findCommand);
if (!status.isOK()) {
return status;
}
@@ -418,36 +417,16 @@ void validateCursorResponse(const BSONObj& outputAsBson) {
// Old QueryRequest parsing code: SOON TO BE DEPRECATED.
//
-StatusWith<std::unique_ptr<FindCommandRequest>> fromLegacyQueryMessage(const QueryMessage& qm,
- bool* explain) {
- auto findCommand = std::make_unique<FindCommandRequest>(NamespaceString(qm.ns));
-
- Status status = initFindCommandRequest(qm.ntoskip,
- qm.ntoreturn,
- qm.queryOptions,
- qm.query,
- qm.fields,
- true,
- findCommand.get(),
- explain);
- if (!status.isOK()) {
- return status;
- }
-
- return std::move(findCommand);
-}
-
StatusWith<std::unique_ptr<FindCommandRequest>> fromLegacyQuery(NamespaceStringOrUUID nssOrUuid,
const BSONObj& queryObj,
const BSONObj& proj,
int ntoskip,
int ntoreturn,
- int queryOptions,
- bool* explain) {
+ int queryOptions) {
auto findCommand = std::make_unique<FindCommandRequest>(std::move(nssOrUuid));
Status status = initFindCommandRequest(
- ntoskip, ntoreturn, queryOptions, queryObj, proj, true, findCommand.get(), explain);
+ ntoskip, ntoreturn, queryOptions, queryObj, proj, true, findCommand.get());
if (!status.isOK()) {
return status;
}
diff --git a/src/mongo/db/query/query_request_helper.h b/src/mongo/db/query/query_request_helper.h
index 2617c9231d4..14409c62e39 100644
--- a/src/mongo/db/query/query_request_helper.h
+++ b/src/mongo/db/query/query_request_helper.h
@@ -148,13 +148,6 @@ void validateCursorResponse(const BSONObj& outputAsBson);
//
/**
- * Parse the provided QueryMessage and return a heap constructed FindCommandRequest, which
- * represents it or an error.
- */
-StatusWith<std::unique_ptr<FindCommandRequest>> fromLegacyQueryMessage(const QueryMessage& qm,
- bool* explain);
-
-/**
* Parse the provided legacy query object and parameters to construct a FindCommandRequest.
*/
StatusWith<std::unique_ptr<FindCommandRequest>> fromLegacyQuery(NamespaceStringOrUUID nsOrUuid,
@@ -162,8 +155,7 @@ StatusWith<std::unique_ptr<FindCommandRequest>> fromLegacyQuery(NamespaceStringO
const BSONObj& proj,
int ntoskip,
int ntoreturn,
- int queryOptions,
- bool* explain);
+ int queryOptions);
} // namespace query_request_helper
} // namespace mongo
diff --git a/src/mongo/db/query/query_request_test.cpp b/src/mongo/db/query/query_request_test.cpp
index 8518c0e4661..2e92a48f4e9 100644
--- a/src/mongo/db/query/query_request_test.cpp
+++ b/src/mongo/db/query/query_request_test.cpp
@@ -1562,17 +1562,14 @@ TEST(QueryRequestTest, ParseFromLegacyQuery) {
query: {query: 1},
orderby: {sort: 1},
$hint: {hint: 1},
- $explain: false,
$min: {x: 'min'},
$max: {x: 'max'}
})");
- bool explain = false;
unique_ptr<FindCommandRequest> findCommand(assertGet(query_request_helper::fromLegacyQuery(
- nss, queryObj, BSON("proj" << 1), kSkip, kNToReturn, QueryOption_Exhaust, &explain)));
+ nss, queryObj, BSON("proj" << 1), kSkip, kNToReturn, QueryOption_Exhaust)));
ASSERT_EQ(*findCommand->getNamespaceOrUUID().nss(), nss);
- ASSERT_EQ(explain, false);
ASSERT_BSONOBJ_EQ(findCommand->getFilter(), fromjson("{query: 1}"));
ASSERT_BSONOBJ_EQ(findCommand->getProjection(), fromjson("{proj: 1}"));
ASSERT_BSONOBJ_EQ(findCommand->getSort(), fromjson("{sort: 1}"));
@@ -1597,9 +1594,8 @@ TEST(QueryRequestTest, ParseFromLegacyQueryOplogReplayFlagAllowed) {
// Test that parsing succeeds even if the oplog replay bit is set in the OP_QUERY message. This
// flag may be set by old clients.
auto options = QueryOption_OplogReplay_DEPRECATED;
- bool explain = false;
unique_ptr<FindCommandRequest> findCommand(assertGet(query_request_helper::fromLegacyQuery(
- nss, queryObj, projectionObj, nToSkip, nToReturn, options, &explain)));
+ nss, queryObj, projectionObj, nToSkip, nToReturn, options)));
// Verify that if we reserialize the find command, the 'oplogReplay' field
// does not appear.
@@ -1619,9 +1615,8 @@ TEST(QueryRequestTest, ParseFromLegacyQueryUnwrapped) {
foo: 1
})");
const NamespaceString nss("test.testns");
- bool explain = false;
unique_ptr<FindCommandRequest> findCommand(assertGet(query_request_helper::fromLegacyQuery(
- nss, queryObj, BSONObj(), 0, 0, QueryOption_Exhaust, &explain)));
+ nss, queryObj, BSONObj(), 0, 0, QueryOption_Exhaust)));
ASSERT_EQ(*findCommand->getNamespaceOrUUID().nss(), nss);
ASSERT_BSONOBJ_EQ(findCommand->getFilter(), fromjson("{foo: 1}"));
@@ -1647,15 +1642,24 @@ TEST(QueryRequestTest, ParseFromLegacyQueryTooNegativeNToReturn) {
})");
const NamespaceString nss("test.testns");
- bool explain = false;
- ASSERT_NOT_OK(query_request_helper::fromLegacyQuery(nss,
- queryObj,
- BSONObj(),
- 0,
- std::numeric_limits<int>::min(),
- QueryOption_Exhaust,
- &explain)
- .getStatus());
+ ASSERT_NOT_OK(
+ query_request_helper::fromLegacyQuery(
+ nss, queryObj, BSONObj(), 0, std::numeric_limits<int>::min(), QueryOption_Exhaust)
+ .getStatus());
+}
+
+TEST(QueryRequestTest, ParseFromLegacyQueryExplainError) {
+ BSONObj queryObj = fromjson(R"({
+ query: {query: 1},
+ $explain: false
+ })");
+
+ const NamespaceString nss("test.testns");
+ ASSERT_EQUALS(
+ query_request_helper::fromLegacyQuery(nss, queryObj, BSONObj(), 0, -1, QueryOption_Exhaust)
+ .getStatus()
+ .code(),
+ static_cast<ErrorCodes::Error>(5856600));
}
class QueryRequestTest : public ServiceContextTest {};
diff --git a/src/mongo/s/commands/cluster_explain_cmd.cpp b/src/mongo/s/commands/cluster_explain_cmd.cpp
index 287ec9902d7..9ee65bdbc49 100644
--- a/src/mongo/s/commands/cluster_explain_cmd.cpp
+++ b/src/mongo/s/commands/cluster_explain_cmd.cpp
@@ -40,15 +40,6 @@ namespace {
/**
* Implements the explain command on mongos.
- *
- * "Old-style" explains (i.e. queries which have the $explain flag set), do not run
- * through this path. Such explains will be supported for backwards compatibility,
- * and must succeed in multiversion clusters.
- *
- * "New-style" explains use the explain command. When the explain command is routed
- * through mongos, it is forwarded to all relevant shards. If *any* shard does not
- * support a new-style explain, then the entire explain will fail (i.e. new-style
- * explains cannot be used in multiversion clusters).
*/
class ClusterExplainCmd final : public Command {
diff --git a/src/mongo/shell/explain_query.js b/src/mongo/shell/explain_query.js
index b4935fd07d4..453751d88de 100644
--- a/src/mongo/shell/explain_query.js
+++ b/src/mongo/shell/explain_query.js
@@ -9,37 +9,6 @@ var DBExplainQuery = (function() {
//
/**
- * In 2.6 and before, .explain(), .explain(false), or .explain(<falsy value>) instructed the
- * shell to reduce the explain verbosity by removing certain fields from the output. This
- * is implemented here for backwards compatibility.
- */
- function removeVerboseFields(obj) {
- if (typeof (obj) !== "object") {
- return;
- }
-
- delete obj.allPlans;
- delete obj.oldPlan;
- delete obj.stats;
-
- if (typeof (obj.length) === "number") {
- for (var i = 0; i < obj.length; i++) {
- removeVerboseFields(obj[i]);
- }
- }
-
- if (obj.shards) {
- for (var key in obj.shards) {
- removeVerboseFields(obj.shards[key]);
- }
- }
-
- if (obj.clauses) {
- removeVerboseFields(obj.clauses);
- }
- }
-
- /**
* Many of the methods of an explain query just pass through to the underlying
* non-explained DBQuery. Use this to generate a function which calls function 'name' on
* 'destObj' and then returns this.
@@ -51,28 +20,6 @@ var DBExplainQuery = (function() {
};
}
- /**
- * Where possible, the explain query will be sent to the server as an explain command.
- * However, if one of the nodes we are talking to (either a standalone or a shard in
- * a sharded cluster) is of a version that doesn't have the explain command, we will
- * use this function to fall back on the $explain query option.
- */
- function explainWithLegacyQueryOption(explainQuery) {
- // The wire protocol version indicates that the server does not have the explain
- // command. Add $explain to the query and send it to the server.
- var clone = explainQuery._query.clone();
- clone._addSpecial("$explain", true);
- var result = clone.next();
-
- // Remove some fields from the explain if verbosity is
- // just "queryPlanner".
- if ("queryPlanner" === explainQuery._verbosity) {
- removeVerboseFields(result);
- }
-
- return Explainable.throwOrReturn(result);
- }
-
function constructor(query, verbosity) {
//
// Private vars.
@@ -136,47 +83,35 @@ var DBExplainQuery = (function() {
// Explain always gets pretty printed.
this._query._prettyShell = true;
- if (this._mongo.hasExplainCommand()) {
- // The wire protocol version indicates that the server has the explain command.
- // Convert this explain query into an explain command, and send the command to
- // the server.
- var innerCmd;
- if (this._isCount) {
- // True means to always apply the skip and limit values.
- innerCmd = this._query._convertToCountCmd(this._applySkipLimit);
- } else {
- var canAttachReadPref = false;
- innerCmd = this._query._convertToCommand(canAttachReadPref);
- }
-
- var explainCmd = {explain: innerCmd};
- explainCmd["verbosity"] = this._verbosity;
- // If "maxTimeMS" is set on innerCmd, it needs to be propagated to the top-level
- // of explainCmd so that it has the intended effect.
- if (innerCmd.hasOwnProperty("maxTimeMS")) {
- explainCmd.maxTimeMS = innerCmd.maxTimeMS;
- }
-
- var explainDb = this._query._db;
-
- if ("$readPreference" in this._query._query) {
- var prefObj = this._query._query.$readPreference;
- explainCmd = explainDb._attachReadPreferenceToCommand(explainCmd, prefObj);
- }
-
- var explainResult =
- explainDb.runReadCommand(explainCmd, null, this._query._options);
-
- if (!explainResult.ok && explainResult.code === ErrorCodes.CommandNotFound) {
- // One of the shards doesn't have the explain command available. Retry using
- // the legacy $explain format, which should be supported by all shards.
- return explainWithLegacyQueryOption(this);
- }
-
- return Explainable.throwOrReturn(explainResult);
+ // Convert this explain query into an explain command, and send the command to
+ // the server.
+ var innerCmd;
+ if (this._isCount) {
+ // True means to always apply the skip and limit values.
+ innerCmd = this._query._convertToCountCmd(this._applySkipLimit);
} else {
- return explainWithLegacyQueryOption(this);
+ var canAttachReadPref = false;
+ innerCmd = this._query._convertToCommand(canAttachReadPref);
}
+
+ var explainCmd = {explain: innerCmd};
+ explainCmd["verbosity"] = this._verbosity;
+ // If "maxTimeMS" is set on innerCmd, it needs to be propagated to the top-level
+ // of explainCmd so that it has the intended effect.
+ if (innerCmd.hasOwnProperty("maxTimeMS")) {
+ explainCmd.maxTimeMS = innerCmd.maxTimeMS;
+ }
+
+ var explainDb = this._query._db;
+
+ if ("$readPreference" in this._query._query) {
+ var prefObj = this._query._query.$readPreference;
+ explainCmd = explainDb._attachReadPreferenceToCommand(explainCmd, prefObj);
+ }
+
+ var explainResult = explainDb.runReadCommand(explainCmd, null, this._query._options);
+
+ return Explainable.throwOrReturn(explainResult);
};
this.next = function() {
diff --git a/src/mongo/shell/mongo.js b/src/mongo/shell/mongo.js
index cf05337eead..7146fd8670a 100644
--- a/src/mongo/shell/mongo.js
+++ b/src/mongo/shell/mongo.js
@@ -418,11 +418,6 @@ connect = function(url, user, pass, apiParameters) {
return db;
};
-Mongo.prototype.hasExplainCommand = function() {
- var hasExplain = (this.getMinWireVersion() <= 3 && 3 <= this.getMaxWireVersion());
- return hasExplain;
-};
-
//
// Write Concern can be set at the connection level, and is used for all write operations unless
// overridden at the collection level.
diff --git a/src/mongo/transport/service_state_machine.cpp b/src/mongo/transport/service_state_machine.cpp
index f1deac76b13..bd96331bd50 100644
--- a/src/mongo/transport/service_state_machine.cpp
+++ b/src/mongo/transport/service_state_machine.cpp
@@ -68,61 +68,12 @@ namespace {
MONGO_FAIL_POINT_DEFINE(doNotSetMoreToCome);
MONGO_FAIL_POINT_DEFINE(beforeCompressingExhaustResponse);
/**
- * Creates and returns a legacy exhaust message, if exhaust is allowed. The returned message is to
- * be used as the subsequent 'synthetic' exhaust request. Returns an empty message if exhaust is not
- * allowed. Any messages that do not have an opcode of OP_MSG are considered legacy.
- */
-Message makeLegacyExhaustMessage(Message* m, const DbResponse& dbresponse) {
- // OP_QUERY responses are always of type OP_REPLY.
- invariant(dbresponse.response.operation() == opReply);
-
- if (!dbresponse.shouldRunAgainForExhaust) {
- return Message();
- }
-
- // Legacy find operations via the OP_QUERY/OP_GET_MORE network protocol never provide the next
- // invocation for exhaust.
- invariant(!dbresponse.nextInvocation);
-
- DbMessage dbmsg(*m);
- invariant(dbmsg.messageShouldHaveNs());
- const char* ns = dbmsg.getns();
-
- MsgData::View header = dbresponse.response.header();
- QueryResult::View qr = header.view2ptr();
- long long cursorid = qr.getCursorId();
-
- if (cursorid == 0) {
- return Message();
- }
-
- // Generate a message that will act as the subsequent 'synthetic' exhaust request.
- BufBuilder b(512);
- b.appendNum(static_cast<int>(0)); // size set later in setLen()
- b.appendNum(header.getId()); // message id
- b.appendNum(header.getResponseToMsgId()); // in response to
- b.appendNum(static_cast<int>(dbGetMore)); // opCode is OP_GET_MORE
- b.appendNum(static_cast<int>(0)); // Must be ZERO (reserved)
- b.appendStr(StringData(ns)); // Namespace
- b.appendNum(static_cast<int>(0)); // ntoreturn
- b.appendNum(cursorid); // cursor id from the OP_REPLY
-
- MsgData::View(b.buf()).setLen(b.len());
-
- return Message(b.release());
-}
-
-/**
* Given a request and its already generated response, checks for exhaust flags. If exhaust is
* allowed, produces the subsequent request message, and modifies the response message to indicate
* it is part of an exhaust stream. Returns the subsequent request message, which is known as a
* 'synthetic' exhaust request. Returns an empty message if exhaust is not allowed.
*/
Message makeExhaustMessage(Message requestMsg, DbResponse* dbresponse) {
- if (requestMsg.operation() == dbQuery) {
- return makeLegacyExhaustMessage(&requestMsg, *dbresponse);
- }
-
if (!OpMsgRequest::isFlagSet(requestMsg, OpMsg::kExhaustSupported)) {
return Message();
}