SERVER-83211 Enable counting index tests on sharded passthrough suites (#43649)

GitOrigin-RevId: dcb676f1697884eb629906f0d8d8979f10ef4035
This commit is contained in:
Silvia Surroca 2025-11-12 15:10:21 +01:00 committed by MongoDB Bot
parent f50352a5c2
commit 3d3328e613
92 changed files with 748 additions and 786 deletions

2
.github/CODEOWNERS vendored
View File

@ -961,6 +961,8 @@ WORKSPACE.bazel @10gen/devprod-build @svc-auto-approve-bot
/jstests/libs/**/*.sha1 @10gen/server-security @svc-auto-approve-bot
/jstests/libs/**/*.sha256 @10gen/server-security @svc-auto-approve-bot
/jstests/libs/**/*.pfx @10gen/server-security @svc-auto-approve-bot
/jstests/libs/**/fixture_helpers.js @10gen/server-catalog-and-routing-routing-and-topology @svc-auto-approve-bot
/jstests/libs/**/index_utils.js @10gen/server-catalog-and-routing-shard-catalog @svc-auto-approve-bot
# The following patterns are parsed from ./jstests/libs/clustered_collections/OWNERS.yml
/jstests/libs/clustered_collections/**/* @10gen/server-collection-write-path @svc-auto-approve-bot

View File

@ -88,7 +88,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -68,10 +68,6 @@ selector:
- jstests/core/**/geo_2d_explain.js
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/benchrun_pipeline_updates.js
- jstests/core/timeseries/write/timeseries_delete_hint.js
- jstests/core/**/set_param1.js

View File

@ -58,11 +58,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -100,11 +100,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -100,11 +100,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -98,7 +98,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -98,7 +98,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -90,7 +90,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -90,7 +90,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -91,7 +91,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -91,7 +91,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -91,7 +91,6 @@ selector:
- jstests/core/**/fsync.js
- jstests/core/**/shell_connection_strings.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/batch_write_command_w0.js
- jstests/core/**/bench_test*.js

View File

@ -84,7 +84,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -84,7 +84,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -63,11 +63,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -63,11 +63,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -63,11 +63,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -65,11 +65,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -62,11 +62,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -70,11 +70,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -70,11 +70,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -98,7 +98,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -98,7 +98,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -116,7 +116,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -116,7 +116,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -115,7 +115,6 @@ selector:
- jstests/core/**/currentop.js
- jstests/core/**/fsync.js
- jstests/core/**/indexes_multiple_commands.js
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
- jstests/core/**/coveredIndex1.js
- jstests/core/**/sortc.js

View File

@ -70,10 +70,6 @@ selector:
- jstests/core/**/geo_2d_explain.js
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/benchrun_pipeline_updates.js
- jstests/core/timeseries/write/timeseries_delete_hint.js
- jstests/core/**/set_param1.js

View File

@ -60,11 +60,6 @@ selector:
- jstests/core/**/geo_s2explain.js
- jstests/core/**/geo_s2sparse.js
- jstests/core/**/operation_latency_histogram.js
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
- jstests/core/**/distinct_index1.js
- jstests/core/**/expr_index_use.js
- jstests/core/**/index_multikey.js

View File

@ -32,7 +32,6 @@
# Expect certain responses, but retries of successfully completed commands may return
# different values:
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
# Expect results to return in a certain order, secondaries may apply ops out of order.
@ -115,7 +114,6 @@
# Expect certain responses, but retries of successfully completed commands may return
# different values:
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
# Unacknowledged writes prohibited in an explicit session.

View File

@ -45,8 +45,9 @@ selector:
- jstests/core/txns/create_collection_parallel.js
- jstests/core/txns/create_indexes.js
- jstests/core/txns/create_indexes_parallel.js
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
# The following tests fail because they count indexes without accounting for the fact that
# a collection may be implicitly recreated after a drop(), causing the default index {_id: 1}
# to exist unexpectedly.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js

View File

@ -31,13 +31,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -32,13 +32,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -42,9 +42,10 @@ selector:
- jstests/core/query/or/or_to_in.js
# The following test fires a large query that takes too long with wildcard indexes.
- jstests/core/query/query_settings/query_settings_size_limits.js
# TODO (SERVER-95786): Fails because this suite overrides DBCollection.prototype.getIndexes
# and re-implements it using $indexStats, which (by design) doesn't return clustered indexes
# Fails because the test creates a wildcard index that results in an IndexOptionsConflict error
# because the index already exists.
- jstests/core/catalog/list_catalog_stage_consistency.js
- jstests/core/index/index_count_scan.js
exclude_with_any_tags:
# This suite implicitly creates compound wildcard indexes.

View File

@ -35,13 +35,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -33,13 +33,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -31,13 +31,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -31,13 +31,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -31,13 +31,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -31,13 +31,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -31,13 +31,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -32,7 +32,6 @@ selector:
# Expect certain responses, but retries of successfully completed commands may return
# different values:
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
# Expect results to return in a certain order, secondaries may apply ops out of order.

View File

@ -27,12 +27,6 @@ selector:
- jstests/core/**/geo_2d_explain.js # executionSuccess in different spot in explain().
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# This test uses `benchRun` which spawns connections which do not inherit the causal session.
- jstests/core/**/benchrun_pipeline_updates.js

View File

@ -27,12 +27,6 @@ selector:
- jstests/core/**/geo_2d_explain.js # executionSuccess in different spot in explain().
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# This test uses `benchRun` which spawns connections which do not inherit the causal session.
- jstests/core/**/benchrun_pipeline_updates.js

View File

@ -34,13 +34,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -33,13 +33,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -36,13 +36,6 @@ selector:
# The following tests fail because explain expect a different plan query when collections live on separate shards
# This test expects sharded collections to be sharded across multiple shards.
- jstests/core/administrative/current_op/currentop_shell.js
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -67,13 +67,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -33,7 +33,6 @@ selector:
# Expect certain responses, but retries of successfully completed commands may return
# different values:
- jstests/core/**/create_indexes.js
- jstests/core/**/objid5.js
# Expect results to return in a certain order, secondaries may apply ops out of order.

View File

@ -31,13 +31,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -31,13 +31,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -27,12 +27,6 @@ selector:
- jstests/core/**/geo_2d_explain.js # executionSuccess in different spot in explain().
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# This test uses `benchRun` which spawns connections which do not inherit the causal session.
- jstests/core/**/benchrun_pipeline_updates.js

View File

@ -27,12 +27,6 @@ selector:
- jstests/core/**/geo_2d_explain.js # executionSuccess in different spot in explain().
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# This test uses `benchRun` which spawns connections which do not inherit the causal session.
- jstests/core/**/benchrun_pipeline_updates.js
exclude_with_any_tags:

View File

@ -34,13 +34,6 @@ selector:
- jstests/core/**/geo_s2explain.js # inputStage in different spot in explain().
- jstests/core/**/geo_s2sparse.js # keysPerIndex in different spot in validate().
- jstests/core/**/operation_latency_histogram.js # Stats are counted differently on mongos, SERVER-24880.
# The following tests fail because they count indexes. These counts do not take into account the
# additional hashed shard key indexes that are automatically added by this passthrough.
- jstests/core/**/apitest_dbcollection.js
- jstests/core/**/bad_index_plugin.js
- jstests/core/**/create_indexes.js
- jstests/core/**/list_indexes_non_existent_ns.js
- jstests/core/**/mr_preserve_indexes.js
# TODO: Remove after fixing SERVER-103278. executionStats.nReturned is incorrect for sharded distinct commands.
- jstests/core/**/distinct_index1.js
# TODO SERVER-32311: These tests use plan stage helpers which can't handle sharded explain output.

View File

@ -4,9 +4,10 @@
// output collection is sharded.
// @tags: [
// assumes_unsharded_collection,
// # Asserts on the number of indexes.
// assumes_no_implicit_index_creation,
// ]
import {IndexUtils} from "jstests/libs/index_utils.js";
const coll = db.out_read_write_to_same_collection;
coll.drop();
assert.commandWorked(
@ -57,6 +58,6 @@ assert.eq(
const indexMetadata = coll
.aggregate([{$indexStats: {}}, {$project: {key: 1}}, {$sort: {key: 1}}, {$replaceWith: "$key"}])
.toArray();
assert.eq(indexMetadata, [{_id: 1}, {total: 1}]);
IndexUtils.assertIndexesMatch(coll, [{_id: 1}, {total: 1}], indexMetadata);
coll.drop();

View File

@ -2,9 +2,9 @@
* Test that $unionWith works with $geoNear, $text, and $indexStats
* Some of these stages cannot be used in facets.
* @tags: [
* # Asserts on the output of $indexStats.
* assumes_no_implicit_index_creation,
* do_not_wrap_aggregations_in_facets,
* # TODO (SERVER-113608) Enable the test for sharded collections once this ticket is addressed.
* assumes_unsharded_collection,
* ]
*/
@ -60,43 +60,42 @@ checkResults(
// Test that $unionWith works with $indexStats
// $match removes all real documents from the pipeline, so we can just check the index documents.
let resObj = testDB.runCommand({
aggregate: collA.getName(),
pipeline: [
let docArray = collA
.aggregate([
{$match: {val: {$exists: false}}},
{$unionWith: {coll: textColl.getName(), pipeline: [{$indexStats: {}}]}},
{$sort: {name: 1}},
],
cursor: {},
});
let docArray = resObj.cursor.firstBatch;
])
.toArray();
if (FixtureHelpers.isMongos(testDB) && FixtureHelpers.isSharded(collA)) {
// We expect each shard to have an _id_, _id_hashed, and str_text index
const numShards = FixtureHelpers.numberOfShardsForCollection(collA);
assert.eq(docArray.length, 3 * numShards);
assert.eq(docArray.length, 3 * numShards, tojson(docArray));
for (let i = 0; i < numShards; i++) {
assert.eq(docArray[i].name, "_id_");
assert.eq(docArray[i + numShards].name, "_id_hashed");
assert.eq(docArray[i + numShards * 2].name, "str_text");
assert.eq(docArray[i].name, "_id_", tojson(docArray));
assert.eq(docArray[i + numShards].name, "_id_hashed", tojson(docArray));
assert.eq(docArray[i + numShards * 2].name, "str_text", tojson(docArray));
}
} else {
assert.eq(docArray.length, 2);
assert.eq(docArray[0].name, "_id_");
assert.eq(docArray[1].name, "str_text");
assert.eq(docArray.length, 2, tojson(docArray));
assert.eq(docArray[0].name, "_id_", tojson(docArray));
assert.eq(docArray[1].name, "str_text", tojson(docArray));
}
// Test that $unionWith fails if $indexStats is not first stage in the sub-pipeline.
resObj = testDB.runCommand({
aggregate: collA.getName(),
pipeline: [
{$match: {val: {$exists: false}}},
{
$unionWith: {coll: textColl.getName(), pipeline: [{$match: {val: "foo"}}, {$indexStats: {}}]},
},
],
cursor: {},
});
assert.eq(resObj.code, 40602, resObj);
assert.commandFailedWithCode(
testDB.runCommand({
aggregate: collA.getName(),
pipeline: [
{$match: {val: {$exists: false}}},
{
$unionWith: {coll: textColl.getName(), pipeline: [{$match: {val: "foo"}}, {$indexStats: {}}]},
},
],
cursor: {},
}),
40602,
);
// Test that $unionWith works with $geoNear
const geoColl = testDB.geoColl;
@ -133,7 +132,7 @@ const geoNearResults = testDB.runCommand({
});
assert.commandWorked(geoNearResults);
const geoNearArray = geoNearResults.cursor.firstBatch;
assert.eq(geoNearArray.length, resSet.length);
assert.eq(geoNearArray.length, resSet.length, tojson(geoNearArray));
// First check the geo object.
const geoObj = geoNearArray[0];
@ -150,25 +149,27 @@ for (let i = 1; i < geoNearArray.length; i++) {
}
// Test that $unionWith fails if $geoNear is not first stage in the sub-pipeline.
resObj = testDB.runCommand({
aggregate: collA.getName(),
pipeline: [
{
$unionWith: {
coll: geoColl.getName(),
pipeline: [
{$match: {val: "foo"}},
{
$geoNear: {
near: {type: "Point", coordinates: [10, 10]},
distanceField: "dist",
maxDistance: 2,
assert.commandFailedWithCode(
testDB.runCommand({
aggregate: collA.getName(),
pipeline: [
{
$unionWith: {
coll: geoColl.getName(),
pipeline: [
{$match: {val: "foo"}},
{
$geoNear: {
near: {type: "Point", coordinates: [10, 10]},
distanceField: "dist",
maxDistance: 2,
},
},
},
],
],
},
},
},
],
cursor: {},
});
assert.eq(resObj.code, 40603, resObj);
],
cursor: {},
}),
40603,
);

View File

@ -2,11 +2,8 @@
* Basic tests for the $listCatalog aggregation stage.
*
* @tags: [
* # Asserts on number of indexes.
* assumes_no_implicit_index_creation,
* # Time-series collection inserts are not supported in multi-document transactions.
* does_not_support_transactions,
* requires_fcv_60,
* # $listCatalog result can be large and may be returned in multiple batches.
* requires_getmore,
* requires_timeseries,
@ -20,42 +17,13 @@ import {
getTimeseriesBucketsColl,
} from "jstests/core/timeseries/libs/viewless_timeseries_util.js";
import {FixtureHelpers} from "jstests/libs/fixture_helpers.js";
import {after, afterEach, before, beforeEach, describe, it} from "jstests/libs/mochalite.js";
const testDB = db.getSiblingDB(jsTestName());
assert.commandWorked(testDB.dropDatabase());
const adminDB = testDB.getSiblingDB("admin");
// Simple collection with one secondary index.
const collSimple = testDB.simple;
assert.commandWorked(collSimple.createIndex({a: 1}));
assert.commandWorked(collSimple.insert({_id: 0, a: 0}));
// Simple view.
const viewSimpleName = "simple_view";
assert.commandWorked(testDB.createView(viewSimpleName, collSimple.getName(), [{$project: {a: 0}}]));
// Time-series collection.
assert.commandWorked(testDB.createCollection("ts", {timeseries: {timeField: "tt"}}));
const collTimeseries = testDB.ts;
assert.commandWorked(collTimeseries.insert({_id: 1, tt: ISODate(), x: 123}));
// Collection with clustered index.
assert.commandWorked(testDB.createCollection("clustered", {clusteredIndex: {key: {_id: 1}, unique: true}}));
const collClustered = testDB.clustered;
assert.commandWorked(collClustered.insert({_id: 2, y: "abc"}));
const numIndexes = function (coll, entry, numSecondaryIndexes) {
let numIndexes = numSecondaryIndexes + 1;
if (entry.md.options.clusteredIndex) {
--numIndexes;
}
if (FixtureHelpers.isSharded(coll)) {
++numIndexes;
}
return numIndexes;
};
const checkEntries = function (collName, entries, type, {numSecondaryIndexes, viewOn}) {
const ns = testDB.getName() + "." + collName;
function checkEntries(coll, entries, type, {numSecondaryIndexes, viewOn}) {
const ns = coll.getFullName();
assert(entries.some((entry) => entry.ns === ns));
for (const entry of entries) {
if (entry.ns !== ns) {
@ -63,7 +31,7 @@ const checkEntries = function (collName, entries, type, {numSecondaryIndexes, vi
}
assert.eq(entry.db, testDB.getName());
assert.eq(entry.name, collName);
assert.eq(entry.name, coll.getName());
assert.eq(entry.type, type);
if (FixtureHelpers.isMongos(testDB)) {
assert(entry.shard);
@ -77,65 +45,131 @@ const checkEntries = function (collName, entries, type, {numSecondaryIndexes, vi
assert.eq(entry.viewOn, viewOn);
}
// Going to check the indexes field.
//
// Avoid checking index metadata of unsplittable collections that are not in the proper
// shard. Unsplittable collections can exist both in the primary shard and in the
// owning shard local catalog, but createIndexes will only contact the owning shard.
let checkIndexes = true;
if (FixtureHelpers.isMongos(testDB)) {
const configDB = db.getSiblingDB("config");
const coll = configDB.collections.findOne({_id: entry.ns});
if (coll && coll.unsplittable) {
const chunk = configDB.chunks.findOne({uuid: coll.uuid});
checkIndexes = chunk.shard == entry.shard;
if (type === "collection" && !FixtureHelpers.isUnsplittable(coll)) {
// Adding the {_id:1} to the index count.
let expectedNumIndexes = numSecondaryIndexes + 1;
if (entry.md.options.clusteredIndex) {
// The _id clustered index is shown under 'md.options.clusteredIndex' instead of
// 'md.indexes'.
--expectedNumIndexes;
}
}
if (checkIndexes && type === "collection") {
assert.eq(entry.md.indexes.length, numIndexes(testDB[collName], entry, numSecondaryIndexes));
if (FixtureHelpers.isSharded(coll)) {
// Adding the shard key index to the index count.
++expectedNumIndexes;
}
if (TestData.implicitWildcardIndexesEnabled) {
// An implicit wildcard index is created for every secondary index.
expectedNumIndexes += numSecondaryIndexes;
}
assert.eq(expectedNumIndexes, entry.md.indexes.length);
}
}
};
let result = collSimple.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog(collSimple.getFullName() + " $listCatalog: " + tojson(result));
checkEntries(collSimple.getName(), result, "collection", {numSecondaryIndexes: 1});
result = collClustered.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog(collClustered.getFullName() + " $listCatalog: " + tojson(result));
checkEntries(collClustered.getName(), result, "collection", {numSecondaryIndexes: 0});
if (areViewlessTimeseriesEnabled(testDB)) {
result = collTimeseries.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog(collTimeseries.getFullName() + " $listCatalog: " + tojson(result));
checkEntries(collTimeseries.getName(), result, "timeseries", {numSecondaryIndexes: 0});
} else {
assert.commandFailedWithCode(
testDB.runCommand({aggregate: collTimeseries.getName(), pipeline: [{$listCatalog: {}}], cursor: {}}),
40602,
);
}
assert.commandFailedWithCode(
testDB.runCommand({aggregate: viewSimpleName, pipeline: [{$listCatalog: {}}], cursor: {}}),
40602,
);
assert.commandFailedWithCode(
testDB.runCommand({aggregate: 1, pipeline: [{$listCatalog: {}}], cursor: {}}),
ErrorCodes.InvalidNamespace,
);
const adminDB = testDB.getSiblingDB("admin");
result = adminDB.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog("Collectionless $listCatalog: " + tojson(result));
checkEntries(collSimple.getName(), result, "collection", {numSecondaryIndexes: 1});
checkEntries(collClustered.getName(), result, "collection", {numSecondaryIndexes: 0});
checkEntries(viewSimpleName, result, "view", {viewOn: collSimple.getName()});
if (areViewlessTimeseriesEnabled(testDB)) {
checkEntries(collTimeseries.getName(), result, "timeseries", {numSecondaryIndexes: 0});
} else {
checkEntries(collTimeseries.getName(), result, "timeseries", {
viewOn: getTimeseriesBucketsColl(collTimeseries).getName(),
describe("Basic tests for the $listCatalog aggregation stage", function () {
before(() => {
assert.commandWorked(testDB.dropDatabase());
});
}
it("simple collection with one secondary index", () => {
const collSimple = testDB.collSimple;
assert.commandWorked(collSimple.createIndex({a: 1}));
assert.commandWorked(collSimple.insert({_id: 0, a: 0}));
// collection-ful aggregate
{
const res = collSimple.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog(collSimple.getFullName() + " $listCatalog: " + tojson(res));
checkEntries(collSimple, res, "collection", {numSecondaryIndexes: 1});
}
// collection-less aggregate
{
const res = adminDB.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog("Collectionless $listCatalog: " + tojson(res));
checkEntries(collSimple, res, "collection", {numSecondaryIndexes: 1});
}
});
it("simple view", () => {
const viewSimpleName = "viewSimple";
const collViewOn = testDB.collViewOn;
assert.commandWorked(collViewOn.insert({_id: 0, a: 0}));
assert.commandWorked(testDB.createView(viewSimpleName, collViewOn.getName(), [{$project: {a: 0}}]));
const viewSimple = testDB.getCollection(viewSimpleName);
// collection-ful aggregate
assert.commandFailedWithCode(
testDB.runCommand({aggregate: viewSimpleName, pipeline: [{$listCatalog: {}}], cursor: {}}),
40602,
);
// collection-less aggregate
const res = adminDB.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog("Collectionless $listCatalog: " + tojson(res));
checkEntries(viewSimple, res, "view", {viewOn: collViewOn.getName()});
});
it("timeseries collection", () => {
assert.commandWorked(testDB.createCollection("ts", {timeseries: {timeField: "tt"}}));
const collTimeseries = testDB.ts;
assert.commandWorked(collTimeseries.insert({_id: 1, tt: ISODate(), x: 123}));
// collection-ful aggregate
if (areViewlessTimeseriesEnabled(testDB)) {
const res = collTimeseries.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog(collTimeseries.getFullName() + " $listCatalog: " + tojson(res));
checkEntries(collTimeseries, res, "timeseries", {numSecondaryIndexes: 0});
} else {
assert.commandFailedWithCode(
testDB.runCommand({aggregate: collTimeseries.getName(), pipeline: [{$listCatalog: {}}], cursor: {}}),
40602,
);
}
// collection-less aggregate
const res = adminDB.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog("Collectionless $listCatalog: " + tojson(res));
if (areViewlessTimeseriesEnabled(testDB)) {
checkEntries(collTimeseries, res, "timeseries", {numSecondaryIndexes: 0});
} else {
checkEntries(collTimeseries, res, "timeseries", {
viewOn: getTimeseriesBucketsColl(collTimeseries).getName(),
});
}
});
it("clustered collection", () => {
assert.commandWorked(testDB.createCollection("clustered", {clusteredIndex: {key: {_id: 1}, unique: true}}));
const collClustered = testDB.clustered;
assert.commandWorked(collClustered.insert({_id: 2, y: "abc"}));
// collection-ful aggregate
{
const res = collClustered.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog(collClustered.getFullName() + " $listCatalog: " + tojson(res));
checkEntries(collClustered, res, "collection", {numSecondaryIndexes: 0});
}
// collection-less aggregate
{
const res = adminDB.aggregate([{$listCatalog: {}}]).toArray();
jsTestLog("Collectionless $listCatalog: " + tojson(res));
checkEntries(collClustered, res, "collection", {numSecondaryIndexes: 0});
}
});
it("$listCatalog can't run on a non-admin DB", () => {
assert.commandFailedWithCode(
testDB.runCommand({aggregate: 1, pipeline: [{$listCatalog: {}}], cursor: {}}),
ErrorCodes.InvalidNamespace,
);
});
});

View File

@ -122,6 +122,7 @@ createIndexAndCheckConsistency(db.collection_simple, {fHidden: 1}, {hidden: true
createIndexAndCheckConsistency(db.collection_simple, {fNamed: 1}, {name: "namedindex"});
createIndexAndCheckConsistency(db.collection_simple, {fCollation: 1}, {collation: {locale: "es"}});
createIndexAndCheckConsistency(db.collection_simple, {"$**": 1});
createIndexAndCheckConsistency(db.collection_simple, {fCompoundWildcard: 1, "b.$**": 1});
createIndexAndCheckConsistency(db.collection_simple, {fText: "text"});
createIndexAndCheckConsistency(db.collection_simple, {fHashed: "hashed"});
createIndexAndCheckConsistency(db.collection_simple, {f2d: "2d"});

View File

@ -1,9 +1,4 @@
// @tags: [
// # Cannot implicitly shard accessed collections because of collection existing when none
// # expected.
// assumes_no_implicit_collection_creation_after_drop,
// # Asserts on the output of listIndexes.
// assumes_no_implicit_index_creation,
// requires_getmore,
// # This test relies on listIncex command returning specific batch-sized responses.
// assumes_no_implicit_cursor_exhaustion,
@ -12,6 +7,7 @@
// Basic functional tests for the listIndexes command.
import {FixtureHelpers} from "jstests/libs/fixture_helpers.js";
import {IndexUtils} from "jstests/libs/index_utils.js";
let coll = db.list_indexes1;
let cursor;
@ -29,7 +25,11 @@ assert.commandWorked(res);
assert.eq("object", typeof res.cursor);
assert.eq(0, res.cursor.id);
assert.eq(coll.getFullName(), res.cursor.ns);
assert.eq(1, res.cursor.firstBatch.length);
if (!FixtureHelpers.isSharded(coll)) {
assert.eq(1, res.cursor.firstBatch.length);
} else {
assert.gte(res.cursor.firstBatch.length, 1);
}
assert.eq("_id_", res.cursor.firstBatch[0].name);
//
@ -41,20 +41,18 @@ let getListIndexesCursor = function (coll, options, subsequentBatchSize) {
};
let cursorGetIndexSpecs = function (cursor) {
return cursor.toArray().sort(function (a, b) {
return a.name > b.name;
});
return cursor.toArray();
};
let cursorGetIndexNames = function (cursor) {
let cursorGetIndexKeys = function (cursor) {
return cursorGetIndexSpecs(cursor).map(function (spec) {
return spec.name;
return spec.key;
});
};
coll.drop();
assert.commandWorked(coll.getDB().createCollection(coll.getName()));
assert.eq(["_id_"], cursorGetIndexNames(getListIndexesCursor(coll)));
IndexUtils.assertIndexesMatch(coll, [{_id: 1}], cursorGetIndexKeys(getListIndexesCursor(coll)));
//
// Test that the index metadata object is returned correctly.
@ -62,15 +60,18 @@ assert.eq(["_id_"], cursorGetIndexNames(getListIndexesCursor(coll)));
coll.drop();
assert.commandWorked(coll.getDB().createCollection(coll.getName()));
assert.commandWorked(coll.createIndex({a: 1}, {unique: true}));
specs = cursorGetIndexSpecs(getListIndexesCursor(coll));
assert.eq(2, specs.length);
assert.eq("_id_", specs[0].name);
assert.eq({_id: 1}, specs[0].key);
assert(!specs[0].hasOwnProperty("unique"));
assert.eq("a_1", specs[1].name);
assert.eq({a: 1}, specs[1].key);
assert.eq(true, specs[1].unique);
assert.commandWorked(coll.createIndex({a: 1}, {sparse: true}));
const specIndexes = cursorGetIndexSpecs(getListIndexesCursor(coll));
IndexUtils.assertIndexesMatch(
coll,
[{_id: 1}, {a: 1}],
specIndexes.map((spec) => spec.key),
);
const idSpec = specIndexes.find((spec) => spec.name === "_id_");
assert.neq(undefined, idSpec);
assert.eq(undefined, idSpec.sparse);
assert.eq(true, specIndexes.find((spec) => spec.name === "a_1").sparse);
//
// Test that the command does not accept invalid values for the collection.
@ -87,31 +88,31 @@ assert.commandFailed(coll.getDB().runCommand({listIndexes: []}));
coll.drop();
assert.commandWorked(coll.getDB().createCollection(coll.getName()));
assert.commandWorked(coll.createIndex({a: 1}, {unique: true}));
assert.commandWorked(coll.createIndex({a: 1}, {sparse: true}));
cursor = getListIndexesCursor(coll, {cursor: {batchSize: 2}});
assert.eq(2, cursor.objsLeftInBatch());
assert.eq(["_id_", "a_1"], cursorGetIndexNames(cursor));
IndexUtils.assertIndexesMatch(coll, [{_id: 1}, {a: 1}], cursorGetIndexKeys(cursor));
cursor = getListIndexesCursor(coll, {cursor: {batchSize: 1}});
assert.eq(1, cursor.objsLeftInBatch());
assert.eq(["_id_", "a_1"], cursorGetIndexNames(cursor));
IndexUtils.assertIndexesMatch(coll, [{_id: 1}, {a: 1}], cursorGetIndexKeys(cursor));
cursor = getListIndexesCursor(coll, {cursor: {batchSize: 0}});
assert.eq(0, cursor.objsLeftInBatch());
assert.eq(["_id_", "a_1"], cursorGetIndexNames(cursor));
IndexUtils.assertIndexesMatch(coll, [{_id: 1}, {a: 1}], cursorGetIndexKeys(cursor));
cursor = getListIndexesCursor(coll, {cursor: {batchSize: NumberInt(2)}});
assert.eq(2, cursor.objsLeftInBatch());
assert.eq(["_id_", "a_1"], cursorGetIndexNames(cursor));
IndexUtils.assertIndexesMatch(coll, [{_id: 1}, {a: 1}], cursorGetIndexKeys(cursor));
cursor = getListIndexesCursor(coll, {cursor: {batchSize: NumberLong(2)}});
assert.eq(2, cursor.objsLeftInBatch());
assert.eq(["_id_", "a_1"], cursorGetIndexNames(cursor));
IndexUtils.assertIndexesMatch(coll, [{_id: 1}, {a: 1}], cursorGetIndexKeys(cursor));
cursor = getListIndexesCursor(coll, {cursor: {batchSize: Math.pow(2, 62)}});
assert.eq(2, cursor.objsLeftInBatch());
assert.eq(["_id_", "a_1"], cursorGetIndexNames(cursor));
assert.gte(cursor.objsLeftInBatch(), 2);
IndexUtils.assertIndexesMatch(coll, [{_id: 1}, {a: 1}], cursorGetIndexKeys(cursor));
// Ensure that the server accepts an empty object for "cursor". This is equivalent to not
// specifying "cursor" at all.
@ -119,7 +120,7 @@ assert.eq(["_id_", "a_1"], cursorGetIndexNames(cursor));
// We do not test for objsLeftInBatch() here, since the default batch size for this command is
// not specified.
cursor = getListIndexesCursor(coll, {cursor: {}});
assert.eq(["_id_", "a_1"], cursorGetIndexNames(cursor));
IndexUtils.assertIndexesMatch(coll, [{_id: 1}, {a: 1}], cursorGetIndexKeys(cursor));
//
// Test more than 2 batches of results.
@ -127,9 +128,9 @@ assert.eq(["_id_", "a_1"], cursorGetIndexNames(cursor));
coll.drop();
assert.commandWorked(coll.getDB().createCollection(coll.getName()));
assert.commandWorked(coll.createIndex({a: 1}, {unique: true}));
assert.commandWorked(coll.createIndex({b: 1}, {unique: true}));
assert.commandWorked(coll.createIndex({c: 1}, {unique: true}));
assert.commandWorked(coll.createIndex({a: 1}, {sparse: true}));
assert.commandWorked(coll.createIndex({b: 1}, {sparse: true}));
assert.commandWorked(coll.createIndex({c: 1}, {sparse: true}));
cursor = getListIndexesCursor(coll, {cursor: {batchSize: 0}}, 2);
assert.eq(0, cursor.objsLeftInBatch());
@ -149,7 +150,9 @@ assert(cursor.hasNext());
assert.eq(1, cursor.objsLeftInBatch());
cursor.next();
assert(!cursor.hasNext());
if (!FixtureHelpers.isSharded(coll) && !TestData.implicitWildcardIndexesEnabled) {
assert(!cursor.hasNext());
}
//
// Test killCursors against a listCollections cursor.
@ -157,9 +160,9 @@ assert(!cursor.hasNext());
coll.drop();
assert.commandWorked(coll.getDB().createCollection(coll.getName()));
assert.commandWorked(coll.createIndex({a: 1}, {unique: true}));
assert.commandWorked(coll.createIndex({b: 1}, {unique: true}));
assert.commandWorked(coll.createIndex({c: 1}, {unique: true}));
assert.commandWorked(coll.createIndex({a: 1}, {sparse: true}));
assert.commandWorked(coll.createIndex({b: 1}, {sparse: true}));
assert.commandWorked(coll.createIndex({c: 1}, {sparse: true}));
res = coll.runCommand("listIndexes", {cursor: {batchSize: 0}});
cursor = new DBCommandCursor(coll.getDB(), res, 2);

View File

@ -2,11 +2,9 @@
* Tests that clustered collections respect collation for the _id field and any other fields
*
* @tags: [
* assumes_against_mongod_not_mongos,
* assumes_no_implicit_collection_creation_after_drop,
* assumes_no_implicit_index_creation,
* # Clustered collections cannot be sharded.
* assumes_unsharded_collection,
* does_not_support_stepdowns,
* requires_fcv_53,
* ]
*/

View File

@ -1,11 +1,13 @@
// SERVER-5826 ensure you can't build an index with a non-existent plugin
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.bad_index_plugin;
assert.commandWorked(t.createIndex({good: 1}));
assert.eq(t.getIndexes().length, 2); // good + _id
IndexUtils.assertIndexes(t, [{_id: 1}, {good: 1}]);
let err = t.createIndex({bad: "bad"});
assert.commandFailed(err);
assert(err.code >= 0);
assert.eq(t.getIndexes().length, 2); // good + _id (no bad)
IndexUtils.assertIndexes(t, [{_id: 1}, {good: 1}]); // (no bad)

View File

@ -1,133 +1,20 @@
/**
* @tags: [
* assumes_superuser_permissions,
* # TODO SERVER-88069: this test can be run in upgrade downgrade once
* # createdCollectionAutomatically is removed.
* cannot_run_during_upgrade_downgrade,
* # simulate_atlas_proxy.js can't simulate req on config.transaction as tested
* simulate_atlas_proxy_incompatible,
* ]
* fcv49 for the change to error code in createIndexes invalid field reply.
*/
import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js";
import {FixtureHelpers} from "jstests/libs/fixture_helpers.js";
const runningOnMongos = FixtureHelpers.isMongos(db);
const extractResult = function (obj) {
if (!runningOnMongos) return obj;
// Sample mongos format:
// {
// raw: {
// "localhost:30000": {
// createdCollectionAutomatically: false,
// numIndexesBefore: 3,
// numIndexesAfter: 5,
// ok: 1
// }
// },
// ok: 1
// }
let numFields = 0;
let result = null;
for (let field in obj.raw) {
result = obj.raw[field];
numFields++;
}
assert.neq(null, result);
assert.eq(1, numFields);
return result;
};
// TODO SERVER-88069: remove check once createdCollectionAutomatically is removed.
const checkImplicitCreate = function (admin, createIndexResult) {
const isMultiversion = Boolean(jsTest.options().useRandomBinVersionsWithinReplicaSet);
if (!isMultiversion && !FeatureFlagUtil.isPresentAndEnabled(admin, "80CollectionCreationPath")) {
assert.eq(true, createIndexResult.createdCollectionAutomatically);
}
};
const assertIndexes = function (coll, expectedIndexNames) {
const indexSpecs = coll.getIndexes();
const indexNames = indexSpecs.map((spec) => spec.name);
assert.sameMembers(indexNames, expectedIndexNames, tojson(indexSpecs));
};
import {IndexUtils} from "jstests/libs/index_utils.js";
const dbTest = db.getSiblingDB("create_indexes_db");
dbTest.dropDatabase();
// Database does not exist
const collDbNotExist = dbTest.create_indexes_no_db;
let res = assert.commandWorked(collDbNotExist.runCommand("createIndexes", {indexes: [{key: {x: 1}, name: "x_1"}]}));
res = extractResult(res);
checkImplicitCreate(dbTest.getSiblingDB("config"), res);
assert.eq(res.numIndexesAfter, res.numIndexesBefore + 1);
assert.isnull(res.note, "createIndexes.note should not be present in results when adding a new index: " + tojson(res));
// Collection does not exist, but database does
const t = dbTest.create_indexes;
res = assert.commandWorked(t.runCommand("createIndexes", {indexes: [{key: {x: 1}, name: "x_1"}]}));
res = extractResult(res);
checkImplicitCreate(dbTest.getSiblingDB("config"), res);
assert.eq(res.numIndexesAfter, res.numIndexesBefore + 1);
assert.isnull(res.note, "createIndexes.note should not be present in results when adding a new index: " + tojson(res));
// Both database and collection exist
res = assert.commandWorked(t.runCommand("createIndexes", {indexes: [{key: {x: 1}, name: "x_1"}]}));
res = extractResult(res);
assert(!res.createdCollectionAutomatically);
assert.eq(
res.numIndexesBefore,
res.numIndexesAfter,
"numIndexesAfter missing from createIndexes result when adding a duplicate index: " + tojson(res),
);
assert(res.note, "createIndexes.note should be present in results when adding a duplicate index: " + tojson(res));
res = t.runCommand("createIndexes", {
indexes: [
{key: {"x": 1}, name: "x_1"},
{key: {"y": 1}, name: "y_1"},
],
});
res = extractResult(res);
assert(!res.createdCollectionAutomatically);
assert.eq(res.numIndexesAfter, res.numIndexesBefore + 1);
res = assert.commandWorked(
t.runCommand("createIndexes", {
indexes: [
{key: {a: 1}, name: "a_1"},
{key: {b: 1}, name: "b_1"},
],
}),
);
res = extractResult(res);
assert(!res.createdCollectionAutomatically);
assert.eq(res.numIndexesAfter, res.numIndexesBefore + 2);
assert.isnull(res.note, "createIndexes.note should not be present in results when adding new indexes: " + tojson(res));
res = assert.commandWorked(
t.runCommand("createIndexes", {
indexes: [
{key: {a: 1}, name: "a_1"},
{key: {b: 1}, name: "b_1"},
],
}),
);
res = extractResult(res);
assert.eq(
res.numIndexesBefore,
res.numIndexesAfter,
"numIndexesAfter missing from createIndexes result when adding duplicate indexes: " + tojson(res),
);
assert(res.note, "createIndexes.note should be present in results when adding a duplicate index: " + tojson(res));
dbTest.createCollection(t.getName());
// Test that index creation fails with an empty list of specs.
res = t.runCommand("createIndexes", {indexes: []});
let res = t.runCommand("createIndexes", {indexes: []});
assert.commandFailedWithCode(res, ErrorCodes.BadValue);
// Test that index creation fails on specs that are missing required fields such as 'key'.
@ -138,10 +25,11 @@ assert.commandFailedWithCode(res, ErrorCodes.FailedToParse);
// will not result in new indexes in the catalog.
res = t.runCommand("createIndexes", {indexes: [{}, {key: {m: 1}, name: "asd"}]});
assert.commandFailedWithCode(res, ErrorCodes.FailedToParse);
assertIndexes(t, ["_id_", "x_1", "y_1", "a_1", "b_1"]);
IndexUtils.assertIndexes(t, [{_id: 1}]);
res = t.runCommand("createIndexes", {indexes: [{key: {"c": 1}, sparse: true, name: "c_1"}]});
assertIndexes(t, ["_id_", "x_1", "y_1", "a_1", "b_1", "c_1"]);
IndexUtils.assertIndexes(t, [{_id: 1}, {c: 1}]);
assert.eq(
1,
t.getIndexes().filter(function (z) {
@ -153,22 +41,26 @@ assert.eq(
res = t.runCommand("createIndexes", {indexes: [{key: {"x": "invalid_index_type"}, name: "x_1"}]});
assert.commandFailedWithCode(res, ErrorCodes.CannotCreateIndex);
assertIndexes(t, ["_id_", "x_1", "y_1", "a_1", "b_1", "c_1"]);
IndexUtils.assertIndexes(t, [{_id: 1}, {c: 1}]);
// Test that an index name, if provided by the user, cannot be empty.
res = t.runCommand("createIndexes", {indexes: [{key: {"x": 1}, name: ""}]});
assert.commandFailedWithCode(res, ErrorCodes.CannotCreateIndex);
assertIndexes(t, ["_id_", "x_1", "y_1", "a_1", "b_1", "c_1"]);
IndexUtils.assertIndexes(t, [{_id: 1}, {c: 1}]);
// Test that v0 indexes cannot be created.
res = t.runCommand("createIndexes", {indexes: [{key: {d: 1}, name: "d_1", v: 0}]});
assert.commandFailed(res, "v0 index creation should fail");
IndexUtils.assertIndexes(t, [{_id: 1}, {c: 1}]);
// Test that v1 indexes can be created explicitly.
res = t.runCommand("createIndexes", {indexes: [{key: {d: 1}, name: "d_1", v: 1}]});
assert.commandWorked(res, "v1 index creation should succeed");
IndexUtils.assertIndexes(t, [{_id: 1}, {c: 1}, {d: 1}]);
// Test that index creation fails with an invalid top-level field.
res = t.runCommand("createIndexes", {indexes: [{key: {e: 1}, name: "e_1"}], "invalidField": 1});
assert.commandFailedWithCode(res, ErrorCodes.IDLUnknownField);
@ -181,6 +73,8 @@ assert.commandFailedWithCode(res, ErrorCodes.InvalidIndexSpecificationOption);
res = t.runCommand("createIndexes", {indexes: [{key: {e: 1}, name: "e_1", "v": 1, "invalidField": 1}]});
assert.commandFailedWithCode(res, ErrorCodes.InvalidIndexSpecificationOption);
IndexUtils.assertIndexes(t, [{_id: 1}, {c: 1}, {d: 1}]);
// Test that index creation fails with an index named '*'.
res = t.runCommand("createIndexes", {indexes: [{key: {star: 1}, name: "*"}]});
assert.commandFailedWithCode(res, ErrorCodes.BadValue);
@ -198,6 +92,8 @@ res = t.runCommand("createIndexes", {
});
assert.commandFailedWithCode(res, ErrorCodes.IndexKeySpecsConflict);
IndexUtils.assertIndexes(t, [{_id: 1}, {c: 1}, {d: 1}]);
// Test that creating an index on a view fails with CollectionUUIDMismatch if a collection UUID is
// provided. CollectionUUIDMismatch has to prevail over CommandNotSupportedOnView for mongosync.
assert.commandWorked(db.createView("toApple", "apple", []));

View File

@ -0,0 +1,117 @@
/**
* Tests the fields in the response of the createIndexes command.
*
* @tags: [
* # The createIndexes response fields are not reliable on stepdowns due to implicit retries.
* # Therefore, the numIndexesBefore may be equal to numIndexesAfter if the index was created
* # before the migration.
* does_not_support_stepdowns,
* # Migrations may interrupt createIndexes operations, forcing a retry. Therefore, the
* # numIndexesBefore may be equal to numIndexesAfter if the index was created before the
* # migration.
* assumes_balancer_off,
* ]
*/
import {FixtureHelpers} from "jstests/libs/fixture_helpers.js";
const dbTest = db.getSiblingDB(jsTestName());
dbTest.dropDatabase();
function checkResponse(res, coll, checkFunc) {
assert(checkFunc, "checkFunc must be provided to checkResponse");
if (!FixtureHelpers.isMongos(dbTest)) {
checkFunc(res);
return;
}
// On sharded clusters, check the 'raw' field for each shard.
assert(res.hasOwnProperty("raw"), "Expected 'raw' field in createIndexes response: " + tojson(res));
for (const shardField in res.raw) {
checkFunc(res.raw[shardField]);
}
if (!FixtureHelpers.isSharded(coll)) {
// If the collection is not sharded, also check the top-level response.
checkFunc(res);
}
}
// Database does not exist
const collDbNotExist = dbTest.create_indexes_no_db;
let res = assert.commandWorked(collDbNotExist.runCommand("createIndexes", {indexes: [{key: {x: 1}, name: "x_1"}]}));
checkResponse(res, collDbNotExist, (res) => {
assert.eq(res.numIndexesAfter, res.numIndexesBefore + 1);
assert.isnull(
res.note,
"createIndexes.note should not be present in results when adding a new index: " + tojson(res),
);
});
// Collection does not exist, but database does
const t = dbTest.create_indexes;
res = assert.commandWorked(t.runCommand("createIndexes", {indexes: [{key: {x: 1}, name: "x_1"}]}));
checkResponse(res, t, (res) => {
assert.eq(res.numIndexesAfter, res.numIndexesBefore + 1);
assert.isnull(
res.note,
"createIndexes.note should not be present in results when adding a new index: " + tojson(res),
);
});
// Both database and collection exist
res = assert.commandWorked(t.runCommand("createIndexes", {indexes: [{key: {x: 1}, name: "x_1"}]}));
checkResponse(res, t, (res) => {
assert.eq(
res.numIndexesBefore,
res.numIndexesAfter,
"numIndexesAfter missing from createIndexes result when adding a duplicate index: " + tojson(res),
);
assert(res.note, "createIndexes.note should be present in results when adding a duplicate index: " + tojson(res));
});
res = t.runCommand("createIndexes", {
indexes: [
{key: {"x": 1}, name: "x_1"},
{key: {"y": 1}, name: "y_1"},
],
});
checkResponse(res, t, (res) => {
assert.eq(res.numIndexesAfter, res.numIndexesBefore + 1);
});
res = assert.commandWorked(
t.runCommand("createIndexes", {
indexes: [
{key: {a: 1}, name: "a_1"},
{key: {b: 1}, name: "b_1"},
],
}),
);
checkResponse(res, t, (res) => {
assert.eq(res.numIndexesAfter, res.numIndexesBefore + 2);
assert.isnull(
res.note,
"createIndexes.note should not be present in results when adding new indexes: " + tojson(res),
);
});
res = assert.commandWorked(
t.runCommand("createIndexes", {
indexes: [
{key: {a: 1}, name: "a_1"},
{key: {b: 1}, name: "b_1"},
],
}),
);
checkResponse(res, t, (res) => {
assert.eq(
res.numIndexesBefore,
res.numIndexesAfter,
"numIndexesAfter missing from createIndexes result when adding duplicate indexes: " + tojson(res),
);
assert(res.note, "createIndexes.note should be present in results when adding a duplicate index: " + tojson(res));
});

View File

@ -1,37 +1,18 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [assumes_no_implicit_index_creation]
import {FixtureHelpers} from "jstests/libs/fixture_helpers.js";
import {IndexUtils} from "jstests/libs/index_utils.js";
const t = db.drop_index;
t.drop();
/**
* Extracts index names from listIndexes result.
*/
function getIndexNames(cmdRes) {
return t.getIndexes().map((spec) => spec.name);
}
/**
* Checks that collection contains the given list of non-id indexes and nothing else.
*/
function assertIndexes(expectedIndexNames, msg) {
const actualIndexNames = getIndexNames();
const testMsgSuffix = () =>
msg + ": expected " + tojson(expectedIndexNames) + " but got " + tojson(actualIndexNames) + " instead.";
assert.eq(
expectedIndexNames.length + 1,
actualIndexNames.length,
"unexpected number of indexes after " + testMsgSuffix(),
);
assert(actualIndexNames.includes("_id_"), "_id index missing after " + msg + ": " + tojson(actualIndexNames));
for (let expectedIndexName of expectedIndexNames) {
assert(
actualIndexNames.includes(expectedIndexName),
expectedIndexName + " index missing after " + testMsgSuffix(),
);
}
function assertIndexes(expectedIndexes, msg) {
expectedIndexes.push({_id: 1});
IndexUtils.assertIndexes(t, expectedIndexes, "Unexpected indexes after " + msg);
}
assert.commandWorked(t.insert({_id: 1, a: 2, b: 3, c: 1, d: 1, e: 1}));
@ -42,16 +23,16 @@ assert.commandWorked(t.createIndex({b: 1}));
assert.commandWorked(t.createIndex({c: 1}));
assert.commandWorked(t.createIndex({d: 1}));
assert.commandWorked(t.createIndex({e: 1}));
assertIndexes(["a_1", "b_1", "c_1", "d_1", "e_1"], "creating indexes");
assertIndexes([{a: 1}, {b: 1}, {c: 1}, {d: 1}, {e: 1}], "creating indexes");
// Drop single index by name.
// Collection.dropIndex() throws if the dropIndexes command fails.
assert.commandWorked(t.dropIndex(t._genIndexName({a: 1})));
assertIndexes(["b_1", "c_1", "d_1", "e_1"], "dropping {a: 1} by name");
assertIndexes([{b: 1}, {c: 1}, {d: 1}, {e: 1}], "dropping {a: 1} by name");
// Drop single index by key pattern.
assert.commandWorked(t.dropIndex({b: 1}));
assertIndexes(["c_1", "d_1", "e_1"], "dropping {b: 1} by key pattern");
assertIndexes([{c: 1}, {d: 1}, {e: 1}], "dropping {b: 1} by key pattern");
const runningOnMongos = FixtureHelpers.isMongos(db);
@ -70,8 +51,8 @@ for (const dropIndexArg of ["_id_", {_id: 1}]) {
// Prior to SERVER-7168, the shell used to cache names of indexes created using
// Collection.createIndex().
assert.commandWorked(t.createIndex({a: 1}));
assertIndexes(["a_1", "c_1", "d_1", "e_1"], "recreating {a: 1}");
assertIndexes([{a: 1}, {c: 1}, {d: 1}, {e: 1}], "recreating {a: 1}");
// Drop single index with dropIndexes().
assert.commandWorked(t.dropIndexes(["c_1"]));
assertIndexes(["a_1", "d_1", "e_1"], "dropping {c: 1}");
assertIndexes([{a: 1}, {d: 1}, {e: 1}], "dropping {c: 1}");

View File

@ -1,7 +1,9 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection. Cannot be handled correctly in a stepdown suite since dropIndexes() with multiple
// names cannot be retried properly.
// @tags: [assumes_no_implicit_index_creation, does_not_support_stepdowns]
/**
* Tests the dropIndexes command.
*/
import {IndexUtils} from "jstests/libs/index_utils.js";
const t = db.drop_indexes;
t.drop();
@ -34,18 +36,18 @@ function assertIndexes(expectedIndexNames, msg) {
}
assert.commandWorked(t.insert({_id: 1, a: 2, b: 3, c: 1, d: 1, e: 1}));
assertIndexes([], "inserting test document");
IndexUtils.assertIndexes(t, [{_id: 1}], "inserting test document");
assert.commandWorked(t.createIndex({a: 1}));
assert.commandWorked(t.createIndex({b: 1}));
assert.commandWorked(t.createIndex({c: 1}));
assert.commandWorked(t.createIndex({d: 1}));
assert.commandWorked(t.createIndex({e: 1}));
assertIndexes(["a_1", "b_1", "c_1", "d_1", "e_1"], "creating indexes");
IndexUtils.assertIndexes(t, [{_id: 1}, {a: 1}, {b: 1}, {c: 1}, {d: 1}, {e: 1}], "creating indexes");
// Drop multiple indexes.
assert.commandWorked(t.dropIndexes(["c_1", "d_1"]));
assertIndexes(["a_1", "b_1", "e_1"], "dropping {c: 1} and {d: 1}");
IndexUtils.assertIndexes(t, [{_id: 1}, {a: 1}, {b: 1}, {e: 1}], "dropping {c: 1} and {d: 1}");
// Must drop all the indexes provided or none at all - for example, if one of the index names
// provided is invalid.
@ -53,11 +55,15 @@ let ex = assert.throws(() => {
t.dropIndexes(["a_1", "_id_"]);
});
assert.commandFailedWithCode(ex, ErrorCodes.InvalidOptions);
assertIndexes(["a_1", "b_1", "e_1"], "failed dropIndexes command with _id index");
IndexUtils.assertIndexes(t, [{_id: 1}, {a: 1}, {b: 1}, {e: 1}], "failed dropIndexes command with _id index");
// List of index names must contain only strings.
ex = assert.throws(() => {
t.dropIndexes(["a_1", 123]);
});
assert.commandFailedWithCode(ex, ErrorCodes.TypeMismatch);
assertIndexes(["a_1", "b_1", "e_1"], "failed dropIndexes command with non-string index name");
IndexUtils.assertIndexes(
t,
[{_id: 1}, {a: 1}, {b: 1}, {e: 1}],
"failed dropIndexes command with non-string index name",
);

View File

@ -1,8 +1,3 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// ]
import {queryIDS} from "jstests/libs/fts.js";
const coll = db.text1;

View File

@ -1,8 +1,4 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// ]
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.text_blogwild;
t.drop();
@ -19,7 +15,7 @@ t.save({
// specify weights if you want a field to be more meaningful
t.createIndex({dummy: "text"}, {weights: "$**"});
// ensure listIndexes can handle a string-valued "weights"
assert.eq(2, t.getIndexes().length);
IndexUtils.assertIndexes(t, [{_id: 1}, {_fts: "text", _ftsx: 1}]);
let res = t.find({"$text": {"$search": "blog"}});
assert.eq(3, res.length(), "A1");
@ -29,7 +25,8 @@ assert.eq(3, res.length(), "B1");
// mixing
t.dropIndex("dummy_text");
assert.eq(1, t.getIndexKeys().length, "C1");
IndexUtils.assertIndexes(t, [{_id: 1}]);
t.createIndex({dummy: "text"}, {weights: {"$**": 1, title: 2}});
res = t.find({"$text": {"$search": "write"}}, {score: {"$meta": "textScore"}}).sort({

View File

@ -1,10 +1,9 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// requires_fastcount,
// ]
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.geo1;
t.drop();
@ -15,12 +14,13 @@ t.insert({zip: "10024", loc: [40.786387, 73.97709]});
assert.commandWorked(t.insert({zip: "94061", loc: [37.463911, 122.23396]}));
// test "2d" has to be first
assert.eq(1, t.getIndexKeys().length, "S1");
t.createIndex({zip: 1, loc: "2d"});
assert.eq(1, t.getIndexKeys().length, "S2");
t.createIndex(idx);
assert.eq(2, t.getIndexKeys().length, "S3");
IndexUtils.assertIndexes(t, [{_id: 1}]);
assert.commandFailed(t.createIndex({zip: 1, loc: "2d"}));
IndexUtils.assertIndexes(t, [{_id: 1}]);
assert.commandWorked(t.createIndex(idx));
IndexUtils.assertIndexes(t, [{_id: 1}, idx]);
assert.eq(3, t.count(), "B1");
assert.writeError(t.insert({loc: [200, 200]}));
@ -39,5 +39,5 @@ assert.eq("06525", t.find({loc: wb.loc})[0].zip, "C3");
t.drop();
t.createIndex({loc: "2d"}, {min: -500, max: 500, bits: 4});
assert.commandWorked(t.createIndex({loc: "2d"}, {min: -500, max: 500, bits: 4}));
assert.commandWorked(t.insert({loc: [200, 200]}));

View File

@ -1,24 +1,23 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// requires_getmore,
// ]
// Test for SERVER-2746
import {IndexUtils} from "jstests/libs/index_utils.js";
let coll = db.geo10;
coll.drop();
assert.commandWorked(db.geo10.createIndex({c: "2d", t: 1}, {min: 0, max: Math.pow(2, 40)}));
assert.eq(2, db.geo10.getIndexes().length, "A3");
assert.commandWorked(coll.createIndex({c: "2d", t: 1}, {min: 0, max: Math.pow(2, 40)}));
IndexUtils.assertIndexes(coll, [{_id: 1}, {c: "2d", t: 1}]);
assert.commandWorked(db.geo10.insert({c: [1, 1], t: 1}));
assert.commandWorked(db.geo10.insert({c: [3600, 3600], t: 1}));
assert.commandWorked(db.geo10.insert({c: [0.001, 0.001], t: 1}));
assert.commandWorked(coll.insert({c: [1, 1], t: 1}));
assert.commandWorked(coll.insert({c: [3600, 3600], t: 1}));
assert.commandWorked(coll.insert({c: [0.001, 0.001], t: 1}));
printjson(
db.geo10
coll
.find({
c: {
$within: {

View File

@ -1,11 +1,11 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// requires_getmore,
// ]
// Make sure the very basics of geo arrays are sane by creating a few multi location docs
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.geoarray;
function test(index) {
@ -35,7 +35,7 @@ function test(index) {
if (index) {
assert.commandWorked(t.createIndex({loc: "2d", zip: 1}));
assert.eq(2, t.getIndexKeys().length);
IndexUtils.assertIndexes(t, [{_id: 1}, {loc: "2d", zip: 1}]);
}
res = t.insert({

View File

@ -1,12 +1,11 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// requires_getmore,
// ]
// Make sure nesting of location arrays also works.
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.geonest;
t.drop();
@ -34,7 +33,7 @@ let res = t.insert({
assert.commandWorked(res);
assert.commandWorked(t.createIndex({"data.loc": "2d", zip: 1}));
assert.eq(2, t.getIndexKeys().length);
IndexUtils.assertIndexes(t, [{_id: 1}, {"data.loc": "2d", zip: 1}]);
res = t.insert({
zip: "10004",
@ -111,7 +110,7 @@ res = t.insert({zip: "10003", data: [{loc: [{x: 30, y: 30}, [50, 50]], type: "ho
assert(!res.hasWriteError());
assert.commandWorked(t.createIndex({"data.loc": "2d", zip: 1}));
assert.eq(2, t.getIndexKeys().length);
IndexUtils.assertIndexes(t, [{_id: 1}, {"data.loc": "2d", zip: 1}]);
res = t.insert({
zip: "10004",

View File

@ -1,12 +1,11 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// requires_getmore,
// ]
// Test distance queries with interleaved distances
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.multinest;
t.drop();
@ -34,7 +33,7 @@ let res = t.insert({
assert.commandWorked(res);
assert.commandWorked(t.createIndex({"data.loc": "2d", zip: 1}));
assert.eq(2, t.getIndexKeys().length);
IndexUtils.assertIndexes(t, [{_id: 1}, {"data.loc": "2d", zip: 1}]);
res = t.insert({
zip: "10004",

View File

@ -1,9 +1,3 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// ]
//
// We should prohibit polygons with holes not bounded by their exterior shells.
//
@ -13,6 +7,10 @@
// any others must be interior rings or holes."
// http://geojson.org/geojson-spec.html#polygon
//
// @tags: [
// # TODO (SERVER-113531) enable once the ticket is addressed.
// assumes_balancer_off,
// ]
const coordinates = [
// One square.

View File

@ -1,10 +1,6 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// ]
// Testing indexes in nested fields.
// index4.js
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.index4;
t.drop();
@ -14,10 +10,11 @@ t.save({name: "alleyinsider", instances: [{pool: "prod1"}, {pool: "dev1"}]});
t.save({name: "clusterstock", instances: [{pool: "dev1"}]});
// this should fail, not allowed -- we confirm that.
t.createIndex({instances: {pool: 1}});
assert.eq(1, t.getIndexes().length, "no indexes other than _id should be here yet");
assert.commandFailed(t.createIndex({instances: {pool: 1}}));
IndexUtils.assertIndexes(t, [{_id: 1}], "no indexes other than _id should be here yet");
t.createIndex({"instances.pool": 1});
assert.commandWorked(t.createIndex({"instances.pool": 1}));
IndexUtils.assertIndexes(t, [{_id: 1}, {"instances.pool": 1}]);
sleep(10);

View File

@ -3,8 +3,6 @@
// @tags: [
// # The test runs commands that are not allowed with security token: reIndex.
// not_allowed_with_signed_security_token,
// # Asserts on the output of listIndexes.
// assumes_no_implicit_index_creation,
// # Cannot implicitly shard accessed collections because of not being able to create unique
// # index using hashed shard key pattern.
// cannot_create_unique_index_when_using_hashed_shard_key,
@ -12,6 +10,8 @@
// requires_getmore,
// ]
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.jstests_index8;
t.drop();
@ -21,13 +21,10 @@ t.drop();
t.createIndex({c: 1}, [false, "cIndex"]);
const checkIndexUniqueness = () => {
let indexes = t.getIndexes();
assert.eq(4, indexes.length);
indexes = Object.fromEntries(indexes.map((idx) => [idx.name, idx]));
assert.sameMembers(Object.keys(indexes), ["_id_", "a_1", "b_1", "cIndex"], tojson(indexes));
assert(!indexes["a_1"].unique);
assert(indexes["b_1"].unique);
assert(!indexes["cIndex"].unique);
IndexUtils.assertIndexes(t, [{_id: 1}, {a: 1}, {b: 1}, {c: 1}]);
assert(IndexUtils.indexExists(t, {a: 1}, {unique: undefined}), t.getIndexes());
assert(IndexUtils.indexExists(t, {b: 1}, {unique: true}), t.getIndexes());
assert(IndexUtils.indexExists(t, {c: 1}, {unique: undefined, name: "cIndex"}), t.getIndexes());
};
checkIndexUniqueness();

View File

@ -1,10 +1,11 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// requires_getmore,
// ]
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.index_arr1;
t.drop();
@ -15,10 +16,9 @@ t.insert({_id: 3, a: 5});
assert.eq(3, t.find({a: 5}).itcount(), "A1");
t.createIndex({a: 1, "b.x": 1});
assert.eq(3, t.find({a: 5}).itcount(), "A2"); // SERVER-1082
IndexUtils.assertIndexes(t, [{_id: 1}, {a: 1, "b.x": 1}], "B1");
assert.eq(2, t.getIndexes().length, "B1");
t.insert({_id: 4, a: 5, b: []});
t.createIndex({a: 1, "b.a": 1, "b.c": 1});
assert.eq(3, t.getIndexes().length, "B2");
IndexUtils.assertIndexes(t, [{_id: 1}, {a: 1, "b.x": 1}, {a: 1, "b.a": 1, "b.c": 1}], "B1");

View File

@ -1,10 +1,13 @@
/**
* Test interactions with big index keys. There should be no size limit for index keys.
*
* assumes_no_implicit_index_creation: Cannot implicitly shard accessed collections because of extra
* shard key index in sharded collection.
* requires_non_retryable_writes: This test uses delete which is not retryable
* @tags: [assumes_no_implicit_index_creation, requires_non_retryable_writes]
* @tags: [
* # This test uses delete which is not retryable
* requires_non_retryable_writes,
* # Cannot implicitly shard accessed collections because of not being able to create unique
* # index using hashed shard key pattern.
* cannot_create_unique_index_when_using_hashed_shard_key,
* ]
*/
import {testAllInteractionsWithBigIndexKeys} from "jstests/libs/index_builds/index_bigkeys.js";

View File

@ -6,9 +6,9 @@
// for retrying on interrupt is not prepared to handle aggregation explain.
// @tags: [
// assumes_unsharded_collection,
// # Aggregation commands with explain can't run on stepdown suites because them may return
// # incomplete results if interrupted by a stepdown.
// does_not_support_stepdowns,
// # Test may fail with "index already exists".
// assumes_no_implicit_index_creation,
// # Explain for the aggregate command cannot run within a multi-document transaction.
// does_not_support_transactions,
// ]

View File

@ -1,6 +1,9 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [assumes_no_implicit_index_creation]
// @tags: [
// # Sharded collections can't be clustered.
// assumes_unsharded_collection,
// # This test tests kMaxNumIndexesAllowed.
// assumes_no_implicit_index_creation
// ]
import {ClusteredCollectionUtil} from "jstests/libs/clustered_collections/clustered_collection_util.js";
@ -32,13 +35,13 @@ assert.soon(() => {
// Index creation May fail due to stepdowns and shutdowns. Keep trying until we reach the
// server limit for indexes in a collection.
try {
const numCurrentIndexes = t.getIndexKeys().length;
const numCurrentIndexes = t.getIndexes().length;
for (let i = numCurrentIndexes + 1; i <= maxNumIndexesAllowed; i++) {
const key = make(i);
const res = assert.commandWorked(t.createIndex(key));
jsTestLog("createIndex: " + tojson(key) + ": " + tojson(res));
}
assert.eq(t.getIndexKeys().length, maxNumIndexesAllowed);
assert.eq(t.getIndexes().length, maxNumIndexesAllowed);
return true;
} catch (e) {
jsTest.log("Failed to create indexes: " + e);

View File

@ -1,32 +1,33 @@
// @tags: [
// # Cannot implicitly shard accessed collections because of extra shard key index in sharded
// # collection.
// assumes_no_implicit_index_creation,
// Test partial index creation and drops.
//
// @tags: [
// # Builds index in the background
// requires_background_index,
//
// uses_full_validation,
// requires_fcv_51,
// requires_getmore,
//
// ]
// Test partial index creation and drops.
import {IndexUtils} from "jstests/libs/index_utils.js";
let coll = db.index_partial_create_drop;
let getNumKeys = function (idxName) {
let res = assert.commandWorked(coll.validate({full: true}));
let kpi;
const res = assert.commandWorked(coll.validate({full: true}));
let isShardedNS = res.hasOwnProperty("raw");
if (isShardedNS) {
kpi = res.raw[Object.getOwnPropertyNames(res.raw)[0]].keysPerIndex;
} else {
kpi = res.keysPerIndex;
// If collection is sharded, accumulate number of keys from all shards.
const isShardedColl = res.hasOwnProperty("raw");
if (isShardedColl) {
let totalKpi = 0;
for (let shardId in res.raw) {
const kpi = res.raw[shardId].keysPerIndex[idxName];
if (kpi) {
totalKpi += kpi;
}
}
return totalKpi;
}
return kpi[idxName];
return res.keysPerIndex[idxName];
};
coll.drop();
@ -60,47 +61,71 @@ for (let i = 0; i < 10; i++) {
// Create partial index.
assert.commandWorked(coll.createIndex({x: 1}, {partialFilterExpression: {a: {$lt: 5}}}));
assert.eq(5, getNumKeys("x_1"));
assert(IndexUtils.indexExists(coll, {x: 1}, {partialFilterExpression: {a: {$lt: 5}}}), coll.getIndexes());
assert.commandWorked(coll.dropIndex({x: 1}));
assert.eq(1, coll.getIndexes().length);
assert(!IndexUtils.indexExists(coll, {x: 1}, {partialFilterExpression: {a: {$lt: 5}}}), coll.getIndexes());
IndexUtils.assertIndexes(coll, [{_id: 1}]);
// Create partial index in background.
assert.commandWorked(coll.createIndex({x: 1}, {partialFilterExpression: {a: {$lt: 5}}}));
assert.eq(5, getNumKeys("x_1"));
assert(IndexUtils.indexExists(coll, {x: 1}, {partialFilterExpression: {a: {$lt: 5}}}), coll.getIndexes());
assert.commandWorked(coll.dropIndex({x: 1}));
assert.eq(1, coll.getIndexes().length);
assert(!IndexUtils.indexExists(coll, {x: 1}, {partialFilterExpression: {a: {$lt: 5}}}), coll.getIndexes());
IndexUtils.assertIndexes(coll, [{_id: 1}]);
// Create complete index, same key as previous indexes.
assert.commandWorked(coll.createIndex({x: 1}));
assert.eq(10, getNumKeys("x_1"));
IndexUtils.assertIndexes(coll, [{_id: 1}, {x: 1}]);
assert.commandWorked(coll.dropIndex({x: 1}));
assert.eq(1, coll.getIndexes().length);
IndexUtils.assertIndexes(coll, [{_id: 1}]);
// Partial indexes can't also be sparse indexes.
assert.commandFailed(coll.createIndex({x: 1}, {partialFilterExpression: {a: 1}, sparse: true}));
assert.commandFailed(coll.createIndex({x: 1}, {partialFilterExpression: {a: 1}, sparse: 1}));
assert.commandWorked(coll.createIndex({x: 1}, {partialFilterExpression: {a: 1}, sparse: false}));
assert.eq(2, coll.getIndexes().length);
assert(IndexUtils.indexExists(coll, {x: 1}, {partialFilterExpression: {a: 1}, sparse: false}), coll.getIndexes());
assert.commandWorked(coll.dropIndex({x: 1}));
assert.eq(1, coll.getIndexes().length);
IndexUtils.assertIndexes(coll, [{_id: 1}]);
// SERVER-18858: Verify that query compatible w/ partial index succeeds after index drop.
assert.commandWorked(coll.createIndex({x: 1}, {partialFilterExpression: {a: {$lt: 5}}}));
assert.commandWorked(coll.dropIndex({x: 1}));
assert.eq(1, coll.find({x: 0, a: 0}).itcount());
IndexUtils.assertIndexes(coll, [{_id: 1}]);
// Can create multiple partial indexes on the same key pattern as long as the filter is different.
assert.commandWorked(coll.dropIndexes());
IndexUtils.assertIndexes(coll, [{_id: 1}]);
let numIndexesBefore = coll.getIndexes().length;
assert.commandWorked(coll.createIndex({x: 1}, {name: "partialIndex1", partialFilterExpression: {a: {$lt: 5}}}));
assert.eq(coll.getIndexes().length, numIndexesBefore + 1);
assert(
IndexUtils.indexExists(coll, {x: 1}, {name: "partialIndex1", partialFilterExpression: {a: {$lt: 5}}}),
coll.getIndexes(),
);
IndexUtils.assertIndexes(coll, [{_id: 1}, {x: 1}]);
numIndexesBefore = coll.getIndexes().length;
assert.commandWorked(coll.createIndex({x: 1}, {name: "partialIndex2", partialFilterExpression: {a: {$gte: 5}}}));
assert.eq(coll.getIndexes().length, numIndexesBefore + 1);
assert(
IndexUtils.indexExists(coll, {x: 1}, {name: "partialIndex2", partialFilterExpression: {a: {$gte: 5}}}),
coll.getIndexes(),
);
IndexUtils.assertIndexes(coll, [{_id: 1}, {x: 1}, {x: 1}]);
// Index drop by key pattern fails when more than one index exists with the given key.
numIndexesBefore = coll.getIndexes().length;
assert.commandFailedWithCode(coll.dropIndex({x: 1}), ErrorCodes.AmbiguousIndexKeyPattern);
IndexUtils.assertIndexes(coll, [{_id: 1}, {x: 1}, {x: 1}]);
assert.commandWorked(coll.dropIndex("partialIndex2"));
assert.eq(coll.getIndexes().length, numIndexesBefore - 1);
assert(
!IndexUtils.indexExists(coll, {x: 1}, {name: "partialIndex2", partialFilterExpression: {a: {$gte: 5}}}),
coll.getIndexes(),
);
assert(
IndexUtils.indexExists(coll, {x: 1}, {name: "partialIndex1", partialFilterExpression: {a: {$lt: 5}}}),
coll.getIndexes(),
);

View File

@ -1,12 +1,14 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// requires_non_retryable_writes,
// requires_fastcount,
// requires_getmore,
// # TODO SERVER-113670: Investigate why this test fails with primary_driven_index_builds suites.
// primary_driven_index_builds_incompatible,
// ]
import {IndexUtils} from "jstests/libs/index_utils.js";
import {FixtureHelpers} from "jstests/libs/fixture_helpers.js";
let t = db.index_sparse1;
t.drop();
@ -20,30 +22,43 @@ assert.eq(5, t.count(), "A1");
assert.eq(5, t.find().sort({x: 1}).itcount(), "A2");
t.createIndex({x: 1});
assert.eq(2, t.getIndexes().length, "B1");
IndexUtils.assertIndexes(t, [{_id: 1}, {x: 1}], "B1");
assert.eq(5, t.find().sort({x: 1}).itcount(), "B2");
t.dropIndex({x: 1});
assert.eq(1, t.getIndexes().length, "B3");
IndexUtils.assertIndexes(t, [{_id: 1}], "B3");
t.createIndex({x: 1}, {sparse: 1});
assert.eq(2, t.getIndexes().length, "C1");
IndexUtils.assertIndexes(t, [{_id: 1}, {x: 1}], "C1");
assert.eq(5, t.find().sort({x: 1}).itcount(), "C2");
t.dropIndex({x: 1});
assert.eq(1, t.getIndexes().length, "C3");
IndexUtils.assertIndexes(t, [{_id: 1}], "C3");
// -- sparse & unique
t.remove({_id: 2});
// test that we can't create a unique index without sparse
assert.commandFailed(t.createIndex({x: 1}, {unique: 1}));
assert.eq(1, t.getIndexes().length, "D2");
// Test that we can't create a unique index without sparse
assert.commandFailedWithCode(
t.createIndex({x: 1}, {unique: 1}),
[ErrorCodes.DuplicateKey, ErrorCodes.CannotCreateIndex],
"D1",
);
IndexUtils.assertIndexes(t, [{_id: 1}], "D2");
t.createIndex({x: 1}, {unique: 1, sparse: 1});
assert.eq(2, t.getIndexes().length, "E1");
t.dropIndex({x: 1});
assert.eq(1, t.getIndexes().length, "E3");
if (!FixtureHelpers.isSharded(t)) {
// Can't create unique indexes on sharded collections.
t.insert({_id: 2, x: 2});
t.createIndex({x: 1}, {unique: 1, sparse: 1});
assert.eq(1, t.getIndexes().length, "F1");
t.createIndex({x: 1}, {unique: 1, sparse: 1});
IndexUtils.assertIndexes(t, [{_id: 1}, {x: 1}], "E1");
t.dropIndex({x: 1});
IndexUtils.assertIndexes(t, [{_id: 1}], "E2");
t.insert({_id: 2, x: 2});
assert.commandFailedWithCode(
t.createIndex({x: 1}, {unique: 1, sparse: 1}),
[ErrorCodes.DuplicateKey, ErrorCodes.CannotCreateIndex],
"E3",
);
IndexUtils.assertIndexes(t, [{_id: 1}], "E4");
assert.eq(1, t.getIndexes().length, "E5");
}

View File

@ -1,11 +1,12 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// requires_fastcount,
// requires_getmore,
// ]
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.index_sparse2;
t.drop();
@ -14,15 +15,15 @@ t.insert({_id: 2, x: 2});
t.insert({_id: 3});
t.createIndex({x: 1, y: 1});
assert.eq(2, t.getIndexes().length, "A1");
IndexUtils.assertIndexes(t, [{_id: 1}, {x: 1, y: 1}], "A1");
assert.eq(3, t.find().sort({x: 1, y: 1}).count(), "A2 count()");
assert.eq(3, t.find().sort({x: 1, y: 1}).itcount(), "A2 itcount()");
t.dropIndex({x: 1, y: 1});
assert.eq(1, t.getIndexes().length, "A3");
IndexUtils.assertIndexes(t, [{_id: 1}], "A3");
t.createIndex({x: 1, y: 1}, {sparse: 1});
assert.eq(2, t.getIndexes().length, "B1");
IndexUtils.assertIndexes(t, [{_id: 1}, {x: 1, y: 1}], "B1");
assert.eq(3, t.find().sort({x: 1, y: 1}).count(), "B2 count()");
assert.eq(3, t.find().sort({x: 1, y: 1}).itcount(), "B2 itcount()");
t.dropIndex({x: 1, y: 1});
assert.eq(1, t.getIndexes().length, "B3");
IndexUtils.assertIndexes(t, [{_id: 1}], "B3");

View File

@ -3,9 +3,6 @@
* It is equivalent to creating a normal sparse index, and the value persists in the catalog.
*
* @tags: [
* # Cannot implicitly shard accessed collections because of extra shard key index in sharded
* # collection.
* assumes_no_implicit_index_creation,
* # $listCatalog not supported inside of a multi-document transaction.
* does_not_support_transactions,
* # $listCatalog does not include the tenant prefix in its results.
@ -15,6 +12,8 @@
* ]
*/
import {IndexUtils} from "jstests/libs/index_utils.js";
let t = db.index_sparse_create_index_non_boolean_value;
t.drop();
@ -27,7 +26,7 @@ t.insert({_id: 4});
t.insert({_id: 5});
t.createIndex({x: 1}, {sparse: nonBooleanValue});
assert.eq(2, t.getIndexes().length);
IndexUtils.assertIndexes(t, [{_id: 1}, {x: 1}]);
assert.eq(5, t.find().sort({x: 1}).itcount());
// Verify that the original value has been persisted in the catalog.

View File

@ -1,9 +1,9 @@
// Cannot implicitly shard accessed collections because of extra shard key index in sharded
// collection.
// @tags: [
// assumes_no_implicit_index_creation,
// requires_fastcount,
// requires_getmore,
// # Cannot implicitly shard accessed collections because of not being able to create unique
// # index using hashed shard key pattern.
// cannot_create_unique_index_when_using_hashed_shard_key,
//]
// unique index constraint test for updates

View File

@ -1,9 +1,11 @@
// stats will return ok:1 for non-existant colls
import {IndexUtils} from "jstests/libs/index_utils.js";
/**
* Tests for the db collection
*
* @tags: [
* requires_capped,
* requires_collstats,
* requires_fastcount,
* # In-memory data structures are not causally consistent.
@ -51,10 +53,10 @@ for (var i = 0; i < 100; i++) {
}
(function () {
let validateResult = assert.commandWorked(coll.validate());
// Extract validation results from mongos output if running in a sharded context.
let isShardedNS = validateResult.hasOwnProperty("raw");
const validateResult = assert.commandWorked(coll.validate());
// Extract validation results from mongos output if running in a sharded context.
const isShardedNS = validateResult.hasOwnProperty("raw");
if (isShardedNS) {
// Sample mongos format:
// {
@ -72,25 +74,30 @@ for (var i = 0; i < 100; i++) {
// "ok": 1
// }
let numFields = 0;
let result = null;
let nrecords = 0;
for (let field in validateResult.raw) {
result = validateResult.raw[field];
numFields++;
}
const rawValidateResult = validateResult.raw[field];
assert.neq(null, rawValidateResult);
assert.eq(1, numFields);
assert.neq(null, result);
validateResult = result;
assert.eq(
"test." + collName,
rawValidateResult.ns,
"incorrect namespace in testDb.collection.validate() result: " + tojson(rawValidateResult),
);
assert(rawValidateResult.valid, "collection validation failed");
nrecords += rawValidateResult.nrecords;
}
assert.eq(100, nrecords, "11");
} else {
assert.eq(
"test." + collName,
validateResult.ns,
"incorrect namespace in testDb.collection.validate() result: " + tojson(validateResult),
);
assert.eq(100, validateResult.nrecords, "11");
}
assert.eq(
"test." + collName,
validateResult.ns,
"incorrect namespace in testDb.collection.validate() result: " + tojson(validateResult),
);
assert(validateResult.valid, "collection validation failed");
assert.eq(100, validateResult.nrecords, "11");
})();
/*
@ -98,63 +105,69 @@ for (var i = 0; i < 100; i++) {
*/
coll.drop();
assert.eq(0, coll.count(), "12");
IndexUtils.assertIndexes(coll, [], "12");
coll.dropIndexes();
assert.eq(0, coll.getIndexes().length, "13");
IndexUtils.assertIndexes(coll, [], "13");
coll.save({a: 10});
assert.eq(1, coll.getIndexes().length, "14");
IndexUtils.assertIndexes(coll, [{_id: 1}], "14");
coll.createIndex({a: 1});
coll.save({a: 10});
print(tojson(coll.getIndexes()));
assert.eq(2, coll.getIndexes().length, "15");
IndexUtils.assertIndexes(coll, [{_id: 1}, {a: 1}], "15");
coll.dropIndex({a: 1});
assert.eq(1, coll.getIndexes().length, "16");
IndexUtils.assertIndexes(coll, [{_id: 1}], "16");
coll.save({a: 10});
coll.createIndex({a: 1});
coll.save({a: 10});
assert.eq(2, coll.getIndexes().length, "17");
IndexUtils.assertIndexes(coll, [{_id: 1}, {a: 1}], "17");
coll.dropIndex("a_1");
assert.eq(1, coll.getIndexes().length, "18");
IndexUtils.assertIndexes(coll, [{_id: 1}], "18");
coll.save({a: 10, b: 11});
coll.createIndex({a: 1});
coll.createIndex({b: 1});
coll.save({a: 10, b: 12});
assert.eq(3, coll.getIndexes().length, "19");
IndexUtils.assertIndexes(coll, [{_id: 1}, {a: 1}, {b: 1}], "19");
coll.dropIndex({b: 1});
assert.eq(2, coll.getIndexes().length, "20");
IndexUtils.assertIndexes(coll, [{_id: 1}, {a: 1}], "20");
coll.dropIndex({a: 1});
assert.eq(1, coll.getIndexes().length, "21");
IndexUtils.assertIndexes(coll, [{_id: 1}], "21");
coll.save({a: 10, b: 11});
coll.createIndex({a: 1});
coll.createIndex({b: 1});
coll.save({a: 10, b: 12});
assert.eq(3, coll.getIndexes().length, "22");
IndexUtils.assertIndexes(coll, [{_id: 1}, {a: 1}, {b: 1}], "22");
coll.dropIndexes();
assert.eq(1, coll.getIndexes().length, "23");
IndexUtils.assertIndexes(coll, [{_id: 1}], "23");
coll.find();
coll.drop();
assert.eq(0, coll.getIndexes().length, "24");
IndexUtils.assertIndexes(coll, [], "24");
/*
* stats()
*/
(function () {
if (typeof globalThis.ImplicitlyShardAccessCollSettings !== "undefined") {
print("Skipping this test because collections are implicitly sharded and sharded collections can't be capped.");
return;
}
let t = testDb.apttest_dbcollection;
// Non-existent collection.
@ -291,6 +304,11 @@ assert.eq(0, coll.getIndexes().length, "24");
(function () {
let t = testDb.apitest_dbcollection;
if (typeof globalThis.ImplicitlyShardAccessCollSettings !== "undefined") {
print("Skipping this test for sharded collections.");
return;
}
t.drop();
let emptyStats = assert.commandWorked(t.stats());
assert.eq(emptyStats.storageSize, 0);

View File

@ -8,6 +8,8 @@
// does_not_support_stepdowns,
// uses_map_reduce_with_temp_collections,
// requires_scripting,
// # mapReduce cannot replace a sharded collection as output.
// assumes_unsharded_collection,
// ]
const coll = db.mr_preserve_indexes;
coll.drop();

View File

@ -111,3 +111,9 @@ filters:
- "*.pfx":
approvers:
- 10gen/server-security
- "fixture_helpers.js":
approvers:
- 10gen/server-catalog-and-routing-routing-and-topology
- "index_utils.js":
approvers:
- 10gen/server-catalog-and-routing-shard-catalog

View File

@ -499,22 +499,29 @@ export function assertCatalogListOperationsConsistencyForCollection(collection)
// so we can assume that the database is not read-only when running a sharded cluster.
const isDbReadOnly = !FixtureHelpers.isMongos(db) && db.serverStatus().storageEngine.readOnly;
const listCollections = db.getCollectionInfos({name: {$in: collectionNames}});
const listIndexes = listCollections
.filter((e) => !isViewListCollectionsEntry(e))
.map((coll) => ({
name: coll.name,
indexes: db.getCollection(coll.name).getIndexes(getRawOperationSpec(db)),
}));
const originalHideImplicitlyCreatedIndexesFromListIndexes = TestData.hideImplicitlyCreatedIndexesFromListIndexes;
try {
TestData.hideImplicitlyCreatedIndexesFromListIndexes = false;
let listCatalog = db
.getSiblingDB("admin")
.aggregate([{$listCatalog: {}}, {$match: {db: db.getName(), name: {$in: collectionNames}}}])
.toArray();
const listCollections = db.getCollectionInfos({name: {$in: collectionNames}});
const listIndexes = listCollections
.filter((e) => !isViewListCollectionsEntry(e))
.map((coll) => ({
name: coll.name,
indexes: db.getCollection(coll.name).getIndexes(getRawOperationSpec(db)),
}));
listCatalog = filterListCatalogEntriesFromShardsWithoutChunks(db, listCatalog);
let listCatalog = db
.getSiblingDB("admin")
.aggregate([{$listCatalog: {}}, {$match: {db: db.getName(), name: {$in: collectionNames}}}])
.toArray();
validateCatalogListOperationsConsistency(listCatalog, listCollections, listIndexes, isDbReadOnly, true);
listCatalog = filterListCatalogEntriesFromShardsWithoutChunks(db, listCatalog);
validateCatalogListOperationsConsistency(listCatalog, listCollections, listIndexes, isDbReadOnly, true);
} finally {
TestData.hideImplicitlyCreatedIndexesFromListIndexes = originalHideImplicitlyCreatedIndexesFromListIndexes;
}
}
export function assertCatalogListOperationsConsistencyForDb(db, tenantId) {
@ -617,14 +624,22 @@ export function assertCatalogListOperationsConsistencyForDb(db, tenantId) {
return true;
}
// TODO SERVER-75675: do not skip index consistency check on sharded clusters.
collIndexes = !isMongos
? collInfo
.filter((e) => !isViewListCollectionsEntry(e))
.map((coll) => ({
name: coll.name,
indexes: db.getCollection(coll.name).getIndexes(getRawOperationSpec(db)),
}))
: null;
const originalHideImplicitlyCreatedIndexesFromListIndexes =
TestData.hideImplicitlyCreatedIndexesFromListIndexes;
try {
TestData.hideImplicitlyCreatedIndexesFromListIndexes = false;
collIndexes = !isMongos
? collInfo
.filter((e) => !isViewListCollectionsEntry(e))
.map((coll) => ({
name: coll.name,
indexes: db.getCollection(coll.name).getIndexes(getRawOperationSpec(db)),
}))
: null;
} finally {
TestData.hideImplicitlyCreatedIndexesFromListIndexes =
originalHideImplicitlyCreatedIndexesFromListIndexes;
}
} catch (ex) {
// In a sharded cluster with in-progress validate command for the config database
// (i.e. on the config server), catalog accesses on a mongos or shardsvr mongod that

View File

@ -4,6 +4,8 @@
///////////////////////////////////////////////////////////////////////////////
import {IndexUtils} from "jstests/libs/index_utils.js";
// Case 1: Big string as key
export var bigStringKeys = (() => {
let keys = [];
@ -78,15 +80,15 @@ export function deleteIndexKeysByUpdateDocs(testDB, collName, keys) {
}
export function createIndex(testColl, unique) {
let numIndexesBefore = testColl.getIndexes().length;
assert(!IndexUtils.indexExists(testColl, {k: 1}), testColl.getIndexes());
assert.commandWorked(testColl.createIndex({k: 1}, {unique: unique}));
assert.eq(numIndexesBefore + 1, testColl.getIndexes().length);
assert(IndexUtils.indexExists(testColl, {k: 1}), testColl.getIndexes());
}
export function dropIndex(testColl) {
let numIndexesBefore = testColl.getIndexes().length;
assert(IndexUtils.indexExists(testColl, {k: 1}));
assert.commandWorked(testColl.dropIndex({k: 1}));
assert.eq(numIndexesBefore - 1, testColl.getIndexes().length);
assert(!IndexUtils.indexExists(testColl, {k: 1}));
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,83 @@
import {FixtureHelpers} from "jstests/libs/fixture_helpers.js";
export var IndexUtils = (function () {
/**
* Verifies that the indexes on 'coll' match those in 'expectedIndexes'.
*
* This function takes into account indexes that may have been created implicitly. For suites
* that implicitly shard collections, indexes such as the shard key or _id may exist. Similarly,
* for suites that implicitly create a wildcard index, those are also considered.
*/
function assertIndexes(coll, expectedIndexes, msg) {
const actualIndexes = coll.getIndexes().map((spec) => spec.key);
assertIndexesMatch(coll, expectedIndexes, actualIndexes, msg);
}
/**
* Verifies that the 'actualIndexes' match those in 'expectedIndexes' for the given collection.
*
* This function takes into account indexes that may have been created implicitly. For suites
* that implicitly shard collections, indexes such as the shard key or _id may exist. Similarly,
* for suites that implicitly create a wildcard index, those are also considered.
*/
function assertIndexesMatch(coll, expectedIndexes, actualIndexes, msg) {
assert(actualIndexes);
const addIfNotExists = (arr, value) => {
if (!arr.some((v) => v === value || bsonUnorderedFieldsCompare(v, value) === 0)) {
arr.push(value);
}
};
if (FixtureHelpers.isSharded(coll)) {
// If the collection has been dropped, it will be automatically recreated on 'sharded'
// suites. Hence, the index {_id: 1} will exist.
//
// Note that this doesn't affect unsharded tracked collections because the drop
// operation doesn't recreate the collection on suites that implicitly create
// unsplittable collections.
addIfNotExists(expectedIndexes, {_id: 1});
// If the shard key index exists, add it to the expected indexes.
const shardKey = coll.getShardKey();
if (coll.getIndexByKey(shardKey)) {
addIfNotExists(expectedIndexes, shardKey);
}
}
if (TestData.implicitWildcardIndexesEnabled) {
actualIndexes.forEach((index) => {
if (Object.keys(index).some((key) => key.endsWith("$**"))) {
addIfNotExists(expectedIndexes, index);
}
});
}
assert.sameMembers(expectedIndexes, actualIndexes, msg);
}
/**
* Checks whether the specified index exists.
*
* If `options` are provided, only the specified fields will be verified.
* To check that a field does not exist, you can use the syntax: { field: undefined }.
*/
function indexExists(coll, indexKey, options = undefined) {
return coll
.getIndexes()
.some(
(index) =>
bsonWoCompare(indexKey, index.key) === 0 &&
(!options ||
Object.keys(options).every(
(optionKey) => bsonWoCompare(options[optionKey], index[optionKey]) === 0,
)),
);
}
return {
assertIndexes: assertIndexes,
assertIndexesMatch: assertIndexesMatch,
indexExists: indexExists,
};
})();

View File

@ -9,6 +9,9 @@ const isHiddenWildcardIndex = {
$regexMatch: {input: "$name", regex: prefix},
};
TestData.implicitWildcardIndexesEnabled = true;
TestData.hideImplicitlyCreatedIndexesFromListIndexes = true;
/**
* Error codes we ignore when trying to create implicit indexes because they depend on the test
* structure itself.
@ -143,7 +146,7 @@ function runCommandOverride(conn, dbName, cmdName, cmdObj, originalRunCommand, m
} else if (cmdName == "listIndexes" && res.ok) {
// If we're listing indexes, we need to make sure we eliminate any of the
// implicitly created indexes from consideration.
if (res.cursor.firstBatch) {
if (TestData.hideImplicitlyCreatedIndexesFromListIndexes && res.cursor.firstBatch) {
res.cursor.firstBatch = res.cursor.firstBatch.filter((idx) => !idx.name.startsWith(prefix));
}
} else if (cmdName == "insert" && res.ok) {
@ -170,31 +173,5 @@ function runCommandOverride(conn, dbName, cmdName, cmdObj, originalRunCommand, m
return res;
}
/**
* Hides any implicitly created wildcard indexes. Note that tests using {$indexStats} directly have
* to be manually excluded from the suite, since they won't pass through this override.
*/
DBCollection.prototype.getIndexes = function (params) {
const res = this.aggregate(
[
{$indexStats: {}},
// Hide the implicitly created index(es) from tests that look
// for indexes.
{$addFields: {isHidden: isHiddenWildcardIndex}},
{$match: {isHidden: false}},
// The information listed in 'spec' is usually returned inline
// at the root level.
{$replaceWith: {$mergeObjects: ["$$ROOT", "$spec"]}},
// This info isn't shown in 'getIndexes'.
{$project: {host: 0, accesses: 0, spec: 0, isHidden: 0}},
],
params,
).toArray();
return res;
};
DBCollection.prototype.getIndices = DBCollection.prototype.getIndexes;
DBCollection.prototype.getIndexSpecs = DBCollection.prototype.getIndexes;
OverrideHelpers.prependOverrideInParallelShell("jstests/libs/override_methods/implicit_wildcard_indexes.js");
OverrideHelpers.overrideRunCommand(runCommandOverride);

View File

@ -169,6 +169,12 @@ describe("testing incompatible shard key indexes", function () {
ErrorCodes.CannotDropShardKeyIndex,
);
assert.commandFailedWithCode(this.coll.hideIndex(compatibleShardKeyIndex), ErrorCodes.InvalidOptions);
// Attempt to drop all indexes and check that the compatible shard key index still exist.
this.coll.dropIndexes();
const shardKeyIndex = this.coll.getIndexByKey(compatibleShardKeyIndex);
assert.neq(shardKeyIndex, null, "shard key index is missing");
});
it("reshardCollection will attempt to create a shard key index", () => {