Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/mongo/db/modules/eloq/src/eloq_record_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,11 @@ Status EloqRecordStore::updateRecord(OperationContext* opCtx,
uint64_t pkeySchemaVersion = table._schema->KeySchema()->SchemaTs();

mongoRecord->SetEncodedBlob(reinterpret_cast<const unsigned char*>(data), len);
const BSONObj idObj = getIdBSONObjWithoutFieldName(recordObj);
const KeyString idKeyString(KeyString::kLatestVersion, idObj, kIdOrdering);
if (const auto& typeBits = idKeyString.getTypeBits(); !typeBits.isAllZeros()) {
mongoRecord->SetUnpackInfo(typeBits.getBuffer(), typeBits.getSize());
}
auto err = ru->setKV(_tableName,
pkeySchemaVersion,
std::move(mongoKey),
Expand Down
79 changes: 79 additions & 0 deletions tests/jstests/eloq_basic/update_index_validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Updates must preserve index consistency and the exact BSON type of index keys.
(function() {
"use strict";

const indexNames = ["_id_", "stable_1", "value_1"];
const testCases = [
{name: "int control", suffix: "int", id: NumberInt(101)},
{name: "long", suffix: "long", id: NumberLong("102")},
{name: "integral double", suffix: "double", id: 103.0},
{name: "decimal", suffix: "decimal", id: NumberDecimal("104.0")},
{name: "negative double zero", suffix: "negative_double_zero", id: -0.0},
{name: "decimal zero", suffix: "decimal_zero", id: NumberDecimal("-0E3")},
{
name: "embedded long",
suffix: "embedded_long",
id: {kind: "embedded", sequence: NumberLong("105")},
},
];

function assertSingleReturnedKey(coll, query, indexName, expectedKey, context) {
const keys = coll.find(query).hint(indexName).returnKey().toArray();
assert.eq(1, keys.length, context + ": " + tojson(keys));
assert(bsonBinaryEqual(expectedKey, keys[0]),
context + ": expected " + tojson(expectedKey) + ", got " + tojson(keys[0]));
}

function assertFullValidation(coll, stage) {
const result = coll.validate({full: true});
assert.commandWorked(result);
assert(result.valid, stage + ": " + tojson(result));
assert.eq(indexNames.length, result.nIndexes, stage + ": " + tojson(result));

indexNames.forEach(function(indexName) {
const detailName = coll.getFullName() + ".$" + indexName;
assert(result.indexDetails[detailName].valid,
stage + ": " + indexName + " is invalid: " + tojson(result));
});
}

testCases.forEach(function(testCase) {
const coll = db.getCollection("update_index_validation_" + testCase.suffix);
const context = testCase.name;

coll.drop();
assert.commandWorked(coll.createIndex({stable: 1}, {name: "stable_1"}));
assert.commandWorked(coll.createIndex({value: 1}, {name: "value_1"}));
assert.writeOK(coll.insert({_id: testCase.id, stable: "unchanged", value: 10.0}));

assertFullValidation(coll, context + " after insert");
assertSingleReturnedKey(
coll, {_id: testCase.id}, "_id_", {_id: testCase.id}, context + " after insert");

assert.writeOK(coll.update({_id: testCase.id}, {$set: {value: 20.0}}));
assert.eq(20.0, coll.findOne({_id: testCase.id}).value, context);
assert.eq(0,
coll.find({value: 10.0}).hint("value_1").itcount(),
context + ": stale value index key");
assert.eq(1,
coll.find({value: 20.0}).hint("value_1").itcount(),
context + ": missing value index key");
assert.eq(1,
coll.find({stable: "unchanged"}).hint("stable_1").itcount(),
context + ": missing unchanged index key");

assertFullValidation(coll, context + " after update");
assertSingleReturnedKey(
coll, {_id: testCase.id}, "_id_", {_id: testCase.id}, context + " after update");
assertSingleReturnedKey(coll,
{stable: "unchanged"},
"stable_1",
{stable: "unchanged"},
context + " unchanged secondary index");
assertSingleReturnedKey(coll,
{value: 20.0},
"value_1",
{value: 20.0},
context + " updated secondary index");
});
})();
Loading