diff options
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/exec/sbe/expressions/expression.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/stages/ix_scan.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/stages/scan.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/values/bson.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/values/slot.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/values/value.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/values/value.h | 5 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/vm/vm.cpp | 19 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/vm/vm.h | 2 | ||||
-rw-r--r-- | src/mongo/db/query/plan_executor_sbe.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/query/sbe_stage_builder_coll_scan.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/query/sbe_stage_builder_index_scan.cpp | 4 |
12 files changed, 55 insertions, 11 deletions
diff --git a/src/mongo/db/exec/sbe/expressions/expression.cpp b/src/mongo/db/exec/sbe/expressions/expression.cpp index 3eee0f6a57b..1fc6504b2b0 100644 --- a/src/mongo/db/exec/sbe/expressions/expression.cpp +++ b/src/mongo/db/exec/sbe/expressions/expression.cpp @@ -449,6 +449,8 @@ static stdx::unordered_map<std::string, InstrFn> kInstrFunctions = { InstrFn{[](size_t n) { return n == 1; }, &vm::CodeFragment::appendIsBinData, false}}, {"isDate", InstrFn{[](size_t n) { return n == 1; }, &vm::CodeFragment::appendIsDate, false}}, {"isNaN", InstrFn{[](size_t n) { return n == 1; }, &vm::CodeFragment::appendIsNaN, false}}, + {"isRecordId", + InstrFn{[](size_t n) { return n == 1; }, &vm::CodeFragment::appendIsRecordId, false}}, {"sum", InstrFn{[](size_t n) { return n == 1; }, &vm::CodeFragment::appendSum, true}}, {"min", InstrFn{[](size_t n) { return n == 1; }, &vm::CodeFragment::appendMin, true}}, {"max", InstrFn{[](size_t n) { return n == 1; }, &vm::CodeFragment::appendMax, true}}, diff --git a/src/mongo/db/exec/sbe/stages/ix_scan.cpp b/src/mongo/db/exec/sbe/stages/ix_scan.cpp index 78bf0b09de5..a45e25542d2 100644 --- a/src/mongo/db/exec/sbe/stages/ix_scan.cpp +++ b/src/mongo/db/exec/sbe/stages/ix_scan.cpp @@ -274,7 +274,7 @@ PlanState IndexScanStage::getNext() { } if (_recordIdAccessor) { - _recordIdAccessor->reset(value::TypeTags::NumberInt64, + _recordIdAccessor->reset(value::TypeTags::RecordId, value::bitcastFrom<int64_t>(_nextRecord->loc.repr())); } diff --git a/src/mongo/db/exec/sbe/stages/scan.cpp b/src/mongo/db/exec/sbe/stages/scan.cpp index 029cdcb9587..f4d428fa3ed 100644 --- a/src/mongo/db/exec/sbe/stages/scan.cpp +++ b/src/mongo/db/exec/sbe/stages/scan.cpp @@ -184,7 +184,7 @@ void ScanStage::open(bool reOpen) { const auto msgTag = tag; uassert(ErrorCodes::BadValue, str::stream() << "seek key is wrong type: " << msgTag, - tag == value::TypeTags::NumberInt64); + tag == value::TypeTags::RecordId); _key = RecordId{value::bitcastTo<int64_t>(val)}; } @@ -221,7 +221,7 @@ PlanState ScanStage::getNext() { } if (_recordIdAccessor) { - _recordIdAccessor->reset(value::TypeTags::NumberInt64, + _recordIdAccessor->reset(value::TypeTags::RecordId, value::bitcastFrom<int64_t>(nextRecord->id.repr())); } @@ -527,7 +527,7 @@ PlanState ParallelScanStage::getNext() { } if (_recordIdAccessor) { - _recordIdAccessor->reset(value::TypeTags::NumberInt64, + _recordIdAccessor->reset(value::TypeTags::RecordId, value::bitcastFrom<int64_t>(nextRecord->id.repr())); } diff --git a/src/mongo/db/exec/sbe/values/bson.cpp b/src/mongo/db/exec/sbe/values/bson.cpp index 5f28c6122c0..a0f45a576bb 100644 --- a/src/mongo/db/exec/sbe/values/bson.cpp +++ b/src/mongo/db/exec/sbe/values/bson.cpp @@ -231,6 +231,7 @@ void convertToBsonObj(BSONArrayBuilder& builder, value::ArrayEnumerator arr) { case value::TypeTags::NumberInt32: builder.append(value::bitcastTo<int32_t>(val)); break; + case value::TypeTags::RecordId: case value::TypeTags::NumberInt64: builder.append(value::bitcastTo<int64_t>(val)); break; @@ -317,6 +318,7 @@ void convertToBsonObj(BSONObjBuilder& builder, value::Object* obj) { case value::TypeTags::NumberInt32: builder.append(name, value::bitcastTo<int32_t>(val)); break; + case value::TypeTags::RecordId: case value::TypeTags::NumberInt64: builder.append(name, value::bitcastTo<int64_t>(val)); break; diff --git a/src/mongo/db/exec/sbe/values/slot.cpp b/src/mongo/db/exec/sbe/values/slot.cpp index 65017593bd1..401718fe24d 100644 --- a/src/mongo/db/exec/sbe/values/slot.cpp +++ b/src/mongo/db/exec/sbe/values/slot.cpp @@ -46,6 +46,7 @@ static std::pair<TypeTags, Value> deserializeTagVal(BufReader& buf) { case TypeTags::NumberInt32: val = bitcastFrom<int32_t>(buf.read<int32_t>()); break; + case TypeTags::RecordId: case TypeTags::NumberInt64: val = bitcastFrom<int64_t>(buf.read<int64_t>()); break; @@ -184,6 +185,7 @@ static void serializeTagValue(BufBuilder& buf, TypeTags tag, Value val) { case TypeTags::NumberInt32: buf.appendNum(bitcastTo<int32_t>(val)); break; + case TypeTags::RecordId: case TypeTags::NumberInt64: buf.appendNum(bitcastTo<int64_t>(val)); break; @@ -300,6 +302,7 @@ static int getApproximateSize(TypeTags tag, Value val) { case TypeTags::Timestamp: case TypeTags::Boolean: case TypeTags::StringSmall: + case TypeTags::RecordId: break; // There are deep types. case TypeTags::NumberDecimal: diff --git a/src/mongo/db/exec/sbe/values/value.cpp b/src/mongo/db/exec/sbe/values/value.cpp index a2b1a398753..df65fa01f81 100644 --- a/src/mongo/db/exec/sbe/values/value.cpp +++ b/src/mongo/db/exec/sbe/values/value.cpp @@ -161,6 +161,9 @@ void writeTagToStream(T& stream, const TypeTags tag) { case TypeTags::timeZoneDB: stream << "timeZoneDB"; break; + case TypeTags::RecordId: + stream << "RecordId"; + break; default: stream << "unknown tag"; break; @@ -370,6 +373,9 @@ void writeValueToStream(T& stream, TypeTags tag, Value val) { stream << "TimeZoneDatabase(" + timeZones.front() + "..." + timeZones.back() + ")"; break; } + case value::TypeTags::RecordId: + stream << "RecordId(" << bitcastTo<int64_t>(val) << ")"; + break; default: MONGO_UNREACHABLE; } @@ -401,6 +407,7 @@ BSONType tagToType(TypeTags tag) noexcept { return BSONType::EOO; case TypeTags::NumberInt32: return BSONType::NumberInt; + case TypeTags::RecordId: case TypeTags::NumberInt64: return BSONType::NumberLong; case TypeTags::NumberDouble: @@ -449,6 +456,7 @@ std::size_t hashValue(TypeTags tag, Value val) noexcept { switch (tag) { case TypeTags::NumberInt32: return absl::Hash<int32_t>{}(bitcastTo<int32_t>(val)); + case TypeTags::RecordId: case TypeTags::NumberInt64: return absl::Hash<int64_t>{}(bitcastTo<int64_t>(val)); case TypeTags::NumberDouble: { @@ -695,6 +703,9 @@ std::pair<TypeTags, Value> compareValue(TypeTags lhsTag, } else if (lhsTag == TypeTags::Nothing && rhsTag == TypeTags::Nothing) { // Special case for Nothing in a hash table (group) and sort comparison. return {TypeTags::NumberInt32, bitcastFrom<int32_t>(0)}; + } else if (lhsTag == TypeTags::RecordId && rhsTag == TypeTags::RecordId) { + auto result = compareHelper(bitcastTo<int64_t>(lhsValue), bitcastTo<int64_t>(rhsValue)); + return {TypeTags::NumberInt32, bitcastFrom<int32_t>(result)}; } else { // Different types. auto result = diff --git a/src/mongo/db/exec/sbe/values/value.h b/src/mongo/db/exec/sbe/values/value.h index 581da63af19..17c3a970698 100644 --- a/src/mongo/db/exec/sbe/values/value.h +++ b/src/mongo/db/exec/sbe/values/value.h @@ -99,6 +99,7 @@ enum class TypeTags : uint8_t { Object, ObjectId, + RecordId, // TODO add the rest of mongo types (regex, etc.) @@ -145,6 +146,10 @@ inline constexpr bool isBinData(TypeTags tag) noexcept { return tag == TypeTags::bsonBinData; } +inline constexpr bool isRecordId(TypeTags tag) noexcept { + return tag == TypeTags::RecordId; +} + BSONType tagToType(TypeTags tag) noexcept; /** diff --git a/src/mongo/db/exec/sbe/vm/vm.cpp b/src/mongo/db/exec/sbe/vm/vm.cpp index cf067c690dc..8848c87227e 100644 --- a/src/mongo/db/exec/sbe/vm/vm.cpp +++ b/src/mongo/db/exec/sbe/vm/vm.cpp @@ -100,6 +100,7 @@ int Instruction::stackOffset[Instruction::Tags::lastInstruction] = { 0, // isBinData 0, // isDate 0, // isNaN + 0, // isRecordId 0, // typeMatch 0, // function is special, the stack offset is encoded in the instruction itself @@ -326,6 +327,10 @@ void CodeFragment::appendIsNaN() { appendSimpleInstruction(Instruction::isNaN); } +void CodeFragment::appendIsRecordId() { + appendSimpleInstruction(Instruction::isRecordId); +} + void CodeFragment::appendTypeMatch(uint32_t typeMask) { Instruction i; i.tag = Instruction::typeMatch; @@ -2602,6 +2607,20 @@ std::tuple<uint8_t, value::TypeTags, value::Value> ByteCode::run(const CodeFragm } break; } + case Instruction::isRecordId: { + auto [owned, tag, val] = getFromStack(0); + + if (tag != value::TypeTags::Nothing) { + topStack(false, + value::TypeTags::Boolean, + value::bitcastFrom<bool>(value::isRecordId(tag))); + } + + if (owned) { + value::releaseValue(tag, val); + } + break; + } case Instruction::typeMatch: { auto typeMask = value::readFromMemory<uint32_t>(pcPointer); pcPointer += sizeof(typeMask); diff --git a/src/mongo/db/exec/sbe/vm/vm.h b/src/mongo/db/exec/sbe/vm/vm.h index d3d5d360748..124a82217e5 100644 --- a/src/mongo/db/exec/sbe/vm/vm.h +++ b/src/mongo/db/exec/sbe/vm/vm.h @@ -151,6 +151,7 @@ struct Instruction { isBinData, isDate, isNaN, + isRecordId, typeMatch, function, @@ -297,6 +298,7 @@ public: void appendIsBinData(); void appendIsDate(); void appendIsNaN(); + void appendIsRecordId(); void appendTypeMatch(uint32_t typeMask); void appendFunction(Builtin f, uint8_t arity); void appendJump(int jumpOffset); diff --git a/src/mongo/db/query/plan_executor_sbe.cpp b/src/mongo/db/query/plan_executor_sbe.cpp index 875956d117e..30d2e2dc602 100644 --- a/src/mongo/db/query/plan_executor_sbe.cpp +++ b/src/mongo/db/query/plan_executor_sbe.cpp @@ -217,7 +217,7 @@ PlanExecutor::ExecState PlanExecutorSBE::getNext(BSONObj* out, RecordId* dlOut) uassert(4946306, "Collection scan was asked to track resume token, but found a result " "without a valid RecordId", - tag == sbe::value::TypeTags::NumberInt64 || + tag == sbe::value::TypeTags::RecordId || tag == sbe::value::TypeTags::Nothing); _env->resetSlot(*_resumeRecordIdSlot, tag, val, false); } @@ -276,7 +276,7 @@ BSONObj PlanExecutorSBE::getPostBatchResumeToken() const { str::stream() << "Collection scan was asked to track resume token, " "but found a result without a valid RecordId: " << msgTag, - tag == sbe::value::TypeTags::NumberInt64); + tag == sbe::value::TypeTags::RecordId); return BSON("$recordId" << sbe::value::bitcastTo<int64_t>(val)); } } @@ -313,7 +313,7 @@ sbe::PlanState fetchNext(sbe::PlanStage* root, if (dlOut) { invariant(recordIdSlot); auto [tag, val] = recordIdSlot->getViewOfValue(); - if (tag == sbe::value::TypeTags::NumberInt64) { + if (tag == sbe::value::TypeTags::RecordId) { *dlOut = RecordId{sbe::value::bitcastTo<int64_t>(val)}; } } 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 2eef4ba2165..e1fb3257f3d 100644 --- a/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp +++ b/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp @@ -191,7 +191,7 @@ generateOptimizedOplogScan(OperationContext* opCtx, sbe::makeS<sbe::CoScanStage>(csn->nodeId()), 1, boost::none, csn->nodeId()), csn->nodeId(), *seekRecordIdSlot, - sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::NumberInt64, + sbe::makeE<sbe::EConstant>(sbe::value::TypeTags::RecordId, sbe::value::bitcastFrom<int64_t>(seekRecordId->repr()))), std::move(stage), sbe::makeSV(), @@ -359,7 +359,7 @@ generateGenericCollScan(OperationContext* opCtx, csn->nodeId(), seekSlot, sbe::makeE<sbe::EConstant>( - sbe::value::TypeTags::NumberInt64, + sbe::value::TypeTags::RecordId, sbe::value::bitcastFrom<int64_t>(csn->resumeAfterRecordId->repr()))); // Construct a 'seek' branch of the 'union'. If we're succeeded to reposition the cursor, 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 64f5543c73f..92dd96f4dc3 100644 --- a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp +++ b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp @@ -603,7 +603,7 @@ generateGenericMultiIntervalIndexScan(const CollectionPtr& collection, makeSlotVector(resultSlot, std::move(indexKeySlots)), sbe::makeE<sbe::EPrimUnary>( sbe::EPrimUnary::logicNot, - sbe::makeE<sbe::EFunction>("isNumber"sv, + sbe::makeE<sbe::EFunction>("isRecordId"sv, sbe::makeEs(sbe::makeE<sbe::EVariable>(resultSlot)))), ixn->nodeId()); @@ -611,7 +611,7 @@ generateGenericMultiIntervalIndexScan(const CollectionPtr& collection, return {resultSlot, sbe::makeS<sbe::FilterStage<false>>( std::move(spool), - sbe::makeE<sbe::EFunction>("isNumber"sv, + sbe::makeE<sbe::EFunction>("isRecordId"sv, sbe::makeEs(sbe::makeE<sbe::EVariable>(resultSlot))), ixn->nodeId())}; } |