SERVER-83211 Enable counting index tests on sharded passthrough suites (#43649)
GitOrigin-RevId: dcb676f1697884eb629906f0d8d8979f10ef4035
This commit is contained in:
parent
f50352a5c2
commit
3d3328e613
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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,
|
||||
);
|
||||
|
||||
@ -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,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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"});
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
* ]
|
||||
*/
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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", []));
|
||||
|
||||
117
jstests/core/ddl/create_indexes_response_fields.js
Normal file
117
jstests/core/ddl/create_indexes_response_fields.js
Normal 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));
|
||||
});
|
||||
@ -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}");
|
||||
|
||||
@ -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",
|
||||
);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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({
|
||||
|
||||
@ -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]}));
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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({
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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";
|
||||
|
||||
|
||||
@ -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,
|
||||
// ]
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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(),
|
||||
);
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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}));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
83
jstests/libs/index_utils.js
Normal file
83
jstests/libs/index_utils.js
Normal 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,
|
||||
};
|
||||
})();
|
||||
@ -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);
|
||||
|
||||
@ -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", () => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user