SERVER-126800: Fix $arrayToObject reversed k/v validation in SBE (#53850)

GitOrigin-RevId: c58450c92b84ec14fde4606ae851908184780a48
This commit is contained in:
Projjal Chanda 2026-05-21 18:18:13 +01:00 committed by MongoDB Bot
parent aa63d84077
commit 1fd842a9bb
2 changed files with 34 additions and 1 deletions

View File

@ -264,4 +264,37 @@ TEST_F(SBEObjectArrayConversionTest, ArrayToObjectExpression) {
runAndAssertErrorCode(compiledArrayToObject.get(), *errCode);
}
}
TEST_F(SBEObjectArrayConversionTest, ArrayToObjectAcceptsReversedKV) {
value::OwnedValueAccessor inputAccessor;
auto inputSlot = bindAccessor(&inputAccessor);
auto arrayToObjectExpr =
sbe::makeE<sbe::EFunction>(EFn::kArrayToObject, sbe::makeEs(makeE<EVariable>(inputSlot)));
auto compiledArrayToObject = compileExpression(*arrayToObjectExpr);
// [{"v": 1, "k": "field1"}, {"v": {"innerField": 2}, "k": "field2"}]
const BSONArray reversedArr =
BSON_ARRAY(BSON("v" << 1 << "k" << "field1") << BSON("v" << BSON("innerField" << 2) << "k"
<< "field2"));
inputAccessor.reset_raw(
false, value::TypeTags::bsonArray, value::bitcastFrom<const char*>(reversedArr.objdata()));
runAndAssertExpression(compiledArrayToObject.get(),
value::TypeTags::Object,
value::TypeTags::bsonObject,
value::bitcastFrom<const char*>(bsonObj.objdata()));
// Mixed orderings within the same array.
const BSONArray mixedArr = BSON_ARRAY(BSON("k" << "field1"
<< "v" << 1)
<< BSON("v" << BSON("innerField" << 2) << "k"
<< "field2"));
inputAccessor.reset_raw(
false, value::TypeTags::bsonArray, value::bitcastFrom<const char*>(mixedArr.objdata()));
runAndAssertExpression(compiledArrayToObject.get(),
value::TypeTags::Object,
value::TypeTags::bsonObject,
value::bitcastFrom<const char*>(bsonObj.objdata()));
}
} // namespace mongo::sbe

View File

@ -1058,7 +1058,7 @@ value::TagValueMaybeOwned ByteCode::builtinArrayToObject(ArityType arity) {
uassert(5153212,
"$arrayToObject requires an object with keys 'k' and 'v'.",
((keyName == "k" && valueName == "v") || (keyName == "k" && valueName == "v")));
((keyName == "k" && valueName == "v") || (keyName == "v" && valueName == "k")));
if (keyName == "v" && valueName == "k") {
std::swap(key, val);
}