SERVER-118712 Revert SERVER-113888 SERVER-113889 (#47355)

GitOrigin-RevId: cc1adb6b0875cc3003854ac2489818e459686f0b
This commit is contained in:
Benjamin Pearce
2026-02-02 15:28:27 -05:00
committed by MongoDB Bot
parent af851bae82
commit 1078adc56c
7 changed files with 3 additions and 138 deletions

View File

@@ -879,8 +879,6 @@ last-continuous:
ticket: SERVER-113532
- test_file: jstests/sharding/migration_fails_with_spurious_documents.js
ticket: SERVER-110953
- test_file: jstests/core/index/index_on_incorrect_collection.js
ticket: SERVER-113888
suites: null
last-lts:
all:
@@ -1822,6 +1820,4 @@ last-lts:
ticket: SERVER-113532
- test_file: jstests/sharding/migration_fails_with_spurious_documents.js
ticket: SERVER-110953
- test_file: jstests/core/index/index_on_incorrect_collection.js
ticket: SERVER-113888
suites: null

View File

@@ -1,28 +0,0 @@
/**
* If an incompatible index exists on a collection, the server should prevent updates to that index with non-fatal errors.
* @tags: [
* # Older versions are expected to have fatal failures.
* requires_fcv_80
* ]
*/
// Nonfatal error when attempting to update an improper timeseries-only index on a non-timeseries collection.
const collName = jsTestName();
const coll = db.getCollection(collName);
coll.drop();
assert.commandWorked(db.createCollection(collName));
// Prevents updating 2dsphere_bucket indices for top-level measurements.
// Authorization rules will normally prevent a non-system user from creating this index.
assert.commandWorked(coll.createIndex({x: "2dsphere_bucket"}));
assert.commandFailed(coll.insert({control: {version: 2}, x: HexData(0, "00")}));
// Prevents updating 2dsphere_bucket indices for nested measurements.
// Authorization rules will normally prevent a non-system user from creating this index.
assert.commandWorked(coll.createIndex({"data.a.b.c": "2dsphere_bucket"}));
assert.commandFailed(coll.insert({control: {version: 2}, data: {a: {b: {c: [0, 0]}}}}));
coll.drop();

View File

@@ -1,56 +0,0 @@
/**
* Ensures that a createIndexes command request fails when creating an index with illegal options.
*/
import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js";
// Specifying index type in the createIndex command.
const collName = jsTestName();
const testUser = "mongo";
const testPass = "mongo";
const conn = MongoRunner.runMongod({auth: "", bind_ip: "127.0.0.1"});
const admin = conn.getDB("admin");
admin.createUser({user: testUser, pwd: testPass, roles: jsTest.adminUserRoles});
admin.logout();
admin.auth({user: testUser, pwd: testPass});
const test = admin.getSiblingDB("test");
const illegalIndexTypes = [
{type: "2dsphere_bucket", codes: [ErrorCodes.IndexOptionsConflict]},
{type: "queryable_encrypted_range", codes: [ErrorCodes.IndexOptionsConflict]},
{type: "wildcard", codes: [7246202]},
{type: "columnstore", codes: [ErrorCodes.NotImplemented, ErrorCodes.CannotCreateIndex]},
{type: "geoHaystack", codes: [ErrorCodes.CannotCreateIndex]},
];
const legalIndexTypes = [1, "2d", "2dsphere", "text", "hashed"];
// Cannot create illegal indexes.
illegalIndexTypes.forEach((args) => {
const indexType = args.type;
const expectedErrorCodes = args.codes;
const testCollName = collName + "." + indexType;
assert.commandFailedWithCode(
test[testCollName].createIndex({"foo": indexType}),
expectedErrorCodes,
);
// TODO(SERVER-114308): Primary-driven index builds eagerly create the collection, this assertion will fail on those build variants.
if (!FeatureFlagUtil.isPresentAndEnabled(test, "PrimaryDrivenIndexBuilds")) {
assert.doesNotContain(
test.getCollectionNames(),
[testCollName],
`The ${testCollName} collection should not be implicitly created upon failing to create the index.`,
);
}
test[testCollName].drop();
});
// Can create illegal indexes.
legalIndexTypes.forEach(function (indexType) {
const testCollName = collName + "." + indexType;
assert.commandWorked(test[testCollName].createIndex({"foo": indexType}));
test[testCollName].drop();
});
MongoRunner.stopMongod(conn);

View File

@@ -213,31 +213,6 @@ void validateTTLOptions(OperationContext* opCtx,
}
}
/**
* Ensures that the user is authorized to create an index of a given type.
*/
void validateIndexType(OperationContext* opCtx, const CreateIndexesCommand& cmd) {
const boost::optional<auth::ValidatedTenancyScope>& vts =
auth::ValidatedTenancyScope::get(opCtx);
const auto tenantId =
vts && vts->hasTenantId() ? boost::make_optional(vts->tenantId()) : boost::none;
const bool isAuthForInternal =
AuthorizationSession::get(opCtx->getClient())
->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(tenantId),
ActionType::internal);
for (const auto& elem : cmd.getIndexes()) {
for (const auto& key : elem.getField("key").Obj()) {
const auto type = key.str(); // will return "" for btree
if (IndexNames::isInternalOnly(type)) {
uassert(ErrorCodes::IndexOptionsConflict,
fmt::format("Index Type {} is for internal use only", type),
isAuthForInternal);
}
}
}
}
void checkEncryptedFieldIndexRestrictions(OperationContext* opCtx,
const Collection* coll,
const CreateIndexesCommand& cmd) {
@@ -578,7 +553,6 @@ CreateIndexesReply runCreateIndexesWithCoordinator(OperationContext* opCtx,
}
validateTTLOptions(opCtx, collection.getCollectionPtr().get(), cmd);
validateIndexType(opCtx, cmd);
if (collection.exists() &&
!UncommittedCatalogUpdates::get(opCtx).isCreatedCollection(opCtx, ns)) {

View File

@@ -105,18 +105,4 @@ IndexType IndexNames::nameToType(StringData accessMethod) {
return typeIt->second;
}
// static
bool IndexNames::isInternalOnly(const std::string& name) {
if (isKnownName(name)) {
switch (nameToType(name)) {
case INDEX_2DSPHERE_BUCKET:
case INDEX_ENCRYPTED_RANGE:
return true;
default:
return false;
}
}
return false;
}
} // namespace mongo

View File

@@ -86,11 +86,6 @@ public:
* Convert an index name to an IndexType.
*/
static IndexType nameToType(StringData accessMethod);
/**
* Index is not intended to be user facing.
*/
static bool isInternalOnly(const std::string& name);
};
/**

View File

@@ -173,7 +173,7 @@ boost::optional<BSONColumn> _extractAllElementsAlongBucketPath(
case 0:
case 1: {
if (auto res = _splitPath(path)) {
const auto& [left, next] = *res;
auto& [left, next] = *res;
BSONElement e = obj.getField(left);
if (depth > 0 || left == timeseries::kBucketDataFieldName) {
if (e.type() == Object) {
@@ -228,9 +228,7 @@ boost::optional<BSONColumn> _extractAllElementsAlongBucketPath(
// measurement field (i.e. data.a) and we need to iterate over each of the
// numerically-indexed entries (i.e. data.a.1, data.a.5, etc.) to extract
// the actual field we want.
massert(11388801,
"Malformed measurement field in compressed timeseries bucket",
depth == 1);
invariant(depth == 1);
BSONColumn storage{e};
for (const BSONElement& e2 : storage) {
if (!e2.eoo()) {
@@ -252,7 +250,7 @@ boost::optional<BSONColumn> _extractAllElementsAlongBucketPath(
// numerically-indexed entries (i.e. data.a.1, data.a.5, etc.) to extract the actual
// field we want. If we are after a top-level field, then we already have the element we
// want in 'e'. If we are after a nested field, then we need to recurse.
massert(11388802, "Expected uncompressed bucket", !isCompressed);
invariant(!isCompressed);
for (const BSONElement& e : obj) {
if (path.empty()) {
// The top-level measurement field (i.e. data.a) is the indexed field we are