summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorAlexander Ignatyev <alexander.ignatyev@mongodb.com>2023-02-10 20:24:26 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-02-11 04:10:25 +0000
commit7b969531de3dd18e28175fc59082e3e2ff9eb16c (patch)
tree841b16b121abed451ed5621eea426215cc704437 /jstests
parent36d9f82090f1d84f38d3d444319ce17393455353 (diff)
downloadmongo-7b969531de3dd18e28175fc59082e3e2ff9eb16c.tar.gz
SERVER-72468 Test Compound Wildcard Index filters and hiding
Diffstat (limited to 'jstests')
-rw-r--r--jstests/core/index/wildcard/compound_wildcard_index_filter.js154
-rw-r--r--jstests/core/index/wildcard/compound_wildcard_index_hiding.js156
2 files changed, 310 insertions, 0 deletions
diff --git a/jstests/core/index/wildcard/compound_wildcard_index_filter.js b/jstests/core/index/wildcard/compound_wildcard_index_filter.js
new file mode 100644
index 00000000000..8ac0bdedf6d
--- /dev/null
+++ b/jstests/core/index/wildcard/compound_wildcard_index_filter.js
@@ -0,0 +1,154 @@
+/**
+ * Tests that Compound Wildcard Indexes can be added/removed/listed from index filters.
+ *
+ * @tags: [
+ * not_allowed_with_security_token,
+ * does_not_support_stepdowns,
+ * featureFlagCompoundWildcardIndexes,
+ * ]
+ */
+
+(function() {
+"use strict";
+
+function findFilter(cwiFilter, filterList) {
+ for (const filter of filterList) {
+ if (bsonWoCompare(cwiFilter.query, filter.query) == 0) {
+ if (filter.indexes.find(keyPattern =>
+ bsonWoCompare(cwiFilter.keyPattern, keyPattern) == 0)) {
+ return filter;
+ }
+ if (filter.indexes.find(indexName => cwiFilter.indexName == indexName)) {
+ return filter;
+ }
+ }
+ }
+
+ return null;
+}
+
+function getIndexName(coll, keyPattern) {
+ const indexes = coll.getIndexes();
+ const index = indexes.find(index => bsonWoCompare(index.key, keyPattern) == 0);
+ if (index !== undefined) {
+ return index.name;
+ }
+ return null;
+}
+
+const collectionName = "compound_wildcard_index_filter";
+const coll = db[collectionName];
+coll.drop();
+
+const cwiFilterList = [
+ // Note: 'wildcardProjection' cannot be specified if the wildcard field is not "$**".
+ {
+ keyPattern: {a: 1, b: 1, "c.$**": 1},
+ wildcardProjection: undefined,
+ query: {a: 1, b: 1, "c.d": 1},
+ },
+ {
+ keyPattern: {a: 1, "c.$**": 1, b: 1},
+ wildcardProjection: undefined,
+ query: {a: 1, b: 1, "c.a": 1},
+ },
+ {
+ keyPattern: {"c.$**": 1, a: 1, b: 1},
+ wildcardProjection: undefined,
+ query: {a: 1, b: 1, "c.front": 1},
+ },
+ {
+ keyPattern: {a: 1, b: 1, "$**": 1},
+ wildcardProjection: {"c": 1},
+ query: {a: 1, b: 1, "c": 1},
+ },
+ {
+ keyPattern: {a: 1, "$**": 1, b: 1},
+ wildcardProjection: {"d": 1},
+ query: {a: 1, b: 1, "d": 1},
+ },
+ {
+ keyPattern: {"$**": 1, a: 1, b: 1},
+ wildcardProjection: {"front": 1},
+ query: {a: 1, b: 1, "front": 1},
+ },
+];
+
+// create indexes
+for (const cwiFilter of cwiFilterList) {
+ const options = {};
+ if (cwiFilter.wildcardProjection) {
+ options["wildcardProjection"] = cwiFilter.wildcardProjection;
+ }
+
+ assert.commandWorked(coll.createIndex(cwiFilter.keyPattern, options));
+ cwiFilter.indexName = getIndexName(coll, cwiFilter.keyPattern);
+ assert.neq(null, cwiFilter.indexName);
+}
+
+let expectedNumberOfFilters = 0;
+
+// create and validate filters using indexes' key patterns
+for (const cwiFilter of cwiFilterList) {
+ assert.commandWorked(db.runCommand({
+ planCacheSetFilter: collectionName,
+ query: cwiFilter.query,
+ indexes: [cwiFilter.keyPattern],
+ }));
+
+ expectedNumberOfFilters += 1;
+
+ const filters = assert.commandWorked(db.runCommand({planCacheListFilters: collectionName}));
+ assert.eq(expectedNumberOfFilters, filters.filters.length, filters);
+
+ assert.neq(null, findFilter(cwiFilter, filters.filters), filters.filters);
+}
+
+// clear and validate filters using indexes' key patterns
+for (const cwiFilter of cwiFilterList) {
+ assert.commandWorked(db.runCommand({
+ planCacheClearFilters: collectionName,
+ query: cwiFilter.query,
+ indexes: [cwiFilter.keyPattern],
+ }));
+
+ expectedNumberOfFilters -= 1;
+
+ const filters = assert.commandWorked(db.runCommand({planCacheListFilters: collectionName}));
+ assert.eq(expectedNumberOfFilters, filters.filters.length, filters);
+
+ assert.eq(null, findFilter(cwiFilter, filters.filters), filters.filters);
+}
+
+// create and validate filters using indexes' names
+for (const cwiFilter of cwiFilterList) {
+ assert.commandWorked(db.runCommand({
+ planCacheSetFilter: collectionName,
+ query: cwiFilter.query,
+ indexes: [cwiFilter.indexName],
+ }));
+
+ expectedNumberOfFilters += 1;
+
+ const filters = assert.commandWorked(db.runCommand({planCacheListFilters: collectionName}));
+ assert.eq(expectedNumberOfFilters, filters.filters.length, filters);
+
+ assert.neq(null, findFilter(cwiFilter, filters.filters), filters.filters);
+}
+
+// clear and validate filters using indexes' names
+for (const cwiFilter of cwiFilterList) {
+ assert.commandWorked(db.runCommand({
+ planCacheClearFilters: collectionName,
+ query: cwiFilter.query,
+ indexes: [cwiFilter.indexName],
+ }));
+
+ expectedNumberOfFilters -= 1;
+
+ const filters = assert.commandWorked(db.runCommand({planCacheListFilters: collectionName}));
+ assert.eq(expectedNumberOfFilters, filters.filters.length, filters);
+
+ assert.eq(null, findFilter(cwiFilter, filters.filters), filters.filters);
+}
+})();
diff --git a/jstests/core/index/wildcard/compound_wildcard_index_hiding.js b/jstests/core/index/wildcard/compound_wildcard_index_hiding.js
new file mode 100644
index 00000000000..609b7cff019
--- /dev/null
+++ b/jstests/core/index/wildcard/compound_wildcard_index_hiding.js
@@ -0,0 +1,156 @@
+/**
+ * Tests that Compound Wildcard Indexes can be hidden.
+ *
+ * @tags: [
+ * not_allowed_with_security_token,
+ * does_not_support_stepdowns,
+ * featureFlagCompoundWildcardIndexes,
+ * ]
+ */
+
+(function() {
+"use strict";
+
+const collectionName = "compound_wildcard_index_hiding";
+const cwiList = [
+ {
+ keyPattern: {a: 1, b: 1, "c.$**": 1},
+ wildcardProjection: undefined,
+ },
+ {
+ keyPattern: {a: 1, "c.$**": 1, b: 1},
+ wildcardProjection: undefined,
+ },
+ {
+ keyPattern: {"c.$**": 1, a: 1, b: 1},
+ wildcardProjection: undefined,
+ },
+ {
+ keyPattern: {a: 1, b: 1, "$**": 1},
+ wildcardProjection: {"c": 1},
+ },
+ {
+ keyPattern: {a: 1, "$**": 1, b: 1},
+ wildcardProjection: {"d": 1},
+ },
+ {
+ keyPattern: {"$**": 1, a: 1, b: 1},
+ wildcardProjection: {"front": 1},
+ },
+];
+
+function getIndexName(coll, keyPattern) {
+ const indexes = coll.getIndexes();
+ const index = indexes.find(index => bsonWoCompare(index.key, keyPattern) == 0);
+ if (index !== undefined) {
+ return index.name;
+ }
+ return null;
+}
+
+function findIndex(coll, indexSpec) {
+ const indexes = coll.getIndexes();
+
+ for (const index of indexes) {
+ if (bsonWoCompare(index.key, indexSpec.keyPattern) == 0) {
+ return index;
+ }
+ }
+
+ return null;
+}
+
+function createIndex(coll, indexSpec) {
+ const options = {};
+ if (indexSpec.wildcardProjection) {
+ options["wildcardProjection"] = indexSpec.wildcardProjection;
+ }
+ if (indexSpec.hidden) {
+ options["hidden"] = true;
+ }
+
+ assert.commandWorked(coll.createIndex(indexSpec.keyPattern, options));
+ indexSpec.indexName = getIndexName(coll, indexSpec.keyPattern);
+ assert.neq(null, indexSpec.indexName);
+}
+
+function validateIndex(coll, indexSpec) {
+ const index = findIndex(coll, indexSpec);
+ assert.neq(null, index);
+
+ if (indexSpec.hidden) {
+ assert.eq(true, index.hidden);
+ } else {
+ assert.neq(true, index.hidden);
+ }
+}
+
+function setIndexVisibilityByKeyPattern(collectionName, keyPattern, hidden) {
+ assert.commandWorked(db.runCommand({collMod: collectionName, index: {keyPattern, hidden}}));
+}
+
+function setIndexVisibilityByIndexName(collectionName, indexName, hidden) {
+ assert.commandWorked(
+ db.runCommand({collMod: collectionName, index: {name: indexName, hidden}}));
+}
+
+function testCompoundWildcardIndexesHiding(cwiList, collectionName) {
+ db[collectionName].drop();
+ assert.commandWorked(db.createCollection(collectionName));
+ const coll = db[collectionName];
+ let expectedNumberOfIndexes = coll.getIndexes().length;
+
+ // create indexes
+ for (const indexSpec of cwiList) {
+ createIndex(coll, indexSpec);
+
+ expectedNumberOfIndexes += 1;
+ assert.eq(expectedNumberOfIndexes, coll.getIndexes().length);
+ validateIndex(coll, indexSpec);
+ }
+
+ // Toggle index visibility twice by key pattern
+ for (let i = 0; i < 2; ++i) {
+ for (const indexSpec of cwiList) {
+ indexSpec.hidden = !indexSpec.hidden;
+ setIndexVisibilityByKeyPattern(collectionName, indexSpec.keyPattern, indexSpec.hidden);
+ validateIndex(coll, indexSpec);
+ }
+ }
+
+ // Toggle index visibility twice by index name
+ for (let i = 0; i < 2; ++i) {
+ for (const indexSpec of cwiList) {
+ indexSpec.hidden = !indexSpec.hidden;
+ setIndexVisibilityByIndexName(collectionName, indexSpec.indexName, indexSpec.hidden);
+ validateIndex(coll, indexSpec);
+ }
+ }
+
+ // remove indexes
+ for (const indexSpec of cwiList) {
+ assert.commandWorked(coll.dropIndex(indexSpec.keyPattern));
+
+ expectedNumberOfIndexes -= 1;
+ assert.eq(expectedNumberOfIndexes, coll.getIndexes().length);
+ const index = findIndex(coll, indexSpec);
+ assert.eq(null, index);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////
+// 1. Create, hide, unhide, and delete Compound Wildcard Indexes.
+
+for (const index of cwiList) {
+ index["hidden"] = false;
+}
+testCompoundWildcardIndexesHiding(cwiList, collectionName);
+
+/////////////////////////////////////////////////////////////////////////
+// 2. Create hidden, unhide, hide, and delete Compound Wildcard Indexes.
+
+for (const index of cwiList) {
+ index["hidden"] = true;
+}
+testCompoundWildcardIndexesHiding(cwiList, collectionName);
+})();