summaryrefslogtreecommitdiff
path: root/src/mongo/db/exec/sbe/vm
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/exec/sbe/vm')
-rw-r--r--src/mongo/db/exec/sbe/vm/arith.cpp114
-rw-r--r--src/mongo/db/exec/sbe/vm/vm.cpp339
-rw-r--r--src/mongo/db/exec/sbe/vm/vm.h67
3 files changed, 24 insertions, 496 deletions
diff --git a/src/mongo/db/exec/sbe/vm/arith.cpp b/src/mongo/db/exec/sbe/vm/arith.cpp
index e6c9d380ffd..e4c67775ad8 100644
--- a/src/mongo/db/exec/sbe/vm/arith.cpp
+++ b/src/mongo/db/exec/sbe/vm/arith.cpp
@@ -503,57 +503,6 @@ void ByteCode::aggDoubleDoubleSumImpl(value::Array* arr,
}
}
-void ByteCode::aggMergeDoubleDoubleSumsImpl(value::Array* accumulator,
- value::TypeTags rhsTag,
- value::Value rhsValue) {
- auto [accumWidestType, _1] = accumulator->getAt(AggSumValueElems::kNonDecimalTotalTag);
-
- tassert(7039532, "value must be of type 'Array'", rhsTag == value::TypeTags::Array);
- auto nextDoubleDoubleArr = value::getArrayView(rhsValue);
-
- tassert(7039533,
- "array does not have enough elements",
- nextDoubleDoubleArr->size() >= AggSumValueElems::kMaxSizeOfArray - 1);
-
- // First aggregate the non-decimal sum, then the non-decimal addend. Both should be doubles.
- auto [sumTag, sum] = nextDoubleDoubleArr->getAt(AggSumValueElems::kNonDecimalTotalSum);
- tassert(7039534, "expected 'NumberDouble'", sumTag == value::TypeTags::NumberDouble);
- aggDoubleDoubleSumImpl(accumulator, sumTag, sum);
-
- auto [addendTag, addend] = nextDoubleDoubleArr->getAt(AggSumValueElems::kNonDecimalTotalAddend);
- tassert(7039535, "expected 'NumberDouble'", addendTag == value::TypeTags::NumberDouble);
- // There is a special case when the 'sum' is infinite and the 'addend' is NaN. This DoubleDouble
- // value represents infinity, not NaN. Therefore, we avoid incorporating the NaN 'addend' value
- // into the sum.
- if (std::isfinite(value::bitcastTo<double>(sum)) ||
- !std::isnan(value::bitcastTo<double>(addend))) {
- aggDoubleDoubleSumImpl(accumulator, addendTag, addend);
- }
-
- // Determine the widest non-decimal type that we've seen so far, and set the accumulator state
- // accordingly. We do this after computing the sums, since 'aggDoubleDoubleSumImpl()' will
- // set the widest type to 'NumberDouble' when we call it above.
- auto [newValWidestType, _2] = nextDoubleDoubleArr->getAt(AggSumValueElems::kNonDecimalTotalTag);
- tassert(
- 7039536, "unexpected 'NumberDecimal'", newValWidestType != value::TypeTags::NumberDecimal);
- tassert(
- 7039537, "unexpected 'NumberDecimal'", accumWidestType != value::TypeTags::NumberDecimal);
- auto widestType = getWidestNumericalType(newValWidestType, accumWidestType);
- accumulator->setAt(
- AggSumValueElems::kNonDecimalTotalTag, widestType, value::bitcastFrom<int32_t>(0));
-
- // If there's a decimal128 sum as part of the incoming DoubleDouble sum, incorporate it into the
- // accumulator.
- if (nextDoubleDoubleArr->size() == AggSumValueElems::kMaxSizeOfArray) {
- auto [decimalTotalTag, decimalTotalVal] =
- nextDoubleDoubleArr->getAt(AggSumValueElems::kDecimalTotal);
- tassert(7039538,
- "The decimalTotal must be 'NumberDecimal'",
- decimalTotalTag == TypeTags::NumberDecimal);
- aggDoubleDoubleSumImpl(accumulator, decimalTotalTag, decimalTotalVal);
- }
-}
-
void ByteCode::aggStdDevImpl(value::Array* arr, value::TypeTags rhsTag, value::Value rhsValue) {
if (!isNumber(rhsTag)) {
return;
@@ -602,67 +551,6 @@ void ByteCode::aggStdDevImpl(value::Array* arr, value::TypeTags rhsTag, value::V
return setStdDevArray(newCountVal, newMeanVal, newM2Val, arr);
}
-void ByteCode::aggMergeStdDevsImpl(value::Array* accumulator,
- value::TypeTags rhsTag,
- value::Value rhsValue) {
- tassert(7039542, "expected value of type 'Array'", rhsTag == value::TypeTags::Array);
- auto nextArr = value::getArrayView(rhsValue);
-
- tassert(7039543,
- "expected array to have exactly 3 elements",
- accumulator->size() == AggStdDevValueElems::kSizeOfArray);
- tassert(7039544,
- "expected array to have exactly 3 elements",
- nextArr->size() == AggStdDevValueElems::kSizeOfArray);
-
- auto [newCountTag, newCountVal] = nextArr->getAt(AggStdDevValueElems::kCount);
- tassert(7039545, "expected 64-bit int", newCountTag == value::TypeTags::NumberInt64);
- int64_t newCount = value::bitcastTo<int64_t>(newCountVal);
-
- // If the incoming partial aggregate has a count of zero, then it represents the partial
- // standard deviation of no data points. This means that it can be safely ignored, and we return
- // the accumulator as is.
- if (newCount == 0) {
- return;
- }
-
- auto [oldCountTag, oldCountVal] = accumulator->getAt(AggStdDevValueElems::kCount);
- tassert(7039546, "expected 64-bit int", oldCountTag == value::TypeTags::NumberInt64);
- int64_t oldCount = value::bitcastTo<int64_t>(oldCountVal);
-
- auto [oldMeanTag, oldMeanVal] = accumulator->getAt(AggStdDevValueElems::kRunningMean);
- tassert(7039547, "expected double", oldMeanTag == value::TypeTags::NumberDouble);
- double oldMean = value::bitcastTo<double>(oldMeanVal);
-
- auto [newMeanTag, newMeanVal] = nextArr->getAt(AggStdDevValueElems::kRunningMean);
- tassert(7039548, "expected double", newMeanTag == value::TypeTags::NumberDouble);
- double newMean = value::bitcastTo<double>(newMeanVal);
-
- auto [oldM2Tag, oldM2Val] = accumulator->getAt(AggStdDevValueElems::kRunningM2);
- tassert(7039531, "expected double", oldM2Tag == value::TypeTags::NumberDouble);
- double oldM2 = value::bitcastTo<double>(oldM2Val);
-
- auto [newM2Tag, newM2Val] = nextArr->getAt(AggStdDevValueElems::kRunningM2);
- tassert(7039541, "expected double", newM2Tag == value::TypeTags::NumberDouble);
- double newM2 = value::bitcastTo<double>(newM2Val);
-
- const double delta = newMean - oldMean;
- // We've already handled the case where 'newCount' is zero above. This means that 'totalCount'
- // must be positive, and prevents us from ever dividing by zero in the subsequent calculation.
- int64_t totalCount = oldCount + newCount;
- if (delta != 0) {
- newMean = ((oldCount * oldMean) + (newCount * newMean)) / totalCount;
- newM2 += delta * delta *
- (static_cast<double>(oldCount) * static_cast<double>(newCount) / totalCount);
- }
- newM2 += oldM2;
-
- setStdDevArray(value::bitcastFrom<int64_t>(totalCount),
- value::bitcastFrom<double>(newMean),
- value::bitcastFrom<double>(newM2),
- accumulator);
-}
-
std::tuple<bool, value::TypeTags, value::Value> ByteCode::aggStdDevFinalizeImpl(
value::Value fieldValue, bool isSamp) {
auto arr = value::getArrayView(fieldValue);
@@ -1027,7 +915,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::genericLn(value::TypeT
if (!operand.isGreater(Decimal128::kNormalizedZero) && !operand.isNaN()) {
return {false, value::TypeTags::Nothing, 0};
}
- auto operandLn = operand.naturalLogarithm();
+ auto operandLn = operand.logarithm();
auto [tag, value] = value::makeCopyDecimal(operandLn);
return {true, tag, value};
diff --git a/src/mongo/db/exec/sbe/vm/vm.cpp b/src/mongo/db/exec/sbe/vm/vm.cpp
index 812de5232af..7eb8eb7149e 100644
--- a/src/mongo/db/exec/sbe/vm/vm.cpp
+++ b/src/mongo/db/exec/sbe/vm/vm.cpp
@@ -1072,40 +1072,35 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::aggSum(value::TypeTags
return genericAdd(accTag, accValue, fieldTag, fieldValue);
}
-template <bool merging>
std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinAggDoubleDoubleSum(
ArityType arity) {
+
auto [_, fieldTag, fieldValue] = getFromStack(1);
// Move the incoming accumulator state from the stack. Given that we are now the owner of the
// state we are free to do any in-place update as we see fit.
auto [accTag, accValue] = moveOwnedFromStack(0);
+ value::ValueGuard guard{accTag, accValue};
// Initialize the accumulator.
if (accTag == value::TypeTags::Nothing) {
std::tie(accTag, accValue) = value::makeNewArray();
- value::ValueGuard newArrGuard{accTag, accValue};
+ value::ValueGuard guard{accTag, accValue};
auto arr = value::getArrayView(accValue);
arr->reserve(AggSumValueElems::kMaxSizeOfArray);
- // The order of the following three elements should match to 'AggSumValueElems'. An absent
- // 'kDecimalTotal' element means that we've not seen any decimal value. So, we're not adding
- // 'kDecimalTotal' element yet.
+ // The order of the following three elements should match to 'AggSumValueElems'.
arr->push_back(value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(0));
arr->push_back(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.0));
arr->push_back(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.0));
- newArrGuard.reset();
+ // The absent 'kDecimalTotal' element means that we've not seen any decimal value. So, we're
+ // not adding 'kDecimalTotal' element yet.
+ aggDoubleDoubleSumImpl(arr, fieldTag, fieldValue);
+ guard.reset();
+ return {true, accTag, accValue};
}
-
- value::ValueGuard guard{accTag, accValue};
tassert(5755317, "The result slot must be Array-typed", accTag == value::TypeTags::Array);
- auto accumulator = value::getArrayView(accValue);
-
- if constexpr (merging) {
- aggMergeDoubleDoubleSumsImpl(accumulator, fieldTag, fieldValue);
- } else {
- aggDoubleDoubleSumImpl(accumulator, fieldTag, fieldValue);
- }
+ aggDoubleDoubleSumImpl(value::getArrayView(accValue), fieldTag, fieldValue);
guard.reset();
return {true, accTag, accValue};
}
@@ -1240,37 +1235,31 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinDoubleDoublePar
return {true, tag, val};
}
-template <bool merging>
std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinAggStdDev(ArityType arity) {
auto [_, fieldTag, fieldValue] = getFromStack(1);
// Move the incoming accumulator state from the stack. Given that we are now the owner of the
// state we are free to do any in-place update as we see fit.
auto [accTag, accValue] = moveOwnedFromStack(0);
+ value::ValueGuard guard{accTag, accValue};
// Initialize the accumulator.
if (accTag == value::TypeTags::Nothing) {
- std::tie(accTag, accValue) = value::makeNewArray();
- value::ValueGuard newArrGuard{accTag, accValue};
- auto arr = value::getArrayView(accValue);
+ auto [newAccTag, newAccValue] = value::makeNewArray();
+ value::ValueGuard newGuard{newAccTag, newAccValue};
+ auto arr = value::getArrayView(newAccValue);
arr->reserve(AggStdDevValueElems::kSizeOfArray);
// The order of the following three elements should match to 'AggStdDevValueElems'.
arr->push_back(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(0));
arr->push_back(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.0));
arr->push_back(value::TypeTags::NumberDouble, value::bitcastFrom<double>(0.0));
- newArrGuard.reset();
+ aggStdDevImpl(arr, fieldTag, fieldValue);
+ newGuard.reset();
+ return {true, newAccTag, newAccValue};
}
-
- value::ValueGuard guard{accTag, accValue};
tassert(5755210, "The result slot must be Array-typed", accTag == value::TypeTags::Array);
- auto accumulator = value::getArrayView(accValue);
-
- if constexpr (merging) {
- aggMergeStdDevsImpl(accumulator, fieldTag, fieldValue);
- } else {
- aggStdDevImpl(accumulator, fieldTag, fieldValue);
- }
+ aggStdDevImpl(value::getArrayView(accValue), fieldTag, fieldValue);
guard.reset();
return {true, accTag, accValue};
}
@@ -3030,120 +3019,6 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinConcat(ArityTyp
return {true, strTag, strValue};
}
-std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinConcatArrays(ArityType arity) {
- auto [resTag, resVal] = value::makeNewArray();
- value::ValueGuard resGuard{resTag, resVal};
- auto resView = value::getArrayView(resVal);
-
- for (ArityType idx = 0; idx < arity; ++idx) {
- auto [_, tag, val] = getFromStack(idx);
- if (!value::isArray(tag)) {
- return {false, value::TypeTags::Nothing, 0};
- }
-
- for (auto ae = value::ArrayEnumerator{tag, val}; !ae.atEnd(); ae.advance()) {
- auto [elTag, elVal] = ae.getViewOfValue();
- auto [copyTag, copyVal] = value::copyValue(elTag, elVal);
- resView->push_back(copyTag, copyVal);
- }
- }
-
- resGuard.reset();
-
- return {true, resTag, resVal};
-}
-
-std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinAggConcatArraysCapped(
- ArityType arity) {
- auto [ownArr, tagArr, valArr] = getFromStack(0);
- auto [tagNewElem, valNewElem] = moveOwnedFromStack(1);
- value::ValueGuard guardNewElem{tagNewElem, valNewElem};
- auto [_, tagSizeCap, valSizeCap] = getFromStack(2);
-
- tassert(7039508,
- "'cap' parameter must be a 32-bit int",
- tagSizeCap == value::TypeTags::NumberInt32);
- const int32_t sizeCap = value::bitcastTo<int32_t>(valSizeCap);
-
- // We expect the new value we are adding to the accumulator to be a two-element array where
- // the first element is the array to concatenate and the second value is the corresponding size.
- tassert(7039512, "expected value of type 'Array'", tagNewElem == value::TypeTags::Array);
- auto newArr = value::getArrayView(valNewElem);
- tassert(7039527,
- "array had unexpected size",
- newArr->size() == static_cast<size_t>(AggArrayWithSize::kLast));
-
- // Create a new array to hold size and added elements, if is it does not exist yet.
- if (tagArr == value::TypeTags::Nothing) {
- ownArr = true;
- std::tie(tagArr, valArr) = value::makeNewArray();
- auto arr = value::getArrayView(valArr);
-
- auto [tagAccArr, valAccArr] = value::makeNewArray();
-
- // The order is important! The accumulated array should be at index
- // AggArrayWithSize::kValues, and the size should be at index
- // AggArrayWithSize::kSizeOfValues.
- arr->push_back(tagAccArr, valAccArr);
- arr->push_back(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(0));
- } else {
- // Take ownership of the accumulator.
- topStack(false, value::TypeTags::Nothing, 0);
- }
-
- tassert(7039513, "expected array to be owned", ownArr);
- value::ValueGuard accumulatorGuard{tagArr, valArr};
- tassert(7039514, "expected accumulator to have type 'Array'", tagArr == value::TypeTags::Array);
- auto arr = value::getArrayView(valArr);
- tassert(7039515,
- "accumulator was array of unexpected size",
- arr->size() == static_cast<size_t>(AggArrayWithSize::kLast));
-
- // Check that the accumulated size after concatentation won't exceed the limit.
- {
- auto [tagAccSize, valAccSize] =
- arr->getAt(static_cast<size_t>(AggArrayWithSize::kSizeOfValues));
- auto [tagNewSize, valNewSize] =
- newArr->getAt(static_cast<size_t>(AggArrayWithSize::kSizeOfValues));
- tassert(7039516, "expected 64-bit int", tagAccSize == value::TypeTags::NumberInt64);
- tassert(7039517, "expected 64-bit int", tagNewSize == value::TypeTags::NumberInt64);
- const int64_t currentSize = value::bitcastTo<int64_t>(valAccSize);
- const int64_t newSize = value::bitcastTo<int64_t>(valNewSize);
- const int64_t totalSize = currentSize + newSize;
-
- if (totalSize >= static_cast<int64_t>(sizeCap)) {
- uasserted(ErrorCodes::ExceededMemoryLimit,
- str::stream() << "Used too much memory for a single array. Memory limit: "
- << sizeCap << ". Concatentating array of " << arr->size()
- << " elements and " << currentSize << " bytes with array of "
- << newArr->size() << " elements and " << newSize << " bytes.");
- }
-
- // We are still under the size limit. Set the new total size in the accumulator.
- arr->setAt(static_cast<size_t>(AggArrayWithSize::kSizeOfValues),
- value::TypeTags::NumberInt64,
- value::bitcastFrom<int64_t>(totalSize));
- }
-
- auto [tagAccArr, valAccArr] = arr->getAt(static_cast<size_t>(AggArrayWithSize::kValues));
- tassert(7039518, "expected value of type 'Array'", tagAccArr == value::TypeTags::Array);
- auto accArr = value::getArrayView(valAccArr);
-
- auto [tagNewArray, valNewArray] = newArr->getAt(static_cast<size_t>(AggArrayWithSize::kValues));
- tassert(7039519, "expected value of type 'Array'", tagNewArray == value::TypeTags::Array);
-
- for (auto i = value::ArrayEnumerator{tagNewArray, valNewArray}; !i.atEnd(); i.advance()) {
- auto [elTag, elVal] = i.getViewOfValue();
- // TODO SERVER-71952: Since 'valNewArray' is owned here, in the future we could avoid this
- // copy by moving the element out of the array.
- auto [copyTag, copyVal] = value::copyValue(elTag, elVal);
- accArr->push_back(copyTag, copyVal);
- }
-
- accumulatorGuard.reset();
- return {ownArr, tagArr, valArr};
-}
-
std::pair<value::TypeTags, value::Value> ByteCode::genericIsMember(value::TypeTags lhsTag,
value::Value lhsVal,
value::TypeTags rhsTag,
@@ -3521,166 +3396,6 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinSetUnion(ArityT
return setUnion(argTags, argVals);
}
-std::tuple<bool, value::TypeTags, value::Value> ByteCode::aggSetUnionCappedImpl(
- value::TypeTags tagNewElem,
- value::Value valNewElem,
- int32_t sizeCap,
- CollatorInterface* collator) {
- value::ValueGuard guardNewElem{tagNewElem, valNewElem};
- auto [ownAcc, tagAcc, valAcc] = getFromStack(0);
-
- // We expect the new value we are adding to the accumulator to be a two-element array where
- // the first element is the new set of values and the second value is the corresponding size.
- tassert(7039526, "expected value of type 'Array'", tagNewElem == value::TypeTags::Array);
- auto newArr = value::getArrayView(valNewElem);
- tassert(7039528,
- "array had unexpected size",
- newArr->size() == static_cast<size_t>(AggArrayWithSize::kLast));
-
- // Create a new array is it does not exist yet.
- if (tagAcc == value::TypeTags::Nothing) {
- ownAcc = true;
- std::tie(tagAcc, valAcc) = value::makeNewArray();
- auto accArray = value::getArrayView(valAcc);
-
- auto [tagAccSet, valAccSet] = value::makeNewArraySet(collator);
-
- // The order is important! The accumulated array should be at index
- // AggArrayWithSize::kValues, and the size should be at index
- // AggArrayWithSize::kSizeOfValues.
- accArray->push_back(tagAccSet, valAccSet);
- accArray->push_back(value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(0));
- } else {
- // Take ownership of the accumulator.
- topStack(false, value::TypeTags::Nothing, 0);
- }
-
- tassert(7039520, "expected accumulator value to be owned", ownAcc);
- value::ValueGuard guardArr{tagAcc, valAcc};
-
- tassert(
- 7039521, "expected accumulator to be of type 'Array'", tagAcc == value::TypeTags::Array);
- auto accArray = value::getArrayView(valAcc);
- tassert(7039522,
- "array had unexpected size",
- accArray->size() == static_cast<size_t>(AggArrayWithSize::kLast));
-
- auto [tagAccArrSet, valAccArrSet] =
- accArray->getAt(static_cast<size_t>(AggArrayWithSize::kValues));
- tassert(
- 7039523, "expected value of type 'ArraySet'", tagAccArrSet == value::TypeTags::ArraySet);
- auto accArrSet = value::getArraySetView(valAccArrSet);
-
- // Extract the current size of the accumulator. As we add elements to the set, we will increment
- // the current size accordingly and throw an exception if we ever exceed the size limit. We
- // cannot simply sum the two sizes, since the two sets could have a substantial intersection.
- auto [tagAccSize, valAccSize] =
- accArray->getAt(static_cast<size_t>(AggArrayWithSize::kSizeOfValues));
- tassert(7039524, "expected 64-bit int", tagAccSize == value::TypeTags::NumberInt64);
- int64_t currentSize = value::bitcastTo<int64_t>(valAccSize);
-
- auto [tagNewValSet, valNewValSet] =
- newArr->getAt(static_cast<size_t>(AggArrayWithSize::kValues));
- tassert(
- 7039525, "expected value of type 'ArraySet'", tagNewValSet == value::TypeTags::ArraySet);
-
- for (auto i = value::ArrayEnumerator{tagNewValSet, valNewValSet}; !i.atEnd(); i.advance()) {
- auto [elTag, elVal] = i.getViewOfValue();
- int elemSize = value::getApproximateSize(elTag, elVal);
- // TODO SERVER-71952: Since 'valNewValSet' is owned here, in the future we could avoid this
- // copy by moving the element out of the array.
- auto [copyTag, copyVal] = value::copyValue(elTag, elVal);
- bool inserted = accArrSet->push_back(copyTag, copyVal);
-
- if (inserted) {
- currentSize += elemSize;
- if (currentSize >= static_cast<int64_t>(sizeCap)) {
- uasserted(ErrorCodes::ExceededMemoryLimit,
- str::stream() << "Used too much memory for a single array. Memory limit: "
- << sizeCap << ". Current set has " << accArrSet->size()
- << " elements and is " << currentSize << " bytes.");
- }
- }
- }
-
- // Update the accumulator with the new total size.
- accArray->setAt(static_cast<size_t>(AggArrayWithSize::kSizeOfValues),
- value::TypeTags::NumberInt64,
- value::bitcastFrom<int64_t>(currentSize));
-
- guardArr.reset();
- return {ownAcc, tagAcc, valAcc};
-}
-
-std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinAggSetUnion(ArityType arity) {
- auto [ownAcc, tagAcc, valAcc] = getFromStack(0);
-
- if (tagAcc == value::TypeTags::Nothing) {
- // Initialize the accumulator.
- ownAcc = true;
- std::tie(tagAcc, valAcc) = value::makeNewArraySet();
- } else {
- // Take ownership of the accumulator.
- topStack(false, value::TypeTags::Nothing, 0);
- }
-
- tassert(7039552, "accumulator must be owned", ownAcc);
- value::ValueGuard guardAcc{tagAcc, valAcc};
- tassert(7039553, "accumulator must be of type ArraySet", tagAcc == value::TypeTags::ArraySet);
- auto acc = value::getArraySetView(valAcc);
-
- auto [tagNewSet, valNewSet] = moveOwnedFromStack(1);
- value::ValueGuard guardNewSet{tagNewSet, valNewSet};
- if (!value::isArray(tagNewSet)) {
- return {false, value::TypeTags::Nothing, 0};
- }
-
- auto i = value::ArrayEnumerator{tagNewSet, valNewSet};
- while (!i.atEnd()) {
- auto [elTag, elVal] = i.getViewOfValue();
- auto [copyTag, copyVal] = value::copyValue(elTag, elVal);
- acc->push_back(copyTag, copyVal);
- i.advance();
- }
-
- guardAcc.reset();
- return {ownAcc, tagAcc, valAcc};
-}
-
-std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinAggSetUnionCapped(
- ArityType arity) {
- auto [tagNewElem, valNewElem] = moveOwnedFromStack(1);
- value::ValueGuard guardNewElem{tagNewElem, valNewElem};
-
- auto [_, tagSizeCap, valSizeCap] = getFromStack(2);
- tassert(7039509,
- "'cap' parameter must be a 32-bit int",
- tagSizeCap == value::TypeTags::NumberInt32);
- const size_t sizeCap = value::bitcastTo<int32_t>(valSizeCap);
-
- guardNewElem.reset();
- return aggSetUnionCappedImpl(tagNewElem, valNewElem, sizeCap, nullptr /*collator*/);
-}
-
-std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinAggCollSetUnionCapped(
- ArityType arity) {
- auto [_1, tagColl, valColl] = getFromStack(1);
- auto [tagNewElem, valNewElem] = moveOwnedFromStack(2);
- value::ValueGuard guardNewElem{tagNewElem, valNewElem};
- auto [_2, tagSizeCap, valSizeCap] = getFromStack(3);
-
- tassert(7039510, "expected value of type 'collator'", tagColl == value::TypeTags::collator);
- tassert(7039511,
- "'cap' parameter must be a 32-bit int",
- tagSizeCap == value::TypeTags::NumberInt32);
-
- guardNewElem.reset();
- return aggSetUnionCappedImpl(tagNewElem,
- valNewElem,
- value::bitcastTo<int32_t>(valSizeCap),
- value::getCollatorView(valColl));
-}
-
std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinCollSetIntersection(
ArityType arity) {
invariant(arity >= 1);
@@ -4667,7 +4382,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::dispatchBuiltin(Builti
case Builtin::doubleDoubleSum:
return builtinDoubleDoubleSum(arity);
case Builtin::aggDoubleDoubleSum:
- return builtinAggDoubleDoubleSum<false /*merging*/>(arity);
+ return builtinAggDoubleDoubleSum(arity);
case Builtin::doubleDoubleSumFinalize:
return builtinDoubleDoubleSumFinalize<>(arity);
case Builtin::doubleDoubleMergeSumFinalize:
@@ -4676,12 +4391,8 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::dispatchBuiltin(Builti
return builtinDoubleDoubleSumFinalize<true /*keepIntegerPrecision*/>(arity);
case Builtin::doubleDoublePartialSumFinalize:
return builtinDoubleDoublePartialSumFinalize(arity);
- case Builtin::aggMergeDoubleDoubleSums:
- return builtinAggDoubleDoubleSum<true /*merging*/>(arity);
case Builtin::aggStdDev:
- return builtinAggStdDev<false /*merging*/>(arity);
- case Builtin::aggMergeStdDevs:
- return builtinAggStdDev<true /*merging*/>(arity);
+ return builtinAggStdDev(arity);
case Builtin::stdDevPopFinalize:
return builtinStdDevPopFinalize(arity);
case Builtin::stdDevSampFinalize:
@@ -4734,16 +4445,6 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::dispatchBuiltin(Builti
return builtinRound(arity);
case Builtin::concat:
return builtinConcat(arity);
- case Builtin::concatArrays:
- return builtinConcatArrays(arity);
- case Builtin::aggConcatArraysCapped:
- return builtinAggConcatArraysCapped(arity);
- case Builtin::aggSetUnion:
- return builtinAggSetUnion(arity);
- case Builtin::aggSetUnionCapped:
- return builtinAggSetUnionCapped(arity);
- case Builtin::aggCollSetUnionCapped:
- return builtinAggCollSetUnionCapped(arity);
case Builtin::isMember:
return builtinIsMember(arity);
case Builtin::collIsMember:
diff --git a/src/mongo/db/exec/sbe/vm/vm.h b/src/mongo/db/exec/sbe/vm/vm.h
index e5148e8d4b2..255a1a497c2 100644
--- a/src/mongo/db/exec/sbe/vm/vm.h
+++ b/src/mongo/db/exec/sbe/vm/vm.h
@@ -511,33 +511,12 @@ enum class Builtin : uint8_t {
collAddToSet, // agg function to append to a set (with collation)
collAddToSetCapped, // agg function to append to a set (with collation), fails when the set
// reaches specified size
-
- // Special double summation.
- doubleDoubleSum,
- // A variant of the standard sum aggregate function which maintains a DoubleDouble as the
- // accumulator's underlying state.
+ doubleDoubleSum, // special double summation
aggDoubleDoubleSum,
- // Converts a DoubleDouble sum into a single numeric scalar for use once the summation is
- // complete.
doubleDoubleSumFinalize,
- // A form of doubleDoubleSum finalization only necessary for sharding support when the cluster
- // is not yet fully upgraded to FCV 6.0.
doubleDoubleMergeSumFinalize,
- // Converts a partial sum into a format suitable for serialization over the wire to the merging
- // node. The merging node expects the internal state of the DoubleDouble summation to be
- // serialized in a particular format.
doubleDoublePartialSumFinalize,
- // An agg function which can be used to sum a sequence of DoubleDouble inputs, producing the
- // resulting total as a DoubleDouble.
- aggMergeDoubleDoubleSums,
-
- // Implements Welford's online algorithm for computing sample or population standard deviation
- // in a single pass.
aggStdDev,
- // Combines standard deviations that have been partially computed on a subset of the data
- // using Welford's online algorithm.
- aggMergeStdDevs,
-
stdDevPopFinalize,
stdDevSampFinalize,
bitTestZero, // test bitwise mask & value is zero
@@ -548,18 +527,6 @@ enum class Builtin : uint8_t {
toLower,
coerceToString,
concat,
- concatArrays,
-
- // Agg function to concatenate arrays, failing when the accumulator reaches a specified size.
- aggConcatArraysCapped,
-
- // Agg functions to compute the set union of two arrays, failing when the accumulator reaches a
- // specified size.
- aggSetUnionCapped,
- aggCollSetUnionCapped,
- // Agg function for a simple set union (with no size cap or collation).
- aggSetUnion,
-
acos,
acosh,
asin,
@@ -1013,19 +980,11 @@ private:
value::TypeTags fieldTag,
value::Value fieldValue);
- void aggDoubleDoubleSumImpl(value::Array* accumulator,
- value::TypeTags rhsTag,
- value::Value rhsValue);
- void aggMergeDoubleDoubleSumsImpl(value::Array* accumulator,
- value::TypeTags rhsTag,
- value::Value rhsValue);
+ void aggDoubleDoubleSumImpl(value::Array* arr, value::TypeTags rhsTag, value::Value rhsValue);
// This is an implementation of the following algorithm:
// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm
- void aggStdDevImpl(value::Array* accumulator, value::TypeTags rhsTag, value::Value rhsValue);
- void aggMergeStdDevsImpl(value::Array* accumulator,
- value::TypeTags rhsTag,
- value::Value rhsValue);
+ void aggStdDevImpl(value::Array* arr, value::TypeTags rhsTag, value::Value rhsValue);
std::tuple<bool, value::TypeTags, value::Value> aggStdDevFinalizeImpl(value::Value fieldValue,
bool isSamp);
@@ -1144,24 +1103,14 @@ private:
CollatorInterface* collator);
std::tuple<bool, value::TypeTags, value::Value> builtinAddToSetCapped(ArityType arity);
std::tuple<bool, value::TypeTags, value::Value> builtinCollAddToSetCapped(ArityType arity);
-
std::tuple<bool, value::TypeTags, value::Value> builtinDoubleDoubleSum(ArityType arity);
- // The template parameter is false for a regular DoubleDouble summation and true if merging
- // partially computed DoubleDouble sums.
- template <bool merging>
std::tuple<bool, value::TypeTags, value::Value> builtinAggDoubleDoubleSum(ArityType arity);
-
// This is only for compatibility with mongos/sharding and we will revisit this later.
template <bool keepIntegerPrecision = false>
std::tuple<bool, value::TypeTags, value::Value> builtinDoubleDoubleSumFinalize(ArityType arity);
std::tuple<bool, value::TypeTags, value::Value> builtinDoubleDoublePartialSumFinalize(
ArityType arity);
-
- // The template parameter is false for a regular std dev and true if merging partially computed
- // standard devations.
- template <bool merging>
std::tuple<bool, value::TypeTags, value::Value> builtinAggStdDev(ArityType arity);
-
std::tuple<bool, value::TypeTags, value::Value> builtinStdDevPopFinalize(ArityType arity);
std::tuple<bool, value::TypeTags, value::Value> builtinStdDevSampFinalize(ArityType arity);
std::tuple<bool, value::TypeTags, value::Value> builtinBitTestZero(ArityType arity);
@@ -1188,16 +1137,6 @@ private:
std::tuple<bool, value::TypeTags, value::Value> builtinTanh(ArityType arity);
std::tuple<bool, value::TypeTags, value::Value> builtinRound(ArityType arity);
std::tuple<bool, value::TypeTags, value::Value> builtinConcat(ArityType arity);
- std::tuple<bool, value::TypeTags, value::Value> builtinConcatArrays(ArityType arity);
- std::tuple<bool, value::TypeTags, value::Value> builtinAggConcatArraysCapped(ArityType arity);
- std::tuple<bool, value::TypeTags, value::Value> builtinAggSetUnion(ArityType arity);
- std::tuple<bool, value::TypeTags, value::Value> builtinAggSetUnionCapped(ArityType arity);
- std::tuple<bool, value::TypeTags, value::Value> builtinAggCollSetUnionCapped(ArityType arity);
- std::tuple<bool, value::TypeTags, value::Value> aggSetUnionCappedImpl(
- value::TypeTags tagNewElem,
- value::Value valNewElem,
- int32_t sizeCap,
- CollatorInterface* collator);
std::tuple<bool, value::TypeTags, value::Value> builtinIsMember(ArityType arity);
std::tuple<bool, value::TypeTags, value::Value> builtinCollIsMember(ArityType arity);
std::tuple<bool, value::TypeTags, value::Value> builtinIndexOfBytes(ArityType arity);