summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/evergreen.yml10
-rw-r--r--src/mongo/db/exec/sbe/expressions/expression.cpp11
-rw-r--r--src/mongo/db/exec/sbe/expressions/sbe_bson_size_test.cpp15
-rw-r--r--src/mongo/db/exec/sbe/expressions/sbe_coerce_to_string_test.cpp6
-rw-r--r--src/mongo/db/exec/sbe/expressions/sbe_concat_test.cpp8
-rw-r--r--src/mongo/db/exec/sbe/expressions/sbe_is_member_builtin_test.cpp39
-rw-r--r--src/mongo/db/exec/sbe/expressions/sbe_to_upper_to_lower_test.cpp12
-rw-r--r--src/mongo/db/exec/sbe/expressions/sbe_trigonometric_expressions_test.cpp99
-rw-r--r--src/mongo/db/exec/sbe/parser/parser.cpp7
-rw-r--r--src/mongo/db/exec/sbe/sbe_filter_test.cpp16
-rw-r--r--src/mongo/db/exec/sbe/sbe_key_string_test.cpp12
-rw-r--r--src/mongo/db/exec/sbe/sbe_limit_skip_test.cpp2
-rw-r--r--src/mongo/db/exec/sbe/sbe_math_builtins_test.cpp52
-rw-r--r--src/mongo/db/exec/sbe/sbe_numeric_convert_test.cpp3
-rw-r--r--src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp7
-rw-r--r--src/mongo/db/exec/sbe/sbe_test.cpp2
-rw-r--r--src/mongo/db/exec/sbe/stages/branch.cpp2
-rw-r--r--src/mongo/db/exec/sbe/stages/check_bounds.cpp5
-rw-r--r--src/mongo/db/exec/sbe/stages/ix_scan.cpp2
-rw-r--r--src/mongo/db/exec/sbe/stages/text_match.cpp2
-rw-r--r--src/mongo/db/exec/sbe/stages/unwind.cpp6
-rw-r--r--src/mongo/db/exec/sbe/stages/unwind.h2
-rw-r--r--src/mongo/db/exec/sbe/values/bson.cpp47
-rw-r--r--src/mongo/db/exec/sbe/values/slot.cpp20
-rw-r--r--src/mongo/db/exec/sbe/values/slot.h2
-rw-r--r--src/mongo/db/exec/sbe/values/value.cpp50
-rw-r--r--src/mongo/db/exec/sbe/values/value.h143
-rw-r--r--src/mongo/db/exec/sbe/values/value_builder.h16
-rw-r--r--src/mongo/db/exec/sbe/vm/arith.cpp106
-rw-r--r--src/mongo/db/exec/sbe/vm/vm.cpp117
-rw-r--r--src/mongo/db/exec/sbe/vm/vm.h22
-rw-r--r--src/mongo/db/query/sbe_stage_builder.cpp5
-rw-r--r--src/mongo/db/query/sbe_stage_builder_coll_scan.cpp11
-rw-r--r--src/mongo/db/query/sbe_stage_builder_expression.cpp63
-rw-r--r--src/mongo/db/query/sbe_stage_builder_filter.cpp54
-rw-r--r--src/mongo/db/query/sbe_stage_builder_helpers.cpp12
-rw-r--r--src/mongo/db/query/sbe_stage_builder_index_scan.cpp19
37 files changed, 567 insertions, 440 deletions
diff --git a/etc/evergreen.yml b/etc/evergreen.yml
index 8bd42764bd5..053d2875452 100644
--- a/etc/evergreen.yml
+++ b/etc/evergreen.yml
@@ -9158,7 +9158,7 @@ buildvariants:
- name: .integration !.audit
distros:
- ubuntu1804-zseries-build
- - name: .jscore .common !.auth !.sbe
+ - name: .jscore .common !.auth
- name: jsCore_op_query
- name: .read_write_concern
- name: replica_sets
@@ -11598,7 +11598,7 @@ buildvariants:
- name: .integration !.audit
distros:
- rhel72-zseries-build
- - name: .jscore .common !.auth !.sbe
+ - name: .jscore .common !.auth
- name: jsCore_op_query
- name: .read_write_concern
- name: replica_sets
@@ -11670,7 +11670,7 @@ buildvariants:
- name: .integration !.audit !.sharded
distros:
- rhel67-zseries-build
- - name: .jscore .common !.sbe
+ - name: .jscore .common
- name: jsCore_minimum_batch_size
- name: replica_sets_jscore_passthrough
- name: sasl
@@ -11924,7 +11924,7 @@ buildvariants:
- name: .integration !.audit
distros:
- suse12-zseries-build
- - name: .jscore .common !.auth !.sbe
+ - name: .jscore .common !.auth
- name: jsCore_op_query
- name: .read_write_concern
- name: replica_sets
@@ -12489,7 +12489,7 @@ buildvariants:
- name: .integration !.audit
distros:
- rhel72-zseries-build
- - name: .jscore .common !.decimal !.sbe
+ - name: .jscore .common !.decimal
- name: jsCore_op_query
- name: .read_write_concern !.durable_history
- name: replica_sets
diff --git a/src/mongo/db/exec/sbe/expressions/expression.cpp b/src/mongo/db/exec/sbe/expressions/expression.cpp
index b4e010ba383..b752de92e2d 100644
--- a/src/mongo/db/exec/sbe/expressions/expression.cpp
+++ b/src/mongo/db/exec/sbe/expressions/expression.cpp
@@ -183,7 +183,8 @@ std::unique_ptr<vm::CodeFragment> EPrimBinary::compile(CompileCtx& ctx) const {
break;
case EPrimBinary::logicAnd: {
auto codeFalseBranch = std::make_unique<vm::CodeFragment>();
- codeFalseBranch->appendConstVal(value::TypeTags::Boolean, false);
+ codeFalseBranch->appendConstVal(value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(false));
// Jump to the merge point that will be right after the thenBranch (rhs).
codeFalseBranch->appendJump(rhs->instrs().size());
@@ -198,7 +199,8 @@ std::unique_ptr<vm::CodeFragment> EPrimBinary::compile(CompileCtx& ctx) const {
}
case EPrimBinary::logicOr: {
auto codeTrueBranch = std::make_unique<vm::CodeFragment>();
- codeTrueBranch->appendConstVal(value::TypeTags::Boolean, true);
+ codeTrueBranch->appendConstVal(value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(true));
// Jump to the merge point that will be right after the thenBranch (true branch).
rhs->appendJump(codeTrueBranch->instrs().size());
@@ -633,9 +635,10 @@ std::unique_ptr<vm::CodeFragment> EFail::compile(CompileCtx& ctx) const {
auto code = std::make_unique<vm::CodeFragment>();
code->appendConstVal(value::TypeTags::NumberInt64,
- value::bitcastFrom(static_cast<int64_t>(_code)));
+ value::bitcastFrom<int64_t>(static_cast<int64_t>(_code)));
- code->appendConstVal(value::TypeTags::StringBig, value::bitcastFrom(_message.c_str()));
+ code->appendConstVal(value::TypeTags::StringBig,
+ value::bitcastFrom<const char*>(_message.c_str()));
code->appendFail();
diff --git a/src/mongo/db/exec/sbe/expressions/sbe_bson_size_test.cpp b/src/mongo/db/exec/sbe/expressions/sbe_bson_size_test.cpp
index 511bbbed7ad..cb37d2b06af 100644
--- a/src/mongo/db/exec/sbe/expressions/sbe_bson_size_test.cpp
+++ b/src/mongo/db/exec/sbe/expressions/sbe_bson_size_test.cpp
@@ -45,12 +45,13 @@ TEST_F(SBEBsonSizeTest, ComputesSizeForBsonDocument) {
objBuilder.append("citizen", true);
auto bsonObj = objBuilder.done();
- slotAccessor.reset(value::TypeTags::bsonObject, value::bitcastFrom(bsonObj.objdata()));
+ slotAccessor.reset(value::TypeTags::bsonObject,
+ value::bitcastFrom<const char*>(bsonObj.objdata()));
auto [tag, val] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(tag, val);
ASSERT_EQUALS(value::TypeTags::NumberInt32, tag);
- ASSERT_EQUALS(value::bitcastTo<uint32_t>(val), bsonObj.objsize());
+ ASSERT_EQUALS(value::bitcastTo<int32_t>(val), bsonObj.objsize());
}
TEST_F(SBEBsonSizeTest, ComputesSizeForSbeObject) {
@@ -64,8 +65,8 @@ TEST_F(SBEBsonSizeTest, ComputesSizeForSbeObject) {
auto [tagArg2, valArg2] = value::makeNewObject();
auto obj = value::getObjectView(valArg2);
obj->push_back("name", tagArg1, valArg1);
- obj->push_back("age", value::TypeTags::NumberInt32, value::bitcastFrom(32));
- obj->push_back("citizen", value::TypeTags::Boolean, value::bitcastFrom(true));
+ obj->push_back("age", value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(32));
+ obj->push_back("citizen", value::TypeTags::Boolean, value::bitcastFrom<bool>(true));
value::ValueGuard argGuard(tagArg2, valArg2);
slotAccessor.reset(value::TypeTags::Object, valArg2);
@@ -73,7 +74,7 @@ TEST_F(SBEBsonSizeTest, ComputesSizeForSbeObject) {
value::ValueGuard guard(tag, val);
ASSERT_EQUALS(value::TypeTags::NumberInt32, tag);
- ASSERT_EQUALS(value::bitcastTo<uint32_t>(val), 54);
+ ASSERT_EQUALS(value::bitcastTo<int32_t>(val), 54);
}
TEST_F(SBEBsonSizeTest, ReturnsNothingForNonObject) {
@@ -89,12 +90,12 @@ TEST_F(SBEBsonSizeTest, ReturnsNothingForNonObject) {
auto [tagArg2, valArg2] = value::makeNewArray();
value::ValueGuard guard2(tagArg2, valArg2);
auto arr = value::getArrayView(valArg2);
- arr->push_back(value::TypeTags::NumberInt32, value::bitcastFrom(32));
+ arr->push_back(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(32));
auto [tagArg3, valArg3] = value::copyValue(tagArg1, valArg1);
arr->push_back(tagArg3, valArg3);
std::vector<std::pair<value::TypeTags, value::Value>> testData = {
- std::make_pair(value::TypeTags::NumberInt32, value::bitcastFrom(12789)),
+ std::make_pair(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(12789)),
std::make_pair(tagArg1, valArg1),
std::make_pair(tagArg2, valArg2)};
diff --git a/src/mongo/db/exec/sbe/expressions/sbe_coerce_to_string_test.cpp b/src/mongo/db/exec/sbe/expressions/sbe_coerce_to_string_test.cpp
index 56533b8b7ae..bd68938cf41 100644
--- a/src/mongo/db/exec/sbe/expressions/sbe_coerce_to_string_test.cpp
+++ b/src/mongo/db/exec/sbe/expressions/sbe_coerce_to_string_test.cpp
@@ -81,12 +81,12 @@ TEST_F(SBECoerceToStringTest, BasicCoerceToString) {
// BSONString test.
auto bsonString = BSON("string"
<< "hello");
- auto bsonStringVal = value::bitcastFrom(bsonString["string"].value());
+ auto bsonStringVal = value::bitcastFrom<const char*>(bsonString["string"].value());
coerceToStringAccessor.reset(value::TypeTags::bsonString, bsonStringVal);
runAndAssertExpression(compiledExpr.get(), "hello");
// Date test.
- coerceToStringAccessor.reset(sbe::value::TypeTags::Date, value::bitcastFrom<uint64_t>(4400));
+ coerceToStringAccessor.reset(sbe::value::TypeTags::Date, value::bitcastFrom<int64_t>(4400));
runAndAssertExpression(compiledExpr.get(), "1970-01-01T00:00:04.400Z");
// TimeStamp test.
@@ -101,7 +101,7 @@ TEST_F(SBECoerceToStringTest, BasicCoerceToString) {
// BSONObj test.
auto bsonObj = BSON("number" << 42);
- auto bsonData = value::bitcastFrom(bsonObj.objdata());
+ auto bsonData = value::bitcastFrom<const char*>(bsonObj.objdata());
auto [bsonTag, bsonVal] = value::copyValue(value::TypeTags::bsonObject, bsonData);
coerceToStringAccessor.reset(bsonTag, bsonVal);
runAndAssertNothing(compiledExpr.get());
diff --git a/src/mongo/db/exec/sbe/expressions/sbe_concat_test.cpp b/src/mongo/db/exec/sbe/expressions/sbe_concat_test.cpp
index 3ad44358ab8..65fb350647f 100644
--- a/src/mongo/db/exec/sbe/expressions/sbe_concat_test.cpp
+++ b/src/mongo/db/exec/sbe/expressions/sbe_concat_test.cpp
@@ -103,8 +103,8 @@ TEST_F(SBEConcatTest, ComputesStringConcat) {
<< "bson ");
auto bsonString2 = BSON("key"
<< "string");
- auto bsonStringVal1 = value::bitcastFrom(bsonString1["key"].value());
- auto bsonStringVal2 = value::bitcastFrom(bsonString2["key"].value());
+ auto bsonStringVal1 = value::bitcastFrom<const char*>(bsonString1["key"].value());
+ auto bsonStringVal2 = value::bitcastFrom<const char*>(bsonString2["key"].value());
slotAccessor1.reset(value::TypeTags::bsonString, bsonStringVal1);
slotAccessor2.reset(value::TypeTags::bsonString, bsonStringVal2);
runAndAssertExpression(compiledExpr.get(), "bson string");
@@ -128,7 +128,7 @@ TEST_F(SBEConcatTest, ComputesManyStringsConcat) {
auto bsonString = BSON("key"
<< "Test ");
- auto bsonStringVal = value::bitcastFrom(bsonString["key"].value());
+ auto bsonStringVal = value::bitcastFrom<const char*>(bsonString["key"].value());
auto [tag2, val2] = value::makeSmallString("for ");
auto [tag3, val3] = value::makeNewString("many strings ");
auto [tag4, val4] = value::makeSmallString("concat");
@@ -150,7 +150,7 @@ TEST_F(SBEConcatTest, ReturnsNothingForNonStringsConcat) {
auto [tag1, val1] = value::makeNewString("abc");
slotAccessor1.reset(tag1, val1);
- slotAccessor2.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{100}));
+ slotAccessor2.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(100));
runAndAssertNothing(compiledExpr.get());
}
diff --git a/src/mongo/db/exec/sbe/expressions/sbe_is_member_builtin_test.cpp b/src/mongo/db/exec/sbe/expressions/sbe_is_member_builtin_test.cpp
index d510af3b032..80b45d16505 100644
--- a/src/mongo/db/exec/sbe/expressions/sbe_is_member_builtin_test.cpp
+++ b/src/mongo/db/exec/sbe/expressions/sbe_is_member_builtin_test.cpp
@@ -49,11 +49,11 @@ protected:
int numBytes = ba.objsize();
uint8_t* data = new uint8_t[numBytes];
memcpy(data, reinterpret_cast<const uint8_t*>(ba.objdata()), numBytes);
- return {value::TypeTags::bsonArray, value::bitcastFrom(data)};
+ return {value::TypeTags::bsonArray, value::bitcastFrom<uint8_t*>(data)};
}
std::pair<value::TypeTags, value::Value> makeViewOfObject(const BSONObj& obj) {
- return {value::TypeTags::bsonObject, value::bitcastFrom(obj.objdata())};
+ return {value::TypeTags::bsonObject, value::bitcastFrom<const char*>(obj.objdata())};
}
std::pair<value::TypeTags, value::Value> makeArraySet(const BSONArray& arr) {
@@ -108,19 +108,19 @@ TEST_F(SBEBuiltinIsMemberTest, IsMemberArraySet) {
auto inputSlot = bindAccessor(&inputSlotAccessor);
// Test that isMember can find basic values.
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 1);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(inputSlot, makeArraySet(BSON_ARRAY(1 << 2)), true);
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 3);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(3));
runAndAssertExpression(inputSlot, makeArraySet(BSON_ARRAY(1 << 2)), false);
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 3);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(3));
runAndAssertExpression(inputSlot, makeArraySet(BSON_ARRAY(BSONObj())), false);
- inputSlotAccessor.reset(value::TypeTags::NumberInt64, 1);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(1));
runAndAssertExpression(inputSlot, makeArraySet(BSON_ARRAY(1 << 2)), true);
- inputSlotAccessor.reset(value::TypeTags::NumberInt64, 3);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(3));
runAndAssertExpression(inputSlot, makeArraySet(BSON_ARRAY(1 << 2)), false);
auto [decimalTag, decimalVal] = value::makeCopyDecimal(Decimal128{9});
@@ -172,19 +172,19 @@ TEST_F(SBEBuiltinIsMemberTest, IsMemberArray) {
auto inputSlot = bindAccessor(&inputSlotAccessor);
// Test that isMember can find basic values.
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 1);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(inputSlot, makeArray(BSON_ARRAY(1 << 2)), true);
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 3);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(3));
runAndAssertExpression(inputSlot, makeArray(BSON_ARRAY(1 << 2)), false);
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 3);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(3));
runAndAssertExpression(inputSlot, makeArray(BSON_ARRAY(BSONObj())), false);
- inputSlotAccessor.reset(value::TypeTags::NumberInt64, 1);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(1));
runAndAssertExpression(inputSlot, makeArray(BSON_ARRAY(1 << 2)), true);
- inputSlotAccessor.reset(value::TypeTags::NumberInt64, 3);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(3));
runAndAssertExpression(inputSlot, makeArray(BSON_ARRAY(1 << 2)), false);
auto [decimalTag, decimalVal] = value::makeCopyDecimal(Decimal128{9});
@@ -237,19 +237,19 @@ TEST_F(SBEBuiltinIsMemberTest, IsMemberBSONArray) {
auto inputSlot = bindAccessor(&inputSlotAccessor);
// Test that isMember can find basic values.
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 1);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(inputSlot, makeValue(BSON_ARRAY(1 << 2)), true);
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 3);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(3));
runAndAssertExpression(inputSlot, makeValue(BSON_ARRAY(1 << 2)), false);
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 3);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(3));
runAndAssertExpression(inputSlot, makeValue(BSON_ARRAY(BSONObj())), false);
- inputSlotAccessor.reset(value::TypeTags::NumberInt64, 1);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(1));
runAndAssertExpression(inputSlot, makeValue(BSON_ARRAY(1 << 2)), true);
- inputSlotAccessor.reset(value::TypeTags::NumberInt64, 3);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(3));
runAndAssertExpression(inputSlot, makeValue(BSON_ARRAY(1 << 2)), false);
auto [decimalTag, decimalVal] = value::makeCopyDecimal(Decimal128{9});
@@ -302,7 +302,8 @@ TEST_F(SBEBuiltinIsMemberTest, IsMemberReturnsNothing) {
auto inputSlot = bindAccessor(&inputSlotAccessor);
// Test that invocation of 'isMember' returns nothing if the second argument isn't an array.
- inputSlotAccessor.reset(value::TypeTags::NumberInt32, 1);
- runAndAssertExpression(inputSlot, {value::TypeTags::NumberInt32, 0}, false);
+ inputSlotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
+ runAndAssertExpression(
+ inputSlot, {value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(0)}, false);
}
} // namespace mongo::sbe
diff --git a/src/mongo/db/exec/sbe/expressions/sbe_to_upper_to_lower_test.cpp b/src/mongo/db/exec/sbe/expressions/sbe_to_upper_to_lower_test.cpp
index a484a588d24..5c3e04bfeec 100644
--- a/src/mongo/db/exec/sbe/expressions/sbe_to_upper_to_lower_test.cpp
+++ b/src/mongo/db/exec/sbe/expressions/sbe_to_upper_to_lower_test.cpp
@@ -70,7 +70,7 @@ TEST_F(SBEToUpperToLowerTest, BasicToUpper) {
// BSONString test.
auto bsonStringObj = BSON("string"
<< "hello");
- auto bsonStringVal = value::bitcastFrom(bsonStringObj["string"].value());
+ auto bsonStringVal = value::bitcastFrom<const char*>(bsonStringObj["string"].value());
toUpperAccessor.reset(value::TypeTags::bsonString, bsonStringVal);
runAndAssertExpression(compiledExpr.get(), "HELLO");
@@ -92,7 +92,7 @@ TEST_F(SBEToUpperToLowerTest, BasicToUpper) {
runAndAssertNothing(compiledExpr.get());
// Date test.
- toUpperAccessor.reset(sbe::value::TypeTags::Date, value::bitcastFrom<uint64_t>(4400));
+ toUpperAccessor.reset(sbe::value::TypeTags::Date, value::bitcastFrom<int64_t>(4400));
runAndAssertNothing(compiledExpr.get());
// Timestamp test.
@@ -102,7 +102,7 @@ TEST_F(SBEToUpperToLowerTest, BasicToUpper) {
// BSONObj test.
auto bsonObj = BSON("number" << 42);
- auto bsonData = value::bitcastFrom(bsonObj.objdata());
+ auto bsonData = value::bitcastFrom<const char*>(bsonObj.objdata());
auto [bsonTag, bsonVal] = value::copyValue(value::TypeTags::bsonObject, bsonData);
toUpperAccessor.reset(bsonTag, bsonVal);
runAndAssertNothing(compiledExpr.get());
@@ -138,7 +138,7 @@ TEST_F(SBEToUpperToLowerTest, BasicToLower) {
// BSONString test.
auto bsonStringObj = BSON("string"
<< "HELLO");
- auto bsonStringVal = value::bitcastFrom(bsonStringObj["string"].value());
+ auto bsonStringVal = value::bitcastFrom<const char*>(bsonStringObj["string"].value());
toLowerAccessor.reset(value::TypeTags::bsonString, bsonStringVal);
runAndAssertExpression(compiledExpr.get(), "hello");
@@ -160,7 +160,7 @@ TEST_F(SBEToUpperToLowerTest, BasicToLower) {
runAndAssertNothing(compiledExpr.get());
// Date test.
- toLowerAccessor.reset(sbe::value::TypeTags::Date, value::bitcastFrom<uint64_t>(4400));
+ toLowerAccessor.reset(sbe::value::TypeTags::Date, value::bitcastFrom<int64_t>(4400));
runAndAssertNothing(compiledExpr.get());
// Timestamp test.
@@ -170,7 +170,7 @@ TEST_F(SBEToUpperToLowerTest, BasicToLower) {
// BSONObj test.
auto bsonObj = BSON("number" << 42);
- auto bsonData = value::bitcastFrom(bsonObj.objdata());
+ auto bsonData = value::bitcastFrom<const char*>(bsonObj.objdata());
auto [bsonTag, bsonVal] = value::copyValue(value::TypeTags::bsonObject, bsonData);
toLowerAccessor.reset(bsonTag, bsonVal);
runAndAssertNothing(compiledExpr.get());
diff --git a/src/mongo/db/exec/sbe/expressions/sbe_trigonometric_expressions_test.cpp b/src/mongo/db/exec/sbe/expressions/sbe_trigonometric_expressions_test.cpp
index 14ff23d85d9..9ff545a4980 100644
--- a/src/mongo/db/exec/sbe/expressions/sbe_trigonometric_expressions_test.cpp
+++ b/src/mongo/db/exec/sbe/expressions/sbe_trigonometric_expressions_test.cpp
@@ -65,13 +65,13 @@ TEST_F(SBETrigonometricExprTest, ComputesAcos) {
auto acosExpr = sbe::makeE<sbe::EFunction>("acos", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*acosExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(0));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(0));
runAndAssertExpression(compiledExpr.get(), std::acos(0));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{1}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(1));
runAndAssertExpression(compiledExpr.get(), std::acos(1));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
runAndAssertExpression(compiledExpr.get(), std::acos(0.10001));
Decimal128 arg(0.777);
@@ -90,13 +90,13 @@ TEST_F(SBETrigonometricExprTest, ComputesAcosh) {
auto acoshExpr = sbe::makeE<sbe::EFunction>("acosh", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*acoshExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(compiledExpr.get(), std::acosh(1));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{7}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(7));
runAndAssertExpression(compiledExpr.get(), std::acosh(7));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(1.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(1.10001));
runAndAssertExpression(compiledExpr.get(), std::acosh(1.10001));
Decimal128 arg(7.777);
@@ -115,13 +115,13 @@ TEST_F(SBETrigonometricExprTest, ComputesAsin) {
auto asinExpr = sbe::makeE<sbe::EFunction>("asin", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*asinExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(0));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(0));
runAndAssertExpression(compiledExpr.get(), std::asin(0));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{1}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(1));
runAndAssertExpression(compiledExpr.get(), std::asin(1));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
runAndAssertExpression(compiledExpr.get(), std::asin(0.10001));
Decimal128 arg(0.9);
@@ -140,13 +140,13 @@ TEST_F(SBETrigonometricExprTest, ComputesAsinh) {
auto asinhExpr = sbe::makeE<sbe::EFunction>("asinh", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*asinhExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(0));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(0));
runAndAssertExpression(compiledExpr.get(), std::asinh(0));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{1}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(1));
runAndAssertExpression(compiledExpr.get(), std::asinh(1));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
runAndAssertExpression(compiledExpr.get(), std::asinh(0.10001));
Decimal128 arg(1.5);
@@ -166,13 +166,13 @@ TEST_F(SBETrigonometricExprTest, ComputesAtan) {
auto atanExpr = sbe::makeE<sbe::EFunction>("atan", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*atanExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(compiledExpr.get(), std::atan(1));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{2}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(2));
runAndAssertExpression(compiledExpr.get(), std::atan(2));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
runAndAssertExpression(compiledExpr.get(), std::atan(0.10001));
Decimal128 arg(1.0471975512);
@@ -191,13 +191,13 @@ TEST_F(SBETrigonometricExprTest, ComputesAtanh) {
auto atanhExpr = sbe::makeE<sbe::EFunction>("atanh", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*atanhExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(0));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(0));
runAndAssertExpression(compiledExpr.get(), std::atanh(0));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{0}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(0));
runAndAssertExpression(compiledExpr.get(), std::atanh(0));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
runAndAssertExpression(compiledExpr.get(), std::atanh(0.10001));
Decimal128 arg(-0.345);
@@ -218,16 +218,16 @@ TEST_F(SBETrigonometricExprTest, ComputesAtan2) {
"atan2", sbe::makeEs(makeE<EVariable>(argSlot1), makeE<EVariable>(argSlot2)));
auto compiledExpr = compileExpression(*atan2Expr);
- slotAccessor1.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
- slotAccessor2.reset(value::TypeTags::NumberInt32, value::bitcastFrom(0));
+ slotAccessor1.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
+ slotAccessor2.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(0));
runAndAssertExpression(compiledExpr.get(), std::atan2(1, 0));
- slotAccessor1.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{0}));
- slotAccessor2.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{-1}));
+ slotAccessor1.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(0));
+ slotAccessor2.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(-1));
runAndAssertExpression(compiledExpr.get(), std::atan2(0, -1));
- slotAccessor1.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
- slotAccessor2.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.707106781187));
+ slotAccessor1.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
+ slotAccessor2.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.707106781187));
runAndAssertExpression(compiledExpr.get(), std::atan2(0.10001, 0.707106781187));
Decimal128 arg1(0.5), arg2(0.866025403784);
@@ -239,7 +239,7 @@ TEST_F(SBETrigonometricExprTest, ComputesAtan2) {
auto [tagStrArg, valStrArg] = value::makeNewString("xyz");
slotAccessor1.reset(tagStrArg, valStrArg);
- slotAccessor2.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor2.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertNothing(compiledExpr.get());
}
@@ -249,13 +249,13 @@ TEST_F(SBETrigonometricExprTest, ComputesCos) {
auto cosExpr = sbe::makeE<sbe::EFunction>("cos", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*cosExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(compiledExpr.get(), std::cos(1));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{2}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(2));
runAndAssertExpression(compiledExpr.get(), std::cos(2));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
runAndAssertExpression(compiledExpr.get(), std::cos(0.10001));
Decimal128 arg(1.000001);
@@ -274,13 +274,13 @@ TEST_F(SBETrigonometricExprTest, ComputesCosh) {
auto coshExpr = sbe::makeE<sbe::EFunction>("cosh", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*coshExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(compiledExpr.get(), std::cosh(1));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{2}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(2));
runAndAssertExpression(compiledExpr.get(), std::cosh(2));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
runAndAssertExpression(compiledExpr.get(), std::cosh(0.10001));
Decimal128 arg(4.18879020479);
@@ -300,13 +300,13 @@ TEST_F(SBETrigonometricExprTest, ComputesDegreesToRadians) {
sbe::makeE<sbe::EFunction>("degreesToRadians", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*degreesToRadiansExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(45));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(45));
runAndAssertExpression(compiledExpr.get(), 0.7853981633974483);
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{135}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(135));
runAndAssertExpression(compiledExpr.get(), 2.356194490192345);
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(240.0));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(240.0));
runAndAssertExpression(compiledExpr.get(), 4.1887902047863905);
Decimal128 arg(180);
@@ -326,13 +326,14 @@ TEST_F(SBETrigonometricExprTest, ComputesRadiansToDegrees) {
sbe::makeE<sbe::EFunction>("radiansToDegrees", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*radiansToDegreesExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(compiledExpr.get(), 57.29577951308232);
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{3}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(3));
runAndAssertExpression(compiledExpr.get(), 171.88733853924697);
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(5.235987755982989));
+ slotAccessor.reset(value::TypeTags::NumberDouble,
+ value::bitcastFrom<double>(5.235987755982989));
runAndAssertExpression(compiledExpr.get(), 300.0);
Decimal128 arg(3.141592653589793);
@@ -351,13 +352,13 @@ TEST_F(SBETrigonometricExprTest, ComputesSin) {
auto sinExpr = sbe::makeE<sbe::EFunction>("sin", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*sinExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(compiledExpr.get(), std::sin(1));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{2}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(2));
runAndAssertExpression(compiledExpr.get(), std::sin(2));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
runAndAssertExpression(compiledExpr.get(), std::sin(0.10001));
Decimal128 arg(1.000001);
@@ -376,13 +377,13 @@ TEST_F(SBETrigonometricExprTest, ComputesSinh) {
auto sinhExpr = sbe::makeE<sbe::EFunction>("sinh", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*sinhExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(compiledExpr.get(), std::sinh(1));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{2}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(2));
runAndAssertExpression(compiledExpr.get(), std::sinh(2));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.523598775598));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.523598775598));
runAndAssertExpression(compiledExpr.get(), std::sinh(0.523598775598));
Decimal128 arg(3.66519142919);
@@ -400,13 +401,13 @@ TEST_F(SBETrigonometricExprTest, ComputesTan) {
auto tanExpr = sbe::makeE<sbe::EFunction>("tan", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*tanExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(compiledExpr.get(), std::tan(1));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{2}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(2));
runAndAssertExpression(compiledExpr.get(), std::tan(2));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(0.10001));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.10001));
runAndAssertExpression(compiledExpr.get(), std::tan(0.10001));
Decimal128 arg(1.000001);
@@ -425,13 +426,13 @@ TEST_F(SBETrigonometricExprTest, ComputesTanh) {
auto tanhExpr = sbe::makeE<sbe::EFunction>("tanh", sbe::makeEs(makeE<EVariable>(argSlot)));
auto compiledExpr = compileExpression(*tanhExpr);
- slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(1));
+ slotAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(1));
runAndAssertExpression(compiledExpr.get(), std::tanh(1));
- slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{2}));
+ slotAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(2));
runAndAssertExpression(compiledExpr.get(), std::tanh(2));
- slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(1.0471975512));
+ slotAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(1.0471975512));
runAndAssertExpression(compiledExpr.get(), std::tanh(1.0471975512));
Decimal128 arg(0.785398163397);
diff --git a/src/mongo/db/exec/sbe/parser/parser.cpp b/src/mongo/db/exec/sbe/parser/parser.cpp
index f650ac6ed1c..480951b5acc 100644
--- a/src/mongo/db/exec/sbe/parser/parser.cpp
+++ b/src/mongo/db/exec/sbe/parser/parser.cpp
@@ -429,12 +429,13 @@ void Parser::walkPrimaryExpr(AstQuery& ast) {
ast.expr = makeE<EVariable>(lookupSlotStrict(ast.nodes[0]->identifier));
}
} else if (ast.nodes[0]->tag == "NUMBER"_) {
- ast.expr = makeE<EConstant>(value::TypeTags::NumberInt64, std::stoll(ast.nodes[0]->token));
+ ast.expr = makeE<EConstant>(value::TypeTags::NumberInt64,
+ value::bitcastFrom<int64_t>(std::stoll(ast.nodes[0]->token)));
} else if (ast.nodes[0]->tag == "CONST_TOK"_) {
if (ast.nodes[0]->token == "true") {
- ast.expr = makeE<EConstant>(value::TypeTags::Boolean, 1);
+ ast.expr = makeE<EConstant>(value::TypeTags::Boolean, value::bitcastFrom<bool>(true));
} else if (ast.nodes[0]->token == "false") {
- ast.expr = makeE<EConstant>(value::TypeTags::Boolean, 0);
+ ast.expr = makeE<EConstant>(value::TypeTags::Boolean, value::bitcastFrom<bool>(false));
} else if (ast.nodes[0]->token == "null") {
ast.expr = makeE<EConstant>(value::TypeTags::Null, 0);
} else if (ast.nodes[0]->token == "#") {
diff --git a/src/mongo/db/exec/sbe/sbe_filter_test.cpp b/src/mongo/db/exec/sbe/sbe_filter_test.cpp
index bb687794c52..033d436cdf9 100644
--- a/src/mongo/db/exec/sbe/sbe_filter_test.cpp
+++ b/src/mongo/db/exec/sbe/sbe_filter_test.cpp
@@ -53,7 +53,9 @@ TEST_F(FilterStageTest, ConstantFilterAlwaysTrueTest) {
auto makeStageFn = [](value::SlotId scanSlot, std::unique_ptr<PlanStage> scanStage) {
// Build a constant FilterStage whose filter expression is always boolean true.
auto filter = makeS<FilterStage<true>>(
- std::move(scanStage), makeE<EConstant>(value::TypeTags::Boolean, 1), kEmptyPlanNodeId);
+ std::move(scanStage),
+ makeE<EConstant>(value::TypeTags::Boolean, value::bitcastFrom<bool>(true)),
+ kEmptyPlanNodeId);
return std::make_pair(scanSlot, std::move(filter));
};
@@ -74,7 +76,9 @@ TEST_F(FilterStageTest, ConstantFilterAlwaysFalseTest) {
auto makeStageFn = [](value::SlotId scanSlot, std::unique_ptr<PlanStage> scanStage) {
// Build a constant FilterStage whose filter expression is always boolean false.
auto filter = makeS<FilterStage<true>>(
- std::move(scanStage), makeE<EConstant>(value::TypeTags::Boolean, 0), kEmptyPlanNodeId);
+ std::move(scanStage),
+ makeE<EConstant>(value::TypeTags::Boolean, value::bitcastFrom<bool>(false)),
+ kEmptyPlanNodeId);
return std::make_pair(scanSlot, std::move(filter));
};
@@ -95,7 +99,9 @@ TEST_F(FilterStageTest, FilterAlwaysTrueTest) {
auto makeStageFn = [](value::SlotId scanSlot, std::unique_ptr<PlanStage> scanStage) {
// Build a non-constant FilterStage whose filter expression is always boolean true.
auto filter = makeS<FilterStage<false>>(
- std::move(scanStage), makeE<EConstant>(value::TypeTags::Boolean, 1), kEmptyPlanNodeId);
+ std::move(scanStage),
+ makeE<EConstant>(value::TypeTags::Boolean, value::bitcastFrom<bool>(true)),
+ kEmptyPlanNodeId);
return std::make_pair(scanSlot, std::move(filter));
};
@@ -116,7 +122,9 @@ TEST_F(FilterStageTest, FilterAlwaysFalseTest) {
auto makeStageFn = [](value::SlotId scanSlot, std::unique_ptr<PlanStage> scanStage) {
// Build a non-constant FilterStage whose filter expression is always boolean false.
auto filter = makeS<FilterStage<false>>(
- std::move(scanStage), makeE<EConstant>(value::TypeTags::Boolean, 0), kEmptyPlanNodeId);
+ std::move(scanStage),
+ makeE<EConstant>(value::TypeTags::Boolean, value::bitcastFrom<bool>(false)),
+ kEmptyPlanNodeId);
return std::make_pair(scanSlot, std::move(filter));
};
diff --git a/src/mongo/db/exec/sbe/sbe_key_string_test.cpp b/src/mongo/db/exec/sbe/sbe_key_string_test.cpp
index 05015520b0a..bc9c581d649 100644
--- a/src/mongo/db/exec/sbe/sbe_key_string_test.cpp
+++ b/src/mongo/db/exec/sbe/sbe_key_string_test.cpp
@@ -138,7 +138,8 @@ TEST_F(SBEKeyStringTest, Basic) {
makeEs(makeE<EVariable>(bsonObjSlot), makeE<EVariable>(fieldNameSlot))));
auto compiledExpr = compileExpression(*comparisonExpr);
- bsonObjAccessor.reset(value::TypeTags::bsonObject, value::bitcastFrom(testValues.objdata()));
+ bsonObjAccessor.reset(value::TypeTags::bsonObject,
+ value::bitcastFrom<const char*>(testValues.objdata()));
std::vector<sbe::value::ViewOfValueAccessor> keyStringValues;
BufBuilder builder;
for (auto&& element : testValues) {
@@ -189,11 +190,12 @@ TEST(SBEKeyStringTest, KeyComponentInclusion) {
readKeyStringValueIntoAccessors(
keyString, KeyString::ALL_ASCENDING, &builder, &accessors, indexKeysToInclude);
- ASSERT(std::make_pair(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{12345})) ==
- accessors[0].getViewOfValue())
- << "Incorrect value from accessor: " << valueDebugString(accessors[0].getViewOfValue());
+ auto value = accessors[0].getViewOfValue();
+ ASSERT(value::TypeTags::NumberInt64 == value.first &&
+ 12345 == value::bitcastTo<int64_t>(value.second))
+ << "Incorrect value from accessor: " << valueDebugString(value);
- auto value = accessors[1].getViewOfValue();
+ value = accessors[1].getViewOfValue();
ASSERT(value::isString(value.first) &&
("I know the kings of England, and I quote the fights historical" ==
value::getStringView(value.first, value.second)))
diff --git a/src/mongo/db/exec/sbe/sbe_limit_skip_test.cpp b/src/mongo/db/exec/sbe/sbe_limit_skip_test.cpp
index 076212c7992..023fdee286c 100644
--- a/src/mongo/db/exec/sbe/sbe_limit_skip_test.cpp
+++ b/src/mongo/db/exec/sbe/sbe_limit_skip_test.cpp
@@ -63,7 +63,7 @@ TEST_F(LimitSkipStageTest, LimitSkipSimpleTest) {
auto inputView = value::getArrayView(inputVal);
int i;
for (i = 0; i < 1000; ++i) {
- inputView->push_back(value::TypeTags::NumberInt64, i);
+ inputView->push_back(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(i));
}
// Make a "limit 200 skip 300" stage.
diff --git a/src/mongo/db/exec/sbe/sbe_math_builtins_test.cpp b/src/mongo/db/exec/sbe/sbe_math_builtins_test.cpp
index bd76816dcc0..490eb3dd931 100644
--- a/src/mongo/db/exec/sbe/sbe_math_builtins_test.cpp
+++ b/src/mongo/db/exec/sbe/sbe_math_builtins_test.cpp
@@ -46,7 +46,7 @@ TEST_F(SBEMathBuiltinTest, Abs) {
auto compiledExpr = compileExpression(*callExpr);
{
- inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(int32_t{-6}));
+ inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(-6));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -56,7 +56,7 @@ TEST_F(SBEMathBuiltinTest, Abs) {
{
inputAccessor.reset(value::TypeTags::NumberInt32,
- value::bitcastFrom(std::numeric_limits<int32_t>::min()));
+ value::bitcastFrom<int32_t>(std::numeric_limits<int32_t>::min()));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -66,7 +66,7 @@ TEST_F(SBEMathBuiltinTest, Abs) {
}
{
- inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{-6000000000}));
+ inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(-6000000000));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -76,7 +76,7 @@ TEST_F(SBEMathBuiltinTest, Abs) {
{
inputAccessor.reset(value::TypeTags::NumberInt64,
- value::bitcastFrom(std::numeric_limits<int64_t>::min()));
+ value::bitcastFrom<int64_t>(std::numeric_limits<int64_t>::min()));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -84,7 +84,7 @@ TEST_F(SBEMathBuiltinTest, Abs) {
}
{
- inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(-6e300));
+ inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(-6e300));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -112,7 +112,7 @@ TEST_F(SBEMathBuiltinTest, Ceil) {
auto compiledExpr = compileExpression(*callExpr);
{
- inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(double{-10.0001}));
+ inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(-10.0001));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -132,7 +132,7 @@ TEST_F(SBEMathBuiltinTest, Ceil) {
}
{
- inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(int32_t{-10}));
+ inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(-10));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -142,7 +142,7 @@ TEST_F(SBEMathBuiltinTest, Ceil) {
{
inputAccessor.reset(value::TypeTags::NumberInt64,
- value::bitcastFrom(int64_t{-10000000000}));
+ value::bitcastFrom<int64_t>(-10000000000));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -159,7 +159,7 @@ TEST_F(SBEMathBuiltinTest, Floor) {
auto compiledExpr = compileExpression(*callExpr);
{
- inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(double{-10.0001}));
+ inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(-10.0001));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -179,7 +179,7 @@ TEST_F(SBEMathBuiltinTest, Floor) {
}
{
- inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(int32_t{-10}));
+ inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(-10));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -189,7 +189,7 @@ TEST_F(SBEMathBuiltinTest, Floor) {
{
inputAccessor.reset(value::TypeTags::NumberInt64,
- value::bitcastFrom(int64_t{-10000000000}));
+ value::bitcastFrom<int64_t>(-10000000000));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -206,7 +206,7 @@ TEST_F(SBEMathBuiltinTest, Exp) {
auto compiledExpr = compileExpression(*callExpr);
{
- inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(int32_t{2}));
+ inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(2));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -215,7 +215,7 @@ TEST_F(SBEMathBuiltinTest, Exp) {
}
{
- inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{3}));
+ inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(3));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -224,7 +224,7 @@ TEST_F(SBEMathBuiltinTest, Exp) {
}
{
- inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(double{2.5}));
+ inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(2.5));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -254,7 +254,7 @@ TEST_F(SBEMathBuiltinTest, Ln) {
auto compiledExpr = compileExpression(*callExpr);
{
- inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(int32_t{2}));
+ inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(2));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -263,7 +263,7 @@ TEST_F(SBEMathBuiltinTest, Ln) {
}
{
- inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{20000000000}));
+ inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(20000000000));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -272,7 +272,7 @@ TEST_F(SBEMathBuiltinTest, Ln) {
}
{
- inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(double{2.1e20}));
+ inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(2.1e20));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -295,7 +295,7 @@ TEST_F(SBEMathBuiltinTest, Ln) {
// Non-positive values evaluate to Nothing
{
- inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(int32_t{0}));
+ inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(0));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -311,7 +311,7 @@ TEST_F(SBEMathBuiltinTest, Log10) {
auto compiledExpr = compileExpression(*callExpr);
{
- inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(int32_t{100}));
+ inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(100));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -320,7 +320,7 @@ TEST_F(SBEMathBuiltinTest, Log10) {
}
{
- inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{10000000000}));
+ inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(10000000000));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -329,7 +329,7 @@ TEST_F(SBEMathBuiltinTest, Log10) {
}
{
- inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(double{2.1e20}));
+ inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(2.1e20));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -356,7 +356,7 @@ TEST_F(SBEMathBuiltinTest, Sqrt) {
auto compiledExpr = compileExpression(*callExpr);
{
- inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom(int32_t{4}));
+ inputAccessor.reset(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(4));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -365,7 +365,7 @@ TEST_F(SBEMathBuiltinTest, Sqrt) {
}
{
- inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom(int64_t{10000000000}));
+ inputAccessor.reset(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(10000000000));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -374,7 +374,7 @@ TEST_F(SBEMathBuiltinTest, Sqrt) {
}
{
- inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(double{2.5}));
+ inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(2.5));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -398,7 +398,7 @@ TEST_F(SBEMathBuiltinTest, Sqrt) {
// For types with signed zero, we do not distinguish -0 from 0. The domain of sqrt _does_
// include -0, and -0 evaluates to a value that is equal to zero.
{
- inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom(double{-0.0}));
+ inputAccessor.reset(value::TypeTags::NumberDouble, value::bitcastFrom<double>(-0.0));
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
value::ValueGuard guard(resultTag, resultVal);
@@ -475,7 +475,7 @@ TEST_F(SBEMathBuiltinTest, InvalidInputsToUnaryNumericFunctions) {
// NaN is a valid input but returns NaN
{
inputAccessor.reset(value::TypeTags::NumberDouble,
- value::bitcastFrom(std::numeric_limits<double>::quiet_NaN()));
+ value::bitcastFrom<double>(std::numeric_limits<double>::quiet_NaN()));
for (auto&& compiledExpr : compiledExpressionList) {
auto [resultTag, resultVal] = runCompiledExpression(compiledExpr.get());
diff --git a/src/mongo/db/exec/sbe/sbe_numeric_convert_test.cpp b/src/mongo/db/exec/sbe/sbe_numeric_convert_test.cpp
index 11eb54b3d82..2dda3e73a3a 100644
--- a/src/mongo/db/exec/sbe/sbe_numeric_convert_test.cpp
+++ b/src/mongo/db/exec/sbe/sbe_numeric_convert_test.cpp
@@ -35,7 +35,8 @@ template <typename T>
std::unique_ptr<sbe::EExpression> makeEFromNumber(const T in,
value::TypeTags sourceTag,
value::TypeTags targetTag) {
- return makeE<ENumericConvert>(makeE<EConstant>(sourceTag, value::bitcastFrom(in)), targetTag);
+ return makeE<ENumericConvert>(makeE<EConstant>(sourceTag, value::bitcastFrom<T>(in)),
+ targetTag);
}
template <>
diff --git a/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp b/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp
index 0b6621c3c2b..e6529e317e8 100644
--- a/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp
+++ b/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp
@@ -43,14 +43,14 @@ std::pair<value::TypeTags, value::Value> PlanStageTestFixture::makeValue(const B
int numBytes = ba.objsize();
uint8_t* data = new uint8_t[numBytes];
memcpy(data, reinterpret_cast<const uint8_t*>(ba.objdata()), numBytes);
- return {value::TypeTags::bsonArray, value::bitcastFrom(data)};
+ return {value::TypeTags::bsonArray, value::bitcastFrom<uint8_t*>(data)};
}
std::pair<value::TypeTags, value::Value> PlanStageTestFixture::makeValue(const BSONObj& bo) {
int numBytes = bo.objsize();
uint8_t* data = new uint8_t[numBytes];
memcpy(data, reinterpret_cast<const uint8_t*>(bo.objdata()), numBytes);
- return {value::TypeTags::bsonObject, value::bitcastFrom(data)};
+ return {value::TypeTags::bsonObject, value::bitcastFrom<uint8_t*>(data)};
}
std::pair<value::SlotId, std::unique_ptr<PlanStage>> PlanStageTestFixture::generateMockScan(
@@ -103,7 +103,8 @@ PlanStageTestFixture::generateMockScanMulti(int64_t numSlots,
projectSlots.back(),
makeE<EFunction>("getElement"sv,
makeEs(makeE<EVariable>(scanSlot),
- makeE<EConstant>(value::TypeTags::NumberInt64, i))));
+ makeE<EConstant>(value::TypeTags::NumberInt64,
+ value::bitcastFrom<int64_t>(i)))));
}
return {std::move(projectSlots),
diff --git a/src/mongo/db/exec/sbe/sbe_test.cpp b/src/mongo/db/exec/sbe/sbe_test.cpp
index aa88314da57..6687d81eda3 100644
--- a/src/mongo/db/exec/sbe/sbe_test.cpp
+++ b/src/mongo/db/exec/sbe/sbe_test.cpp
@@ -156,7 +156,7 @@ TEST(SBEVM, Add) {
auto [owned, tag, val] = interpreter.run(&code);
ASSERT_EQUALS(tag, value::TypeTags::NumberInt64);
- ASSERT_EQUALS(val, -12);
+ ASSERT_EQUALS(value::bitcastTo<int64_t>(val), -12);
}
{
auto tagInt32 = value::TypeTags::NumberInt32;
diff --git a/src/mongo/db/exec/sbe/stages/branch.cpp b/src/mongo/db/exec/sbe/stages/branch.cpp
index 4c0bb95946b..4d1aa600bb2 100644
--- a/src/mongo/db/exec/sbe/stages/branch.cpp
+++ b/src/mongo/db/exec/sbe/stages/branch.cpp
@@ -115,7 +115,7 @@ void BranchStage::open(bool reOpen) {
value::releaseValue(tag, val);
}
if (tag == value::TypeTags::Boolean) {
- if (val) {
+ if (value::bitcastTo<bool>(val)) {
_activeBranch = 0;
_children[0]->open(reOpen && _thenOpened);
_thenOpened = true;
diff --git a/src/mongo/db/exec/sbe/stages/check_bounds.cpp b/src/mongo/db/exec/sbe/stages/check_bounds.cpp
index 6825968a998..6e91b13d6a3 100644
--- a/src/mongo/db/exec/sbe/stages/check_bounds.cpp
+++ b/src/mongo/db/exec/sbe/stages/check_bounds.cpp
@@ -106,8 +106,9 @@ PlanState CheckBoundsStage::getNext() {
auto seekKey = std::make_unique<KeyString::Value>(
IndexEntryComparison::makeKeyStringFromSeekPointForSeek(
seekPoint, _params.version, _params.ord, _params.direction == 1));
- _outAccessor.reset(
- true, value::TypeTags::ksValue, value::bitcastFrom(seekKey.release()));
+ _outAccessor.reset(true,
+ value::TypeTags::ksValue,
+ value::bitcastFrom<KeyString::Value*>(seekKey.release()));
// We should return the seek key provided by the 'IndexBoundsChecker' to restart
// the index scan, but we should stop on the next call to 'getNext' since we've just
// passed behind the current interval and need to signal the parent stage that we're
diff --git a/src/mongo/db/exec/sbe/stages/ix_scan.cpp b/src/mongo/db/exec/sbe/stages/ix_scan.cpp
index 68c8c6c44cc..ab4df1cc75f 100644
--- a/src/mongo/db/exec/sbe/stages/ix_scan.cpp
+++ b/src/mongo/db/exec/sbe/stages/ix_scan.cpp
@@ -270,7 +270,7 @@ PlanState IndexScanStage::getNext() {
if (_recordAccessor) {
_recordAccessor->reset(value::TypeTags::ksValue,
- value::bitcastFrom(&_nextRecord->keyString));
+ value::bitcastFrom<KeyString::Value*>(&_nextRecord->keyString));
}
if (_recordIdAccessor) {
diff --git a/src/mongo/db/exec/sbe/stages/text_match.cpp b/src/mongo/db/exec/sbe/stages/text_match.cpp
index 6f1096a42a0..10015138378 100644
--- a/src/mongo/db/exec/sbe/stages/text_match.cpp
+++ b/src/mongo/db/exec/sbe/stages/text_match.cpp
@@ -80,7 +80,7 @@ PlanState TextMatchStage::getNext() {
obj = builder.obj();
}
const auto matchResult = _ftsMatcher.matches(obj);
- _outValueAccessor.reset(value::TypeTags::Boolean, matchResult);
+ _outValueAccessor.reset(value::TypeTags::Boolean, value::bitcastFrom<bool>(matchResult));
}
return trackPlanState(state);
diff --git a/src/mongo/db/exec/sbe/stages/unwind.cpp b/src/mongo/db/exec/sbe/stages/unwind.cpp
index 682ccbca2c7..c5b6b1ea47e 100644
--- a/src/mongo/db/exec/sbe/stages/unwind.cpp
+++ b/src/mongo/db/exec/sbe/stages/unwind.cpp
@@ -115,7 +115,8 @@ PlanState UnwindStage::getNext() {
_inArray = false;
if (_preserveNullAndEmptyArrays) {
_outFieldOutputAccessor->reset(value::TypeTags::Nothing, 0);
- _outIndexOutputAccessor->reset(value::TypeTags::NumberInt64, _index);
+ _outIndexOutputAccessor->reset(value::TypeTags::NumberInt64,
+ value::bitcastFrom<int64_t>(_index));
return trackPlanState(PlanState::ADVANCED);
}
}
@@ -136,7 +137,8 @@ PlanState UnwindStage::getNext() {
auto [tagElem, valElem] = _inArrayAccessor.getViewOfValue();
_outFieldOutputAccessor->reset(tagElem, valElem);
- _outIndexOutputAccessor->reset(value::TypeTags::NumberInt64, _index);
+ _outIndexOutputAccessor->reset(value::TypeTags::NumberInt64,
+ value::bitcastFrom<int64_t>(_index));
_inArrayAccessor.advance();
++_index;
diff --git a/src/mongo/db/exec/sbe/stages/unwind.h b/src/mongo/db/exec/sbe/stages/unwind.h
index efe62e70a7a..502d6fba722 100644
--- a/src/mongo/db/exec/sbe/stages/unwind.h
+++ b/src/mongo/db/exec/sbe/stages/unwind.h
@@ -65,7 +65,7 @@ private:
value::ArrayAccessor _inArrayAccessor;
- size_t _index{0};
+ int64_t _index{0};
bool _inArray{false};
};
} // namespace mongo::sbe
diff --git a/src/mongo/db/exec/sbe/values/bson.cpp b/src/mongo/db/exec/sbe/values/bson.cpp
index b932f8e1464..5f28c6122c0 100644
--- a/src/mongo/db/exec/sbe/values/bson.cpp
+++ b/src/mongo/db/exec/sbe/values/bson.cpp
@@ -98,19 +98,19 @@ std::pair<value::TypeTags, value::Value> convertFrom(bool view,
switch (type) {
case BSONType::NumberDouble: {
- auto dbl = ConstDataView(be).read<LittleEndian<double>>();
- return {value::TypeTags::NumberDouble, value::bitcastFrom(dbl)};
+ double dbl = ConstDataView(be).read<LittleEndian<double>>();
+ return {value::TypeTags::NumberDouble, value::bitcastFrom<double>(dbl)};
}
case BSONType::NumberDecimal: {
if (view) {
- return {value::TypeTags::NumberDecimal, value::bitcastFrom(be)};
+ return {value::TypeTags::NumberDecimal, value::bitcastFrom<const char*>(be)};
}
return value::makeCopyDecimal(value::readDecimal128FromMemory(ConstDataView{be}));
}
case BSONType::String: {
if (view) {
- return {value::TypeTags::bsonString, value::bitcastFrom(be)};
+ return {value::TypeTags::bsonString, value::bitcastFrom<const char*>(be)};
}
// len includes trailing zero.
auto len = ConstDataView(be).read<LittleEndian<uint32_t>>();
@@ -127,12 +127,12 @@ std::pair<value::TypeTags, value::Value> convertFrom(bool view,
} else {
auto str = new char[len];
memcpy(str, be, len);
- return {value::TypeTags::StringBig, value::bitcastFrom(str)};
+ return {value::TypeTags::StringBig, value::bitcastFrom<const char*>(str)};
}
}
case BSONType::BinData: {
if (view) {
- return {value::TypeTags::bsonBinData, value::bitcastFrom(be)};
+ return {value::TypeTags::bsonBinData, value::bitcastFrom<const char*>(be)};
}
auto size = ConstDataView(be).read<LittleEndian<uint32_t>>();
@@ -142,18 +142,18 @@ std::pair<value::TypeTags, value::Value> convertFrom(bool view,
auto metaSize = sizeof(uint32_t) + 1;
auto binData = new uint8_t[size + metaSize];
memcpy(binData, be, size + metaSize);
- return {value::TypeTags::bsonBinData, value::bitcastFrom(binData)};
+ return {value::TypeTags::bsonBinData, value::bitcastFrom<uint8_t*>(binData)};
} else {
// The legacy byte array stores an extra int32 in byte[size].
auto metaSize = 2 * sizeof(uint32_t) + 1;
auto binData = new uint8_t[size + metaSize];
memcpy(binData, be, size + metaSize);
- return {value::TypeTags::bsonBinData, value::bitcastFrom(binData)};
+ return {value::TypeTags::bsonBinData, value::bitcastFrom<uint8_t*>(binData)};
}
}
case BSONType::Object: {
if (view) {
- return {value::TypeTags::bsonObject, value::bitcastFrom(be)};
+ return {value::TypeTags::bsonObject, value::bitcastFrom<const char*>(be)};
}
// Skip document length.
be += 4;
@@ -172,7 +172,7 @@ std::pair<value::TypeTags, value::Value> convertFrom(bool view,
}
case BSONType::Array: {
if (view) {
- return {value::TypeTags::bsonArray, value::bitcastFrom(be)};
+ return {value::TypeTags::bsonArray, value::bitcastFrom<const char*>(be)};
}
// Skip array length.
be += 4;
@@ -191,31 +191,31 @@ std::pair<value::TypeTags, value::Value> convertFrom(bool view,
}
case BSONType::jstOID: {
if (view) {
- return {value::TypeTags::bsonObjectId, value::bitcastFrom(be)};
+ return {value::TypeTags::bsonObjectId, value::bitcastFrom<const char*>(be)};
}
auto [tag, val] = value::makeNewObjectId();
memcpy(value::getObjectIdView(val), be, sizeof(value::ObjectIdType));
return {tag, val};
}
case BSONType::Bool:
- return {value::TypeTags::Boolean, *(be)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(*(be))};
case BSONType::Date: {
- auto integer = ConstDataView(be).read<LittleEndian<int64_t>>();
- return {value::TypeTags::Date, value::bitcastFrom(integer)};
+ int64_t integer = ConstDataView(be).read<LittleEndian<int64_t>>();
+ return {value::TypeTags::Date, value::bitcastFrom<int64_t>(integer)};
}
case BSONType::jstNULL:
return {value::TypeTags::Null, 0};
case BSONType::NumberInt: {
- auto integer = ConstDataView(be).read<LittleEndian<int32_t>>();
- return {value::TypeTags::NumberInt32, value::bitcastFrom(integer)};
+ int32_t integer = ConstDataView(be).read<LittleEndian<int32_t>>();
+ return {value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(integer)};
}
case BSONType::bsonTimestamp: {
- auto val = ConstDataView(be).read<LittleEndian<uint64_t>>();
- return {value::TypeTags::Timestamp, value::bitcastFrom(val)};
+ uint64_t val = ConstDataView(be).read<LittleEndian<uint64_t>>();
+ return {value::TypeTags::Timestamp, value::bitcastFrom<uint64_t>(val)};
}
case BSONType::NumberLong: {
- auto val = ConstDataView(be).read<LittleEndian<int64_t>>();
- return {value::TypeTags::NumberInt64, value::bitcastFrom(val)};
+ int64_t val = ConstDataView(be).read<LittleEndian<int64_t>>();
+ return {value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(val)};
}
default:
return {value::TypeTags::Nothing, 0};
@@ -247,7 +247,7 @@ void convertToBsonObj(BSONArrayBuilder& builder, value::ArrayEnumerator arr) {
builder.append(Timestamp(value::bitcastTo<uint64_t>(val)));
break;
case value::TypeTags::Boolean:
- builder.append(val != 0);
+ builder.append(value::bitcastTo<bool>(val));
break;
case value::TypeTags::Null:
builder.appendNull();
@@ -303,7 +303,8 @@ void convertToBsonObj(BSONArrayBuilder& builder, value::ArrayEnumerator arr) {
}
void convertToBsonObj(BSONArrayBuilder& builder, value::Array* arr) {
return convertToBsonObj(
- builder, value::ArrayEnumerator{value::TypeTags::Array, value::bitcastFrom(arr)});
+ builder,
+ value::ArrayEnumerator{value::TypeTags::Array, value::bitcastFrom<value::Array*>(arr)});
}
void convertToBsonObj(BSONObjBuilder& builder, value::Object* obj) {
for (size_t idx = 0; idx < obj->size(); ++idx) {
@@ -332,7 +333,7 @@ void convertToBsonObj(BSONObjBuilder& builder, value::Object* obj) {
builder.append(name, Timestamp(value::bitcastTo<uint64_t>(val)));
break;
case value::TypeTags::Boolean:
- builder.append(name, val != 0);
+ builder.append(name, value::bitcastTo<bool>(val));
break;
case value::TypeTags::Null:
builder.appendNull(name);
diff --git a/src/mongo/db/exec/sbe/values/slot.cpp b/src/mongo/db/exec/sbe/values/slot.cpp
index e1d54fee436..65017593bd1 100644
--- a/src/mongo/db/exec/sbe/values/slot.cpp
+++ b/src/mongo/db/exec/sbe/values/slot.cpp
@@ -44,26 +44,26 @@ static std::pair<TypeTags, Value> deserializeTagVal(BufReader& buf) {
case TypeTags::Nothing:
break;
case TypeTags::NumberInt32:
- val = bitcastFrom(buf.read<int32_t>());
+ val = bitcastFrom<int32_t>(buf.read<int32_t>());
break;
case TypeTags::NumberInt64:
- val = bitcastFrom(buf.read<int64_t>());
+ val = bitcastFrom<int64_t>(buf.read<int64_t>());
break;
case TypeTags::NumberDouble:
- val = bitcastFrom(buf.read<double>());
+ val = bitcastFrom<double>(buf.read<double>());
break;
case TypeTags::NumberDecimal: {
auto [decTag, decVal] = makeCopyDecimal(Decimal128{buf.read<Decimal128::Value>()});
val = decVal;
} break;
case TypeTags::Date:
- val = bitcastFrom(buf.read<int64_t>());
+ val = bitcastFrom<int64_t>(buf.read<int64_t>());
break;
case TypeTags::Timestamp:
- val = bitcastFrom(buf.read<uint64_t>());
+ val = bitcastFrom<uint64_t>(buf.read<uint64_t>());
break;
case TypeTags::Boolean:
- val = bitcastFrom(buf.read<char>());
+ val = bitcastFrom<bool>(buf.read<char>());
break;
case TypeTags::Null:
break;
@@ -129,14 +129,14 @@ static std::pair<TypeTags, Value> deserializeTagVal(BufReader& buf) {
auto size = buf.peek<LittleEndian<uint32_t>>();
auto bson = new uint8_t[size];
memcpy(bson, buf.skip(size), size);
- val = bitcastFrom(bson);
+ val = bitcastFrom<uint8_t*>(bson);
break;
}
case TypeTags::bsonArray: {
auto size = buf.peek<LittleEndian<uint32_t>>();
auto arr = new uint8_t[size];
memcpy(arr, buf.skip(size), size);
- val = bitcastFrom(arr);
+ val = bitcastFrom<uint8_t*>(arr);
break;
}
case TypeTags::bsonBinData: {
@@ -144,7 +144,7 @@ static std::pair<TypeTags, Value> deserializeTagVal(BufReader& buf) {
auto size = binDataSize + sizeof(uint32_t) + 1;
auto binData = new uint8_t[size];
memcpy(binData, buf.skip(size), size);
- val = bitcastFrom(binData);
+ val = bitcastFrom<uint8_t*>(binData);
break;
}
case TypeTags::ksValue: {
@@ -200,7 +200,7 @@ static void serializeTagValue(BufBuilder& buf, TypeTags tag, Value val) {
buf.appendNum(bitcastTo<uint64_t>(val));
break;
case TypeTags::Boolean:
- buf.appendNum(bitcastTo<char>(val));
+ buf.appendNum(static_cast<char>(bitcastTo<bool>(val)));
break;
case TypeTags::Null:
break;
diff --git a/src/mongo/db/exec/sbe/values/slot.h b/src/mongo/db/exec/sbe/values/slot.h
index bac65dab45e..85a28e1677f 100644
--- a/src/mongo/db/exec/sbe/values/slot.h
+++ b/src/mongo/db/exec/sbe/values/slot.h
@@ -443,7 +443,7 @@ public:
auto [rhsTag, rhsVal] = rhs.getViewOfValue(idx);
auto [tag, val] = compareValue(lhsTag, lhsVal, rhsTag, rhsVal);
- if (tag != value::TypeTags::NumberInt32 || val != 0) {
+ if (tag != value::TypeTags::NumberInt32 || value::bitcastTo<int32_t>(val) != 0) {
return false;
}
}
diff --git a/src/mongo/db/exec/sbe/values/value.cpp b/src/mongo/db/exec/sbe/values/value.cpp
index 1a9fd951bbd..37545057a60 100644
--- a/src/mongo/db/exec/sbe/values/value.cpp
+++ b/src/mongo/db/exec/sbe/values/value.cpp
@@ -44,11 +44,11 @@ namespace value {
std::pair<TypeTags, Value> makeCopyKeyString(const KeyString::Value& inKey) {
auto k = new KeyString::Value(inKey);
- return {TypeTags::ksValue, reinterpret_cast<Value>(k)};
+ return {TypeTags::ksValue, bitcastFrom<KeyString::Value*>(k)};
}
std::pair<TypeTags, Value> makeCopyPcreRegex(const pcrecpp::RE& regex) {
- auto ownedRegexVal = sbe::value::bitcastFrom(new pcrecpp::RE(regex));
+ auto ownedRegexVal = sbe::value::bitcastFrom<pcrecpp::RE*>(new pcrecpp::RE(regex));
return {TypeTags::pcreRegex, ownedRegexVal};
}
@@ -186,7 +186,7 @@ void writeValueToStream(T& stream, TypeTags tag, Value val) {
stream << bitcastTo<int64_t>(val);
break;
case value::TypeTags::Boolean:
- stream << ((val) ? "true" : "false");
+ stream << (bitcastTo<bool>(val) ? "true" : "false");
break;
case value::TypeTags::Null:
stream << "null";
@@ -418,7 +418,7 @@ std::size_t hashValue(TypeTags tag, Value val) noexcept {
case TypeTags::Timestamp:
return absl::Hash<uint64_t>{}(bitcastTo<uint64_t>(val));
case TypeTags::Boolean:
- return val != 0;
+ return bitcastTo<bool>(val);
case TypeTags::Null:
return 0;
case TypeTags::StringSmall:
@@ -513,22 +513,22 @@ std::pair<TypeTags, Value> compareValue(TypeTags lhsTag,
case TypeTags::NumberInt32: {
auto result = compareHelper(numericCast<int32_t>(lhsTag, lhsValue),
numericCast<int32_t>(rhsTag, rhsValue));
- return {TypeTags::NumberInt32, bitcastFrom(result)};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(result)};
}
case TypeTags::NumberInt64: {
auto result = compareHelper(numericCast<int64_t>(lhsTag, lhsValue),
numericCast<int64_t>(rhsTag, rhsValue));
- return {TypeTags::NumberInt32, bitcastFrom(result)};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(result)};
}
case TypeTags::NumberDouble: {
auto result = compareHelper(numericCast<double>(lhsTag, lhsValue),
numericCast<double>(rhsTag, rhsValue));
- return {TypeTags::NumberInt32, bitcastFrom(result)};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(result)};
}
case TypeTags::NumberDecimal: {
auto result = compareHelper(numericCast<Decimal128>(lhsTag, lhsValue),
numericCast<Decimal128>(rhsTag, rhsValue));
- return {TypeTags::NumberInt32, bitcastFrom(result)};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(result)};
}
default:
MONGO_UNREACHABLE;
@@ -537,18 +537,18 @@ std::pair<TypeTags, Value> compareValue(TypeTags lhsTag,
auto lhsStr = getStringView(lhsTag, lhsValue);
auto rhsStr = getStringView(rhsTag, rhsValue);
auto result = lhsStr.compare(rhsStr);
- return {TypeTags::NumberInt32, bitcastFrom(compareHelper(result, 0))};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(compareHelper(result, 0))};
} else if (lhsTag == TypeTags::Date && rhsTag == TypeTags::Date) {
auto result = compareHelper(bitcastTo<int64_t>(lhsValue), bitcastTo<int64_t>(rhsValue));
- return {TypeTags::NumberInt32, bitcastFrom(result)};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(result)};
} else if (lhsTag == TypeTags::Timestamp && rhsTag == TypeTags::Timestamp) {
auto result = compareHelper(bitcastTo<uint64_t>(lhsValue), bitcastTo<uint64_t>(rhsValue));
- return {TypeTags::NumberInt32, bitcastFrom(result)};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(result)};
} else if (lhsTag == TypeTags::Boolean && rhsTag == TypeTags::Boolean) {
- auto result = compareHelper(lhsValue != 0, rhsValue != 0);
- return {TypeTags::NumberInt32, bitcastFrom(result)};
+ auto result = compareHelper(bitcastTo<bool>(lhsValue), bitcastTo<bool>(rhsValue));
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(result)};
} else if (lhsTag == TypeTags::Null && rhsTag == TypeTags::Null) {
- return {TypeTags::NumberInt32, 0};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(0)};
} else if (isArray(lhsTag) && isArray(rhsTag)) {
auto lhsArr = ArrayEnumerator{lhsTag, lhsValue};
auto rhsArr = ArrayEnumerator{rhsTag, rhsValue};
@@ -557,14 +557,14 @@ std::pair<TypeTags, Value> compareValue(TypeTags lhsTag,
auto [rhsTag, rhsVal] = rhsArr.getViewOfValue();
auto [tag, val] = compareValue(lhsTag, lhsVal, rhsTag, rhsVal);
- if (tag != TypeTags::NumberInt32 || val != 0) {
+ if (tag != TypeTags::NumberInt32 || bitcastTo<int32_t>(val) != 0) {
return {tag, val};
}
lhsArr.advance();
rhsArr.advance();
}
if (lhsArr.atEnd() && rhsArr.atEnd()) {
- return {TypeTags::NumberInt32, 0};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(0)};
} else if (lhsArr.atEnd()) {
return {TypeTags::NumberInt32, bitcastFrom<int32_t>(-1)};
} else {
@@ -576,21 +576,21 @@ std::pair<TypeTags, Value> compareValue(TypeTags lhsTag,
while (!lhsObj.atEnd() && !rhsObj.atEnd()) {
auto fieldCmp = lhsObj.getFieldName().compare(rhsObj.getFieldName());
if (fieldCmp != 0) {
- return {TypeTags::NumberInt32, bitcastFrom(compareHelper(fieldCmp, 0))};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(compareHelper(fieldCmp, 0))};
}
auto [lhsTag, lhsVal] = lhsObj.getViewOfValue();
auto [rhsTag, rhsVal] = rhsObj.getViewOfValue();
auto [tag, val] = compareValue(lhsTag, lhsVal, rhsTag, rhsVal);
- if (tag != TypeTags::NumberInt32 || val != 0) {
+ if (tag != TypeTags::NumberInt32 || bitcastTo<int32_t>(val) != 0) {
return {tag, val};
}
lhsObj.advance();
rhsObj.advance();
}
if (lhsObj.atEnd() && rhsObj.atEnd()) {
- return {TypeTags::NumberInt32, 0};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(0)};
} else if (lhsObj.atEnd()) {
return {TypeTags::NumberInt32, bitcastFrom<int32_t>(-1)};
} else {
@@ -602,12 +602,12 @@ std::pair<TypeTags, Value> compareValue(TypeTags lhsTag,
auto rhsObjId = rhsTag == TypeTags::ObjectId ? getObjectIdView(rhsValue)->data()
: bitcastTo<uint8_t*>(rhsValue);
auto result = memcmp(lhsObjId, rhsObjId, sizeof(ObjectIdType));
- return {TypeTags::NumberInt32, bitcastFrom(compareHelper(result, 0))};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(compareHelper(result, 0))};
} else if (isBinData(lhsTag) && isBinData(rhsTag)) {
auto lsz = getBSONBinDataSize(lhsTag, lhsValue);
auto rsz = getBSONBinDataSize(rhsTag, rhsValue);
if (lsz != rsz) {
- return {TypeTags::NumberInt32, bitcastFrom(compareHelper(lsz, rsz))};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(compareHelper(lsz, rsz))};
}
// Since we already compared the size above, skip the first 4 bytes of the buffer and
@@ -615,19 +615,19 @@ std::pair<TypeTags, Value> compareValue(TypeTags lhsTag,
auto result = memcmp(getRawPointerView(lhsValue) + sizeof(uint32_t),
getRawPointerView(rhsValue) + sizeof(uint32_t),
lsz + 1);
- return {TypeTags::NumberInt32, bitcastFrom(compareHelper(result, 0))};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(compareHelper(result, 0))};
} else if (lhsTag == TypeTags::ksValue && rhsTag == TypeTags::ksValue) {
auto result = getKeyStringView(lhsValue)->compare(*getKeyStringView(lhsValue));
- return {TypeTags::NumberInt32, bitcastFrom(result)};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(result)};
} else if (lhsTag == TypeTags::Nothing && rhsTag == TypeTags::Nothing) {
// Special case for Nothing in a hash table (group) and sort comparison.
- return {TypeTags::NumberInt32, 0};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(0)};
} else {
// Different types.
auto result =
canonicalizeBSONType(tagToType(lhsTag)) - canonicalizeBSONType(tagToType(rhsTag));
invariant(result != 0);
- return {TypeTags::NumberInt32, bitcastFrom(compareHelper(result, 0))};
+ return {TypeTags::NumberInt32, bitcastFrom<int32_t>(compareHelper(result, 0))};
}
}
diff --git a/src/mongo/db/exec/sbe/values/value.h b/src/mongo/db/exec/sbe/values/value.h
index d70d5f5a9ea..14782dfa3ba 100644
--- a/src/mongo/db/exec/sbe/values/value.h
+++ b/src/mongo/db/exec/sbe/values/value.h
@@ -226,6 +226,81 @@ private:
Value _value;
};
+inline char* getRawPointerView(Value val) noexcept {
+ return reinterpret_cast<char*>(val);
+}
+
+inline Decimal128 readDecimal128FromMemory(const ConstDataView& view) {
+ uint64_t low = view.read<LittleEndian<uint64_t>>();
+ uint64_t high = view.read<LittleEndian<uint64_t>>(sizeof(uint64_t));
+ return Decimal128{Decimal128::Value{low, high}};
+}
+
+template <class T>
+struct dont_deduce_t {
+ using type = T;
+};
+
+template <class T>
+using dont_deduce = typename dont_deduce_t<T>::type;
+
+template <typename T>
+Value bitcastFrom(const dont_deduce<T> in) noexcept {
+ static_assert(std::is_pointer_v<T> || std::is_integral_v<T> || std::is_floating_point_v<T>);
+
+ static_assert(sizeof(Value) >= sizeof(T));
+
+ // Callers must not try to store a pointer to a Decimal128 object in an sbe::value::Value. Any
+ // Value with the NumberDecimal TypeTag actually stores a pointer to a NumberDecimal as it would
+ // be represented in a BSONElement: a pair of network-ordered (little-endian) uint64_t values.
+ // These bytes are _not_ guaranteed to be the same as the bytes in a Decimal128_t object.
+ //
+ // To get a NumberDecimal value, either call makeCopyDecimal() or store the value in BSON and
+ // use sbe::bson::convertFrom().
+ static_assert(!std::is_same_v<Decimal128, T>);
+ static_assert(!std::is_same_v<Decimal128*, T>);
+
+ if constexpr (std::is_pointer_v<T>) {
+ // Casting from pointer to integer value is OK.
+ return reinterpret_cast<Value>(in);
+ } else if constexpr (std::is_same_v<bool, T>) {
+ // make_signed_t<bool> is not defined, so we handle the bool type separately here.
+ return static_cast<Value>(in);
+ } else if constexpr (std::is_integral_v<T>) {
+ // Native integer types are converted to Value using static_cast with sign extension.
+ return static_cast<Value>(static_cast<std::make_signed_t<T>>(in));
+ }
+
+ Value val{0};
+ memcpy(&val, &in, sizeof(T));
+ return val;
+}
+
+template <typename T>
+T bitcastTo(const Value in) noexcept {
+ static_assert(std::is_pointer_v<T> || std::is_integral_v<T> || std::is_floating_point_v<T> ||
+ std::is_same_v<Decimal128, T>);
+
+ if constexpr (std::is_pointer_v<T>) {
+ // Casting from integer value to pointer is OK.
+ static_assert(sizeof(Value) == sizeof(T));
+ return reinterpret_cast<T>(in);
+ } else if constexpr (std::is_integral_v<T>) {
+ // Values are converted to native integer types using static_cast. If sizeof(T) is less
+ // than sizeof(Value), the upper bits of 'in' are discarded.
+ static_assert(sizeof(Value) >= sizeof(T));
+ return static_cast<T>(in);
+ } else if constexpr (std::is_same_v<Decimal128, T>) {
+ static_assert(sizeof(Value) == sizeof(T*));
+ return readDecimal128FromMemory(ConstDataView{getRawPointerView(in)});
+ } else {
+ static_assert(sizeof(Value) >= sizeof(T));
+ T val;
+ memcpy(&val, &in, sizeof(T));
+ return val;
+ }
+}
+
/**
* This is the SBE representation of objects/documents. It is a relatively simple structure of
* vectors of field names, type tags, and values.
@@ -380,7 +455,7 @@ class ArraySet {
const std::pair<TypeTags, Value>& rhs) const {
auto [tag, val] = compareValue(lhs.first, lhs.second, rhs.first, rhs.second);
- if (tag != TypeTags::NumberInt32 || val != 0) {
+ if (tag != TypeTags::NumberInt32 || bitcastTo<int32_t>(val) != 0) {
return false;
} else {
return true;
@@ -440,10 +515,6 @@ inline char* getBigStringView(Value val) noexcept {
return reinterpret_cast<char*>(val);
}
-inline char* getRawPointerView(Value val) noexcept {
- return reinterpret_cast<char*>(val);
-}
-
inline char* getRawStringView(TypeTags tag, Value& val) noexcept {
if (tag == TypeTags::StringSmall) {
return getSmallStringView(val);
@@ -469,12 +540,6 @@ T readFromMemory(const unsigned char* memory) noexcept {
return val;
}
-inline Decimal128 readDecimal128FromMemory(const ConstDataView& view) {
- uint64_t low = view.read<LittleEndian<long long>>();
- uint64_t high = view.read<LittleEndian<long long>>(sizeof(long long));
- return Decimal128{Decimal128::Value{low, high}};
-}
-
template <typename T>
size_t writeToMemory(unsigned char* memory, const T val) noexcept {
memcpy(memory, &val, sizeof(T));
@@ -482,46 +547,6 @@ size_t writeToMemory(unsigned char* memory, const T val) noexcept {
return sizeof(T);
}
-template <typename T>
-Value bitcastFrom(const T in) noexcept {
- static_assert(sizeof(Value) >= sizeof(T));
-
- // Callers must not try to store a pointer to a Decimal128 object in an sbe::value::Value. Any
- // Value with the NumberDecimal TypeTag actually stores a pointer to a NumberDecimal as it would
- // be represented in a BSONElement: a pair of network-ordered (little-endian) uint64_t values.
- // These bytes are _not_ guaranteed to be the same as the bytes in a Decimal128_t object.
- //
- // To get a NumberDecimal value, either call makeCopyDecimal() or store the value in BSON and
- // use sbe::bson::convertFrom().
- static_assert(!std::is_same_v<Decimal128, T>);
- static_assert(!std::is_same_v<Decimal128*, T>);
-
- // Casting from pointer to integer value is OK.
- if constexpr (std::is_pointer_v<T>) {
- return reinterpret_cast<Value>(in);
- }
- Value val{0};
- memcpy(&val, &in, sizeof(T));
- return val;
-}
-
-template <typename T>
-T bitcastTo(const Value in) noexcept {
- // Casting from integer value to pointer is OK.
- if constexpr (std::is_pointer_v<T>) {
- static_assert(sizeof(Value) == sizeof(T));
- return reinterpret_cast<T>(in);
- } else if constexpr (std::is_same_v<Decimal128, T>) {
- static_assert(sizeof(Value) == sizeof(T*));
- return readDecimal128FromMemory(ConstDataView{getRawPointerView(in)});
- } else {
- static_assert(sizeof(Value) >= sizeof(T));
- T val;
- memcpy(&val, &in, sizeof(T));
- return val;
- }
-}
-
inline std::string_view getStringView(TypeTags tag, Value& val) noexcept {
if (tag == TypeTags::StringSmall) {
return std::string_view(getSmallStringView(val));
@@ -673,7 +698,7 @@ inline std::pair<TypeTags, Value> copyValue(TypeTags tag, Value val) {
auto dst = new char[len + 1];
memcpy(dst, src, len);
dst[len] = 0;
- return {TypeTags::StringBig, bitcastFrom(dst)};
+ return {TypeTags::StringBig, reinterpret_cast<Value>(dst)};
}
case TypeTags::bsonString: {
auto bsonstr = getRawPointerView(val);
@@ -689,28 +714,28 @@ inline std::pair<TypeTags, Value> copyValue(TypeTags tag, Value val) {
auto size = ConstDataView(bson).read<LittleEndian<uint32_t>>();
auto dst = new uint8_t[size];
memcpy(dst, bson, size);
- return {TypeTags::bsonObject, bitcastFrom(dst)};
+ return {TypeTags::bsonObject, reinterpret_cast<Value>(dst)};
}
case TypeTags::bsonObjectId: {
auto bson = getRawPointerView(val);
auto size = sizeof(ObjectIdType);
auto dst = new uint8_t[size];
memcpy(dst, bson, size);
- return {TypeTags::bsonObjectId, bitcastFrom(dst)};
+ return {TypeTags::bsonObjectId, reinterpret_cast<Value>(dst)};
}
case TypeTags::bsonArray: {
auto bson = getRawPointerView(val);
auto size = ConstDataView(bson).read<LittleEndian<uint32_t>>();
auto dst = new uint8_t[size];
memcpy(dst, bson, size);
- return {TypeTags::bsonArray, bitcastFrom(dst)};
+ return {TypeTags::bsonArray, reinterpret_cast<Value>(dst)};
}
case TypeTags::bsonBinData: {
auto binData = getRawPointerView(val);
auto size = getBSONBinDataSize(tag, val);
auto dst = new uint8_t[size + sizeof(uint32_t) + 1];
memcpy(dst, binData, size + sizeof(uint32_t) + 1);
- return {TypeTags::bsonBinData, bitcastFrom(dst)};
+ return {TypeTags::bsonBinData, reinterpret_cast<Value>(dst)};
}
case TypeTags::ksValue:
return makeCopyKeyString(*getKeyStringView(val));
@@ -767,19 +792,19 @@ inline std::tuple<bool, value::TypeTags, value::Value> numericConvLossless(
switch (targetTag) {
case value::TypeTags::NumberInt32: {
if (auto result = representAs<int32_t>(value); result) {
- return {false, value::TypeTags::NumberInt32, value::bitcastFrom(*result)};
+ return {false, value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(*result)};
}
return {false, value::TypeTags::Nothing, 0};
}
case value::TypeTags::NumberInt64: {
if (auto result = representAs<int64_t>(value); result) {
- return {false, value::TypeTags::NumberInt64, value::bitcastFrom(*result)};
+ return {false, value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(*result)};
}
return {false, value::TypeTags::Nothing, 0};
}
case value::TypeTags::NumberDouble: {
if (auto result = representAs<double>(value); result) {
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(*result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(*result)};
}
return {false, value::TypeTags::Nothing, 0};
}
diff --git a/src/mongo/db/exec/sbe/values/value_builder.h b/src/mongo/db/exec/sbe/values/value_builder.h
index a49f39141b1..cc13e970201 100644
--- a/src/mongo/db/exec/sbe/values/value_builder.h
+++ b/src/mongo/db/exec/sbe/values/value_builder.h
@@ -84,15 +84,15 @@ public:
}
void append(const bool in) {
- appendValue(TypeTags::Boolean, value::bitcastFrom(in));
+ appendValue(TypeTags::Boolean, value::bitcastFrom<bool>(in));
}
void append(const Date_t& in) {
- appendValue(TypeTags::Date, value::bitcastFrom(in.toMillisSinceEpoch()));
+ appendValue(TypeTags::Date, value::bitcastFrom<int64_t>(in.toMillisSinceEpoch()));
}
void append(const Timestamp& in) {
- appendValue(TypeTags::Timestamp, value::bitcastFrom(in.asLL()));
+ appendValue(TypeTags::Timestamp, value::bitcastFrom<uint64_t>(in.asULL()));
}
void append(const OID& in) {
@@ -144,7 +144,7 @@ public:
}
void append(double in) {
- appendValue(TypeTags::NumberDouble, value::bitcastFrom(in));
+ appendValue(TypeTags::NumberDouble, value::bitcastFrom<double>(in));
}
void append(const Decimal128& in) {
@@ -153,11 +153,11 @@ public:
}
void append(long long in) {
- appendValue(TypeTags::NumberInt64, value::bitcastFrom(in));
+ appendValue(TypeTags::NumberInt64, value::bitcastFrom<int64_t>(in));
}
void append(int32_t in) {
- appendValue(TypeTags::NumberInt32, value::bitcastFrom(in));
+ appendValue(TypeTags::NumberInt32, value::bitcastFrom<int32_t>(in));
}
BufBuilder& subobjStart() {
@@ -208,7 +208,7 @@ public:
case TypeTags::bsonBinData: {
auto offset = bitcastTo<decltype(bufferLen)>(val);
invariant(offset < bufferLen);
- val = bitcastFrom(_valueBufferBuilder->buf() + offset);
+ val = bitcastFrom<const char*>(_valueBufferBuilder->buf() + offset);
break;
}
default:
@@ -247,7 +247,7 @@ private:
// offset to pointer occurs as part of the 'releaseValues()' function.
void appendValueBufferOffset(TypeTags tag) {
_tagList[_numValues] = tag;
- _valList[_numValues] = value::bitcastFrom(_valueBufferBuilder->len());
+ _valList[_numValues] = value::bitcastFrom<int32_t>(_valueBufferBuilder->len());
++_numValues;
}
diff --git a/src/mongo/db/exec/sbe/vm/arith.cpp b/src/mongo/db/exec/sbe/vm/arith.cpp
index 057b719d580..f663f5880d6 100644
--- a/src/mongo/db/exec/sbe/vm/arith.cpp
+++ b/src/mongo/db/exec/sbe/vm/arith.cpp
@@ -137,7 +137,8 @@ std::tuple<bool, value::TypeTags, value::Value> genericArithmeticOp(value::TypeT
if (!Op::doOperation(numericCast<int32_t>(lhsTag, lhsValue),
numericCast<int32_t>(rhsTag, rhsValue),
result)) {
- return {false, value::TypeTags::NumberInt32, value::bitcastFrom(result)};
+ return {
+ false, value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(result)};
}
// The result does not fit into int32_t so fallthru to the wider type.
}
@@ -146,7 +147,8 @@ std::tuple<bool, value::TypeTags, value::Value> genericArithmeticOp(value::TypeT
if (!Op::doOperation(numericCast<int64_t>(lhsTag, lhsValue),
numericCast<int64_t>(rhsTag, rhsValue),
result)) {
- return {false, value::TypeTags::NumberInt64, value::bitcastFrom(result)};
+ return {
+ false, value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(result)};
}
// The result does not fit into int64_t so fallthru to the wider type.
}
@@ -163,7 +165,7 @@ std::tuple<bool, value::TypeTags, value::Value> genericArithmeticOp(value::TypeT
Op::doOperation(numericCast<double>(lhsTag, lhsValue),
numericCast<double>(rhsTag, rhsValue),
result);
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
default:
MONGO_UNREACHABLE;
@@ -173,19 +175,19 @@ std::tuple<bool, value::TypeTags, value::Value> genericArithmeticOp(value::TypeT
int64_t result;
if (!Op::doOperation(
numericCast<int64_t>(lhsTag, lhsValue), bitcastTo<int64_t>(rhsValue), result)) {
- return {false, value::TypeTags::Date, value::bitcastFrom(result)};
+ return {false, value::TypeTags::Date, value::bitcastFrom<int64_t>(result)};
}
} else if (isNumber(rhsTag)) {
int64_t result;
if (!Op::doOperation(
bitcastTo<int64_t>(lhsValue), numericCast<int64_t>(rhsTag, rhsValue), result)) {
- return {false, value::TypeTags::Date, value::bitcastFrom(result)};
+ return {false, value::TypeTags::Date, value::bitcastFrom<int64_t>(result)};
}
} else {
int64_t result;
if (!Op::doOperation(
bitcastTo<int64_t>(lhsValue), bitcastTo<int64_t>(lhsValue), result)) {
- return {false, value::TypeTags::NumberInt64, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(result)};
}
}
// We got here if the Date operation overflowed.
@@ -340,17 +342,17 @@ std::tuple<bool, value::TypeTags, value::Value> genericTrigonometricFun(value::T
case value::TypeTags::NumberInt32: {
double result;
TrigFunction::computeFunction(numericCast<int32_t>(argTag, argValue), result);
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberInt64: {
double result;
TrigFunction::computeFunction(numericCast<int64_t>(argTag, argValue), result);
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDouble: {
double result;
TrigFunction::computeFunction(numericCast<double>(argTag, argValue), result);
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDecimal: {
Decimal128 result;
@@ -399,19 +401,19 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericDiv(value::Type
assertNonZero(numericCast<double>(rhsTag, rhsValue) != 0);
auto result =
numericCast<double>(lhsTag, lhsValue) / numericCast<double>(rhsTag, rhsValue);
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberInt64: {
assertNonZero(numericCast<double>(rhsTag, rhsValue) != 0);
auto result =
numericCast<double>(lhsTag, lhsValue) / numericCast<double>(rhsTag, rhsValue);
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDouble: {
assertNonZero(numericCast<double>(rhsTag, rhsValue) != 0);
auto result =
numericCast<double>(lhsTag, lhsValue) / numericCast<double>(rhsTag, rhsValue);
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDecimal: {
assertNonZero(!numericCast<Decimal128>(rhsTag, rhsValue).isZero());
@@ -440,13 +442,13 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericIDiv(value::Typ
assertNonZero(numericCast<int32_t>(rhsTag, rhsValue) != 0);
auto result =
numericCast<int32_t>(lhsTag, lhsValue) / numericCast<int32_t>(rhsTag, rhsValue);
- return {false, value::TypeTags::NumberInt32, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(result)};
}
case value::TypeTags::NumberInt64: {
assertNonZero(numericCast<int64_t>(rhsTag, rhsValue) != 0);
auto result =
numericCast<int64_t>(lhsTag, lhsValue) / numericCast<int64_t>(rhsTag, rhsValue);
- return {false, value::TypeTags::NumberInt64, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(result)};
}
case value::TypeTags::NumberDouble: {
auto lhs = representAs<int64_t>(numericCast<double>(lhsTag, lhsValue));
@@ -458,7 +460,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericIDiv(value::Typ
assertNonZero(*rhs != 0);
auto result = *lhs / *rhs;
- return {false, value::TypeTags::NumberInt64, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(result)};
}
case value::TypeTags::NumberDecimal: {
auto lhs = representAs<int64_t>(numericCast<Decimal128>(lhsTag, lhsValue));
@@ -470,7 +472,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericIDiv(value::Typ
assertNonZero(*rhs != 0);
auto result = *lhs / *rhs;
- return {false, value::TypeTags::NumberInt64, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(result)};
}
default:
MONGO_UNREACHABLE;
@@ -492,19 +494,19 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericMod(value::Type
assertNonZero(numericCast<int32_t>(rhsTag, rhsValue) != 0);
auto result = overflow::safeMod(numericCast<int32_t>(lhsTag, lhsValue),
numericCast<int32_t>(rhsTag, rhsValue));
- return {false, value::TypeTags::NumberInt32, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(result)};
}
case value::TypeTags::NumberInt64: {
assertNonZero(numericCast<int32_t>(rhsTag, rhsValue) != 0);
auto result = overflow::safeMod(numericCast<int64_t>(lhsTag, lhsValue),
numericCast<int64_t>(rhsTag, rhsValue));
- return {false, value::TypeTags::NumberInt64, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(result)};
}
case value::TypeTags::NumberDouble: {
assertNonZero(numericCast<int32_t>(rhsTag, rhsValue) != 0);
auto result = fmod(numericCast<double>(lhsTag, lhsValue),
numericCast<double>(rhsTag, rhsValue));
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDecimal: {
assertNonZero(numericCast<Decimal128>(rhsTag, rhsValue).isZero());
@@ -568,12 +570,14 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericAbs(value::Type
case value::TypeTags::NumberInt32: {
auto operand = value::bitcastTo<int32_t>(operandValue);
if (operand == std::numeric_limits<int32_t>::min()) {
- return {false, value::TypeTags::NumberInt64, value::bitcastFrom(-int64_t{operand})};
+ return {false,
+ value::TypeTags::NumberInt64,
+ value::bitcastFrom<int64_t>(-int64_t{operand})};
}
return {false,
value::TypeTags::NumberInt32,
- value::bitcastFrom(operand >= 0 ? operand : -operand)};
+ value::bitcastFrom<int32_t>(operand >= 0 ? operand : -operand)};
}
case value::TypeTags::NumberInt64: {
auto operand = value::bitcastTo<int64_t>(operandValue);
@@ -583,13 +587,13 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericAbs(value::Type
}
return {false,
value::TypeTags::NumberInt64,
- value::bitcastFrom(operand >= 0 ? operand : -operand)};
+ value::bitcastFrom<int64_t>(operand >= 0 ? operand : -operand)};
}
case value::TypeTags::NumberDouble: {
auto operand = value::bitcastTo<double>(operandValue);
return {false,
value::TypeTags::NumberDouble,
- value::bitcastFrom(operand >= 0 ? operand : -operand)};
+ value::bitcastFrom<double>(operand >= 0 ? operand : -operand)};
}
case value::TypeTags::NumberDecimal: {
auto operand = value::bitcastTo<Decimal128>(operandValue);
@@ -607,7 +611,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericCeil(value::Typ
switch (operandTag) {
case value::TypeTags::NumberDouble: {
auto result = std::ceil(value::bitcastTo<double>(operandValue));
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDecimal: {
auto result =
@@ -632,7 +636,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericFloor(value::Ty
switch (operandTag) {
case value::TypeTags::NumberDouble: {
auto result = std::floor(value::bitcastTo<double>(operandValue));
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDecimal: {
auto result =
@@ -656,7 +660,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericExp(value::Type
switch (operandTag) {
case value::TypeTags::NumberDouble: {
auto result = exp(value::bitcastTo<double>(operandValue));
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDecimal: {
auto result = value::bitcastTo<Decimal128>(operandValue).exponential();
@@ -668,7 +672,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericExp(value::Type
auto operand = (operandTag == value::TypeTags::NumberInt32)
? static_cast<double>(value::bitcastTo<int32_t>(operandValue))
: static_cast<double>(value::bitcastTo<int64_t>(operandValue));
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(exp(operand))};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(exp(operand))};
}
default:
return {false, value::TypeTags::Nothing, 0};
@@ -686,7 +690,9 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericLn(value::TypeT
return {false, value::TypeTags::Nothing, 0};
}
// Note: NaN is a legal input to log(), returning NaN.
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(std::log(operand))};
+ return {false,
+ value::TypeTags::NumberDouble,
+ value::bitcastFrom<double>(std::log(operand))};
}
case value::TypeTags::NumberDecimal: {
auto operand = value::bitcastTo<Decimal128>(operandValue);
@@ -706,7 +712,9 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericLn(value::TypeT
if (operand <= 0 && !std::isnan(operand)) {
return {false, value::TypeTags::Nothing, 0};
}
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(std::log(operand))};
+ return {false,
+ value::TypeTags::NumberDouble,
+ value::bitcastFrom<double>(std::log(operand))};
}
default:
return {false, value::TypeTags::Nothing, 0};
@@ -723,7 +731,9 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericLog10(value::Ty
// legal input to log10(), returning NaN.
return {false, value::TypeTags::Nothing, 0};
}
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(std::log10(operand))};
+ return {false,
+ value::TypeTags::NumberDouble,
+ value::bitcastFrom<double>(std::log10(operand))};
}
case value::TypeTags::NumberDecimal: {
auto operand = value::bitcastTo<Decimal128>(operandValue);
@@ -743,7 +753,9 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericLog10(value::Ty
if (operand <= 0 && !std::isnan(operand)) {
return {false, value::TypeTags::Nothing, 0};
}
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(std::log10(operand))};
+ return {false,
+ value::TypeTags::NumberDouble,
+ value::bitcastFrom<double>(std::log10(operand))};
}
default:
return {false, value::TypeTags::Nothing, 0};
@@ -761,7 +773,8 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericSqrt(value::Typ
return {false, value::TypeTags::Nothing, 0};
}
// Note: NaN is a legal input to sqrt(), returning NaN.
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(sqrt(operand))};
+ return {
+ false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(sqrt(operand))};
}
case value::TypeTags::NumberDecimal: {
auto operand = value::bitcastTo<Decimal128>(operandValue);
@@ -779,7 +792,8 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericSqrt(value::Typ
if (operand < 0 && !std::isnan(operand)) {
return {false, value::TypeTags::Nothing, 0};
}
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(sqrt(operand))};
+ return {
+ false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(sqrt(operand))};
}
default:
return {false, value::TypeTags::Nothing, 0};
@@ -789,8 +803,9 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericSqrt(value::Typ
std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericNot(value::TypeTags tag,
value::Value value) {
if (tag == value::TypeTags::Boolean) {
- return {
- false, value::TypeTags::Boolean, value::bitcastFrom(!value::bitcastTo<bool>(value))};
+ return {false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(!value::bitcastTo<bool>(value))};
} else {
return {false, value::TypeTags::Nothing, 0};
}
@@ -808,22 +823,25 @@ std::pair<value::TypeTags, value::Value> ByteCode::genericCompareEq(value::TypeT
auto lhsStr = value::getStringView(lhsTag, lhsValue);
auto rhsStr = value::getStringView(rhsTag, rhsValue);
- return {value::TypeTags::Boolean, lhsStr.compare(rhsStr) == 0};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(lhsStr.compare(rhsStr) == 0)};
} else if (lhsTag == value::TypeTags::Boolean && rhsTag == value::TypeTags::Boolean) {
- return {value::TypeTags::Boolean, (lhsValue != 0) == (rhsValue != 0)};
+ return {value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(value::bitcastTo<bool>(lhsValue) ==
+ value::bitcastTo<bool>(rhsValue))};
} else if (lhsTag == value::TypeTags::Null && rhsTag == value::TypeTags::Null) {
// This is where Mongo differs from SQL.
- return {value::TypeTags::Boolean, true};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(true)};
} else if (lhsTag == value::TypeTags::ObjectId && rhsTag == value::TypeTags::ObjectId) {
return {value::TypeTags::Boolean,
- (*value::getObjectIdView(lhsValue)) == (*value::getObjectIdView(rhsValue))};
+ value::bitcastFrom<bool>(*value::getObjectIdView(lhsValue) ==
+ *value::getObjectIdView(rhsValue))};
} else if ((value::isArray(lhsTag) && value::isArray(rhsTag)) ||
(value::isObject(lhsTag) && value::isObject(rhsTag)) ||
(value::isBinData(lhsTag) && value::isBinData(rhsTag))) {
auto [tag, val] = value::compareValue(lhsTag, lhsValue, rhsTag, rhsValue);
if (tag == value::TypeTags::NumberInt32) {
auto result = (value::bitcastTo<int32_t>(val) == 0);
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
}
}
@@ -836,7 +854,7 @@ std::pair<value::TypeTags, value::Value> ByteCode::genericCompareNeq(value::Type
value::Value rhsValue) {
auto [tag, val] = genericCompareEq(lhsTag, lhsValue, rhsTag, rhsValue);
if (tag == value::TypeTags::Boolean) {
- return {tag, value::bitcastFrom(!value::bitcastTo<bool>(val))};
+ return {tag, value::bitcastFrom<bool>(!value::bitcastTo<bool>(val))};
} else {
return {tag, val};
}
@@ -894,7 +912,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericAtan2(value::Ty
case value::TypeTags::NumberDouble: {
auto result = std::atan2(numericCast<double>(argTag1, argValue1),
numericCast<double>(argTag2, argValue2));
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDecimal: {
auto result = numericCast<Decimal128>(argTag1, argValue1)
@@ -927,7 +945,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericDegreesToRadian
case value::TypeTags::NumberInt64:
case value::TypeTags::NumberDouble: {
auto result = numericCast<double>(argTag, argValue) * kDoublePiOver180;
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDecimal: {
auto result =
@@ -950,7 +968,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericRadiansToDegree
case value::TypeTags::NumberInt64:
case value::TypeTags::NumberDouble: {
auto result = numericCast<double>(argTag, argValue) * kDouble180OverPi;
- return {false, value::TypeTags::NumberDouble, value::bitcastFrom(result)};
+ return {false, value::TypeTags::NumberDouble, value::bitcastFrom<double>(result)};
}
case value::TypeTags::NumberDecimal: {
auto result =
diff --git a/src/mongo/db/exec/sbe/vm/vm.cpp b/src/mongo/db/exec/sbe/vm/vm.cpp
index 52614173e4b..f2f8dfb6d94 100644
--- a/src/mongo/db/exec/sbe/vm/vm.cpp
+++ b/src/mongo/db/exec/sbe/vm/vm.cpp
@@ -416,7 +416,6 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::getField(value::TypeTa
} else if (objTag == value::TypeTags::bsonObject) {
auto be = value::bitcastTo<const char*>(objValue);
auto end = be + ConstDataView(be).read<LittleEndian<uint32_t>>();
- ;
// Skip document length.
be += 4;
while (*be != 0) {
@@ -499,7 +498,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::aggSum(value::TypeTags
// Initialize the accumulator.
if (accTag == value::TypeTags::Nothing) {
accTag = value::TypeTags::NumberInt64;
- accValue = 0;
+ accValue = value::bitcastFrom<int64_t>(0);
}
return genericAdd(accTag, accValue, fieldTag, fieldValue);
@@ -522,7 +521,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::aggMin(value::TypeTags
}
auto [tag, val] = genericCompare<std::less<>>(accTag, accValue, fieldTag, fieldValue);
- if (tag == value::TypeTags::Boolean && val) {
+ if (tag == value::TypeTags::Boolean && value::bitcastTo<bool>(val)) {
auto [tag, val] = value::copyValue(accTag, accValue);
return {true, tag, val};
} else {
@@ -548,7 +547,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::aggMax(value::TypeTags
}
auto [tag, val] = genericCompare<std::greater<>>(accTag, accValue, fieldTag, fieldValue);
- if (tag == value::TypeTags::Boolean && val) {
+ if (tag == value::TypeTags::Boolean && value::bitcastTo<bool>(val)) {
auto [tag, val] = value::copyValue(accTag, accValue);
return {true, tag, val};
} else {
@@ -670,7 +669,6 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinDropFields(uint
if (tagInObj == value::TypeTags::bsonObject) {
auto be = value::bitcastTo<const char*>(valInObj);
auto end = be + ConstDataView(be).read<LittleEndian<uint32_t>>();
- ;
// Skip document length.
be += 4;
while (*be != 0) {
@@ -798,7 +796,9 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinNewKeyString(ui
kb.appendDiscriminator(static_cast<KeyString::Discriminator>(discrimNum));
- return {true, value::TypeTags::ksValue, value::bitcastFrom(new KeyString::Value(kb.release()))};
+ return {true,
+ value::TypeTags::ksValue,
+ value::bitcastFrom<KeyString::Value*>(new KeyString::Value(kb.release()))};
}
std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinAbs(uint8_t arity) {
@@ -927,7 +927,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinRegexMatch(uint
auto pcreRegex = value::getPcreRegexView(valuePcreRegex);
auto regexMatchResult = pcreRegex->PartialMatch(pcreStringView);
- return {false, value::TypeTags::Boolean, regexMatchResult};
+ return {false, value::TypeTags::Boolean, value::bitcastFrom<bool>(regexMatchResult)};
}
std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinDoubleDoubleSum(uint8_t arity) {
@@ -969,7 +969,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinDoubleDoubleSum
}
}
if (haveDate) {
- return {false, value::TypeTags::Date, value::bitcastFrom(sum.toLong())};
+ return {false, value::TypeTags::Date, value::bitcastFrom<int64_t>(sum.toLong())};
} else {
auto [tag, val] = value::makeCopyDecimal(sum);
return {true, tag, val};
@@ -990,27 +990,31 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinDoubleDoubleSum
}
if (haveDate) {
uassert(ErrorCodes::Overflow, "date overflow in $add", sum.fitsLong());
- return {false, value::TypeTags::Date, value::bitcastFrom(sum.getLong())};
+ return {false, value::TypeTags::Date, value::bitcastFrom<int64_t>(sum.getLong())};
} else {
switch (resultTag) {
case value::TypeTags::NumberInt32: {
auto result = sum.getLong();
if (sum.fitsLong() && result >= std::numeric_limits<int32_t>::min() &&
result <= std::numeric_limits<int32_t>::max()) {
- return {false, value::TypeTags::NumberInt32, value::bitcastFrom(result)};
+ return {false,
+ value::TypeTags::NumberInt32,
+ value::bitcastFrom<int32_t>(result)};
}
// Fall through to the larger type.
}
case value::TypeTags::NumberInt64: {
if (sum.fitsLong()) {
- return {
- false, value::TypeTags::NumberInt64, value::bitcastFrom(sum.getLong())};
+ return {false,
+ value::TypeTags::NumberInt64,
+ value::bitcastFrom<int64_t>(sum.getLong())};
}
// Fall through to the larger type.
}
case value::TypeTags::NumberDouble: {
- return {
- false, value::TypeTags::NumberDouble, value::bitcastFrom(sum.getDouble())};
+ return {false,
+ value::TypeTags::NumberDouble,
+ value::bitcastFrom<double>(sum.getDouble())};
}
default:
MONGO_UNREACHABLE;
@@ -1073,7 +1077,7 @@ std::tuple<bool, value::TypeTags, value::Value> builtinDateHelper(
value::numericCast<int64_t>(typeTagMin, valueMin),
value::numericCast<int64_t>(typeTagSec, valueSec),
value::numericCast<int64_t>(typeTagMillis, valueMillis));
- return {false, value::TypeTags::Date, date.asInt64()};
+ return {false, value::TypeTags::Date, value::bitcastFrom<int64_t>(date.asInt64())};
}
std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinDate(uint8_t arity) {
@@ -1159,14 +1163,14 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinBitTestPosition
}
auto bitPositions = value::getArrayView(maskValue);
- auto binDataSize = value::getBSONBinDataSize(valueTag, value);
+ auto binDataSize = static_cast<int64_t>(value::getBSONBinDataSize(valueTag, value));
auto binData = value::getBSONBinData(valueTag, value);
auto bitTestBehavior = BitTestBehavior{value::bitcastTo<int32_t>(valueBitTestBehavior)};
auto isBitSet = false;
for (size_t idx = 0; idx < bitPositions->size(); ++idx) {
auto [tagBitPosition, valueBitPosition] = bitPositions->getAt(idx);
- auto bitPosition = value::bitcastTo<uint64_t>(valueBitPosition);
+ auto bitPosition = value::bitcastTo<int64_t>(valueBitPosition);
if (bitPosition >= binDataSize * 8) {
// If position to test is longer than the data to test against, zero-extend.
isBitSet = false;
@@ -1194,14 +1198,14 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinBitTestPosition
bitTestBehavior == BitTestBehavior::AnySet)))) {
return {false,
value::TypeTags::Boolean,
- bitTestBehavior == BitTestBehavior::AnyClear ||
- bitTestBehavior == BitTestBehavior::AnySet};
+ value::bitcastFrom<bool>(bitTestBehavior == BitTestBehavior::AnyClear ||
+ bitTestBehavior == BitTestBehavior::AnySet)};
}
}
return {false,
value::TypeTags::Boolean,
- bitTestBehavior == BitTestBehavior::AllSet ||
- bitTestBehavior == BitTestBehavior::AllClear};
+ value::bitcastFrom<bool>(bitTestBehavior == BitTestBehavior::AllSet ||
+ bitTestBehavior == BitTestBehavior::AllClear)};
}
@@ -1236,7 +1240,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinBitTestZero(uin
}
auto result =
(value::numericCast<int64_t>(maskTag, maskValue) & value::bitcastTo<int64_t>(numVal)) == 0;
- return {false, value::TypeTags::Boolean, result};
+ return {false, value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
}
std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinBitTestMask(uint8_t arity) {
@@ -1252,7 +1256,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinBitTestMask(uin
auto numMask = value::numericCast<int64_t>(maskTag, maskValue);
auto result = (numMask & value::bitcastTo<int64_t>(numVal)) == numMask;
- return {false, value::TypeTags::Boolean, result};
+ return {false, value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
}
std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinBsonSize(uint8_t arity) {
@@ -1261,12 +1265,12 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinBsonSize(uint8_
if (tagOperand == value::TypeTags::Object) {
BSONObjBuilder objBuilder;
bson::convertToBsonObj(objBuilder, value::getObjectView(valOperand));
- auto sz = objBuilder.done().objsize();
- return {false, value::TypeTags::NumberInt32, value::bitcastFrom(sz)};
+ int32_t sz = objBuilder.done().objsize();
+ return {false, value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(sz)};
} else if (tagOperand == value::TypeTags::bsonObject) {
auto beginObj = value::getRawPointerView(valOperand);
- auto sz = ConstDataView(beginObj).read<LittleEndian<uint32_t>>();
- return {false, value::TypeTags::NumberInt32, value::bitcastFrom(sz)};
+ int32_t sz = ConstDataView(beginObj).read<LittleEndian<int32_t>>();
+ return {false, value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(sz)};
}
return {false, value::TypeTags::Nothing, 0};
}
@@ -1330,7 +1334,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinCoerceToString(
std::string str = str::stream()
<< TimeZoneDatabase::utcZone().formatDate(
kISOFormatString,
- Date_t::fromMillisSinceEpoch(value::bitcastTo<uint64_t>(operandVal)));
+ Date_t::fromMillisSinceEpoch(value::bitcastTo<int64_t>(operandVal)));
auto [strTag, strVal] = value::makeNewString(str);
return {true, strTag, strVal};
}
@@ -1447,7 +1451,8 @@ std::pair<value::TypeTags, value::Value> ByteCode::genericIsMember(value::TypeTa
case value::TypeTags::ArraySet: {
auto arrSet = value::getArraySetView(rhsValue);
auto& values = arrSet->values();
- return {value::TypeTags::Boolean, values.find({lhsTag, lhsValue}) != values.end()};
+ return {value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(values.find({lhsTag, lhsValue}) != values.end())};
}
case value::TypeTags::Array:
case value::TypeTags::bsonArray: {
@@ -1455,12 +1460,13 @@ std::pair<value::TypeTags, value::Value> ByteCode::genericIsMember(value::TypeTa
while (!rhsArr.atEnd()) {
auto [rhsTag, rhsVal] = rhsArr.getViewOfValue();
auto [tag, val] = value::compareValue(lhsTag, lhsValue, rhsTag, rhsVal);
- if (tag == value::TypeTags::NumberInt32 && val == 0) {
- return {value::TypeTags::Boolean, true};
+ if (tag == value::TypeTags::NumberInt32 &&
+ value::bitcastTo<int32_t>(val) == 0) {
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(true)};
}
rhsArr.advance();
}
- return {value::TypeTags::Boolean, false};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(false)};
}
default:
MONGO_UNREACHABLE;
@@ -1875,8 +1881,8 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
case Instruction::negate: {
auto [owned, tag, val] = getFromStack(0);
- auto [resultOwned, resultTag, resultVal] =
- genericSub(value::TypeTags::NumberInt32, 0, tag, val);
+ auto [resultOwned, resultTag, resultVal] = genericSub(
+ value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(0), tag, val);
topStack(resultOwned, resultTag, resultVal);
@@ -2176,7 +2182,9 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
case Instruction::exists: {
auto [owned, tag, val] = getFromStack(0);
- topStack(false, value::TypeTags::Boolean, tag != value::TypeTags::Nothing);
+ topStack(false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(tag != value::TypeTags::Nothing));
if (owned) {
value::releaseValue(tag, val);
@@ -2187,7 +2195,9 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
auto [owned, tag, val] = getFromStack(0);
if (tag != value::TypeTags::Nothing) {
- topStack(false, value::TypeTags::Boolean, tag == value::TypeTags::Null);
+ topStack(false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(tag == value::TypeTags::Null));
}
if (owned) {
@@ -2199,7 +2209,9 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
auto [owned, tag, val] = getFromStack(0);
if (tag != value::TypeTags::Nothing) {
- topStack(false, value::TypeTags::Boolean, value::isObject(tag));
+ topStack(false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(value::isObject(tag)));
}
if (owned) {
@@ -2211,7 +2223,9 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
auto [owned, tag, val] = getFromStack(0);
if (tag != value::TypeTags::Nothing) {
- topStack(false, value::TypeTags::Boolean, value::isArray(tag));
+ topStack(false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(value::isArray(tag)));
}
if (owned) {
@@ -2223,7 +2237,9 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
auto [owned, tag, val] = getFromStack(0);
if (tag != value::TypeTags::Nothing) {
- topStack(false, value::TypeTags::Boolean, value::isString(tag));
+ topStack(false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(value::isString(tag)));
}
if (owned) {
@@ -2235,7 +2251,9 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
auto [owned, tag, val] = getFromStack(0);
if (tag != value::TypeTags::Nothing) {
- topStack(false, value::TypeTags::Boolean, value::isNumber(tag));
+ topStack(false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(value::isNumber(tag)));
}
if (owned) {
@@ -2247,7 +2265,9 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
auto [owned, tag, val] = getFromStack(0);
if (tag != value::TypeTags::Nothing) {
- topStack(false, value::TypeTags::Boolean, value::isBinData(tag));
+ topStack(false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(value::isBinData(tag)));
}
if (owned) {
@@ -2259,7 +2279,9 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
auto [owned, tag, val] = getFromStack(0);
if (tag != value::TypeTags::Nothing) {
- topStack(false, value::TypeTags::Boolean, tag == value::TypeTags::Date);
+ topStack(false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(tag == value::TypeTags::Date));
}
if (owned) {
@@ -2271,7 +2293,9 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
auto [owned, tag, val] = getFromStack(0);
if (tag != value::TypeTags::Nothing) {
- topStack(false, value::TypeTags::Boolean, value::isNaN(tag, val));
+ topStack(false,
+ value::TypeTags::Boolean,
+ value::bitcastFrom<bool>(value::isNaN(tag, val)));
}
if (owned) {
@@ -2287,7 +2311,8 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
if (tag != value::TypeTags::Nothing) {
bool matches = static_cast<bool>(getBSONTypeMask(tag) & typeMask);
- topStack(false, value::TypeTags::Boolean, matches);
+ topStack(
+ false, value::TypeTags::Boolean, value::bitcastFrom<bool>(matches));
}
if (owned) {
@@ -2329,7 +2354,7 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
auto [owned, tag, val] = getFromStack(0);
popStack();
- if (tag == value::TypeTags::Boolean && val) {
+ if (tag == value::TypeTags::Boolean && value::bitcastTo<bool>(val)) {
pcPointer += jumpOffset;
}
@@ -2385,7 +2410,7 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm
bool ByteCode::runPredicate(const CodeFragment* code) {
auto [owned, tag, val] = run(code);
- bool pass = (tag == value::TypeTags::Boolean) && (val != 0);
+ bool pass = (tag == value::TypeTags::Boolean) && value::bitcastTo<bool>(val);
if (owned) {
value::releaseValue(tag, val);
diff --git a/src/mongo/db/exec/sbe/vm/vm.h b/src/mongo/db/exec/sbe/vm/vm.h
index 34818fa805f..3654c9d1190 100644
--- a/src/mongo/db/exec/sbe/vm/vm.h
+++ b/src/mongo/db/exec/sbe/vm/vm.h
@@ -50,22 +50,22 @@ std::pair<value::TypeTags, value::Value> genericNumericCompare(value::TypeTags l
case value::TypeTags::NumberInt32: {
auto result = op(value::numericCast<int32_t>(lhsTag, lhsValue),
value::numericCast<int32_t>(rhsTag, rhsValue));
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
}
case value::TypeTags::NumberInt64: {
auto result = op(value::numericCast<int64_t>(lhsTag, lhsValue),
value::numericCast<int64_t>(rhsTag, rhsValue));
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
}
case value::TypeTags::NumberDouble: {
auto result = op(value::numericCast<double>(lhsTag, lhsValue),
value::numericCast<double>(rhsTag, rhsValue));
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
}
case value::TypeTags::NumberDecimal: {
auto result = op(value::numericCast<Decimal128>(lhsTag, lhsValue),
value::numericCast<Decimal128>(rhsTag, rhsValue));
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
}
default:
MONGO_UNREACHABLE;
@@ -74,27 +74,27 @@ std::pair<value::TypeTags, value::Value> genericNumericCompare(value::TypeTags l
auto lhsStr = getStringView(lhsTag, lhsValue);
auto rhsStr = getStringView(rhsTag, rhsValue);
auto result = op(lhsStr.compare(rhsStr), 0);
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
} else if (lhsTag == value::TypeTags::Date && rhsTag == value::TypeTags::Date) {
auto result = op(value::bitcastTo<int64_t>(lhsValue), value::bitcastTo<int64_t>(rhsValue));
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
} else if (lhsTag == value::TypeTags::Timestamp && rhsTag == value::TypeTags::Timestamp) {
auto result =
op(value::bitcastTo<uint64_t>(lhsValue), value::bitcastTo<uint64_t>(rhsValue));
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
} else if (lhsTag == value::TypeTags::Boolean && rhsTag == value::TypeTags::Boolean) {
- auto result = op(lhsValue != 0, rhsValue != 0);
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ auto result = op(value::bitcastTo<bool>(lhsValue), value::bitcastTo<bool>(rhsValue));
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
} else if (lhsTag == value::TypeTags::Null && rhsTag == value::TypeTags::Null) {
// This is where Mongo differs from SQL.
auto result = op(0, 0);
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
} else if ((value::isArray(lhsTag) && value::isArray(rhsTag)) ||
(value::isObject(lhsTag) && value::isObject(rhsTag))) {
auto [tag, val] = value::compareValue(lhsTag, lhsValue, rhsTag, rhsValue);
if (tag == value::TypeTags::NumberInt32) {
auto result = op(value::bitcastTo<int32_t>(val), 0);
- return {value::TypeTags::Boolean, value::bitcastFrom(result)};
+ return {value::TypeTags::Boolean, value::bitcastFrom<bool>(result)};
}
}
diff --git a/src/mongo/db/query/sbe_stage_builder.cpp b/src/mongo/db/query/sbe_stage_builder.cpp
index 5aecc665071..a343ea4704a 100644
--- a/src/mongo/db/query/sbe_stage_builder.cpp
+++ b/src/mongo/db/query/sbe_stage_builder.cpp
@@ -62,7 +62,7 @@ std::unique_ptr<sbe::RuntimeEnvironment> makeRuntimeEnvironment(
// Register an unowned global timezone database for datetime expression evaluation.
env->registerSlot("timeZoneDB"_sd,
sbe::value::TypeTags::timeZoneDB,
- sbe::value::bitcastFrom(getTimeZoneDatabase(opCtx)),
+ sbe::value::bitcastFrom<const TimeZoneDatabase*>(getTimeZoneDatabase(opCtx)),
false,
slotIdGenerator);
return env;
@@ -261,7 +261,8 @@ std::unique_ptr<sbe::PlanStage> SlotBasedStageBuilder::buildSort(const QuerySolu
sbe::makeE<sbe::EPrimBinary>(sbe::EPrimBinary::cmp3w,
sbe::makeE<sbe::EVariable>(innerVar),
sbe::makeE<sbe::EVariable>(resultVar)),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64, 0)),
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(0))),
sbe::makeE<sbe::EVariable>(innerVar),
sbe::makeE<sbe::EVariable>(resultVar));
diff --git a/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp b/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp
index bf099dee54d..2eef4ba2165 100644
--- a/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp
@@ -192,7 +192,7 @@ generateOptimizedOplogScan(OperationContext* opCtx,
csn->nodeId(),
*seekRecordIdSlot,
sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
- seekRecordId->repr())),
+ sbe::value::bitcastFrom<int64_t>(seekRecordId->repr()))),
std::move(stage),
sbe::makeSV(),
sbe::makeSV(*seekRecordIdSlot),
@@ -212,7 +212,9 @@ generateOptimizedOplogScan(OperationContext* opCtx,
sbe::makeE<sbe::EPrimBinary>(
sbe::EPrimBinary::lessEq,
sbe::makeE<sbe::EVariable>(*tsSlot),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Timestamp, (*csn->maxTs).asULL())),
+ sbe::makeE<sbe::EConstant>(
+ sbe::value::TypeTags::Timestamp,
+ sbe::value::bitcastFrom<uint64_t>((*csn->maxTs).asULL()))),
csn->nodeId());
}
@@ -356,8 +358,9 @@ generateGenericCollScan(OperationContext* opCtx,
sbe::makeS<sbe::CoScanStage>(csn->nodeId()), 1, boost::none, csn->nodeId()),
csn->nodeId(),
seekSlot,
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
- csn->resumeAfterRecordId->repr()));
+ sbe::makeE<sbe::EConstant>(
+ sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(csn->resumeAfterRecordId->repr())));
// Construct a 'seek' branch of the 'union'. If we're succeeded to reposition the cursor,
// the branch will output the 'seekSlot' to start the real scan from, otherwise it will
diff --git a/src/mongo/db/query/sbe_stage_builder_expression.cpp b/src/mongo/db/query/sbe_stage_builder_expression.cpp
index f1d22f661dc..e9989044064 100644
--- a/src/mongo/db/query/sbe_stage_builder_expression.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_expression.cpp
@@ -222,7 +222,7 @@ struct ExpressionVisitorContext {
auto shortCircuitVal = (logicOp == sbe::EPrimBinary::logicOr);
auto shortCircuitExpr = sbe::makeE<sbe::EConstant>(
- sbe::value::TypeTags::Boolean, sbe::value::bitcastFrom(shortCircuitVal));
+ sbe::value::TypeTags::Boolean, sbe::value::bitcastFrom<bool>(shortCircuitVal));
traverseStage = sbe::makeProjectStage(
sbe::makeS<sbe::LimitSkipStage>(
sbe::makeS<sbe::CoScanStage>(planNodeId), 1, boost::none, planNodeId),
@@ -1220,7 +1220,8 @@ public:
: sbe::makeE<sbe::EPrimBinary>(
comparisonOperator,
std::move(cmp3w),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 0));
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(0)));
// If either operand evaluates to "Nothing," then the entire operation expressed by 'cmp'
// will also evaluate to "Nothing." MQL comparisons, however, treat "Nothing" as if it is a
@@ -1358,11 +1359,13 @@ public:
sbe::makeE<sbe::EPrimBinary>(
sbe::EPrimBinary::greaterEq,
var.clone(),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, lower)),
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(lower))),
sbe::makeE<sbe::EPrimBinary>(
sbe::EPrimBinary::lessEq,
var.clone(),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, upper))),
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(upper)))),
sbe::makeE<sbe::EFail>(ErrorCodes::Error{4848972}, errMsg));
};
@@ -1429,7 +1432,8 @@ public:
std::vector<std::unique_ptr<sbe::EExpression>> operands;
if (isIsoWeekYear) {
if (!eIsoWeekYear) {
- eIsoWeekYear = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 1970);
+ eIsoWeekYear = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(1970));
operands.push_back(std::move(eIsoWeekYear));
} else {
boundChecks.push_back(boundedCheck(yearRef, 1, 9999, "isoWeekYear"));
@@ -1437,7 +1441,8 @@ public:
std::move(eIsoWeekYear), _context->frameIdGenerator, "isoWeekYear"));
}
if (!eIsoWeek) {
- eIsoWeek = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 1);
+ eIsoWeek = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(1));
operands.push_back(std::move(eIsoWeek));
} else {
boundChecks.push_back(boundedCheck(monthRef, minInt16, maxInt16, "isoWeek"));
@@ -1445,7 +1450,8 @@ public:
std::move(eIsoWeek), _context->frameIdGenerator, "isoWeek"));
}
if (!eIsoDayOfWeek) {
- eIsoDayOfWeek = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 1);
+ eIsoDayOfWeek = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(1));
operands.push_back(std::move(eIsoDayOfWeek));
} else {
boundChecks.push_back(boundedCheck(dayRef, minInt16, maxInt16, "isoDayOfWeek"));
@@ -1455,7 +1461,8 @@ public:
} else {
// The regular year/month/day case.
if (!eYear) {
- eYear = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 1970);
+ eYear = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(1970));
operands.push_back(std::move(eYear));
} else {
boundChecks.push_back(boundedCheck(yearRef, 1, 9999, "year"));
@@ -1463,7 +1470,8 @@ public:
fieldConversionBinding(std::move(eYear), _context->frameIdGenerator, "year"));
}
if (!eMonth) {
- eMonth = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 1);
+ eMonth = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(1));
operands.push_back(std::move(eMonth));
} else {
boundChecks.push_back(boundedCheck(monthRef, minInt16, maxInt16, "month"));
@@ -1471,7 +1479,8 @@ public:
fieldConversionBinding(std::move(eMonth), _context->frameIdGenerator, "month"));
}
if (!eDay) {
- eDay = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 1);
+ eDay = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(1));
operands.push_back(std::move(eDay));
} else {
boundChecks.push_back(boundedCheck(dayRef, minInt16, maxInt16, "day"));
@@ -1480,7 +1489,8 @@ public:
}
}
if (!eHour) {
- eHour = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 0);
+ eHour = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(0));
operands.push_back(std::move(eHour));
} else {
boundChecks.push_back(boundedCheck(hourRef, minInt16, maxInt16, "hour"));
@@ -1488,7 +1498,8 @@ public:
fieldConversionBinding(std::move(eHour), _context->frameIdGenerator, "hour"));
}
if (!eMinute) {
- eMinute = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 0);
+ eMinute = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(0));
operands.push_back(std::move(eMinute));
} else {
boundChecks.push_back(boundedCheck(minRef, minInt16, maxInt16, "minute"));
@@ -1496,7 +1507,8 @@ public:
fieldConversionBinding(std::move(eMinute), _context->frameIdGenerator, "minute"));
}
if (!eSecond) {
- eSecond = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 0);
+ eSecond = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(0));
operands.push_back(std::move(eSecond));
} else {
// MQL doesn't place bound restrictions on the second field, because seconds carry over
@@ -1505,7 +1517,8 @@ public:
fieldConversionBinding(std::move(eSecond), _context->frameIdGenerator, "second"));
}
if (!eMillisecond) {
- eMillisecond = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, 0);
+ eMillisecond = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(0));
operands.push_back(std::move(eMillisecond));
} else {
// MQL doesn't enforce bound restrictions on millisecond fields because milliseconds
@@ -1874,7 +1887,8 @@ public:
auto exprIsNum = sbe::makeE<sbe::EIf>(
sbe::makeE<sbe::EFunction>("exists", sbe::makeEs(inputRef.clone())),
sbe::makeE<sbe::EFunction>("isNumber", sbe::makeEs(inputRef.clone())),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Boolean, false));
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Boolean,
+ sbe::value::bitcastFrom<bool>(false)));
_context->pushExpr(
sbe::makeE<sbe::ELocalBind>(frameId, std::move(binds), std::move(exprIsNum)));
@@ -2323,9 +2337,9 @@ private:
if (expr->getChildren().size() == 0) {
// Empty $and and $or always evaluate to their logical operator's identity value: true
// and false, respectively.
- bool logicIdentityVal = (logicOp == sbe::EPrimBinary::logicAnd);
+ auto logicIdentityVal = (logicOp == sbe::EPrimBinary::logicAnd);
_context->pushExpr(sbe::makeE<sbe::EConstant>(
- sbe::value::TypeTags::Boolean, sbe::value::bitcastFrom(logicIdentityVal)));
+ sbe::value::TypeTags::Boolean, sbe::value::bitcastFrom<bool>(logicIdentityVal)));
return;
} else if (expr->getChildren().size() == 1) {
// No need for short circuiting logic in a singleton $and/$or. Just execute the branch
@@ -2436,12 +2450,12 @@ private:
lowerCmp,
inputRef.clone(),
sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberDouble,
- sbe::value::bitcastFrom(lowerBound.bound))),
+ sbe::value::bitcastFrom<double>(lowerBound.bound))),
sbe::makeE<sbe::EPrimBinary>(
upperCmp,
inputRef.clone(),
sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberDouble,
- sbe::value::bitcastFrom(upperBound.bound))));
+ sbe::value::bitcastFrom<double>(upperBound.bound))));
auto genericTrignomentricExpr = sbe::makeE<sbe::EIf>(
generateNullOrMissing(frameId, 0),
@@ -2624,7 +2638,8 @@ std::unique_ptr<sbe::EExpression> generateCoerceToBoolExpression(sbe::EVariable
sbe::EPrimBinary::neq,
sbe::makeE<sbe::EPrimBinary>(
sbe::EPrimBinary::cmp3w, branchRef.clone(), std::move(valExpr)),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64, 0));
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(0)));
};
// If any of these are false, the branch is considered false for the purposes of the
@@ -2633,10 +2648,10 @@ std::unique_ptr<sbe::EExpression> generateCoerceToBoolExpression(sbe::EVariable
auto checkNotNull = sbe::makeE<sbe::EPrimUnary>(
sbe::EPrimUnary::logicNot,
sbe::makeE<sbe::EFunction>("isNull", sbe::makeEs(branchRef.clone())));
- auto checkNotFalse =
- makeNeqCheck(sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Boolean, false));
- auto checkNotZero =
- makeNeqCheck(sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64, 0));
+ auto checkNotFalse = makeNeqCheck(sbe::makeE<sbe::EConstant>(
+ sbe::value::TypeTags::Boolean, sbe::value::bitcastFrom<bool>(false)));
+ auto checkNotZero = makeNeqCheck(sbe::makeE<sbe::EConstant>(
+ sbe::value::TypeTags::NumberInt64, sbe::value::bitcastFrom<int64_t>(0)));
return sbe::makeE<sbe::EPrimBinary>(
sbe::EPrimBinary::logicAnd,
diff --git a/src/mongo/db/query/sbe_stage_builder_filter.cpp b/src/mongo/db/query/sbe_stage_builder_filter.cpp
index c963307114d..0b26cc766b5 100644
--- a/src/mongo/db/query/sbe_stage_builder_filter.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_filter.cpp
@@ -391,7 +391,8 @@ EvalExprStagePair generateShortCircuitingLogicalOp(sbe::EPrimBinary::Op logicOp,
// short-circuiting occurs, the output returned should be false. For OR, when short-
// circuiting occurs, the output returned should be true.
auto shortCircuitVal = sbe::makeE<sbe::EConstant>(
- sbe::value::TypeTags::Boolean, (logicOp == sbe::EPrimBinary::logicOr));
+ sbe::value::TypeTags::Boolean,
+ sbe::value::bitcastFrom<bool>(logicOp == sbe::EPrimBinary::logicOr));
slot = slotIdGenerator->generate();
stage = makeProject(std::move(stage), planNodeId, slot, std::move(shortCircuitVal));
} else {
@@ -612,7 +613,8 @@ void generateArraySize(MatchExpressionVisitorContext* context,
makeProject(EvalStage{},
context->planNodeId,
innerSlot,
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64, 1));
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(1)));
auto traverseSlot = context->slotIdGenerator->generate();
auto traverseStage =
@@ -633,12 +635,14 @@ void generateArraySize(MatchExpressionVisitorContext* context,
// and compare it to the user provided value.
auto sizeOutput = sbe::makeE<sbe::EPrimBinary>(
sbe::EPrimBinary::eq,
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64, size),
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(size)),
sbe::makeE<sbe::EIf>(
sbe::makeE<sbe::EFunction>("exists",
sbe::makeEs(sbe::makeE<sbe::EVariable>(traverseSlot))),
sbe::makeE<sbe::EVariable>(traverseSlot),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64, 0)));
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(0))));
return {std::move(sizeOutput), std::move(traverseStage)};
};
@@ -680,7 +684,9 @@ void generateComparison(MatchExpressionVisitorContext* context,
*/
void generateAlwaysBoolean(MatchExpressionVisitorContext* context, bool value) {
auto& frame = context->evalStack.back();
- frame.output = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Boolean, value);
+
+ frame.output = sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Boolean,
+ sbe::value::bitcastFrom<bool>(value));
}
/**
@@ -702,11 +708,12 @@ void generateBitTest(MatchExpressionVisitorContext* context,
auto arr = sbe::value::getArrayView(bitPosVal);
arr->reserve(bitPositions.size());
- std::set<int> seenBits;
+ std::set<uint32_t> seenBits;
for (size_t index = 0; index < bitPositions.size(); ++index) {
auto currentBit = bitPositions[index];
if (auto result = seenBits.insert(currentBit); result.second) {
- arr->push_back(sbe::value::TypeTags::NumberInt64, currentBit);
+ arr->push_back(sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(currentBit));
}
}
@@ -718,13 +725,15 @@ void generateBitTest(MatchExpressionVisitorContext* context,
sbe::makeEs(sbe::makeE<sbe::EConstant>(bitPosTag, bitPosVal),
sbe::makeE<sbe::EVariable>(inputSlot),
sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
- static_cast<int32_t>(bitTestBehavior))));
+ sbe::value::bitcastFrom<int32_t>(
+ static_cast<int32_t>(bitTestBehavior)))));
// Build An EExpression for the numeric bitmask case. The AllSet case tests if (mask &
// value) == mask, and AllClear case tests if (mask & value) == 0. The AnyClear and the
// AnySet case is the negation of the AllSet and AllClear cases, respectively.
auto numericBitTestEExpr =
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64, expr->getBitMask());
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(expr->getBitMask()));
if (bitTestBehavior == sbe::BitTestBehavior::AllSet ||
bitTestBehavior == sbe::BitTestBehavior::AnyClear) {
numericBitTestEExpr = sbe::makeE<sbe::EFunction>(
@@ -1300,7 +1309,7 @@ public:
for (auto&& r : regexes) {
auto regex = RegexMatchExpression::makeRegex(r->getString(), r->getFlags());
arr->push_back(sbe::value::TypeTags::pcreRegex,
- sbe::value::bitcastFrom(regex.release()));
+ sbe::value::bitcastFrom<pcrecpp::RE*>(regex.release()));
}
auto makePredicate =
@@ -1414,17 +1423,18 @@ public:
// to the given remainder.
auto makePredicate = [expr](sbe::value::SlotId inputSlot,
EvalStage inputStage) -> EvalExprStagePair {
- return {
- makeFillEmptyFalse(sbe::makeE<sbe::EPrimBinary>(
- sbe::EPrimBinary::eq,
- sbe::makeE<sbe::EFunction>(
- "mod",
- sbe::makeEs(sbe::makeE<sbe::EVariable>(inputSlot),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
- expr->getDivisor()))),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64,
- expr->getRemainder()))),
- std::move(inputStage)};
+ return {makeFillEmptyFalse(sbe::makeE<sbe::EPrimBinary>(
+ sbe::EPrimBinary::eq,
+ sbe::makeE<sbe::EFunction>(
+ "mod",
+ sbe::makeEs(sbe::makeE<sbe::EVariable>(inputSlot),
+ sbe::makeE<sbe::EConstant>(
+ sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(expr->getDivisor())))),
+ sbe::makeE<sbe::EConstant>(
+ sbe::value::TypeTags::NumberInt64,
+ sbe::value::bitcastFrom<int64_t>(expr->getRemainder())))),
+ std::move(inputStage)};
};
generatePredicate(_context, expr->path(), std::move(makePredicate));
@@ -1455,7 +1465,7 @@ public:
auto makePredicate = [expr](sbe::value::SlotId inputSlot,
EvalStage inputStage) -> EvalExprStagePair {
auto regex = RegexMatchExpression::makeRegex(expr->getString(), expr->getFlags());
- auto ownedRegexVal = sbe::value::bitcastFrom(regex.release());
+ auto ownedRegexVal = sbe::value::bitcastFrom<pcrecpp::RE*>(regex.release());
// TODO: In the future, this needs to account for the fact that the regex match
// expression matches strings, but also matches stored regexes. For example,
diff --git a/src/mongo/db/query/sbe_stage_builder_helpers.cpp b/src/mongo/db/query/sbe_stage_builder_helpers.cpp
index 33546b836a5..97d95397576 100644
--- a/src/mongo/db/query/sbe_stage_builder_helpers.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_helpers.cpp
@@ -68,7 +68,7 @@ std::unique_ptr<sbe::EExpression> generateLongLongMinCheck(const sbe::EVariable&
var.clone(),
sbe::makeE<sbe::EConstant>(
sbe::value::TypeTags::NumberInt64,
- sbe::value::bitcastFrom(std::numeric_limits<int64_t>::min()))));
+ sbe::value::bitcastFrom<int64_t>(std::numeric_limits<int64_t>::min()))));
}
std::unique_ptr<sbe::EExpression> generateNaNCheck(const sbe::EVariable& var) {
@@ -79,14 +79,16 @@ std::unique_ptr<sbe::EExpression> generateNonPositiveCheck(const sbe::EVariable&
return sbe::makeE<sbe::EPrimBinary>(
sbe::EPrimBinary::EPrimBinary::lessEq,
var.clone(),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, sbe::value::bitcastFrom(0)));
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(0)));
}
std::unique_ptr<sbe::EExpression> generateNegativeCheck(const sbe::EVariable& var) {
return sbe::makeE<sbe::EPrimBinary>(
sbe::EPrimBinary::EPrimBinary::less,
var.clone(),
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32, sbe::value::bitcastFrom(0)));
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt32,
+ sbe::value::bitcastFrom<int32_t>(0)));
}
std::unique_ptr<sbe::EExpression> generateNonObjectCheck(const sbe::EVariable& var) {
@@ -114,7 +116,9 @@ std::unique_ptr<sbe::EExpression> makeFillEmptyFalse(std::unique_ptr<sbe::EExpre
using namespace std::literals;
return sbe::makeE<sbe::EFunction>(
"fillEmpty"sv,
- sbe::makeEs(std::move(e), sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Boolean, 0)));
+ sbe::makeEs(std::move(e),
+ sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Boolean,
+ sbe::value::bitcastFrom<bool>(false))));
}
} // namespace mongo::stage_builder
diff --git a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
index 2e98673bb93..dc37ebe42da 100644
--- a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
@@ -291,10 +291,12 @@ generateOptimizedMultiIntervalIndexScan(
for (auto&& [lowKey, highKey] : intervals) {
auto [tag, val] = sbe::value::makeNewObject();
auto obj = sbe::value::getObjectView(val);
- obj->push_back(
- "l"sv, sbe::value::TypeTags::ksValue, sbe::value::bitcastFrom(lowKey.release()));
- obj->push_back(
- "h"sv, sbe::value::TypeTags::ksValue, sbe::value::bitcastFrom(highKey.release()));
+ obj->push_back("l"sv,
+ sbe::value::TypeTags::ksValue,
+ sbe::value::bitcastFrom<KeyString::Value*>(lowKey.release()));
+ obj->push_back("h"sv,
+ sbe::value::TypeTags::ksValue,
+ sbe::value::bitcastFrom<KeyString::Value*>(highKey.release()));
arr->push_back(tag, val);
}
@@ -368,8 +370,9 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> makeAnchorBranchF
auto startKeySlot = slotIdGenerator->generate();
sbe::value::SlotMap<std::unique_ptr<sbe::EExpression>> projects;
projects.insert({startKeySlot,
- sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::ksValue,
- sbe::value::bitcastFrom(startKey.release()))});
+ sbe::makeE<sbe::EConstant>(
+ sbe::value::TypeTags::ksValue,
+ sbe::value::bitcastFrom<KeyString::Value*>(startKey.release()))});
for (auto&& unusedSlot : unusedVarSlots) {
projects.insert({unusedSlot, sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::Nothing, 0)});
}
@@ -638,10 +641,10 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleInt
planNodeId,
lowKeySlot,
sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::ksValue,
- sbe::value::bitcastFrom(lowKey.release())),
+ sbe::value::bitcastFrom<KeyString::Value*>(lowKey.release())),
highKeySlot,
sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::ksValue,
- sbe::value::bitcastFrom(highKey.release())));
+ sbe::value::bitcastFrom<KeyString::Value*>(highKey.release())));
// Scan the index in the range {'lowKeySlot', 'highKeySlot'} (subject to inclusive or
// exclusive boundaries), and produce a single field recordIdSlot that can be used to