diff options
101 files changed, 47 insertions, 2915 deletions
diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency.yml index d8a5284ae5b..32f43611fe5 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency.yml @@ -48,7 +48,6 @@ selector: - jstests/concurrency/fsm_workloads/auth_drop_user.js # uses >100MB of data, which can overwhelm test hosts - - jstests/concurrency/fsm_workloads/agg_group_external.js - jstests/concurrency/fsm_workloads/agg_sort_external.js # compact can only be run against a standalone mongod @@ -72,10 +71,6 @@ selector: # can cause OOM kills on test hosts - jstests/concurrency/fsm_workloads/findAndModify_update_grow.js - # the group command cannot be issued against a sharded cluster - - jstests/concurrency/fsm_workloads/group.js - - jstests/concurrency/fsm_workloads/group_cond.js - - jstests/concurrency/fsm_workloads/group_killop.js # eval doesn't work with sharded collections - jstests/concurrency/fsm_workloads/indexed_insert_eval.js - jstests/concurrency/fsm_workloads/indexed_insert_eval_nolock.js diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency_and_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency_and_balancer.yml index d87180a16f2..4f514d17299 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency_and_balancer.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency_and_balancer.yml @@ -55,7 +55,6 @@ selector: - jstests/concurrency/fsm_workloads/auth_drop_user.js # uses >100MB of data, which can overwhelm test hosts - - jstests/concurrency/fsm_workloads/agg_group_external.js - jstests/concurrency/fsm_workloads/agg_sort_external.js # compact can only be run against a standalone mongod @@ -79,10 +78,6 @@ selector: # can cause OOM kills on test hosts - jstests/concurrency/fsm_workloads/findAndModify_update_grow.js - # the group command cannot be issued against a sharded cluster - - jstests/concurrency/fsm_workloads/group.js - - jstests/concurrency/fsm_workloads/group_cond.js - - jstests/concurrency/fsm_workloads/group_killop.js # eval doesn't work with sharded collections - jstests/concurrency/fsm_workloads/indexed_insert_eval.js - jstests/concurrency/fsm_workloads/indexed_insert_eval_nolock.js diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_replication.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_replication.yml index b5e67ad6a15..778038276e8 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_replication.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_replication.yml @@ -45,7 +45,6 @@ selector: - jstests/concurrency/fsm_workloads/auth_drop_user.js # uses >100MB of data, which can overwhelm test hosts - - jstests/concurrency/fsm_workloads/agg_group_external.js - jstests/concurrency/fsm_workloads/agg_sort_external.js # compact can only be run against a standalone mongod @@ -69,10 +68,6 @@ selector: # can cause OOM kills on test hosts - jstests/concurrency/fsm_workloads/findAndModify_update_grow.js - # the group command cannot be issued against a sharded cluster - - jstests/concurrency/fsm_workloads/group.js - - jstests/concurrency/fsm_workloads/group_cond.js - - jstests/concurrency/fsm_workloads/group_killop.js # eval doesn't work with sharded collections - jstests/concurrency/fsm_workloads/indexed_insert_eval.js - jstests/concurrency/fsm_workloads/indexed_insert_eval_nolock.js diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_replication_with_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_replication_with_balancer.yml index 2f166cd0027..7cf3c955d6e 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_replication_with_balancer.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_replication_with_balancer.yml @@ -52,7 +52,6 @@ selector: - jstests/concurrency/fsm_workloads/auth_drop_user.js # uses >100MB of data, which can overwhelm test hosts - - jstests/concurrency/fsm_workloads/agg_group_external.js - jstests/concurrency/fsm_workloads/agg_sort_external.js # compact can only be run against a standalone mongod @@ -76,10 +75,6 @@ selector: # can cause OOM kills on test hosts - jstests/concurrency/fsm_workloads/findAndModify_update_grow.js - # the group command cannot be issued against a sharded cluster - - jstests/concurrency/fsm_workloads/group.js - - jstests/concurrency/fsm_workloads/group_cond.js - - jstests/concurrency/fsm_workloads/group_killop.js # eval doesn't work with sharded collections - jstests/concurrency/fsm_workloads/indexed_insert_eval.js - jstests/concurrency/fsm_workloads/indexed_insert_eval_nolock.js diff --git a/buildscripts/resmokeconfig/suites/replica_sets_auth_5.yml b/buildscripts/resmokeconfig/suites/replica_sets_auth_5.yml index 63b940fd664..2dffbbb53ea 100644 --- a/buildscripts/resmokeconfig/suites/replica_sets_auth_5.yml +++ b/buildscripts/resmokeconfig/suites/replica_sets_auth_5.yml @@ -27,7 +27,6 @@ selector: - jstests/replsets/maintenance2.js - jstests/replsets/copydb.js - jstests/replsets/sized_zero_capped.js - - jstests/replsets/groupAndMapReduce.js - jstests/replsets/initial_sync_document_validation.js - jstests/replsets/commands_that_write_accept_wc.js - jstests/replsets/startParallelShell.js @@ -102,4 +101,4 @@ executor: keyFile: *keyFile keyFileData: *keyFileData nodb: '' - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/replica_sets_auth_misc.yml b/buildscripts/resmokeconfig/suites/replica_sets_auth_misc.yml index 86c8721ad02..83cac83c708 100644 --- a/buildscripts/resmokeconfig/suites/replica_sets_auth_misc.yml +++ b/buildscripts/resmokeconfig/suites/replica_sets_auth_misc.yml @@ -129,7 +129,6 @@ selector: - jstests/replsets/maintenance2.js - jstests/replsets/copydb.js - jstests/replsets/sized_zero_capped.js - - jstests/replsets/groupAndMapReduce.js - jstests/replsets/initial_sync_document_validation.js - jstests/replsets/commands_that_write_accept_wc.js - jstests/replsets/startParallelShell.js diff --git a/buildscripts/resmokeconfig/suites/replica_sets_ese_5.yml b/buildscripts/resmokeconfig/suites/replica_sets_ese_5.yml index 427e3690820..ab325e4baae 100644 --- a/buildscripts/resmokeconfig/suites/replica_sets_ese_5.yml +++ b/buildscripts/resmokeconfig/suites/replica_sets_ese_5.yml @@ -41,7 +41,6 @@ selector: - jstests/replsets/index_delete.js - jstests/replsets/last_op_visible.js - jstests/replsets/sized_zero_capped.js - - jstests/replsets/groupAndMapReduce.js - jstests/replsets/initial_sync_document_validation.js - jstests/replsets/read_committed_on_secondary.js - jstests/replsets/apply_ops_lastop.js @@ -89,4 +88,4 @@ executor: TestData: enableEncryption: '' encryptionKeyFile: *keyFile - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/replica_sets_ese_misc.yml b/buildscripts/resmokeconfig/suites/replica_sets_ese_misc.yml index a993971d085..0e8753dbb84 100644 --- a/buildscripts/resmokeconfig/suites/replica_sets_ese_misc.yml +++ b/buildscripts/resmokeconfig/suites/replica_sets_ese_misc.yml @@ -140,7 +140,6 @@ selector: - jstests/replsets/index_delete.js - jstests/replsets/last_op_visible.js - jstests/replsets/sized_zero_capped.js - - jstests/replsets/groupAndMapReduce.js - jstests/replsets/initial_sync_document_validation.js - jstests/replsets/read_committed_on_secondary.js - jstests/replsets/apply_ops_lastop.js @@ -244,4 +243,4 @@ executor: TestData: enableEncryption: '' encryptionKeyFile: *keyFile - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/replica_sets_initsync_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_initsync_jscore_passthrough.yml index 1f2352bcdb9..297d53936db 100644 --- a/buildscripts/resmokeconfig/suites/replica_sets_initsync_jscore_passthrough.yml +++ b/buildscripts/resmokeconfig/suites/replica_sets_initsync_jscore_passthrough.yml @@ -71,7 +71,6 @@ selector: - jstests/core/profile_findandmodify.js - jstests/core/profile_geonear.js - jstests/core/profile_getmore.js - - jstests/core/profile_group.js - jstests/core/profile_insert.js - jstests/core/profile_sampling.js - jstests/core/profile_update.js diff --git a/buildscripts/resmokeconfig/suites/secondary_reads_passthrough.yml b/buildscripts/resmokeconfig/suites/secondary_reads_passthrough.yml index f085503bcf8..6842ebc3ae5 100644 --- a/buildscripts/resmokeconfig/suites/secondary_reads_passthrough.yml +++ b/buildscripts/resmokeconfig/suites/secondary_reads_passthrough.yml @@ -32,8 +32,6 @@ selector: - jstests/core/fts_spanish.js - jstests/core/geo_distinct.js - jstests/core/geo_s2ordering.js - - jstests/core/group1.js - - jstests/core/group2.js - jstests/core/maxscan.js - jstests/core/nan.js - jstests/core/null2.js diff --git a/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml index 232df1720cf..4b86fad9420 100644 --- a/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml +++ b/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml @@ -149,8 +149,6 @@ selector: - jstests/core/fts_spanish.js - jstests/core/geo_distinct.js - jstests/core/geo_s2ordering.js - - jstests/core/group1.js - - jstests/core/group2.js - jstests/core/maxscan.js - jstests/core/nan.js - jstests/core/null2.js diff --git a/buildscripts/resmokeconfig/suites/sharding_8.yml b/buildscripts/resmokeconfig/suites/sharding_8.yml index fb81860b6e2..107e3b2db96 100644 --- a/buildscripts/resmokeconfig/suites/sharding_8.yml +++ b/buildscripts/resmokeconfig/suites/sharding_8.yml @@ -19,7 +19,6 @@ selector: - jstests/sharding/balancer_window.js - jstests/sharding/change_streams_primary_shard_unaware.js - jstests/sharding/diffservers1.js - - jstests/sharding/group_slaveok.js - jstests/sharding/write_cmd_auto_split.js - jstests/sharding/geo_near_random1.js - jstests/sharding/mongos_does_not_gossip_logical_time_without_keys.js @@ -44,4 +43,4 @@ executor: config: shell_options: nodb: '' - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/sharding_auth_11.yml b/buildscripts/resmokeconfig/suites/sharding_auth_11.yml index 4b02dd2fe42..0dd46fb7673 100644 --- a/buildscripts/resmokeconfig/suites/sharding_auth_11.yml +++ b/buildscripts/resmokeconfig/suites/sharding_auth_11.yml @@ -25,7 +25,6 @@ selector: - jstests/sharding/prefix_shard_key.js - jstests/sharding/features2.js - jstests/sharding/shard_insert_getlasterror_w2.js - - jstests/sharding/group_slaveok.js - jstests/sharding/names.js - jstests/sharding/cursor_timeout.js - jstests/sharding/mongos_validate_writes.js @@ -48,4 +47,4 @@ executor: keyFile: *keyFile keyFileData: *keyFileData nodb: '' - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/sharding_auth_audit_10.yml b/buildscripts/resmokeconfig/suites/sharding_auth_audit_10.yml index 4c23420f30d..a7918421eec 100644 --- a/buildscripts/resmokeconfig/suites/sharding_auth_audit_10.yml +++ b/buildscripts/resmokeconfig/suites/sharding_auth_audit_10.yml @@ -33,7 +33,6 @@ selector: - jstests/sharding/shard2.js - jstests/sharding/prefix_shard_key.js - jstests/sharding/features2.js - - jstests/sharding/group_slaveok.js - jstests/sharding/cursor_timeout.js - jstests/sharding/mongos_validate_writes.js - jstests/sharding/empty_doc_results.js @@ -49,4 +48,4 @@ executor: keyFile: *keyFile keyFileData: *keyFileData nodb: '' - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/sharding_auth_audit_misc.yml b/buildscripts/resmokeconfig/suites/sharding_auth_audit_misc.yml index f18842f91ed..c8e923acf3e 100644 --- a/buildscripts/resmokeconfig/suites/sharding_auth_audit_misc.yml +++ b/buildscripts/resmokeconfig/suites/sharding_auth_audit_misc.yml @@ -164,7 +164,6 @@ selector: - jstests/sharding/shard2.js - jstests/sharding/prefix_shard_key.js - jstests/sharding/features2.js - - jstests/sharding/group_slaveok.js - jstests/sharding/cursor_timeout.js - jstests/sharding/mongos_validate_writes.js - jstests/sharding/empty_doc_results.js @@ -388,4 +387,4 @@ executor: keyFile: *keyFile keyFileData: *keyFileData nodb: '' - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/sharding_auth_misc.yml b/buildscripts/resmokeconfig/suites/sharding_auth_misc.yml index dbbcabf98d5..5d8062b9444 100644 --- a/buildscripts/resmokeconfig/suites/sharding_auth_misc.yml +++ b/buildscripts/resmokeconfig/suites/sharding_auth_misc.yml @@ -163,7 +163,6 @@ selector: - jstests/sharding/prefix_shard_key.js - jstests/sharding/features2.js - jstests/sharding/shard_insert_getlasterror_w2.js - - jstests/sharding/group_slaveok.js - jstests/sharding/names.js - jstests/sharding/cursor_timeout.js - jstests/sharding/mongos_validate_writes.js @@ -386,4 +385,4 @@ executor: keyFile: *keyFile keyFileData: *keyFileData nodb: '' - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/sharding_continuous_config_stepdown.yml b/buildscripts/resmokeconfig/suites/sharding_continuous_config_stepdown.yml index 433e198f1ab..4a436d7422a 100644 --- a/buildscripts/resmokeconfig/suites/sharding_continuous_config_stepdown.yml +++ b/buildscripts/resmokeconfig/suites/sharding_continuous_config_stepdown.yml @@ -14,7 +14,7 @@ selector: - jstests/sharding/aggregation_currentop.js - jstests/sharding/advance_cluster_time_action_type.js - jstests/sharding/mongod_returns_no_cluster_time_without_keys.js - # Count/write/aggregate/group commands against the config shard do not support retries yet + # Count/write/aggregate commands against the config shard do not support retries yet - jstests/sharding/addshard1.js - jstests/sharding/addshard2.js - jstests/sharding/autosplit.js diff --git a/buildscripts/resmokeconfig/suites/sharding_ese_12.yml b/buildscripts/resmokeconfig/suites/sharding_ese_12.yml index 12512acb76c..633f9c52323 100644 --- a/buildscripts/resmokeconfig/suites/sharding_ese_12.yml +++ b/buildscripts/resmokeconfig/suites/sharding_ese_12.yml @@ -20,7 +20,6 @@ selector: - jstests/sharding/names.js - jstests/sharding/cursor_timeout.js - jstests/sharding/mongos_validate_writes.js - - jstests/sharding/group_slaveok.js - jstests/sharding/mrShardedOutput.js - jstests/sharding/max_time_ms_sharded.js - jstests/sharding/lookup_change_stream_post_image_compound_shard_key.js @@ -44,4 +43,4 @@ executor: TestData: enableEncryption: '' encryptionKeyFile: *keyFile - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/sharding_ese_misc.yml b/buildscripts/resmokeconfig/suites/sharding_ese_misc.yml index b966148b90f..2e81e6a0beb 100644 --- a/buildscripts/resmokeconfig/suites/sharding_ese_misc.yml +++ b/buildscripts/resmokeconfig/suites/sharding_ese_misc.yml @@ -152,7 +152,6 @@ selector: - jstests/sharding/names.js - jstests/sharding/cursor_timeout.js - jstests/sharding/mongos_validate_writes.js - - jstests/sharding/group_slaveok.js - jstests/sharding/mrShardedOutput.js - jstests/sharding/max_time_ms_sharded.js - jstests/sharding/lookup_change_stream_post_image_compound_shard_key.js @@ -394,4 +393,4 @@ executor: TestData: enableEncryption: '' encryptionKeyFile: *keyFile - readMode: commands
\ No newline at end of file + readMode: commands diff --git a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards_5.yml b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards_5.yml index 9849e84e61a..14da0fb109f 100644 --- a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards_5.yml +++ b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards_5.yml @@ -26,7 +26,6 @@ selector: - jstests/sharding/parallel.js - jstests/sharding/diffservers1.js - jstests/sharding/mongos_does_not_gossip_logical_time_without_keys.js - - jstests/sharding/group_slaveok.js - jstests/sharding/shard_existing_coll_chunk_count.js - jstests/sharding/explain_read_pref.js - jstests/sharding/auto_rebalance_parallel.js @@ -45,4 +44,4 @@ executor: mongosBinVersion: 'last-stable' shardMixedBinVersions: true skipCheckingUUIDsConsistentAcrossCluster: true - nodb: ''
\ No newline at end of file + nodb: '' diff --git a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards_misc.yml b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards_misc.yml index 47c059d2e37..50a0e023242 100644 --- a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards_misc.yml +++ b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards_misc.yml @@ -150,7 +150,6 @@ selector: - jstests/sharding/parallel.js - jstests/sharding/diffservers1.js - jstests/sharding/mongos_does_not_gossip_logical_time_without_keys.js - - jstests/sharding/group_slaveok.js - jstests/sharding/shard_existing_coll_chunk_count.js - jstests/sharding/explain_read_pref.js - jstests/sharding/auto_rebalance_parallel.js @@ -429,4 +428,4 @@ executor: mongosBinVersion: 'last-stable' shardMixedBinVersions: true skipCheckingUUIDsConsistentAcrossCluster: true - nodb: ''
\ No newline at end of file + nodb: '' diff --git a/buildscripts/resmokeconfig/suites/sharding_misc.yml b/buildscripts/resmokeconfig/suites/sharding_misc.yml index 235d21c3a0d..76344e33a8d 100644 --- a/buildscripts/resmokeconfig/suites/sharding_misc.yml +++ b/buildscripts/resmokeconfig/suites/sharding_misc.yml @@ -104,7 +104,6 @@ selector: - jstests/sharding/balancer_window.js - jstests/sharding/change_streams_primary_shard_unaware.js - jstests/sharding/diffservers1.js - - jstests/sharding/group_slaveok.js - jstests/sharding/write_cmd_auto_split.js - jstests/sharding/geo_near_random1.js - jstests/sharding/mongos_does_not_gossip_logical_time_without_keys.js diff --git a/jstests/auth/auth1.js b/jstests/auth/auth1.js index 183317414df..cbf1139744f 100644 --- a/jstests/auth/auth1.js +++ b/jstests/auth/auth1.js @@ -60,16 +60,6 @@ function runTest(m) { db.setProfilingLevel(0); assert.lt(0, db.system.profile.find({user: "eliot@test"}).count(), "AP1"); - var p = { - key: {i: true}, - reduce: function(obj, prev) { - prev.count++; - }, - initial: {count: 0} - }; - - assert.eq(1000, t.group(p).length, "A5"); - assert(dbRO.auth("guest", "guest"), "auth failed 2"); assert.eq(1000, tRO.count(), "B1"); @@ -79,23 +69,6 @@ function runTest(m) { assert.writeError(tRO.save({})); assert.eq(1000, tRO.count(), "B6"); - - assert.eq(1000, tRO.group(p).length, "C1"); - - var p = { - key: {i: true}, - reduce: function(obj, prev) { - db.jstests_auth_auth1.save({i: 10000}); - prev.count++; - }, - initial: {count: 0} - }; - - assert.throws(function() { - return t.group(p); - }, [], "write reduce didn't fail"); - assert.eq(1000, dbRO.jstests_auth_auth1.count(), "C3"); - db.getSiblingDB('admin').auth('super', 'super'); assert.eq(1000, diff --git a/jstests/auth/explain_auth.js b/jstests/auth/explain_auth.js index 50c65ff2445..29b00035b6e 100644 --- a/jstests/auth/explain_auth.js +++ b/jstests/auth/explain_auth.js @@ -13,14 +13,13 @@ var coll = db.explain_auth_coll; assert.writeOK(coll.insert({_id: 1, a: 1})); /** - * Runs explains of find, count, group, remove, and update. Checks that they either succeed or - * fail with "not authorized". + * Runs explains of find, count, remove, and update. Checks that they either succeed or fail with + * "not authorized". * * Takes as input a document 'authSpec' with the following format: * { * find: <bool>, * count: <bool>, - * group: <bool>, * remove: <bool>, * update: <bool> * } @@ -47,11 +46,6 @@ function testExplainAuth(authSpec) { cmdResult = db.runCommand({explain: {count: coll.getName()}}); assertCmdResult(cmdResult, authSpec.count); - // .group() - cmdResult = db.runCommand( - {explain: {group: {ns: coll.getName(), key: "a", $reduce: function() {}, initial: {}}}}); - assertCmdResult(cmdResult, authSpec.group); - // .remove() cmdResult = db.runCommand({explain: {delete: coll.getName(), deletes: [{q: {a: 1}, limit: 1}]}}); @@ -93,15 +87,15 @@ admin.logout(); // The "find" action allows explain of read operations. db.auth("findOnly", "pwd"); -testExplainAuth({find: true, count: true, group: true, remove: false, update: false}); +testExplainAuth({find: true, count: true, remove: false, update: false}); db.logout(); db.auth("updateOnly", "pwd"); -testExplainAuth({find: false, count: false, group: false, remove: false, update: true}); +testExplainAuth({find: false, count: false, remove: false, update: true}); db.logout(); db.auth("removeOnly", "pwd"); -testExplainAuth({find: false, count: false, group: false, remove: true, update: false}); +testExplainAuth({find: false, count: false, remove: true, update: false}); db.logout(); -MongoRunner.stopMongod(conn, null, {user: "adminUser", pwd: "pwd"});
\ No newline at end of file +MongoRunner.stopMongod(conn, null, {user: "adminUser", pwd: "pwd"}); diff --git a/jstests/auth/js_scope_leak.js b/jstests/auth/js_scope_leak.js index c8f44cd518a..ef6d539d0db 100644 --- a/jstests/auth/js_scope_leak.js +++ b/jstests/auth/js_scope_leak.js @@ -5,7 +5,7 @@ // auth user 'a' -> auth user 'b' // auth user 'b' -> logout // -// These transitions are tested for dbEval, $where, MapReduce and $group +// These transitions are tested for dbEval, $where and MapReduce. var conn = MongoRunner.runMongod({smallfiles: ""}); var test = conn.getDB("test"); @@ -110,40 +110,4 @@ function testMapReduce() { testMapReduce(); testMapReduce(); -function testGroup() { - var setGlobalInGroup = function(string) { - return test.foo.group({ - key: 'a', - reduce: Function('doc1', 'agg', 'someGlobal = "' + string + '"'), - initial: {} - }); - }; - var getGlobalFromGroup = function(string) { - return test.foo.group({ - key: 'a', - reduce: Function('doc1', 'agg', 'assert(' + missingOrEquals(string) + ')'), - initial: {} - }); - }; - - // set the global variable 'someGlobal' before authenticating - setGlobalInGroup('noUsers'); - - // test new user auth causes scope to be cleared - test.auth('a', 'a'); - assert.doesNotThrow(getGlobalFromGroup, ['a'], "Group: Auth user 'a'"); - - // test auth as another user causes scope to be cleared - setGlobalInGroup('a'); - test.auth('b', 'b'); - assert.doesNotThrow(getGlobalFromGroup, ['a&b'], "Group: Auth user 'b'"); - - // test user logout causes scope to be cleared - setGlobalInGroup('a&b'); - test.logout(); - assert.doesNotThrow(getGlobalFromGroup, ['noUsers'], "Group: Log out"); -} -testGroup(); -testGroup(); - -MongoRunner.stopMongod(conn);
\ No newline at end of file +MongoRunner.stopMongod(conn); diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js index b1cc4d44d5d..5d057a65c2e 100644 --- a/jstests/auth/lib/commands_lib.js +++ b/jstests/auth/lib/commands_lib.js @@ -4087,38 +4087,6 @@ var authCommandsLib = { ] }, { - testname: "group", - command: { - group: { - ns: "x", - key: {groupby: 1}, - initial: {total: 0}, - $reduce: function(curr, result) { - result.total += curr.n; - } - } - }, - setup: function(db) { - db.x.insert({groupby: 1, n: 5}); - db.x.insert({groupby: 1, n: 6}); - }, - teardown: function(db) { - db.x.drop(); - }, - testcases: [ - { - runOnDb: firstDbName, - roles: roles_read, - privileges: [{resource: {db: firstDbName, collection: "x"}, actions: ["find"]}] - }, - { - runOnDb: secondDbName, - roles: roles_readAny, - privileges: [{resource: {db: secondDbName, collection: "x"}, actions: ["find"]}] - } - ] - }, - { testname: "hostInfo", command: {hostInfo: 1}, testcases: [ diff --git a/jstests/concurrency/fsm_all_sharded_replication.js b/jstests/concurrency/fsm_all_sharded_replication.js index 6b72c48a955..5313e1a6a04 100644 --- a/jstests/concurrency/fsm_all_sharded_replication.js +++ b/jstests/concurrency/fsm_all_sharded_replication.js @@ -56,10 +56,8 @@ var blacklist = [ 'findAndModify_update_grow.js', // can cause OOM kills on test hosts 'findAndModify_update_queue.js', // findAndModify requires a shard key 'findAndModify_update_queue_unindexed.js', // findAndModify requires a shard key - 'group.js', // the group command cannot be issued against a sharded cluster - 'group_cond.js', // the group command cannot be issued against a sharded cluster - 'indexed_insert_eval.js', // eval doesn't work with sharded collections - 'indexed_insert_eval_nolock.js', // eval doesn't work with sharded collections + 'indexed_insert_eval.js', // eval doesn't work with sharded collections + 'indexed_insert_eval_nolock.js', // eval doesn't work with sharded collections 'plan_cache_drop_database.js', // cannot ensureIndex after dropDatabase without sharding first 'remove_single_document.js', // our .remove(query, {justOne: true}) calls lack shard keys diff --git a/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js b/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js index 3b9957294c4..191e2316075 100644 --- a/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js +++ b/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js @@ -61,10 +61,8 @@ var blacklist = [ 'findAndModify_update_grow.js', // can cause OOM kills on test hosts 'findAndModify_update_queue.js', // findAndModify requires a shard key 'findAndModify_update_queue_unindexed.js', // findAndModify requires a shard key - 'group.js', // the group command cannot be issued against a sharded cluster - 'group_cond.js', // the group command cannot be issued against a sharded cluster - 'indexed_insert_eval.js', // eval doesn't work with sharded collections - 'indexed_insert_eval_nolock.js', // eval doesn't work with sharded collections + 'indexed_insert_eval.js', // eval doesn't work with sharded collections + 'indexed_insert_eval_nolock.js', // eval doesn't work with sharded collections 'plan_cache_drop_database.js', // cannot ensureIndex after dropDatabase without sharding first 'remove_single_document.js', // our .remove(query, {justOne: true}) calls lack shard keys diff --git a/jstests/concurrency/fsm_all_sharded_with_stepdowns.js b/jstests/concurrency/fsm_all_sharded_with_stepdowns.js index 92c5216f57f..017db324da3 100644 --- a/jstests/concurrency/fsm_all_sharded_with_stepdowns.js +++ b/jstests/concurrency/fsm_all_sharded_with_stepdowns.js @@ -56,11 +56,8 @@ var blacklist = [ 'findAndModify_update_grow.js', // can cause OOM kills on test hosts 'findAndModify_update_queue.js', // findAndModify requires a shard key 'findAndModify_update_queue_unindexed.js', // findAndModify requires a shard key - 'group.js', // the group command cannot be issued against a sharded cluster - 'group_cond.js', // the group command cannot be issued against a sharded cluster - 'group_killop.js', // the group command cannot be issued against a sharded cluster - 'indexed_insert_eval.js', // eval doesn't work with sharded collections - 'indexed_insert_eval_nolock.js', // eval doesn't work with sharded collections + 'indexed_insert_eval.js', // eval doesn't work with sharded collections + 'indexed_insert_eval_nolock.js', // eval doesn't work with sharded collections 'plan_cache_drop_database.js', // cannot ensureIndex after dropDatabase without sharding first 'remove_single_document.js', // our .remove(query, {justOne: true}) calls lack shard keys diff --git a/jstests/concurrency/fsm_all_sharded_with_stepdowns_and_balancer.js b/jstests/concurrency/fsm_all_sharded_with_stepdowns_and_balancer.js index f11a7180ec2..54c3951f62a 100644 --- a/jstests/concurrency/fsm_all_sharded_with_stepdowns_and_balancer.js +++ b/jstests/concurrency/fsm_all_sharded_with_stepdowns_and_balancer.js @@ -61,11 +61,8 @@ var blacklist = [ 'findAndModify_update_grow.js', // can cause OOM kills on test hosts 'findAndModify_update_queue.js', // findAndModify requires a shard key 'findAndModify_update_queue_unindexed.js', // findAndModify requires a shard key - 'group.js', // the group command cannot be issued against a sharded cluster - 'group_cond.js', // the group command cannot be issued against a sharded cluster - 'group_killop.js', // the group command cannot be issued against a sharded cluster - 'indexed_insert_eval.js', // eval doesn't work with sharded collections - 'indexed_insert_eval_nolock.js', // eval doesn't work with sharded collections + 'indexed_insert_eval.js', // eval doesn't work with sharded collections + 'indexed_insert_eval_nolock.js', // eval doesn't work with sharded collections 'plan_cache_drop_database.js', // cannot ensureIndex after dropDatabase without sharding first 'remove_single_document.js', // our .remove(query, {justOne: true}) calls lack shard keys diff --git a/jstests/concurrency/fsm_workloads/explain_group.js b/jstests/concurrency/fsm_workloads/explain_group.js deleted file mode 100644 index 99e0a0c1266..00000000000 --- a/jstests/concurrency/fsm_workloads/explain_group.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -/** - * explain_group.js - * - * Runs explain() and group() on a collection. - * - */ -load('jstests/concurrency/fsm_libs/extend_workload.js'); // for extendWorkload -load('jstests/concurrency/fsm_workloads/explain.js'); // for $config -load('jstests/libs/analyze_plan.js'); // for planHasStage - -var $config = extendWorkload($config, function($config, $super) { - - $config.states = Object.extend({ - explainBasicGroup: function explainBasicGroup(db, collName) { - var res = - db[collName].explain().group({key: {i: 1}, initial: {}, reduce: function() {}}); - assertAlways.commandWorked(res); - } - }, - $super.states); - - $config.transitions = Object.extend( - {explain: $config.data.assignEqualProbsToTransitions($config.states)}, $super.transitions); - - return $config; -}); diff --git a/jstests/concurrency/fsm_workloads/group.js b/jstests/concurrency/fsm_workloads/group.js deleted file mode 100644 index a02d175f202..00000000000 --- a/jstests/concurrency/fsm_workloads/group.js +++ /dev/null @@ -1,97 +0,0 @@ -'use strict'; - -/** - * group.js - * - * Inserts 1000 documents with a field set to a random - * float value. The group command is then used to partition these documents - * into one of ten buckets: - * [0, 0.09x), [0.10, 0.19x), ..., [0.80, 0.89x), [0.90, 1.0) - * - * The float field is not indexed. - * - */ - -var $config = (function() { - - function generateGroupCmdObj(collName) { - return { - group: { - ns: collName, - initial: {bucketCount: 0, bucketSum: 0}, - $keyf: function $keyf(doc) { - // place doc.rand into appropriate bucket - return {bucket: Math.floor(doc.rand * 10) + 1}; - }, - $reduce: function $reduce(curr, result) { - result.bucketCount++; - result.bucketSum += curr.rand; - }, - finalize: function finalize(result) { - // calculate average float value per bucket - result.bucketAvg = result.bucketSum / (result.bucketCount || 1); - } - } - }; - } - - function sumBucketCount(arr) { - return arr.reduce(function(a, b) { - return a + b.bucketCount; - }, 0); - } - - var data = { - numDocs: 1000, - generateGroupCmdObj: generateGroupCmdObj, - sumBucketCount: sumBucketCount - }; - - var states = (function() { - - function group(db, collName) { - var res = db.runCommand(this.generateGroupCmdObj(collName)); - assertWhenOwnColl.commandWorked(res); - - assertWhenOwnColl.lte(res.count, this.numDocs); - assertWhenOwnColl.lte(res.keys, 10); - assertWhenOwnColl(function() { - assertWhenOwnColl.lte(res.retval.length, 10); - assertWhenOwnColl.eq(this.sumBucketCount(res.retval), res.count); - }.bind(this)); - } - - return {group: group}; - - })(); - - var transitions = {group: {group: 1}}; - - function setup(db, collName, cluster) { - var bulk = db[collName].initializeUnorderedBulkOp(); - for (var i = 0; i < this.numDocs; ++i) { - bulk.insert({rand: Random.rand()}); - } - var res = bulk.execute(); - assertAlways.writeOK(res); - assertAlways.eq(this.numDocs, res.nInserted); - } - - function teardown(db, collName, cluster) { - assertWhenOwnColl(db[collName].drop()); - } - - return { - // Using few threads and iterations because each iteration per thread - // is fairly expensive compared to other workloads' iterations. - threadCount: 3, - iterations: 10, - startState: 'group', - states: states, - transitions: transitions, - data: data, - setup: setup, - teardown: teardown - }; - -})(); diff --git a/jstests/concurrency/fsm_workloads/group_cond.js b/jstests/concurrency/fsm_workloads/group_cond.js deleted file mode 100644 index 03a77993578..00000000000 --- a/jstests/concurrency/fsm_workloads/group_cond.js +++ /dev/null @@ -1,40 +0,0 @@ -'use strict'; - -/** - * group_cond.js - * - * Inserts 1000 documents with a field set to a random - * float value. The group command is then used to partition these documents - * into one of ten buckets: - * [0, 0.09x), [0.10, 0.19x), ..., [0.80, 0.89x), [0.90, 1.0) - * - * To increase testing coverage, the float field is indexed and - * a 'cond' document is supplied to the group command. - * - */ - -load('jstests/concurrency/fsm_libs/extend_workload.js'); // for extendWorkload -load('jstests/concurrency/fsm_workloads/group.js'); // for $config - -var $config = extendWorkload($config, function($config, $super) { - $config.setup = function setup(db, collName, cluster) { - $super.setup.apply(this, arguments); - assertAlways.commandWorked(db[collName].ensureIndex({rand: 1})); - }; - - $config.states.group = function group(db, collName) { - var cmdObj = this.generateGroupCmdObj(collName); - cmdObj.group.cond = {rand: {$gte: 0.5}}; - var res = db.runCommand(cmdObj); - assertWhenOwnColl.commandWorked(res); - - assertWhenOwnColl.lte(res.count, this.numDocs); - assertWhenOwnColl.lte(res.keys, 5); - assertWhenOwnColl(function() { - assertWhenOwnColl.lte(res.retval.length, 5); - assertWhenOwnColl.eq(this.sumBucketCount(res.retval), res.count); - }.bind(this)); - }; - - return $config; -}); diff --git a/jstests/concurrency/fsm_workloads/group_killop.js b/jstests/concurrency/fsm_workloads/group_killop.js deleted file mode 100644 index 88188e2bff4..00000000000 --- a/jstests/concurrency/fsm_workloads/group_killop.js +++ /dev/null @@ -1,62 +0,0 @@ -'use strict'; - -/** - * Run group() continuously, occasionally killing them midway. - */ -load("jstests/libs/fixture_helpers.js"); // For isMongos. -load('jstests/concurrency/fsm_libs/extend_workload.js'); // For extendWorkload. -load('jstests/concurrency/fsm_workloads/group.js'); // For $config. - -var $config = extendWorkload($config, function($config, $super) { - var states = (function() { - - function init(db, collName) { - } - - function group(db, collName) { - const res = db.runCommand(this.generateGroupCmdObj(collName)); - - // The only time this should fail is due to interrupt from the 'killOp'. - if (res.ok) { - assertAlways.commandWorked(res); - } else { - // TODO We really only expect Interrupted here, but until SERVER-32565 is resolved - // there are times when we might get InternalError. - assertAlways.contains(res.code, [ErrorCodes.Interrupted, ErrorCodes.InternalError]); - return; - } - - // lte because the documents are generated randomly, and so not all buckets are - // guaranteed to exist. - assertWhenOwnColl.lte(res.count, this.numDocs); - assertWhenOwnColl.lte(res.keys, 10); - } - - function chooseRandomlyFrom(arr) { - if (!Array.isArray(arr)) { - throw new Error('Expected array for first argument, but got: ' + tojson(arr)); - } - return arr[Random.randInt(arr.length)]; - } - - function killOp(db, collName) { - // Find a group command to kill. - const countOps = db.currentOp({"command.group.ns": collName}).inprog; - if (countOps.length > 0) { - const op = chooseRandomlyFrom(countOps); - const res = db.adminCommand({killOp: 1, op: op.opid}); - assertAlways.commandWorked(res); - } - } - - return {init: init, group: group, killOp: killOp}; - - })(); - - $config.states = states; - $config.transitions = {init: {group: 0.7, killOp: 0.3}, group: {init: 1}, killOp: {init: 1}}; - $config.threadCount = 40; - $config.iterations = 40; - - return $config; -}); diff --git a/jstests/concurrency/fsm_workloads/yield_group.js b/jstests/concurrency/fsm_workloads/yield_group.js deleted file mode 100644 index 6ba3607940f..00000000000 --- a/jstests/concurrency/fsm_workloads/yield_group.js +++ /dev/null @@ -1,86 +0,0 @@ -'use strict'; - -/** - * Tests that the group command either succeeds or fails gracefully when interspersed with inserts - * on a capped collection. Designed to reproduce SERVER-34725. - */ -var $config = (function() { - - var states = { - /* - * Issue a group command against the capped collection. - */ - group: function group(db, collName) { - try { - assert.commandWorked(db.runCommand( - {group: {ns: collName, key: {_id: 1}, $reduce: function() {}, initial: {}}})); - } catch (ex) { - assert.eq(ErrorCodes.CappedPositionLost, ex.code); - } - }, - - /** - * Inserts a document into the capped collection. - */ - insert: function insert(db, collName) { - assertAlways.writeOK(db[collName].insert({a: 1})); - } - }; - - var transitions = { - insert: {insert: 0.5, group: 0.5}, - group: {insert: 0.5, group: 0.5}, - }; - - function setup(db, collName, cluster) { - const nDocs = 200; - - // Create the test capped collection, with a max number of documents. - db[collName].drop(); - assert.commandWorked(db.createCollection(collName, { - capped: true, - size: 4096, - max: this.nDocs, // Set the maximum number of documents in the capped collection such - // that additional inserts will drop older documents and increase the - // likelihood of losing the capped position. - })); - - // Lower the following parameters to increase the probability of yields. - cluster.executeOnMongodNodes(function lowerYieldParams(db) { - assertAlways.commandWorked( - db.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 5})); - assertAlways.commandWorked( - db.adminCommand({setParameter: 1, internalQueryExecYieldPeriodMS: 1})); - }); - - // Set up some data to query. - var bulk = db[collName].initializeUnorderedBulkOp(); - for (let i = 0; i < nDocs; i++) { - bulk.insert({_id: i}); - } - assertAlways.writeOK(bulk.execute()); - } - - /* - * Reset parameters. - */ - function teardown(db, collName, cluster) { - cluster.executeOnMongodNodes(function resetYieldParams(db) { - assertAlways.commandWorked( - db.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 128})); - assertAlways.commandWorked( - db.adminCommand({setParameter: 1, internalQueryExecYieldPeriodMS: 10})); - }); - } - - return { - threadCount: 5, - iterations: 50, - startState: 'insert', - states: states, - transitions: transitions, - setup: setup, - teardown: teardown, - data: {} - }; -})(); diff --git a/jstests/core/apitest_db.js b/jstests/core/apitest_db.js index 8d5d71b70be..25101975240 100644 --- a/jstests/core/apitest_db.js +++ b/jstests/core/apitest_db.js @@ -21,7 +21,6 @@ assert(db.createCollection, "createCollection"); assert(db.getProfilingLevel, "getProfilingLevel"); assert(db.setProfilingLevel, "setProfilingLevel"); assert(db.dbEval, "dbEval"); -assert(db.group, "group"); dd("c"); diff --git a/jstests/core/collation.js b/jstests/core/collation.js index e912578f8b3..5a24b133de0 100644 --- a/jstests/core/collation.js +++ b/jstests/core/collation.js @@ -993,84 +993,6 @@ coll.findAndModify({query: {str: "FOO"}, remove: true, collation: {locale: "simple"}})); // - // Collation tests for group. - // - - // Group should return correct results when collation specified and collection does not exist. - coll.drop(); - assert.eq([], coll.group({ - key: {str: 1}, - initial: {count: 0}, - reduce: function(curr, result) { - result.count += 1; - }, - collation: {locale: "fr"} - })); - - // Group should return correct results when collation specified and no indexes exist. - coll.drop(); - assert.writeOK(coll.insert({_id: 1, str: "foo"})); - assert.writeOK(coll.insert({_id: 2, str: "bar"})); - assert.eq([{str: "foo", count: 1}], coll.group({ - cond: {str: "FOO"}, - key: {str: 1}, - initial: {count: 0}, - reduce: function(curr, result) { - result.count += 1; - }, - collation: {locale: "en_US", strength: 2} - })); - - // Group should return correct results when no collation specified and collection has a default - // collation. - coll.drop(); - assert.commandWorked( - db.createCollection(coll.getName(), {collation: {locale: "en_US", strength: 2}})); - assert.writeOK(coll.insert({_id: 1, str: "foo"})); - assert.eq([{str: "foo", count: 1}], coll.group({ - cond: {str: "FOO"}, - key: {str: 1}, - initial: {count: 0}, - reduce: function(curr, result) { - result.count += 1; - } - })); - - // Group should return correct results when "simple" collation specified and collection has a - // default collation. - coll.drop(); - assert.commandWorked( - db.createCollection(coll.getName(), {collation: {locale: "en_US", strength: 2}})); - assert.writeOK(coll.insert({_id: 1, str: "foo"})); - assert.eq([], coll.group({ - cond: {str: "FOO"}, - key: {str: 1}, - initial: {count: 0}, - reduce: function(curr, result) { - result.count += 1; - }, - collation: {locale: "simple"} - })); - - // Explain of group should return correct results when collation specified. - coll.drop(); - assert.writeOK(coll.insert({_id: 1, str: "foo"})); - assert.writeOK(coll.insert({_id: 2, str: "bar"})); - explainRes = coll.explain("executionStats").group({ - cond: {str: "FOO"}, - key: {str: 1}, - initial: {count: 0}, - reduce: function(curr, result) { - result.count += 1; - }, - collation: {locale: "en_US", strength: 2} - }); - assert.commandWorked(explainRes); - planStage = getPlanStage(explainRes.executionStats.executionStages, "GROUP"); - assert.neq(null, planStage); - assert.eq(planStage.nGroups, 1); - - // // Collation tests for mapReduce. // diff --git a/jstests/core/commands_namespace_parsing.js b/jstests/core/commands_namespace_parsing.js index 30301cd04dd..c3ba15e37a9 100644 --- a/jstests/core/commands_namespace_parsing.js +++ b/jstests/core/commands_namespace_parsing.js @@ -71,12 +71,6 @@ assertFailsWithInvalidNamespacesForField( "distinct", {distinct: "", key: "a"}, isNotFullyQualified, isNotAdminCommand); - // Test group fails with an invalid collection name. - assertFailsWithInvalidNamespacesForField("group.ns", - {group: {ns: "", $reduce: () => {}, initial: {}}}, - isNotFullyQualified, - isNotAdminCommand); - // Test mapReduce fails with an invalid input collection name. assertFailsWithInvalidNamespacesForField("mapreduce", { @@ -362,13 +356,6 @@ isNotFullyQualified, isNotAdminCommand); - // Test explain of group fails with an invalid collection name. - assertFailsWithInvalidNamespacesForField( - "explain.group.ns", - {explain: {group: {ns: "", $reduce: () => {}, initial: {}}}}, - isNotFullyQualified, - isNotAdminCommand); - // Test explain of find fails with an invalid collection name. assertFailsWithInvalidNamespacesForField( "explain.find", {explain: {find: ""}}, isNotFullyQualified, isNotAdminCommand); diff --git a/jstests/core/eval2.js b/jstests/core/eval2.js deleted file mode 100644 index f928a41c0cb..00000000000 --- a/jstests/core/eval2.js +++ /dev/null @@ -1,36 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group uses javascript -// requires_scripting, -// ] - -t = db.eval2; -t.drop(); -t.save({a: 1}); -t.save({a: 1}); - -var f = db.group({ - ns: t.getName(), - key: {a: true}, - cond: {a: 1}, - reduce: function(obj, prev) { - prev.csum++; - }, - initial: {csum: 0} -}); - -assert(f[0].a == 1 && f[0].csum == 2, "on db"); - -var f = t.group({ - key: {a: true}, - cond: {a: 1}, - reduce: function(obj, prev) { - prev.csum++; - }, - initial: {csum: 0} -}); - -assert(f[0].a == 1 && f[0].csum == 2, "on coll"); diff --git a/jstests/core/explain_missing_collection.js b/jstests/core/explain_missing_collection.js index ed579174e2f..e129fb7f16a 100644 --- a/jstests/core/explain_missing_collection.js +++ b/jstests/core/explain_missing_collection.js @@ -1,13 +1,7 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting, -// ] - -// Test explain of various operations against a non-existent collection +/** + * Test explaining various operations against a non-existent collection. + * @tags: [assumes_no_implicit_collection_creation_after_drop] + */ (function() { var missingColl = db.explain_null_collection; @@ -26,13 +20,6 @@ assert.commandWorked(explain); assert("executionStats" in explain); - // .group() - missingColl.drop(); - explainColl = missingColl.explain("executionStats"); - explain = explainColl.group({key: "a", initial: {}, reduce: function() {}}); - assert.commandWorked(explain); - assert("executionStats" in explain); - // .remove() missingColl.drop(); explain = missingColl.explain("executionStats").remove({a: 1}); diff --git a/jstests/core/explain_missing_database.js b/jstests/core/explain_missing_database.js index 8bf65129a78..93123086bde 100644 --- a/jstests/core/explain_missing_database.js +++ b/jstests/core/explain_missing_database.js @@ -1,8 +1,4 @@ // Test explain of various operations against a non-existent database -// @tags: [ -// # group requires javascript -// requires_scripting, -//] (function() { var explainMissingDb = db.getSiblingDB("explainMissingDb"); @@ -21,13 +17,6 @@ assert.commandWorked(explain); assert("executionStats" in explain); - // .group() - explainMissingDb.dropDatabase(); - explainColl = explainMissingDb.collection.explain("executionStats"); - explain = explainColl.group({key: "a", initial: {}, reduce: function() {}}); - assert.commandWorked(explain); - assert("executionStats" in explain); - // .remove() explainMissingDb.dropDatabase(); explain = explainMissingDb.collection.explain("executionStats").remove({a: 1}); diff --git a/jstests/core/explain_multi_plan.js b/jstests/core/explain_multi_plan.js index f1605e3c999..d09e90cf25c 100644 --- a/jstests/core/explain_multi_plan.js +++ b/jstests/core/explain_multi_plan.js @@ -3,9 +3,6 @@ // # update/delete on a sharded collection must contain an exact match on _id or contain the // # shard key. // assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting, // ] /** @@ -58,15 +55,6 @@ coll.explain("allPlansExecution").distinct("a", {a: {$gte: 1}}); }); - assert.doesNotThrow(function() { - coll.explain("allPlansExecution").group({ - key: {a: 1}, - cond: {a: {$gte: 1}}, - reduce: function(curr, result) {}, - initial: {} - }); - }); - // SERVER-21376: Make sure the 'rejectedPlans' field is filled in appropriately. function assertHasRejectedPlans(explainOutput) { var queryPlannerOutput = explainOutput.queryPlanner; diff --git a/jstests/core/explain_shell_helpers.js b/jstests/core/explain_shell_helpers.js index 910c6947e11..a9c32f981d2 100644 --- a/jstests/core/explain_shell_helpers.js +++ b/jstests/core/explain_shell_helpers.js @@ -260,13 +260,6 @@ assert.eq(getPlanStage(explain.queryPlanner.winningPlan, "IXSCAN").indexName, "c assert.commandWorked(t.dropIndex({c: 1})); // -// .group() -// - -explain = t.explain().group({key: "a", initial: {}, reduce: function() {}}); -assert.commandWorked(explain); - -// // .distinct() // @@ -439,11 +432,6 @@ assert.throws(function() { t.explain().update({a: 3}, {$set: {b: 4}}, {multi: true}, true); }); -// Missing "initial" for explaining a group. -assert.throws(function() { - t.explain().group({key: "a", reduce: function() {}}); -}); - // Can't specify both remove and update in a findAndModify assert.throws(function() { t.explain().findAndModify({remove: true, update: {$set: {b: 3}}}); diff --git a/jstests/core/expr.js b/jstests/core/expr.js index 86bf9aef10a..541c32a4bdc 100644 --- a/jstests/core/expr.js +++ b/jstests/core/expr.js @@ -201,44 +201,6 @@ })); // - // $expr in group. - // - - // The group command is not permitted in sharded collections. - if (!isMongos) { - coll.drop(); - assert.writeOK(coll.insert({a: 0})); - assert.eq([{a: 0, count: 1}], coll.group({ - cond: {$expr: {$eq: ["$a", 0]}}, - key: {a: 1}, - initial: {count: 0}, - reduce: function(curr, result) { - result.count += 1; - } - })); - assert.throws(function() { - coll.group({ - cond: {$expr: {$eq: ["$a", "$$unbound"]}}, - key: {a: 1}, - initial: {count: 0}, - reduce: function(curr, result) { - result.count += 1; - } - }); - }); - assert.throws(function() { - coll.group({ - cond: {$expr: {$divide: [1, "$a"]}}, - key: {a: 1}, - initial: {count: 0}, - reduce: function(curr, result) { - result.count += 1; - } - }); - }); - } - - // // $expr in mapReduce. // diff --git a/jstests/core/geo_group.js b/jstests/core/geo_group.js deleted file mode 100644 index a571131e114..00000000000 --- a/jstests/core/geo_group.js +++ /dev/null @@ -1,47 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because group is not supported on sharded -// # collections. -// assumes_unsharded_collection, -// requires_fastcount, -// -// # reduce uses javascript -// requires_scripting, -// ] - -t = db.geo_group; -t.drop(); - -n = 1; -var bulk = t.initializeUnorderedBulkOp(); -for (var x = -100; x < 100; x += 2) { - for (var y = -100; y < 100; y += 2) { - bulk.insert({_id: n++, loc: [x, y]}); - } -} -assert.writeOK(bulk.execute()); - -t.ensureIndex({loc: "2d"}); - -// Test basic count with $near -assert.eq(t.find().count(), 10000); -assert.eq(t.find({loc: {$within: {$center: [[56, 8], 10]}}}).count(), 81); -assert.eq(t.find({loc: {$near: [56, 8, 10]}}).count(), 81); - -// Test basic group that effectively does a count -assert.eq(t.group({ - reduce: function(obj, prev) { - prev.sums = {count: prev.sums.count + 1}; - }, - initial: {sums: {count: 0}} -}), - [{"sums": {"count": 10000}}]); - -// Test basic group + $near that does a count -assert.eq(t.group({ - reduce: function(obj, prev) { - prev.sums = {count: prev.sums.count + 1}; - }, - initial: {sums: {count: 0}}, - cond: {loc: {$near: [56, 8, 10]}} -}), - [{"sums": {"count": 81}}]); diff --git a/jstests/core/group1.js b/jstests/core/group1.js deleted file mode 100644 index 5021f8b48dc..00000000000 --- a/jstests/core/group1.js +++ /dev/null @@ -1,156 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting -// ] -(function() { - "use strict"; - - const coll = db.group1; - coll.drop(); - - assert.writeOK(coll.insert({n: 1, a: 1})); - assert.writeOK(coll.insert({n: 2, a: 1})); - assert.writeOK(coll.insert({n: 3, a: 2})); - assert.writeOK(coll.insert({n: 4, a: 2})); - assert.writeOK(coll.insert({n: 5, a: 2})); - - let p = { - key: {a: true}, - reduce: function(obj, prev) { - prev.count++; - }, - initial: {count: 0} - }; - - function sortFuncGenerator(key) { - return (doc1, doc2) => { - if (doc1[key] < doc2[key]) { - return -1; - } else if (doc1[key] > doc2[key]) { - return 1; - } else { - return 0; - } - }; - } - - const sortOnA = sortFuncGenerator("a"); - let expected = [{a: 1, count: 2}, {a: 2, count: 3}]; - let result = coll.group(p).sort(sortOnA); - assert.eq(result, expected); - - result = coll.groupcmd(p).sort(sortOnA); - assert.eq(result, expected); - - expected = [{count: 5}]; - result = coll.groupcmd({key: {}, reduce: p.reduce, initial: p.initial}); - assert.eq(result, expected); - - expected = [{sum: 15}]; - result = coll.groupcmd({ - key: {}, - reduce: function(obj, prev) { - prev.sum += obj.n; - }, - initial: {sum: 0} - }); - assert.eq(result, expected); - - assert(coll.drop()); - - assert.writeOK(coll.insert({"a": 2})); - assert.writeOK(coll.insert({"b": 5})); - assert.writeOK(coll.insert({"a": 1})); - assert.writeOK(coll.insert({"a": 2})); - - const c = { - key: {a: 1}, - cond: {}, - initial: {"count": 0}, - reduce: function(obj, prev) { - prev.count++; - } - }; - - expected = [{a: null, count: 1}, {a: 1, count: 1}, {a: 2, count: 2}]; - assert.eq(coll.group(c).sort(sortOnA), expected); - assert.eq(coll.groupcmd(c).sort(sortOnA), expected); - - assert(coll.drop()); - - assert.writeOK(coll.insert({name: {first: "a", last: "A"}})); - assert.writeOK(coll.insert({name: {first: "b", last: "B"}})); - assert.writeOK(coll.insert({name: {first: "a", last: "A"}})); - - p = { - key: {'name.first': true}, - reduce: function(obj, prev) { - prev.count++; - }, - initial: {count: 0} - }; - const sortOnNameDotFirst = sortFuncGenerator("name.first"); - - expected = [{"name.first": "a", count: 2}, {"name.first": "b", count: 1}]; - assert.eq(coll.group(p).sort(sortOnNameDotFirst), expected); - - // SERVER-15851 Test invalid user input. - p = { - ns: "group1", - key: {"name.first": true}, - $reduce: function(obj, prev) { - prev.count++; - }, - initial: {count: 0}, - finalize: "abc" - }; - assert.commandFailedWithCode( - db.runCommand({group: p}), ErrorCodes.JSInterpreterFailure, "Illegal finalize function"); - - p = { - ns: "group1", - key: {"name.first": true}, - $reduce: function(obj, prev) { - prev.count++; - }, - initial: {count: 0}, - finalize: function(obj) { - throw new Error("Intentionally throwing exception in finalize function"); - } - }; - assert.commandFailedWithCode( - db.runCommand({group: p}), ErrorCodes.JSInterpreterFailure, "Illegal finalize function 2"); - - p = { - ns: "group1", - $keyf: "a", - $reduce: function(obj, prev) { - prev.count++; - }, - initial: {count: 0}, - finalize: function(obj) { - throw new Error("Intentionally throwing exception in finalize function"); - } - }; - assert.commandFailedWithCode( - db.runCommand({group: p}), ErrorCodes.JSInterpreterFailure, "Illegal keyf function"); - - p = {ns: "group1", key: {"name.first": true}, $reduce: "abc", initial: {count: 0}}; - assert.commandFailedWithCode( - db.runCommand({group: p}), ErrorCodes.JSInterpreterFailure, "Illegal reduce function"); - - p = { - ns: "group1", - key: {"name.first": true}, - $reduce: function(obj, pre) { - prev.count++; - }, - initial: {count: 0} - }; - assert.commandFailedWithCode( - db.runCommand({group: p}), ErrorCodes.JSInterpreterFailure, "Illegal reduce function 2"); -}()); diff --git a/jstests/core/group2.js b/jstests/core/group2.js deleted file mode 100644 index 65faa657fae..00000000000 --- a/jstests/core/group2.js +++ /dev/null @@ -1,49 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting -// ] - -(function() { - "use strict"; - const coll = db.group2; - coll.drop(); - - assert.writeOK(coll.insert({a: 2})); - assert.writeOK(coll.insert({b: 5})); - assert.writeOK(coll.insert({a: 1})); - - const cmd = { - key: {a: 1}, - initial: {count: 0}, - reduce: function(obj, prev) { - prev.count++; - } - }; - const sortFunc = function(doc1, doc2) { - if (doc1.a < doc2.a) { - return -1; - } else if (doc1.a > doc2.a) { - return 1; - } else { - return 0; - } - }; - const expected = [{a: null, count: 1}, {a: 1, count: 1}, {a: 2, count: 1}]; - assert.eq(coll.group(cmd).sort(sortFunc), expected); - - const keyFn = function(x) { - return {a: 'a' in x ? x.a : null}; - }; - - delete cmd.key; - cmd["$keyf"] = keyFn; - assert.eq(coll.group(cmd).sort(sortFunc), expected); - - delete cmd.$keyf; - cmd["keyf"] = keyFn; - assert.eq(coll.group(cmd).sort(sortFunc), expected); -}()); diff --git a/jstests/core/group3.js b/jstests/core/group3.js deleted file mode 100644 index 48eec33eaf8..00000000000 --- a/jstests/core/group3.js +++ /dev/null @@ -1,51 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting -// ] - -t = db.group3; -t.drop(); - -t.save({a: 1}); -t.save({a: 2}); -t.save({a: 3}); -t.save({a: 4}); - -cmd = { - initial: {count: 0, sum: 0}, - reduce: function(obj, prev) { - prev.count++; - prev.sum += obj.a; - }, - finalize: function(obj) { - if (obj.count) { - obj.avg = obj.sum / obj.count; - } else { - obj.avg = 0; - } - }, -}; - -result1 = t.group(cmd); - -assert.eq(1, result1.length, "test1"); -assert.eq(10, result1[0].sum, "test1"); -assert.eq(4, result1[0].count, "test1"); -assert.eq(2.5, result1[0].avg, "test1"); - -cmd['finalize'] = function(obj) { - if (obj.count) { - return obj.sum / obj.count; - } else { - return 0; - } -}; - -result2 = t.group(cmd); - -assert.eq(1, result2.length, "test2"); -assert.eq(2.5, result2[0], "test2"); diff --git a/jstests/core/group4.js b/jstests/core/group4.js deleted file mode 100644 index bb5b91b1752..00000000000 --- a/jstests/core/group4.js +++ /dev/null @@ -1,47 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting -// ] -t = db.group4; -t.drop(); - -function test(c, n) { - var x = {}; - c.forEach(function(z) { - assert.eq(z.count, z.values.length, n + "\t" + tojson(z)); - }); -} - -t.insert({name: 'bob', foo: 1}); -t.insert({name: 'bob', foo: 2}); -t.insert({name: 'alice', foo: 1}); -t.insert({name: 'alice', foo: 3}); -t.insert({name: 'fred', foo: 3}); -t.insert({name: 'fred', foo: 4}); - -x = t.group({ - key: {foo: 1}, - initial: {count: 0, values: []}, - reduce: function(obj, prev) { - prev.count++; - prev.values.push(obj.name); - } -}); -test(x, "A"); - -x = t.group({ - key: {foo: 1}, - initial: {count: 0}, - reduce: function(obj, prev) { - if (!prev.values) { - prev.values = []; - } - prev.count++; - prev.values.push(obj.name); - } -}); -test(x, "B"); diff --git a/jstests/core/group5.js b/jstests/core/group5.js deleted file mode 100644 index 9a08eb9c98b..00000000000 --- a/jstests/core/group5.js +++ /dev/null @@ -1,45 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting -// ] - -t = db.group5; -t.drop(); - -// each group has groupnum+1 5 users -for (var group = 0; group < 10; group++) { - for (var i = 0; i < 5 + group; i++) { - t.save({group: "group" + group, user: i}); - } -} - -function c(group) { - return t.group({ - key: {group: 1}, - q: {group: "group" + group}, - initial: {users: {}}, - reduce: function(obj, prev) { - prev.users[obj.user] = true; // add this user to the hash - }, - finalize: function(x) { - var count = 0; - for (var key in x.users) { - count++; - } - - // replace user obj with count - // count add new field and keep users - x.users = count; - return x; - } - })[0]; // returns array -} - -assert.eq("group0", c(0).group, "g0"); -assert.eq(5, c(0).users, "g0 a"); -assert.eq("group5", c(5).group, "g5"); -assert.eq(10, c(5).users, "g5 a"); diff --git a/jstests/core/group6.js b/jstests/core/group6.js deleted file mode 100644 index f22a10710f1..00000000000 --- a/jstests/core/group6.js +++ /dev/null @@ -1,48 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting -// ] -t = db.jstests_group6; -t.drop(); - -for (i = 1; i <= 10; ++i) { - t.save({i: new NumberLong(i), y: 1}); -} - -assert.eq.automsg( - "55", - "t.group( {key:'y', reduce:function(doc,out){ out.i += doc.i; }, initial:{i:0} } )[ 0 ].i"); - -t.drop(); -for (i = 1; i <= 10; ++i) { - if (i % 2 == 0) { - t.save({i: new NumberLong(i), y: 1}); - } else { - t.save({i: i, y: 1}); - } -} - -assert.eq.automsg( - "55", - "t.group( {key:'y', reduce:function(doc,out){ out.i += doc.i; }, initial:{i:0} } )[ 0 ].i"); - -t.drop(); -for (i = 1; i <= 10; ++i) { - if (i % 2 == 1) { - t.save({i: new NumberLong(i), y: 1}); - } else { - t.save({i: i, y: 1}); - } -} - -assert.eq.automsg( - "55", - "t.group( {key:'y', reduce:function(doc,out){ out.i += doc.i; }, initial:{i:0} } )[ 0 ].i"); - -assert.eq.automsg( - "NumberLong(10)", - "t.group( {$reduce: function(doc, prev) { prev.count += 1; }, initial: {count: new NumberLong(0) }} )[ 0 ].count");
\ No newline at end of file diff --git a/jstests/core/group8.js b/jstests/core/group8.js deleted file mode 100644 index 5590dcba892..00000000000 --- a/jstests/core/group8.js +++ /dev/null @@ -1,48 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting -// ] - -// Test correctness of the "keys" and and "count" fields in the group command output. -var coll = db.group8; -var result; - -coll.drop(); -assert.writeOK(coll.insert({a: 1, b: "x"})); -assert.writeOK(coll.insert({a: 2, b: "x"})); -assert.writeOK(coll.insert({a: 2, b: "x"})); -assert.writeOK(coll.insert({a: 3, b: "y"})); - -// Test case when "count" and "keys" are both zero. -result = coll.runCommand({ - group: { - ns: coll.getName(), - key: {a: 1}, - cond: {b: "z"}, - $reduce: function(x, y) {}, - initial: {} - } -}); -assert.commandWorked(result); -assert.eq(result.count, 0); -assert.eq(result.keys, 0); -assert.eq(result.retval.length, 0); - -// Test case when "count" and "keys" are both non-zero. -result = coll.runCommand({ - group: { - ns: coll.getName(), - key: {a: 1}, - cond: {b: "x"}, - $reduce: function(x, y) {}, - initial: {} - } -}); -assert.commandWorked(result); -assert.eq(result.count, 3); -assert.eq(result.keys, 2); -assert.eq(result.retval.length, 2); diff --git a/jstests/core/group9.js b/jstests/core/group9.js deleted file mode 100644 index d32ae0611f0..00000000000 --- a/jstests/core/group9.js +++ /dev/null @@ -1,29 +0,0 @@ -// @tags: [ -// # Cannot implicitly shard accessed collections because of unsupported group operator on -// # sharded collection. -// assumes_unsharded_collection, -// -// # group requires javascript -// requires_scripting -// ] - -(function() { - 'use strict'; - var t = db.group_owned; - t.drop(); - - assert.writeOK(t.insert({_id: 1, subdoc: {id: 1}})); - assert.writeOK(t.insert({_id: 2, subdoc: {id: 2}})); - - var result = t.group({ - key: {'subdoc.id': 1}, - reduce: function(doc, value) { - value.subdoc = doc.subdoc; - return value; - }, - initial: {}, - finalize: function(res) {} - }); - - assert(result.length == 2); -}()); diff --git a/jstests/core/group_empty.js b/jstests/core/group_empty.js deleted file mode 100644 index 6f5637ac0df..00000000000 --- a/jstests/core/group_empty.js +++ /dev/null @@ -1,13 +0,0 @@ - -t = db.group_empty; -t.drop(); - -res1 = db.runCommand( - {group: {$reduce: function() {}, ns: 'group_empty', cond: {}, key: {}, initial: {count: 0}}}); -t.ensureIndex({x: 1}); -res2 = db.runCommand( - {group: {$reduce: function() {}, ns: 'group_empty', cond: {}, key: {}, initial: {count: 0}}}); - -assert.docEq(res1.retval, res2.retval); -assert.eq(res1.keys, res2.keys); -assert.eq(res1.count, res2.count); diff --git a/jstests/core/index_stats.js b/jstests/core/index_stats.js index 69517475191..6bed899e16e 100644 --- a/jstests/core/index_stats.js +++ b/jstests/core/index_stats.js @@ -144,22 +144,6 @@ assert.eq(countB, getUsageCount("b_1_c_1")); // - // Confirm index stats tick on group(). - // - res = db.runCommand({ - group: { - ns: colName, - key: {b: 1, c: 1}, - cond: {b: {$gt: 0}}, - $reduce: function(curr, result) {}, - initial: {} - } - }); - assert.commandWorked(res); - countB++; - assert.eq(countB, getUsageCount("b_1_c_1")); - - // // Confirm index stats tick on aggregate w/ match. // res = db.runCommand({aggregate: colName, pipeline: [{$match: {b: 1}}], cursor: {}}); diff --git a/jstests/core/operation_latency_histogram.js b/jstests/core/operation_latency_histogram.js index c95c8817b51..12885ade938 100644 --- a/jstests/core/operation_latency_histogram.js +++ b/jstests/core/operation_latency_histogram.js @@ -2,14 +2,13 @@ // // This test attempts to perform write operations and get latency statistics using the $collStats // stage. The former operation must be routed to the primary in a replica set, whereas the latter -// may be routed to a secondary. +// may be routed to a secondary. Additionally, it is incompatible with the mobile storage engine +// because it uses parallelCollectionScan. // // @tags: [ // assumes_read_preference_unchanged, // requires_collstats, -// -// # group uses javascript -// requires_scripting, +// incompatible_with_embedded, // ] (function() { @@ -113,12 +112,9 @@ } lastHistogram = assertHistogramDiffEq(testColl, lastHistogram, numRecords, 0, 0); - // Group - testColl.group({initial: {}, reduce: function() {}, key: {a: 1}}); - lastHistogram = assertHistogramDiffEq(testColl, lastHistogram, 1, 0, 0); - // ParallelCollectionScan - testDB.runCommand({parallelCollectionScan: testColl.getName(), numCursors: 5}); + assert.commandWorked( + testDB.runCommand({parallelCollectionScan: testColl.getName(), numCursors: 1})); lastHistogram = assertHistogramDiffEq(testColl, lastHistogram, 0, 0, 1); // FindAndModify diff --git a/jstests/core/or4.js b/jstests/core/or4.js index 71237eb36af..cd3c42424b9 100644 --- a/jstests/core/or4.js +++ b/jstests/core/or4.js @@ -1,7 +1,4 @@ -// Cannot implicitly shard accessed collections because of unsupported group operator on sharded -// collection. // @tags: [ -// assumes_unsharded_collection, // does_not_support_stepdowns, // requires_getmore, // requires_non_retryable_writes, @@ -67,10 +64,6 @@ assert.eq([1, 2], Array.sort(coll.distinct('a', {$or: [{a: 2}, {b: 3}]}))); - assert.eq( - [{a: 2}, {a: null}, {a: 1}], - coll.group( - {key: {a: 1}, cond: {$or: [{a: 2}, {b: 3}]}, reduce: function(x, y) {}, initial: {}})); assert.eq(5, coll.mapReduce( function() { diff --git a/jstests/core/profile_group.js b/jstests/core/profile_group.js deleted file mode 100644 index 57644e80f93..00000000000 --- a/jstests/core/profile_group.js +++ /dev/null @@ -1,67 +0,0 @@ -// @tags: [does_not_support_stepdowns] - -// Confirms that profiled group execution contains all expected metrics with proper values. - -(function() { - "use strict"; - - // For getLatestProfilerEntry and getProfilerProtocolStringForCommand - load("jstests/libs/profiler.js"); - - var testDB = db.getSiblingDB("profile_group"); - assert.commandWorked(testDB.dropDatabase()); - var conn = testDB.getMongo(); - var coll = testDB.getCollection("test"); - - testDB.setProfilingLevel(2); - - // - // Confirm standard group command metrics. - // - var i; - for (i = 0; i < 10; ++i) { - assert.writeOK(coll.insert({a: i, b: i % 5})); - } - assert.commandWorked(coll.createIndex({b: -1})); - - coll.group({ - key: {a: 1, b: 1}, - cond: {b: 3}, - reduce: function() {}, - initial: {}, - collation: {locale: "fr"} - }); - var profileObj = getLatestProfilerEntry(testDB); - - assert.eq(profileObj.ns, coll.getFullName(), tojson(profileObj)); - assert.eq(profileObj.op, "command", tojson(profileObj)); - assert.eq(profileObj.keysExamined, 2, tojson(profileObj)); - assert.eq(profileObj.docsExamined, 2, tojson(profileObj)); - assert.eq(profileObj.planSummary, "IXSCAN { b: -1 }", tojson(profileObj)); - assert(profileObj.execStats.hasOwnProperty("stage"), tojson(profileObj)); - assert.eq(profileObj.protocol, getProfilerProtocolStringForCommand(conn), tojson(profileObj)); - assert.eq(profileObj.command.group.key, {a: 1, b: 1}, tojson(profileObj)); - assert.eq(profileObj.command.group.collation, {locale: "fr"}, tojson(profileObj)); - assert(profileObj.hasOwnProperty("responseLength"), tojson(profileObj)); - assert(profileObj.command.hasOwnProperty("group"), tojson(profileObj)); - assert(profileObj.hasOwnProperty("millis"), tojson(profileObj)); - assert(profileObj.hasOwnProperty("numYield"), tojson(profileObj)); - assert(profileObj.hasOwnProperty("locks"), tojson(profileObj)); - assert.eq(profileObj.appName, "MongoDB Shell", tojson(profileObj)); - - // - // Confirm "fromMultiPlanner" metric. - // - coll.drop(); - assert.commandWorked(coll.createIndex({a: 1})); - assert.commandWorked(coll.createIndex({b: 1})); - for (i = 0; i < 5; ++i) { - assert.writeOK(coll.insert({a: i, b: i})); - } - - coll.group({key: {a: 1, b: 1}, cond: {a: 3, b: 3}, reduce: function() {}, initial: {}}); - profileObj = getLatestProfilerEntry(testDB); - - assert.eq(profileObj.fromMultiPlanner, true, tojson(profileObj)); - assert.eq(profileObj.appName, "MongoDB Shell", tojson(profileObj)); -})(); diff --git a/jstests/core/txns/commands_not_allowed_in_txn.js b/jstests/core/txns/commands_not_allowed_in_txn.js index 6d7dc9fd0a6..47cda72b780 100644 --- a/jstests/core/txns/commands_not_allowed_in_txn.js +++ b/jstests/core/txns/commands_not_allowed_in_txn.js @@ -97,7 +97,6 @@ {"$eval": "function() {return 1;}"}, {filemd5: 1, root: "fs"}, {geoNear: collName, near: [0, 0]}, - {group: {ns: collName, key: {_id: 1}, $reduce: function(curr, result) {}, initial: {}}}, {mapReduce: collName, map: function() {}, reduce: function(key, vals) {}, out: "out"}, {parallelCollectionScan: collName, numCursors: 1}, {refreshLogicalSessionCacheNow: 1} diff --git a/jstests/core/txns/statement_ids_accepted.js b/jstests/core/txns/statement_ids_accepted.js index 75e71cdfbd9..0a27f3c0c6f 100644 --- a/jstests/core/txns/statement_ids_accepted.js +++ b/jstests/core/txns/statement_ids_accepted.js @@ -225,21 +225,6 @@ autocommit: false })); - jsTestLog("Check that group accepts a statement ID"); - assert.commandWorked(sessionDb.runCommand({ - group: { - ns: collName, - key: {a: 1}, - $reduce: function(curr, result) { - result.total += 1; - }, - initial: {total: 0} - }, - readConcern: {level: "snapshot"}, - txnNumber: NumberLong(txnNumber++), - stmtId: NumberInt(0) - })); - jsTestLog("Check that insert accepts a statement ID"); assert.commandWorked(sessionDb.runCommand({ insert: collName, diff --git a/jstests/core/views/views_all_commands.js b/jstests/core/views/views_all_commands.js index d641b30531b..a3b175f5b3a 100644 --- a/jstests/core/views/views_all_commands.js +++ b/jstests/core/views/views_all_commands.js @@ -317,9 +317,6 @@ grantPrivilegesToRole: {skip: "tested in auth/commands_user_defined_roles.js"}, grantRolesToRole: {skip: isUnrelated}, grantRolesToUser: {skip: isUnrelated}, - group: { - command: {group: {ns: "test.view", key: "x", $reduce: function() {}, initial: {}}}, - }, handshake: {skip: isUnrelated}, hostInfo: {skip: isUnrelated}, insert: {command: {insert: "view", documents: [{x: 1}]}, expectFailure: true}, diff --git a/jstests/libs/override_methods/set_read_and_write_concerns.js b/jstests/libs/override_methods/set_read_and_write_concerns.js index 3ff6618fc59..f3b95d68ec7 100644 --- a/jstests/libs/override_methods/set_read_and_write_concerns.js +++ b/jstests/libs/override_methods/set_read_and_write_concerns.js @@ -28,7 +28,6 @@ "find", "geoNear", "geoSearch", - "group", "parallelCollectionScan", ]); diff --git a/jstests/libs/override_methods/set_read_preference_secondary.js b/jstests/libs/override_methods/set_read_preference_secondary.js index a9479147435..4d743fe002c 100644 --- a/jstests/libs/override_methods/set_read_preference_secondary.js +++ b/jstests/libs/override_methods/set_read_preference_secondary.js @@ -16,7 +16,6 @@ "find", "geoNear", "geoSearch", - "group", "mapReduce", "mapreduce", "parallelCollectionScan", diff --git a/jstests/libs/parallelTester.js b/jstests/libs/parallelTester.js index 69eadd22a84..4e680f703b3 100644 --- a/jstests/libs/parallelTester.js +++ b/jstests/libs/parallelTester.js @@ -261,7 +261,6 @@ if (typeof _threadInject != "undefined") { parallelFilesDir + "/profile_findandmodify.js", parallelFilesDir + "/profile_geonear.js", parallelFilesDir + "/profile_getmore.js", - parallelFilesDir + "/profile_group.js", parallelFilesDir + "/profile_insert.js", parallelFilesDir + "/profile_list_collections.js", parallelFilesDir + "/profile_list_indexes.js", diff --git a/jstests/noPassthrough/commands_handle_kill.js b/jstests/noPassthrough/commands_handle_kill.js index 42e73ec8e56..f03e40036a1 100644 --- a/jstests/noPassthrough/commands_handle_kill.js +++ b/jstests/noPassthrough/commands_handle_kill.js @@ -185,9 +185,6 @@ if (${ canYield }) { } }); - assertCommandPropogatesPlanExecutorKillReason( - {group: {ns: collName, key: "_id", $reduce: function(curr, result) {}, initial: {}}}); - assertCommandPropogatesPlanExecutorKillReason({find: coll.getName(), filter: {}}); assertCommandPropogatesPlanExecutorKillReason( diff --git a/jstests/noPassthrough/commands_preserve_exec_error_code.js b/jstests/noPassthrough/commands_preserve_exec_error_code.js index b8bffb260ce..548a40fb7d7 100644 --- a/jstests/noPassthrough/commands_preserve_exec_error_code.js +++ b/jstests/noPassthrough/commands_preserve_exec_error_code.js @@ -36,15 +36,6 @@ assertFailsWithInternalError(() => coll.updateOne({_id: 1}, {$set: {x: 2}})); assertFailsWithInternalError(() => coll.deleteOne({_id: 1})); assertFailsWithInternalError(() => coll.count({_id: 1})); - assertFailsWithInternalError(() => coll.group({ - key: "_id", - cond: {}, - reduce: () => { - result.total += 1; - }, - initial: {total: 0} - }) - .itcount()); assertFailsWithInternalError(() => coll.aggregate([]).itcount()); assertCmdFailsWithInternalError({distinct: coll.getName(), key: "_id"}); assertCmdFailsWithInternalError({geoNear: coll.getName(), near: [0, 0]}); diff --git a/jstests/noPassthrough/currentop_query.js b/jstests/noPassthrough/currentop_query.js index c352204ad2e..2a24c3e378f 100644 --- a/jstests/noPassthrough/currentop_query.js +++ b/jstests/noPassthrough/currentop_query.js @@ -309,28 +309,6 @@ } ]; - // The 'group' command cannot be run on a sharded collection. - if (!FixtureHelpers.isMongos(coll.getDB())) { - testList.push({ - test: function(db) { - assert.eq(db.currentop_query.group({ - key: {a: 1}, - cond: {a: 1, $comment: "currentop_query"}, - reduce: function() {}, - initial: {}, - collation: {locale: "fr"} - }), - [{"a": 1}]); - }, - command: "group", - planSummary: "COLLSCAN", - currentOpFilter: { - "command.group.cond.$comment": "currentop_query", - "command.group.collation": {locale: "fr"} - } - }); - } - testList.forEach(confirmCurrentOpContents); // diff --git a/jstests/noPassthrough/global_operation_latency_histogram.js b/jstests/noPassthrough/global_operation_latency_histogram.js index 33cb7f0897e..3e5b4bcd8c8 100644 --- a/jstests/noPassthrough/global_operation_latency_histogram.js +++ b/jstests/noPassthrough/global_operation_latency_histogram.js @@ -90,10 +90,6 @@ } lastHistogram = checkHistogramDiff(numRecords, 0, 0); - // Group - testColl.group({initial: {}, reduce: function() {}, key: {a: 1}}); - lastHistogram = checkHistogramDiff(1, 0, 0); - // ParallelCollectionScan testDB.runCommand({parallelCollectionScan: testColl.getName(), numCursors: 5}); lastHistogram = checkHistogramDiff(0, 0, 1); diff --git a/jstests/noPassthrough/group_interrupt_js_execution.js b/jstests/noPassthrough/group_interrupt_js_execution.js deleted file mode 100644 index 2216bca11a5..00000000000 --- a/jstests/noPassthrough/group_interrupt_js_execution.js +++ /dev/null @@ -1,71 +0,0 @@ -// Test what happens when javascript execution inside the group command is interrupted, either from -// killOp, or due to timeout. -(function() { - const conn = MongoRunner.runMongod({}); - assert.neq(null, conn); - - const db = conn.getDB("test"); - const coll = db.group_with_stepdown; - const kFailPointName = "hangInGroupReduceJs"; - - assert.commandWorked(coll.insert({name: "bob", foo: 1})); - assert.commandWorked(coll.insert({name: "alice", foo: 1})); - assert.commandWorked(coll.insert({name: "fred", foo: 3})); - assert.commandWorked(coll.insert({name: "fred", foo: 4})); - - // Attempts to run the group command while the given failpoint is enabled. - let awaitShellFn = null; - try { - assert.commandWorked( - db.adminCommand({configureFailPoint: kFailPointName, mode: "alwaysOn"})); - - // Run a group in the background that will hang. - function runHangingGroup() { - const coll = db.group_with_stepdown; - - const err = assert.throws(() => coll.group({ - key: {foo: 1}, - initial: {count: 0}, - reduce: function(obj, prev) { - while (1) { - sleep(1000); - } - } - }), - [], - "expected group() to fail"); - - assert.eq(err.code, ErrorCodes.Interrupted); - } - awaitShellFn = startParallelShell(runHangingGroup, conn.port); - - // Wait until we know the failpoint has been reached. - let opid = null; - assert.soon(function() { - const arr = db.getSiblingDB("admin") - .aggregate([{$currentOp: {}}, {$match: {"msg": kFailPointName}}]) - .toArray(); - - if (arr.length == 0) { - return false; - } - - // Should never have more than one operation stuck on the failpoint. - assert.eq(arr.length, 1); - opid = arr[0].opid; - return true; - }); - - // Kill the group(). - assert.neq(opid, null); - assert.commandWorked(db.killOp(opid)); - } finally { - assert.commandWorked(db.adminCommand({configureFailPoint: kFailPointName, mode: "off"})); - - if (awaitShellFn) { - awaitShellFn(); - } - } - - assert.eq(0, MongoRunner.stopMongod(conn), "expected mongod to shutdown cleanly"); -})(); diff --git a/jstests/noPassthrough/log_format_slowms_samplerate_loglevel.js b/jstests/noPassthrough/log_format_slowms_samplerate_loglevel.js index 37afb165dd8..2344eae50a1 100644 --- a/jstests/noPassthrough/log_format_slowms_samplerate_loglevel.js +++ b/jstests/noPassthrough/log_format_slowms_samplerate_loglevel.js @@ -337,29 +337,6 @@ } ]; - // The 'group' command cannot be run on a sharded collection. - if (!isMongos) { - testList.push({ - test: function(db) { - assert.eq(db.test.group({ - key: {a: 1}, - cond: {a: 1, $comment: logFormatTestComment}, - reduce: function() {}, - initial: {}, - collation: {locale: "fr"} - }), - [{"a": 1}]); - }, - logFields: { - command: "group", - key: {a: 1}, - planSummary: "COLLSCAN", - cond: {a: 1, $comment: logFormatTestComment}, - collation: {locale: "fr"} - } - }); - } - // Confirm log contains collation for find command. if (readWriteMode === "commands") { testList.push({ diff --git a/jstests/noPassthrough/readConcern_snapshot.js b/jstests/noPassthrough/readConcern_snapshot.js index 20e0aaa2bd9..023eca5873f 100644 --- a/jstests/noPassthrough/readConcern_snapshot.js +++ b/jstests/noPassthrough/readConcern_snapshot.js @@ -150,24 +150,14 @@ // TODO: SERVER-34113 Remove this test when we completely remove snapshot // reads since this command is not supported with transaction api. - // readConcern 'snapshot' is supported by group. + // readConcern 'snapshot' is supported by geoNear. session = rst.getPrimary().getDB(dbName).getMongo().startSession({causalConsistency: false}); sessionDb = session.getDatabase(dbName); - let txnNumber = 0; - assert.commandWorked(sessionDb.runCommand({ - group: {ns: collName, key: {_id: 1}, $reduce: function(curr, result) {}, initial: {}}, - readConcern: {level: "snapshot"}, - txnNumber: NumberLong(txnNumber++) - })); - - // TODO: SERVER-34113 Remove this test when we completely remove snapshot - // reads since this command is not supported with transaction api. - // readConcern 'snapshot' is supported by geoNear. assert.commandWorked(sessionDb.runCommand({ geoNear: collName, near: [0, 0], readConcern: {level: "snapshot"}, - txnNumber: NumberLong(txnNumber++) + txnNumber: NumberLong(0), })); session.endSession(); diff --git a/jstests/noPassthrough/readConcern_snapshot_mongos.js b/jstests/noPassthrough/readConcern_snapshot_mongos.js index 6d5d4b7d342..2d780eec4d5 100644 --- a/jstests/noPassthrough/readConcern_snapshot_mongos.js +++ b/jstests/noPassthrough/readConcern_snapshot_mongos.js @@ -134,7 +134,6 @@ }), ErrorCodes.InvalidOptions); - // TODO SERVER-33354: Add snapshot support for distinct on mongod. // TODO SERVER-33710: Add snapshot support for distinct on mongos. assert.commandFailedWithCode(sessionDb.runCommand({ distinct: collName, @@ -144,7 +143,6 @@ }), ErrorCodes.InvalidOptions); - // TODO SERVER-33354: Add snapshot support for geoNear on mongod. // TODO SERVER-33712: Add snapshot support for geoNear on mongos. assert.commandFailedWithCode(sessionDb.runCommand({ geoNear: collName, @@ -154,14 +152,5 @@ }), ErrorCodes.InvalidOptions); - // TODO SERVER-33354: Add snapshot support for group on mongod. - // TODO SERVER-33711: Add snapshot support for group on mongos. - assert.commandFailedWithCode(sessionDb.runCommand({ - group: {ns: collName, key: {_id: 1}, $reduce: function(curr, result) {}, initial: {}}, - readConcern: {level: "snapshot"}, - txnNumber: NumberLong(txnNumber++) - }), - ErrorCodes.InvalidOptions); - st.stop(); }()); diff --git a/jstests/noPassthrough/read_concern_snapshot_yielding.js b/jstests/noPassthrough/read_concern_snapshot_yielding.js index 98030280298..90d55560c97 100644 --- a/jstests/noPassthrough/read_concern_snapshot_yielding.js +++ b/jstests/noPassthrough/read_concern_snapshot_yielding.js @@ -303,21 +303,6 @@ assert.eq(res.values.length, 4, tojson(res)); }, {"command.distinct": "coll"}); - // TODO: SERVER-34113 Remove this test when we completely remove snapshot - // reads since this command is not supported with transaction api. - // Test group. - testCommand(function() { - const sessionId = db.getMongo().startSession({causalConsistency: false}).getSessionId(); - const res = assert.commandWorked(db.runCommand({ - group: {ns: "coll", key: {_id: 1}, $reduce: function(curr, result) {}, initial: {}}, - readConcern: {level: "snapshot"}, - lsid: sessionId, - txnNumber: NumberLong(0) - })); - assert(res.hasOwnProperty("count"), tojson(res)); - assert.eq(res.count, 4); - }, {"command.group.ns": "coll"}); - // Test update. testCommand(function() { const session = db.getMongo().startSession({causalConsistency: false}); diff --git a/jstests/noPassthrough/read_majority_reads.js b/jstests/noPassthrough/read_majority_reads.js index 1f196856dd7..eec0ddc80cb 100644 --- a/jstests/noPassthrough/read_majority_reads.js +++ b/jstests/noPassthrough/read_majority_reads.js @@ -5,7 +5,6 @@ * - find command * - aggregation * - distinct - * - group * - count * - parallelCollectionScan * - geoNear @@ -131,26 +130,6 @@ expectedBefore: 'before', expectedAfter: 'after', }, - group: { - run: function(coll) { - var res = coll.runCommand({ - 'group': { - ns: coll.getName(), - key: {_id: 1}, - initial: {}, - $reduce: function(curr, result) { - result.state = curr.state; - }, - }, - readConcern: {level: 'majority'}, - }); - assert.commandWorked(res); - assert.eq(res.retval.length, 1, tojson(res)); - return res.retval[0].state; - }, - expectedBefore: 'before', - expectedAfter: 'after', - }, }; function runTests(coll, mongodConnection) { @@ -276,13 +255,6 @@ var db = shardingTest.getDB("throughMongos"); var collection = db.shardedCollection; shardingTest.adminCommand({shardCollection: collection.getFullName(), key: {_id: 1}}); - - // The group command isn't supported on sharded collections. It also uses a weird syntax so - // code to check that it isn't supported can't be reused with other commands. - assert.eq(collection.runCommand({'group': {ns: collection.getName()}}).code, - ErrorCodes.IllegalOperation); - delete nonCursorTestCases.group; - runTests(collection, mongod); })(); diff --git a/jstests/noPassthrough/shell_can_use_read_concern.js b/jstests/noPassthrough/shell_can_use_read_concern.js index 65cf66c06cc..b20bb6eeb80 100644 --- a/jstests/noPassthrough/shell_can_use_read_concern.js +++ b/jstests/noPassthrough/shell_can_use_read_concern.js @@ -223,35 +223,6 @@ }); // - // Tests for the "group" command. - // - - testCommandCanBeCausallyConsistent(function() { - const res = assert.commandWorked(db.runCommand({ - group: { - ns: coll.getName(), - key: {x: 1}, - $reduce: function(curr, result) { - ++result.total; - }, - initial: {total: 0} - } - })); - assert.eq([{x: null, total: 5}], res.retval, tojson(res)); - }); - - testCommandCanBeCausallyConsistent(function() { - const res = coll.group({ - key: {x: 1}, - $reduce: function(curr, result) { - ++result.total; - }, - initial: {total: 0} - }); - assert.eq([{x: null, total: 5}], res); - }); - - // // Tests for the "geoNear" command. // diff --git a/jstests/noPassthrough/yield_group.js b/jstests/noPassthrough/yield_group.js deleted file mode 100644 index 4304f326bb7..00000000000 --- a/jstests/noPassthrough/yield_group.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Test that the "group" command yields periodically (SERVER-1395). - */ -(function() { - 'use strict'; - - const nDocsToInsert = 300; - const worksPerYield = 50; - - // Start a mongod that will yield every 50 work cycles. - var conn = - MongoRunner.runMongod({setParameter: `internalQueryExecYieldIterations=${worksPerYield}`}); - assert.neq(null, conn, 'mongod was unable to start up'); - - var coll = conn.getDB('test').yield_group; - - var bulk = coll.initializeUnorderedBulkOp(); - for (var i = 0; i < nDocsToInsert; ++i) { - bulk.insert({_id: i}); - } - - var res = bulk.execute(); - assert.writeOK(res); - assert.eq(nDocsToInsert, res.nInserted, tojson(res)); - - // A "group" command performing a collection scan should yield approximately - // nDocsToInsert / worksPerYield times. - var explain = - coll.explain('executionStats').group({key: {_id: 1}, reduce: function() {}, initial: {}}); - var numYields = explain.executionStats.executionStages.saveState; - assert.gt(numYields, (nDocsToInsert / worksPerYield) - 2, tojson(explain)); - MongoRunner.stopMongod(conn); -})(); diff --git a/jstests/replsets/groupAndMapReduce.js b/jstests/replsets/groupAndMapReduce.js index 10f15d6f538..6dfbe3047fc 100644 --- a/jstests/replsets/groupAndMapReduce.js +++ b/jstests/replsets/groupAndMapReduce.js @@ -46,34 +46,6 @@ doTest = function(signal) { var one = slave.getDB("foo").foo.findOne(); printjson(one); - // stats = slave.getDB("foo").adminCommand({replSetGetStatus:1}); - // printjson(stats); - - print("Calling group() with slaveOk=true, must succeed"); - slave.slaveOk = true; - count = slave.getDB("foo").foo.group({ - initial: {n: 0}, - reduce: function(obj, out) { - out.n++; - } - }); - printjson(count); - assert.eq(len, count[0].n, "slave group count wrong: " + slave); - - print("Calling group() with slaveOk=false, must fail"); - slave.slaveOk = false; - try { - count = slave.getDB("foo").foo.group({ - initial: {n: 0}, - reduce: function(obj, out) { - out.n++; - } - }); - assert(false, "group() succeeded with slaveOk=false"); - } catch (e) { - print("Received exception: " + e); - } - print("Calling inline mr() with slaveOk=true, must succeed"); slave.slaveOk = true; map = function() { diff --git a/jstests/replsets/maintenance2.js b/jstests/replsets/maintenance2.js index b2a1dbec38c..8dd17e61a37 100644 --- a/jstests/replsets/maintenance2.js +++ b/jstests/replsets/maintenance2.js @@ -39,18 +39,6 @@ var stats = slave.getDB("foo").adminCommand({replSetGetStatus: 1}); assert.eq(stats.myState, 3, "Slave should be in recovering state."); - print("group should fail in recovering state..."); - slave.slaveOk = true; - assert.commandFailed(slave.getDB("foo").foo.runCommand({ - group: { - ns: "foo", - initial: {n: 0}, - $reduce: function(obj, out) { - out.n++; - } - } - })); - print("count should fail in recovering state..."); slave.slaveOk = true; assert.commandFailed(slave.getDB("foo").runCommand({count: "foo"})); diff --git a/jstests/sharding/database_and_shard_versioning_all_commands.js b/jstests/sharding/database_and_shard_versioning_all_commands.js index 65fdb8ab2e4..5ffc2abb8d3 100644 --- a/jstests/sharding/database_and_shard_versioning_all_commands.js +++ b/jstests/sharding/database_and_shard_versioning_all_commands.js @@ -255,14 +255,6 @@ grantPrivilegesToRole: {skip: "always targets the config server"}, grantRolesToRole: {skip: "always targets the config server"}, grantRolesToUser: {skip: "always targets the config server"}, - group: { - sendsDbVersion: false, - sendsShardVersion: true, - command: { - group: - {ns: collName, key: {x: 1}, $reduce: function(curr, result) {}, initial: {}} - }, - }, hostInfo: {skip: "executes locally on mongos (not sent to any remote node)"}, insert: { sendsDbVersion: false, diff --git a/jstests/sharding/explain_cmd.js b/jstests/sharding/explain_cmd.js index 0b5dcf8bf30..dece5acff72 100644 --- a/jstests/sharding/explain_cmd.js +++ b/jstests/sharding/explain_cmd.js @@ -73,44 +73,6 @@ } assert.eq(3, collUnsharded.count({b: 1})); - explain = db.runCommand({ - explain: { - group: { - ns: collUnsharded.getName(), - key: "a", - cond: "b", - $reduce: function(curr, result) {}, - initial: {} - } - }, - verbosity: "allPlansExecution" - }); - - // Basic validation: a group command can only be passed through to an unsharded collection, - // so we should confirm that the mongos stage is always SINGLE_SHARD. - printjson(explain); - assert.commandWorked(explain); - assert("queryPlanner" in explain); - assert("executionStats" in explain); - assert.eq("SINGLE_SHARD", explain.queryPlanner.winningPlan.stage); - - // The same group should fail over the sharded collection, because group is only supported - // if it is passed through to an unsharded collection. - explain = db.runCommand({ - explain: { - group: { - ns: collSharded.getName(), - key: "a", - cond: "b", - $reduce: function(curr, result) {}, - initial: {} - } - }, - verbosity: "allPlansExecution" - }); - printjson(explain); - assert.commandFailed(explain); - // ------- // Explain a delete operation and verify that it hits all shards without the shard key diff --git a/jstests/sharding/explain_read_pref.js b/jstests/sharding/explain_read_pref.js index c4131a9b6f4..e84393607d3 100644 --- a/jstests/sharding/explain_read_pref.js +++ b/jstests/sharding/explain_read_pref.js @@ -82,10 +82,6 @@ var testAllModes = function(conn, isMongos) { explain = testDB.user.explain().distinct("_id"); assertCorrectTargeting(explain, isMongos, secExpected); - // .explain().group() - explain = testDB.user.explain().group( - {key: {_id: 1}, reduce: function(curr, result) {}, initial: {}}); - assertCorrectTargeting(explain, isMongos, secExpected); } finally { // Restore old read pref. testDB.getMongo().setReadPref(oldReadPrefMode, oldReadPrefTagSet); diff --git a/jstests/sharding/features1.js b/jstests/sharding/features1.js index 0a31b5c94c9..ec2ae0b7068 100644 --- a/jstests/sharding/features1.js +++ b/jstests/sharding/features1.js @@ -172,53 +172,6 @@ var res = s.admin.runCommand({shardcollection: "test.foo5", key: {num: 1}}); assert(!res.ok, "shard capped: " + tojson(res)); - // ----- group ---- - - db.foo6.save({a: 1}); - db.foo6.save({a: 3}); - db.foo6.save({a: 3}); - db.foo6.ensureIndex({a: 1}); - s.sync(); - printjson(db.foo6.getIndexes()); - - assert.eq(2, - db.foo6 - .group({ - key: {a: 1}, - initial: {count: 0}, - reduce: function(z, prev) { - prev.count++; - } - }) - .length); - - assert.eq(3, db.foo6.find().count()); - assert(s.admin.runCommand({shardcollection: "test.foo6", key: {a: 1}}).ok); - assert.eq(3, db.foo6.find().count()); - - s.adminCommand({split: "test.foo6", middle: {a: 2}}); - - // movechunk commands are wrapped in assert.soon - // Sometimes the TO-side shard isn't immediately ready, this - // causes problems on slow hosts. - // Remove when SERVER-10232 is fixed - - assert.soon(function() { - var cmdRes = s.admin.runCommand( - {movechunk: "test.foo6", find: {a: 3}, to: s.getOther(s.getPrimaryShard("test")).name}); - return cmdRes.ok; - }, 'move chunk test.foo6', 60000, 1000); - - assert.throws(function() { - db.foo6.group({ - key: {a: 1}, - initial: {count: 0}, - reduce: function(z, prev) { - prev.count++; - } - }); - }); - // ---- can't shard non-empty collection without index ----- assert.writeOK(db.foo8.save({a: 1})); diff --git a/jstests/sharding/group_slaveok.js b/jstests/sharding/group_slaveok.js deleted file mode 100644 index 3fb3d6272ae..00000000000 --- a/jstests/sharding/group_slaveok.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Tests group using slaveOk. - */ - -// Checking UUID consistency involves talking to a shard node, which in this test is shutdown -TestData.skipCheckingUUIDsConsistentAcrossCluster = true; - -(function() { - 'use strict'; - - load("jstests/replsets/rslib.js"); - - var st = new ShardingTest({shards: 1, mongos: 1, other: {rs: true, rs0: {nodes: 2}}}); - var rst = st.rs0; - - // Insert data into replica set - var conn = new Mongo(st.s.host); - - var coll = conn.getCollection("test.groupSlaveOk"); - coll.drop(); - - var bulk = coll.initializeUnorderedBulkOp(); - for (var i = 0; i < 300; i++) { - bulk.insert({i: i % 10}); - } - assert.writeOK(bulk.execute()); - - // Wait for client to update itself and replication to finish - rst.awaitReplication(); - - var primary = rst.getPrimary(); - var sec = rst.getSecondary(); - - // Data now inserted... stop the master, since only two in set, other will still be secondary - rst.stop(rst.getPrimary()); - printjson(rst.status()); - - // Wait for the mongos to recognize the slave - awaitRSClientHosts(conn, sec, {ok: true, secondary: true}); - - // Need to check slaveOk=true first, since slaveOk=false will destroy conn in pool when - // master is down - conn.setSlaveOk(); - - // Should not throw exception, since slaveOk'd - assert.eq(10, - coll.group({ - key: {i: true}, - reduce: function(obj, ctx) { - ctx.count += 1; - }, - initial: {count: 0} - }) - .length); - - try { - conn.setSlaveOk(false); - var res = coll.group({ - key: {i: true}, - reduce: function(obj, ctx) { - ctx.count += 1; - }, - initial: {count: 0} - }); - - print("Should not reach here! Group result: " + tojson(res)); - assert(false); - } catch (e) { - print("Non-slaveOk'd connection failed." + tojson(e)); - } - - st.stop(); -})(); diff --git a/jstests/sharding/migrateBig_balancer.js b/jstests/sharding/migrateBig_balancer.js index 2d28244cba7..0b0b231afb7 100644 --- a/jstests/sharding/migrateBig_balancer.js +++ b/jstests/sharding/migrateBig_balancer.js @@ -46,16 +46,13 @@ assert.lt( 5, mongos.getDB("config").chunks.find({ns: "test.stuff"}).count(), "not enough chunks"); - assert.soon(function() { - var res = mongos.getDB("config").chunks.group({ - cond: {ns: "test.stuff"}, - key: {shard: 1}, - reduce: function(doc, out) { - out.nChunks++; - }, - initial: {nChunks: 0} - }); - + assert.soon(() => { + let res = + mongos.getDB("config") + .chunks + .aggregate( + [{$match: {ns: "test.stuff"}}, {$group: {_id: "$shard", nChunks: {$sum: 1}}}]) + .toArray(); printjson(res); return res.length > 1 && Math.abs(res[0].nChunks - res[1].nChunks) <= 3; diff --git a/jstests/sharding/not_allowed_on_sharded_collection_cmd.js b/jstests/sharding/not_allowed_on_sharded_collection_cmd.js index 8c63ad954ee..3784eec3ace 100644 --- a/jstests/sharding/not_allowed_on_sharded_collection_cmd.js +++ b/jstests/sharding/not_allowed_on_sharded_collection_cmd.js @@ -27,8 +27,6 @@ // Test that commands that should not work on sharded collections work on unsharded // collections. - assert.commandWorked(staleMongos.runCommand( - {group: {ns: coll1, key: {_id: 1}, $reduce: function(curr, result) {}, initial: {}}})); assert.commandWorked(staleMongos.runCommand({convertToCapped: coll2, size: 64 * 1024})); // Attempt to shard the collections. coll1 should be able to be sharded, whereas coll2 should @@ -38,15 +36,6 @@ // Test that commands that should not be runnable on sharded collection do not work on sharded // collections, using both fresh mongos and stale mongos instances. - assert.commandFailedWithCode( - freshMongos.runCommand( - {group: {ns: coll1, key: {_id: 1}, $reduce: function(curr, result) {}, initial: {}}}), - ErrorCodes.IllegalOperation); - assert.commandFailedWithCode( - staleMongos.runCommand( - {group: {ns: coll1, key: {_id: 1}, $reduce: function(curr, result) {}, initial: {}}}), - ErrorCodes.IllegalOperation); - assert.commandFailedWithCode(freshMongos.runCommand({convertToCapped: coll1, size: 64 * 1024}), ErrorCodes.IllegalOperation); assert.commandFailedWithCode(staleMongos.runCommand({convertToCapped: coll1, size: 32 * 1024}), diff --git a/jstests/sharding/query_config.js b/jstests/sharding/query_config.js index 4b0761790d4..cb3387a8068 100644 --- a/jstests/sharding/query_config.js +++ b/jstests/sharding/query_config.js @@ -233,22 +233,6 @@ // Distinct query. assert.eq(configDB.chunks.distinct("shard").sort(), [shard1, shard2]); - // Group query. - result = configDB.chunks.group({ - key: {shard: 1}, - cond: {ns: testColl.getFullName()}, - reduce: function(curr, res) { - res.chunks++; - }, - initial: {chunks: 0}, - finalize: function(res) { - res._id = res.shard; - } - }); - assert.eq( - sortArrayById(result), - [{shard: shard1, chunks: 2, _id: shard1}, {shard: shard2, chunks: 3, _id: shard2}]); - // Map reduce query. var mapFunction = function() { if (this.ns == "test2.testColl") { @@ -343,20 +327,6 @@ // Distinct query. assert.eq(userColl.distinct("g").sort(), [1, 2, 3]); - // Group query. - result = userColl.group({ - key: {g: 1}, - reduce: function(curr, res) { - res.prod *= curr.c; - }, - initial: {prod: 1}, - finalize: function(res) { - res._id = res.g; - } - }); - assert.eq(sortArrayById(result), - [{g: 1, prod: 20, _id: 1}, {g: 2, prod: 288, _id: 2}, {g: 3, prod: 22, _id: 3}]); - // Map reduce query. var mapFunction = function() { emit(this.g, 1); diff --git a/jstests/sharding/read_pref_cmd.js b/jstests/sharding/read_pref_cmd.js index 099630fa5c3..2c3e3e2f95e 100644 --- a/jstests/sharding/read_pref_cmd.js +++ b/jstests/sharding/read_pref_cmd.js @@ -158,10 +158,6 @@ var testReadPreference = function(conn, hostList, isMongos, mode, tagSets, secEx // Test other commands that can be sent to secondary. cmdTest({count: 'user'}, true, formatProfileQuery({count: 'user'})); - cmdTest({group: {key: {x: true}, '$reduce': function(a, b) {}, ns: 'mrIn', initial: {x: 0}}}, - true, - formatProfileQuery({'group.ns': 'mrIn'})); - cmdTest({collStats: 'user'}, true, formatProfileQuery({count: 'user'})); cmdTest({dbStats: 1}, true, formatProfileQuery({dbStats: 1})); diff --git a/jstests/sharding/safe_secondary_reads_drop_recreate.js b/jstests/sharding/safe_secondary_reads_drop_recreate.js index 8be8fb2fd7f..b687586816b 100644 --- a/jstests/sharding/safe_secondary_reads_drop_recreate.js +++ b/jstests/sharding/safe_secondary_reads_drop_recreate.js @@ -199,20 +199,6 @@ grantPrivilegesToRole: {skip: "primary only"}, grantRolesToRole: {skip: "primary only"}, grantRolesToUser: {skip: "primary only"}, - group: { - setUp: function(mongosConn) { - assert.writeOK(mongosConn.getCollection(nss).insert({x: 1, y: 1})); - assert.writeOK(mongosConn.getCollection(nss).insert({x: 1, y: 1})); - assert.writeOK(mongosConn.getCollection(nss).insert({x: 2, y: 1})); - assert.writeOK(mongosConn.getCollection(nss).insert({x: 2, y: 1})); - }, - command: {group: {ns: coll, key: {x: 1}}}, - checkResults: function(res) { - // Expect the command to fail, since it cannot run on sharded collections. - assert.commandFailedWithCode(res, ErrorCodes.IllegalOperation, tojson(res)); - }, - behavior: "unshardedOnly" - }, handshake: {skip: "does not return user data"}, hostInfo: {skip: "does not return user data"}, insert: {skip: "primary only"}, diff --git a/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js b/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js index a3b3d9709f8..e51585e26c0 100644 --- a/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js +++ b/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js @@ -239,24 +239,6 @@ grantPrivilegesToRole: {skip: "primary only"}, grantRolesToRole: {skip: "primary only"}, grantRolesToUser: {skip: "primary only"}, - group: { - setUp: function(mongosConn) { - assert.writeOK(mongosConn.getCollection(nss).insert({x: 1, y: 1})); - assert.writeOK(mongosConn.getCollection(nss).insert({x: 1, y: 1})); - assert.writeOK(mongosConn.getCollection(nss).insert({x: 2, y: 1})); - assert.writeOK(mongosConn.getCollection(nss).insert({x: 2, y: 1})); - }, - command: {group: {ns: coll, key: {x: 1}}}, - checkResults: function(res) { - // Expect the command to fail, since it cannot run on sharded collections. - assert.commandFailedWithCode(res, ErrorCodes.IllegalOperation, tojson(res)); - }, - checkAvailableReadConcernResults: function(res) { - // Expect the command to fail, since it cannot run on sharded collections. - assert.commandFailedWithCode(res, ErrorCodes.IllegalOperation, tojson(res)); - }, - behavior: "unshardedOnly" - }, handshake: {skip: "does not return user data"}, hostInfo: {skip: "does not return user data"}, insert: {skip: "primary only"}, diff --git a/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js b/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js index d59eb48b653..9611135a6ac 100644 --- a/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js +++ b/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js @@ -203,20 +203,6 @@ grantPrivilegesToRole: {skip: "primary only"}, grantRolesToRole: {skip: "primary only"}, grantRolesToUser: {skip: "primary only"}, - group: { - setUp: function(mongosConn) { - assert.writeOK(mongosConn.getCollection(nss).insert({x: 1, y: 1})); - assert.writeOK(mongosConn.getCollection(nss).insert({x: 1, y: 1})); - assert.writeOK(mongosConn.getCollection(nss).insert({x: 2, y: 1})); - assert.writeOK(mongosConn.getCollection(nss).insert({x: 2, y: 1})); - }, - command: {group: {ns: coll, key: {x: 1}}}, - checkResults: function(res) { - // Expect the command to fail, since it cannot run on sharded collections. - assert.commandFailedWithCode(res, ErrorCodes.IllegalOperation, tojson(res)); - }, - behavior: "unshardedOnly" - }, handshake: {skip: "does not return user data"}, hostInfo: {skip: "does not return user data"}, insert: {skip: "primary only"}, diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index dbf3eb40306..c9dafe6bc9a 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -927,7 +927,6 @@ env.Library( 'exec/eof.cpp', 'exec/fetch.cpp', 'exec/geo_near.cpp', - 'exec/group.cpp', 'exec/idhack.cpp', 'exec/index_iterator.cpp', 'exec/index_scan.cpp', diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index cbf9fd55bd9..b20118f6ff6 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -275,7 +275,6 @@ env.Library( "do_txn_cmd.cpp", "driverHelpers.cpp", "eval.cpp", - "group_cmd.cpp", "haystack.cpp", "mr.cpp", "oplog_application_checks.cpp", diff --git a/src/mongo/db/commands/group_cmd.cpp b/src/mongo/db/commands/group_cmd.cpp deleted file mode 100644 index 77e5e8e62b5..00000000000 --- a/src/mongo/db/commands/group_cmd.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/** - * Copyright (C) 2014 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::kCommand - -#include "mongo/platform/basic.h" - -#include "mongo/bson/util/bson_extract.h" -#include "mongo/db/auth/action_set.h" -#include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_session.h" -#include "mongo/db/auth/privilege.h" -#include "mongo/db/catalog/collection.h" -#include "mongo/db/client.h" -#include "mongo/db/commands.h" -#include "mongo/db/db_raii.h" -#include "mongo/db/exec/group.h" -#include "mongo/db/exec/working_set_common.h" -#include "mongo/db/namespace_string.h" -#include "mongo/db/query/find_common.h" -#include "mongo/db/query/get_executor.h" -#include "mongo/db/query/plan_summary_stats.h" -#include "mongo/util/log.h" - -namespace mongo { - -using std::unique_ptr; -using std::string; - -namespace { - -/** - * The group command is deprecated. Users should prefer the aggregation framework or mapReduce. See - * http://dochub.mongodb.org/core/group-command-deprecation for more detail. - */ -class GroupCommand : public BasicCommand { -public: - GroupCommand() : BasicCommand("group") {} - -private: - virtual bool supportsWriteConcern(const BSONObj& cmd) const override { - return false; - } - - virtual bool maintenanceOk() const { - return false; - } - - AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { - return AllowedOnSecondary::kOptIn; - } - - bool supportsReadConcern(const std::string& dbName, - const BSONObj& cmdObj, - repl::ReadConcernLevel level) const final { - return true; - } - - ReadWriteType getReadWriteType() const { - return ReadWriteType::kRead; - } - - std::size_t reserveBytesForReply() const override { - return FindCommon::kInitReplyBufferSize; - } - - std::string help() const override { - return "http://dochub.mongodb.org/core/aggregation"; - } - - virtual Status checkAuthForCommand(Client* client, - const std::string& dbname, - const BSONObj& cmdObj) const { - const NamespaceString nss(parseNs(dbname, cmdObj)); - - if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnNamespace( - nss, ActionType::find)) { - return Status(ErrorCodes::Unauthorized, "unauthorized"); - } - return Status::OK(); - } - - virtual std::string parseNs(const std::string& dbname, const BSONObj& cmdObj) const { - const auto nsElt = cmdObj.firstElement().embeddedObjectUserCheck()["ns"]; - uassert(ErrorCodes::InvalidNamespace, - "'ns' must be of type String", - nsElt.type() == BSONType::String); - const NamespaceString nss(dbname, nsElt.valueStringData()); - uassert(ErrorCodes::InvalidNamespace, - str::stream() << "Invalid namespace: " << nss.ns(), - nss.isValid()); - return nss.ns(); - } - - Status explain(OperationContext* opCtx, - const OpMsgRequest& request, - ExplainOptions::Verbosity verbosity, - BSONObjBuilder* out) const override { - std::string dbname = request.getDatabase().toString(); - const BSONObj& cmdObj = request.body; - GroupRequest groupRequest; - Status parseRequestStatus = _parseRequest(dbname, cmdObj, &groupRequest); - if (!parseRequestStatus.isOK()) { - return parseRequestStatus; - } - - groupRequest.explain = true; - - AutoGetCollectionForReadCommand ctx(opCtx, groupRequest.ns); - Collection* coll = ctx.getCollection(); - - auto statusWithPlanExecutor = getExecutorGroup(opCtx, coll, groupRequest); - if (!statusWithPlanExecutor.isOK()) { - return statusWithPlanExecutor.getStatus(); - } - - auto planExecutor = std::move(statusWithPlanExecutor.getValue()); - - Explain::explainStages(planExecutor.get(), coll, verbosity, out); - return Status::OK(); - } - - virtual bool run(OperationContext* opCtx, - const std::string& dbname, - const BSONObj& cmdObj, - BSONObjBuilder& result) { - RARELY { - warning() << "The group command is deprecated. See " - "http://dochub.mongodb.org/core/group-command-deprecation."; - } - - GroupRequest groupRequest; - Status parseRequestStatus = _parseRequest(dbname, cmdObj, &groupRequest); - uassertStatusOK(parseRequestStatus); - - AutoGetCollectionForReadCommand ctx(opCtx, groupRequest.ns); - Collection* coll = ctx.getCollection(); - - auto statusWithPlanExecutor = getExecutorGroup(opCtx, coll, groupRequest); - uassertStatusOK(statusWithPlanExecutor.getStatus()); - - auto planExecutor = std::move(statusWithPlanExecutor.getValue()); - - auto curOp = CurOp::get(opCtx); - { - stdx::lock_guard<Client> lk(*opCtx->getClient()); - curOp->setPlanSummary_inlock(Explain::getPlanSummary(planExecutor.get())); - } - - // Group executors return ADVANCED exactly once, with the entire group result. - BSONObj retval; - PlanExecutor::ExecState state = planExecutor->getNext(&retval, NULL); - if (PlanExecutor::ADVANCED != state) { - invariant(PlanExecutor::FAILURE == state || PlanExecutor::DEAD == state); - - uassertStatusOK(WorkingSetCommon::getMemberObjectStatus(retval).withContext( - "Plan executor error during group command")); - } - - invariant(planExecutor->isEOF()); - - PlanSummaryStats summaryStats; - Explain::getSummaryStats(*planExecutor, &summaryStats); - if (coll) { - coll->infoCache()->notifyOfQuery(opCtx, summaryStats.indexesUsed); - } - curOp->debug().setPlanSummaryMetrics(summaryStats); - - if (curOp->shouldDBProfile()) { - BSONObjBuilder execStatsBob; - Explain::getWinningPlanStats(planExecutor.get(), &execStatsBob); - curOp->debug().execStats = execStatsBob.obj(); - } - - invariant(STAGE_GROUP == planExecutor->getRootStage()->stageType()); - GroupStage* groupStage = static_cast<GroupStage*>(planExecutor->getRootStage()); - const GroupStats* groupStats = - static_cast<const GroupStats*>(groupStage->getSpecificStats()); - const CommonStats* groupChildStats = groupStage->getChildren()[0]->getCommonStats(); - - result.appendArray("retval", retval); - result.append("count", static_cast<long long>(groupChildStats->advanced)); - result.append("keys", static_cast<long long>(groupStats->nGroups)); - - return true; - } - -private: - /** - * Parse a group command object. - * - * If 'cmdObj' is well-formed, returns Status::OK() and fills in out-argument 'request'. - * - * If a parsing error is encountered, returns an error Status. - */ - Status _parseRequest(const std::string& dbname, - const BSONObj& cmdObj, - GroupRequest* request) const { - request->ns = NamespaceString(parseNs(dbname, cmdObj)); - - // By default, group requests are regular group not explain of group. - request->explain = false; - - const BSONObj& p = cmdObj.firstElement().embeddedObjectUserCheck(); - - if (p["cond"].type() == Object) { - request->query = p["cond"].embeddedObject().getOwned(); - } else if (p["condition"].type() == Object) { - request->query = p["condition"].embeddedObject().getOwned(); - } else if (p["query"].type() == Object) { - request->query = p["query"].embeddedObject().getOwned(); - } else if (p["q"].type() == Object) { - request->query = p["q"].embeddedObject().getOwned(); - } - - if (p["key"].type() == Object) { - request->keyPattern = p["key"].embeddedObjectUserCheck().getOwned(); - if (!p["$keyf"].eoo()) { - return Status(ErrorCodes::BadValue, "can't have key and $keyf"); - } - } else if (!p["$keyf"].eoo()) { - request->keyFunctionCode = p["$keyf"]._asCode(); - } else { - // No key specified. Use the entire object as the key. - } - - BSONElement collationElt; - Status collationEltStatus = - bsonExtractTypedField(p, "collation", BSONType::Object, &collationElt); - if (!collationEltStatus.isOK() && (collationEltStatus != ErrorCodes::NoSuchKey)) { - return collationEltStatus; - } - if (collationEltStatus.isOK()) { - request->collation = collationElt.embeddedObject().getOwned(); - } - - BSONElement reduce = p["$reduce"]; - if (reduce.eoo()) { - return Status(ErrorCodes::BadValue, "$reduce has to be set"); - } - request->reduceCode = reduce._asCode(); - - if (reduce.type() == CodeWScope) { - request->reduceScope = reduce.codeWScopeObject().getOwned(); - } - - if (p["initial"].type() != Object) { - return Status(ErrorCodes::BadValue, "initial has to be an object"); - } - request->initial = p["initial"].embeddedObject().getOwned(); - - if (!p["finalize"].eoo()) { - request->finalize = p["finalize"]._asCode(); - } - - return Status::OK(); - } - -} cmdGroup; - -} // namespace -} // namespace mongo diff --git a/src/mongo/db/exec/group.cpp b/src/mongo/db/exec/group.cpp deleted file mode 100644 index fcb2fef78c3..00000000000 --- a/src/mongo/db/exec/group.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/** - * Copyright (C) 2014 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/db/exec/group.h" - -#include "mongo/db/auth/authorization_session.h" -#include "mongo/db/bson/dotted_path_support.h" -#include "mongo/db/catalog/collection.h" -#include "mongo/db/client.h" -#include "mongo/db/curop_failpoint_helpers.h" -#include "mongo/db/exec/scoped_timer.h" -#include "mongo/db/exec/working_set_common.h" -#include "mongo/stdx/memory.h" - -namespace mongo { - -// Forces a hang in the javascript execution while initializing the group stage. -MONGO_FP_DECLARE(hangInGroupReduceJs); - -using std::unique_ptr; -using std::vector; -using stdx::make_unique; - -namespace dps = ::mongo::dotted_path_support; - -namespace { - -// Helper function that extracts the group key from a BSONObj. -Status getKey( - const BSONObj& obj, const BSONObj& keyPattern, ScriptingFunction func, Scope* s, BSONObj* key) { - if (func) { - BSONObjBuilder b(obj.objsize() + 32); - b.append("0", obj); - const BSONObj& k = b.obj(); - try { - s->invoke(func, &k, 0); - } catch (const AssertionException& e) { - return e.toStatus("Failed to invoke group keyf function: "); - } - int type = s->type("__returnValue"); - if (type != Object) { - return Status(ErrorCodes::BadValue, "return of $key has to be an object"); - } - *key = s->getObject("__returnValue"); - return Status::OK(); - } - *key = dps::extractElementsBasedOnTemplate(obj, keyPattern, true).getOwned(); - return Status::OK(); -} - -} // namespace - -// static -const char* GroupStage::kStageType = "GROUP"; - -GroupStage::GroupStage(OperationContext* opCtx, - const GroupRequest& request, - WorkingSet* workingSet, - PlanStage* child) - : PlanStage(kStageType, opCtx), - _request(request), - _ws(workingSet), - _specificStats(), - _groupState(GroupState_Initializing), - _reduceFunction(0), - _keyFunction(0), - _groupMap(SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<int>()) { - _children.emplace_back(child); -} - -Status GroupStage::initGroupScripting() { - // Initialize _scope. - const std::string userToken = - AuthorizationSession::get(Client::getCurrent())->getAuthenticatedUserNamesToken(); - - _scope = getGlobalScriptEngine()->getPooledScope( - getOpCtx(), _request.ns.db().toString(), "group" + userToken); - if (!_request.reduceScope.isEmpty()) { - _scope->init(&_request.reduceScope); - } - _scope->setObject("$initial", _request.initial, true); - - try { - _scope->exec( - "$reduce = " + _request.reduceCode, "group reduce init", false, true, true, 2 * 1000); - } catch (const AssertionException& e) { - return e.toStatus("Failed to initialize group reduce function: "); - } - - try { - _scope->exec("$arr = [];", - "group reduce init 2", - false, // printResult - true, // reportError - true, // assertOnError - 2 * 1000); - } catch (const AssertionException& e) { - return e.toStatus("Failed to initialize group reduce function: "); - } - - // Initialize _reduceFunction. - _reduceFunction = _scope->createFunction( - "function(){ " - " if ( $arr[n] == null ){ " - " next = {}; " - " Object.extend( next , $key ); " - " Object.extend( next , $initial , true ); " - " $arr[n] = next; " - " next = null; " - " } " - " $reduce( obj , $arr[n] ); " - "}"); - - // Initialize _keyFunction, if a key function was provided. - if (_request.keyFunctionCode.size()) { - _keyFunction = _scope->createFunction(_request.keyFunctionCode.c_str()); - } - - return Status::OK(); -} - -Status GroupStage::processObject(const BSONObj& obj) { - BSONObj key; - Status getKeyStatus = getKey(obj, _request.keyPattern, _keyFunction, _scope.get(), &key); - if (!getKeyStatus.isOK()) { - return getKeyStatus; - } - - _scope->advanceGeneration(); - - int& n = _groupMap[key]; - if (n == 0) { - n = _groupMap.size(); - _scope->setObject("$key", key, true); - if (n > 20000) { - return Status(ErrorCodes::BadValue, "group() can't handle more than 20000 unique keys"); - } - } - - BSONObj objCopy = obj.getOwned(); - _scope->setObject("obj", objCopy, true); - _scope->setNumber("n", n - 1); - - boost::optional<std::string> oldMsg; - if (MONGO_FAIL_POINT(hangInGroupReduceJs)) { - oldMsg = CurOpFailpointHelpers::updateCurOpMsg(getOpCtx(), "hangInGroupReduceJs"); - } - auto resetMsgGuard = MakeGuard([&] { - if (oldMsg) { - CurOpFailpointHelpers::updateCurOpMsg(getOpCtx(), *oldMsg); - } - }); - try { - _scope->invoke(_reduceFunction, 0, 0, 0, true /*assertOnError*/); - } catch (const AssertionException& e) { - return e.toStatus("Failed to invoke group reduce function: "); - } - - return Status::OK(); -} - -StatusWith<BSONObj> GroupStage::finalizeResults() { - if (!_request.finalize.empty()) { - try { - _scope->exec("$finalize = " + _request.finalize, - "group finalize init", - false, // printResult - true, // reportError - true, // assertOnError - 2 * 1000); - } catch (const AssertionException& e) { - return e.toStatus("Failed to initialize group finalize function: "); - } - ScriptingFunction finalizeFunction = _scope->createFunction( - "function(){ " - " for(var i=0; i < $arr.length; i++){ " - " var ret = $finalize($arr[i]); " - " if (ret !== undefined) " - " $arr[i] = ret; " - " } " - "}"); - try { - _scope->invoke(finalizeFunction, 0, 0, 0, true /*assertOnError*/); - } catch (const AssertionException& e) { - return e.toStatus("Failed to invoke group finalize function: "); - } - } - - _specificStats.nGroups = _groupMap.size(); - - BSONObj results = _scope->getObject("$arr").getOwned(); - - try { - _scope->exec("$arr = [];", - "group clean up", - false, // printResult - true, // reportError - true, // assertOnError - 2 * 1000); - } catch (const AssertionException& e) { - return e.toStatus("Failed to clean up group: "); - } - - _scope->gc(); - - return results; -} - -PlanStage::StageState GroupStage::doWork(WorkingSetID* out) { - if (isEOF()) { - return PlanStage::IS_EOF; - } - - // On the first call to work(), call initGroupScripting(). - if (_groupState == GroupState_Initializing) { - Status status = initGroupScripting(); - if (!status.isOK()) { - *out = WorkingSetCommon::allocateStatusMember(_ws, status); - return PlanStage::FAILURE; - } - _groupState = GroupState_ReadingFromChild; - return PlanStage::NEED_TIME; - } - - // Otherwise, read from our child. - invariant(_groupState == GroupState_ReadingFromChild); - WorkingSetID id = WorkingSet::INVALID_ID; - StageState state = child()->work(&id); - - if (PlanStage::NEED_TIME == state) { - return state; - } else if (PlanStage::NEED_YIELD == state) { - *out = id; - return state; - } else if (PlanStage::FAILURE == state || PlanStage::DEAD == state) { - // The stage which produces a failure is responsible for allocating a working set member - // with error details. - invariant(WorkingSet::INVALID_ID != id); - *out = id; - return state; - } else if (PlanStage::ADVANCED == state) { - WorkingSetMember* member = _ws->get(id); - // Group queries can't have projections. This means that covering analysis will always - // add a fetch. We should always get fetched data, and never just key data. - invariant(member->hasObj()); - - Status status = processObject(member->obj.value()); - if (!status.isOK()) { - *out = WorkingSetCommon::allocateStatusMember(_ws, status); - return PlanStage::FAILURE; - } - - _ws->free(id); - - return PlanStage::NEED_TIME; - } else { - // We're done reading from our child. - invariant(PlanStage::IS_EOF == state); - - auto results = finalizeResults(); - if (!results.isOK()) { - *out = WorkingSetCommon::allocateStatusMember(_ws, results.getStatus()); - return PlanStage::FAILURE; - } - - // Transition to state "done." Future calls to work() will return IS_EOF. - _groupState = GroupState_Done; - - *out = _ws->allocate(); - WorkingSetMember* member = _ws->get(*out); - member->obj = Snapshotted<BSONObj>(SnapshotId(), results.getValue()); - member->transitionToOwnedObj(); - - return PlanStage::ADVANCED; - } -} - -bool GroupStage::isEOF() { - return _groupState == GroupState_Done; -} - -unique_ptr<PlanStageStats> GroupStage::getStats() { - _commonStats.isEOF = isEOF(); - unique_ptr<PlanStageStats> ret = make_unique<PlanStageStats>(_commonStats, STAGE_GROUP); - ret->specific = make_unique<GroupStats>(_specificStats); - ret->children.emplace_back(child()->getStats()); - return ret; -} - -const SpecificStats* GroupStage::getSpecificStats() const { - return &_specificStats; -} - -} // namespace mongo diff --git a/src/mongo/db/exec/group.h b/src/mongo/db/exec/group.h deleted file mode 100644 index 1c796a7391b..00000000000 --- a/src/mongo/db/exec/group.h +++ /dev/null @@ -1,162 +0,0 @@ -/** - * Copyright (C) 2014 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/bson/simple_bsonobj_comparator.h" -#include "mongo/db/exec/plan_stage.h" -#include "mongo/db/namespace_string.h" -#include "mongo/scripting/engine.h" - -namespace mongo { - -class Collection; - -/** - * A description of a request for a group operation. Copyable. - */ -struct GroupRequest { - // Namespace to operate on (e.g. "foo.bar"). - NamespaceString ns; - - // A predicate describing the set of documents to group. - BSONObj query; - - // The field(s) to group by. Alternative to "keyFunctionCode". Empty if "keyFunctionCode" - // is being used instead. - BSONObj keyPattern; - - // A Javascript function that maps a document to a key object. Alternative to "keyPattern". - // Empty is "keyPattern" is being used instead. - std::string keyFunctionCode; - - // The collation used for string comparisons. If empty, simple binary comparison with memcmp() - // is used. - BSONObj collation; - - // A Javascript function that takes a (input document, group result) pair and - // updates the group result document. - std::string reduceCode; - - // Scope for the reduce function. Optional. - BSONObj reduceScope; - - // The initial value for the group result. - BSONObj initial; - - // A Javascript function that "finalizes" a group result. Optional. - std::string finalize; - - // Whether this is an explain of a group. - bool explain; -}; - -/** - * Stage used by the group command. Consumes input documents from its child stage (returning - * NEED_TIME once for each document produced by the child), returns ADVANCED exactly once with - * the entire group result, then returns EOF. - * - * Only created through the getExecutorGroup path. - */ -class GroupStage final : public PlanStage { - MONGO_DISALLOW_COPYING(GroupStage); - -public: - GroupStage(OperationContext* opCtx, - const GroupRequest& request, - WorkingSet* workingSet, - PlanStage* child); - - StageState doWork(WorkingSetID* out) final; - bool isEOF() final; - - StageType stageType() const final { - return STAGE_GROUP; - } - - std::unique_ptr<PlanStageStats> getStats() final; - - const SpecificStats* getSpecificStats() const final; - - static const char* kStageType; - -private: - /** - * Keeps track of what this group is currently doing so that it can do the right thing on - * the next call to work(). - */ - enum GroupState { - // Need to initialize the underlying Javascript machinery. - GroupState_Initializing, - - // Retrieving the next document from the child stage and processing it. - GroupState_ReadingFromChild, - - // Results have been returned. - GroupState_Done - }; - - // Initializes _scope, _reduceFunction and _keyFunction using the global scripting engine. - Status initGroupScripting(); - - // Updates _groupMap and _scope to account for the group key associated with this object. - // Returns an error status if an error occurred, else Status::OK(). - Status processObject(const BSONObj& obj); - - // Finalize the results for this group operation. On success, returns with a BSONObj with - // the results array. On failure, returns a non-OK status. Does not throw. - StatusWith<BSONObj> finalizeResults(); - - GroupRequest _request; - - // The WorkingSet we annotate with results. Not owned by us. - WorkingSet* _ws; - - GroupStats _specificStats; - - // Current state for this stage. - GroupState _groupState; - - // The Scope object that all script operations for this group stage will use. Initialized - // by initGroupScripting(). Owned here. - std::unique_ptr<Scope> _scope; - - // The reduce function for the group operation. Initialized by initGroupScripting(). Owned - // by _scope. - ScriptingFunction _reduceFunction; - - // The key function for the group operation if one was provided by the user, else 0. - // Initialized by initGroupScripting(). Owned by _scope. - ScriptingFunction _keyFunction; - - // Map from group key => group index. The group index is used to index into "$arr", a - // variable owned by _scope which contains the group data for this key. - BSONObjIndexedMap<int> _groupMap; -}; - -} // namespace mongo diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp index eed63cec24a..c751518004e 100644 --- a/src/mongo/db/query/get_executor.cpp +++ b/src/mongo/db/query/get_executor.cpp @@ -44,7 +44,6 @@ #include "mongo/db/exec/count.h" #include "mongo/db/exec/delete.h" #include "mongo/db/exec/eof.h" -#include "mongo/db/exec/group.h" #include "mongo/db/exec/idhack.h" #include "mongo/db/exec/multi_plan.h" #include "mongo/db/exec/oplogstart.h" @@ -1049,77 +1048,6 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorUpdate( } // -// Group -// - -StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorGroup( - OperationContext* opCtx, Collection* collection, const GroupRequest& request) { - if (!getGlobalScriptEngine()) { - return Status(ErrorCodes::BadValue, "server-side JavaScript execution is disabled"); - } - - unique_ptr<WorkingSet> ws = make_unique<WorkingSet>(); - const auto readConcernArgs = repl::ReadConcernArgs::get(opCtx); - const auto yieldPolicy = - readConcernArgs.getLevel() == repl::ReadConcernLevel::kSnapshotReadConcern - ? PlanExecutor::INTERRUPT_ONLY - : PlanExecutor::YIELD_AUTO; - - if (!collection) { - // Treat collections that do not exist as empty collections. Note that the explain - // reporting machinery always assumes that the root stage for a group operation is a - // GroupStage, so in this case we put a GroupStage on top of an EOFStage. - unique_ptr<PlanStage> root = - make_unique<GroupStage>(opCtx, request, ws.get(), new EOFStage(opCtx)); - - return PlanExecutor::make(opCtx, std::move(ws), std::move(root), request.ns, yieldPolicy); - } - - const NamespaceString nss(request.ns); - auto qr = stdx::make_unique<QueryRequest>(nss); - qr->setFilter(request.query); - qr->setCollation(request.collation); - qr->setExplain(request.explain); - - const ExtensionsCallbackReal extensionsCallback(opCtx, &nss); - - const boost::intrusive_ptr<ExpressionContext> expCtx; - auto statusWithCQ = - CanonicalQuery::canonicalize(opCtx, - std::move(qr), - expCtx, - extensionsCallback, - MatchExpressionParser::kAllowAllSpecialFeatures); - if (!statusWithCQ.isOK()) { - return statusWithCQ.getStatus(); - } - unique_ptr<CanonicalQuery> canonicalQuery = std::move(statusWithCQ.getValue()); - - const size_t defaultPlannerOptions = 0; - StatusWith<PrepareExecutionResult> executionResult = prepareExecution( - opCtx, collection, ws.get(), std::move(canonicalQuery), defaultPlannerOptions); - if (!executionResult.isOK()) { - return executionResult.getStatus(); - } - canonicalQuery = std::move(executionResult.getValue().canonicalQuery); - unique_ptr<QuerySolution> querySolution = std::move(executionResult.getValue().querySolution); - unique_ptr<PlanStage> root = std::move(executionResult.getValue().root); - - invariant(root); - - root = make_unique<GroupStage>(opCtx, request, ws.get(), root.release()); - // We must have a tree of stages in order to have a valid plan executor, but the query - // solution may be null. Takes ownership of all args other than 'collection'. - return PlanExecutor::make(opCtx, - std::move(ws), - std::move(root), - std::move(querySolution), - std::move(canonicalQuery), - collection, - yieldPolicy); -} - -// // Count hack // diff --git a/src/mongo/db/query/get_executor.h b/src/mongo/db/query/get_executor.h index 118e0afbee2..97d4e36480c 100644 --- a/src/mongo/db/query/get_executor.h +++ b/src/mongo/db/query/get_executor.h @@ -43,8 +43,6 @@ namespace mongo { class Collection; class CountRequest; -struct GroupRequest; - /** * Filter indexes retrieved from index catalog by * allowed indices in query settings. @@ -180,16 +178,4 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDele */ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorUpdate( OperationContext* opCtx, OpDebug* opDebug, Collection* collection, ParsedUpdate* parsedUpdate); - -/** - * Get a PlanExecutor for a group operation. - * - * If the query is valid and an executor could be created, returns a StatusWith with the - * PlanExecutor. - * - * If an executor could not be created, returns a Status indicating why. - */ -StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorGroup( - OperationContext* opCtx, Collection* collection, const GroupRequest& request); - } // namespace mongo diff --git a/src/mongo/s/commands/commands_public.cpp b/src/mongo/s/commands/commands_public.cpp index ec5c774c7f6..3b92e72caed 100644 --- a/src/mongo/s/commands/commands_public.cpp +++ b/src/mongo/s/commands/commands_public.cpp @@ -380,75 +380,6 @@ public: } convertToCappedCmd; -class GroupCmd : public NotAllowedOnShardedCollectionCmd { -public: - GroupCmd() : NotAllowedOnShardedCollectionCmd("group") {} - - bool supportsWriteConcern(const BSONObj& cmd) const override { - return false; - } - - AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { - return AllowedOnSecondary::kAlways; - } - - std::string parseNs(const std::string& dbname, const BSONObj& cmdObj) const override { - const auto nsElt = cmdObj.firstElement().embeddedObjectUserCheck()["ns"]; - uassert(ErrorCodes::InvalidNamespace, - "'ns' must be of type String", - nsElt.type() == BSONType::String); - const NamespaceString nss(dbname, nsElt.valueStringData()); - uassert(ErrorCodes::InvalidNamespace, - str::stream() << "Invalid namespace: " << nss.ns(), - nss.isValid()); - return nss.ns(); - } - - void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) const override { - ActionSet actions; - actions.addAction(ActionType::find); - out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions)); - } - - Status explain(OperationContext* opCtx, - const OpMsgRequest& request, - ExplainOptions::Verbosity verbosity, - BSONObjBuilder* out) const override { - const auto dbName = request.getDatabase(); - const auto& cmdObj = request.body; - - const NamespaceString nss(parseNs(dbName.toString(), cmdObj)); - - Timer timer; - const auto explainCommand = ClusterExplain::wrapAsExplain(cmdObj, verbosity); - - auto routingInfo = - uassertStatusOK(Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfo(opCtx, nss)); - - BSONObjBuilder result; - if (!nonShardedCollectionCommandPassthrough(opCtx, - dbName, - nss, - routingInfo, - explainCommand, - Shard::RetryPolicy::kIdempotent, - &result)) { - return getStatusFromCommandResult(result.done()); - } - - Strategy::CommandResult cmdResult; - cmdResult.shardTargetId = routingInfo.db().primaryId(); - cmdResult.result = result.done(); - cmdResult.target = routingInfo.db().primary()->getConnString(); - - return ClusterExplain::buildExplainResult( - opCtx, {cmdResult}, ClusterExplain::kSingleShard, timer.millis(), out); - } - -} groupCmd; - class SplitVectorCmd : public NotAllowedOnShardedCollectionCmd { public: SplitVectorCmd() : NotAllowedOnShardedCollectionCmd("splitVector") {} diff --git a/src/mongo/shell/collection.js b/src/mongo/shell/collection.js index 5ab24203610..93653e08596 100644 --- a/src/mongo/shell/collection.js +++ b/src/mongo/shell/collection.js @@ -84,7 +84,6 @@ DBCollection.prototype.help = function() { print("\tdb." + shortName + ".getDB() get DB object associated with collection"); print("\tdb." + shortName + ".getPlanCache() get query plan cache associated with collection"); print("\tdb." + shortName + ".getIndexes()"); - print("\tdb." + shortName + ".group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )"); print("\tdb." + shortName + ".insert(obj)"); print( "\tdb." + shortName + @@ -1056,16 +1055,6 @@ DBCollection.prototype.aggregate = function(pipeline, aggregateOptions) { return this._db._runAggregate(cmdObj, aggregateOptions); }; -DBCollection.prototype.group = function(params) { - params.ns = this._shortName; - return this._db.group(params); -}; - -DBCollection.prototype.groupcmd = function(params) { - params.ns = this._shortName; - return this._db.groupcmd(params); -}; - MapReduceResult = function(db, o) { Object.extend(this, o); this._o = o; diff --git a/src/mongo/shell/db.js b/src/mongo/shell/db.js index 016dcdb48a5..9a7d61890a8 100644 --- a/src/mongo/shell/db.js +++ b/src/mongo/shell/db.js @@ -757,29 +757,6 @@ var DB; DB.prototype.dbEval = DB.prototype.eval; /** - * - * <p> - * Similar to SQL group by. For example: </p> - * - * <code>select a,b,sum(c) csum from coll where active=1 group by a,b</code> - * - * <p> - * corresponds to the following in 10gen: - * </p> - * - * <code> - db.group( - { - ns: "coll", - key: { a:true, b:true }, - // keyf: ..., - cond: { active:1 }, - reduce: function(obj,prev) { prev.csum += obj.c; }, - initial: { csum: 0 } - }); - </code> - * - * * <p> * An array of grouped items is returned. The array must fit in RAM, thus this function is not * suitable when the return set is extremely large. @@ -829,16 +806,6 @@ var DB; return this.eval(groupFunction, this._groupFixParms(parmsObj)); }; - DB.prototype.groupcmd = function(parmsObj) { - var ret = this.runCommand({"group": this._groupFixParms(parmsObj)}); - if (!ret.ok) { - throw _getErrorWithCode(ret, "group command failed: " + tojson(ret)); - } - return ret.retval; - }; - - DB.prototype.group = DB.prototype.groupcmd; - DB.prototype._groupFixParms = function(parmsObj) { var parms = Object.extend({}, parmsObj); diff --git a/src/mongo/shell/explainable.js b/src/mongo/shell/explainable.js index 67348a7e8e9..3e8de059af8 100644 --- a/src/mongo/shell/explainable.js +++ b/src/mongo/shell/explainable.js @@ -66,7 +66,6 @@ var Explainable = (function() { print("\t.distinct(...) - explain a distinct operation"); print("\t.find(...) - get an explainable query"); print("\t.findAndModify(...) - explain a findAndModify operation"); - print("\t.group(...) - explain a group operation"); print("\t.remove(...) - explain a remove operation"); print("\t.update(...) - explain an update operation"); print("Explainable collection methods"); @@ -144,14 +143,6 @@ var Explainable = (function() { return throwOrReturn(explainResult); }; - this.group = function(params) { - params.ns = this._collection.getName(); - var grpCmd = {"group": this._collection.getDB()._groupFixParms(params)}; - var explainCmd = {"explain": grpCmd, "verbosity": this._verbosity}; - var explainResult = this._collection.runReadCommand(explainCmd); - return throwOrReturn(explainResult); - }; - this.distinct = function(keyString, query, options) { var distinctCmd = { distinct: this._collection.getName(), |