summaryrefslogtreecommitdiff
path: root/src/mongo/db/matcher/expression_leaf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/matcher/expression_leaf.cpp')
-rw-r--r--src/mongo/db/matcher/expression_leaf.cpp111
1 files changed, 19 insertions, 92 deletions
diff --git a/src/mongo/db/matcher/expression_leaf.cpp b/src/mongo/db/matcher/expression_leaf.cpp
index 721b93c8da4..31157666e92 100644
--- a/src/mongo/db/matcher/expression_leaf.cpp
+++ b/src/mongo/db/matcher/expression_leaf.cpp
@@ -39,7 +39,6 @@
#include "mongo/bson/bsonmisc.h"
#include "mongo/bson/bsonobj.h"
#include "mongo/config.h"
-#include "mongo/db/exec/document_value/value.h"
#include "mongo/db/field_ref.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/matcher/expression_parser.h"
@@ -94,10 +93,8 @@ void ComparisonMatchExpressionBase::debugString(StringBuilder& debug, int indent
debug << "\n";
}
-void ComparisonMatchExpressionBase::appendSerializedRightHandSide(BSONObjBuilder* bob,
- const SerializationOptions& opts,
- bool includePath) const {
- opts.appendLiteral(bob, name(), _rhs);
+BSONObj ComparisonMatchExpressionBase::getSerializedRightHandSide() const {
+ return BSON(name() << _rhs);
}
ComparisonMatchExpression::ComparisonMatchExpression(MatchType type,
@@ -293,19 +290,15 @@ void RegexMatchExpression::debugString(StringBuilder& debug, int indentationLeve
debug << "\n";
}
-void RegexMatchExpression::appendSerializedRightHandSide(BSONObjBuilder* bob,
- const SerializationOptions& opts,
- bool includePath) const {
- // We need to be careful to generate a valid regex representative value, and the default string
- // "?" is not valid.
- opts.appendLiteral(bob, "$regex", _regex, Value("\\?"_sd));
+BSONObj RegexMatchExpression::getSerializedRightHandSide() const {
+ BSONObjBuilder regexBuilder;
+ regexBuilder.append("$regex", _regex);
if (!_flags.empty()) {
- // We need to make sure the $options value can be re-parsed as legal regex options, so
- // we'll set the representative value in this case to be the string "i" rather than
- // "?", which is the standard representative for string values.
- opts.appendLiteral(bob, "$options", _flags, Value("i"_sd));
+ regexBuilder.append("$options", _flags);
}
+
+ return regexBuilder.obj();
}
void RegexMatchExpression::serializeToBSONTypeRegex(BSONObjBuilder* out) const {
@@ -378,11 +371,8 @@ void ModMatchExpression::debugString(StringBuilder& debug, int indentationLevel)
debug << "\n";
}
-void ModMatchExpression::appendSerializedRightHandSide(BSONObjBuilder* bob,
- const SerializationOptions& opts,
- bool includePath) const {
- bob->append("$mod",
- BSON_ARRAY(opts.serializeLiteral(_divisor) << opts.serializeLiteral(_remainder)));
+BSONObj ModMatchExpression::getSerializedRightHandSide() const {
+ return BSON("$mod" << BSON_ARRAY(_divisor << _remainder));
}
bool ModMatchExpression::equivalent(const MatchExpression* other) const {
@@ -417,10 +407,8 @@ void ExistsMatchExpression::debugString(StringBuilder& debug, int indentationLev
debug << "\n";
}
-void ExistsMatchExpression::appendSerializedRightHandSide(BSONObjBuilder* bob,
- const SerializationOptions& opts,
- bool includePath) const {
- opts.appendLiteral(bob, "$exists", true);
+BSONObj ExistsMatchExpression::getSerializedRightHandSide() const {
+ return BSON("$exists" << true);
}
bool ExistsMatchExpression::equivalent(const MatchExpression* other) const {
@@ -446,7 +434,6 @@ std::unique_ptr<MatchExpression> InMatchExpression::shallowClone() const {
}
next->_hasNull = _hasNull;
next->_hasEmptyArray = _hasEmptyArray;
- next->_hasNonEmptyArrayOrObject = _hasNonEmptyArrayOrObject;
next->_equalitySet = _equalitySet;
next->_originalEqualityVector = _originalEqualityVector;
next->_equalityStorage = _equalityStorage;
@@ -502,45 +489,9 @@ void InMatchExpression::debugString(StringBuilder& debug, int indentationLevel)
debug << "\n";
}
-namespace {
-/**
- * Reduces the potentially large vector of elements to just the first of each "canonical" type.
- * Different types of numbers are not considered distinct.
- *
- * For example, collapses [2, 4, NumberInt(3), "string", "another", 3, 5] into just [2, "string"].
- */
-std::vector<Value> justFirstOfEachType(std::vector<BSONElement> elems) {
- stdx::unordered_set<int> seenTypes;
- std::vector<Value> result;
- for (auto&& elem : elems) {
- bool inserted = seenTypes.insert(canonicalizeBSONType(elem.type())).second;
- if (inserted) {
- // A new type.
- result.emplace_back(elem);
- }
- }
- return result;
-}
-} // namespace
-
-void InMatchExpression::serializeToShape(BSONObjBuilder* bob,
- const SerializationOptions& opts) const {
- std::vector<Value> firstOfEachType = justFirstOfEachType(_equalitySet);
- if (hasRegex()) {
- firstOfEachType.emplace_back(BSONRegEx());
- }
- opts.appendLiteral(bob, "$in", std::move(firstOfEachType));
-}
-
-void InMatchExpression::appendSerializedRightHandSide(BSONObjBuilder* bob,
- const SerializationOptions& opts,
- bool includePath) const {
- if (opts.literalPolicy != LiteralSerializationPolicy::kUnchanged) {
- serializeToShape(bob, opts);
- return;
- }
-
- BSONArrayBuilder arrBob(bob->subarrayStart("$in"));
+BSONObj InMatchExpression::getSerializedRightHandSide() const {
+ BSONObjBuilder inBob;
+ BSONArrayBuilder arrBob(inBob.subarrayStart("$in"));
for (auto&& _equality : _equalitySet) {
arrBob.append(_equality);
}
@@ -550,6 +501,7 @@ void InMatchExpression::appendSerializedRightHandSide(BSONObjBuilder* bob,
arrBob.append(regexBob.obj().firstElement());
}
arrBob.doneFast();
+ return inBob.obj();
}
bool InMatchExpression::equivalent(const MatchExpression* other) const {
@@ -625,8 +577,6 @@ Status InMatchExpression::setEqualities(std::vector<BSONElement> equalities) {
_hasNull = true;
} else if (equality.type() == BSONType::Array && equality.Obj().isEmpty()) {
_hasEmptyArray = true;
- } else if (equality.type() == BSONType::Array || equality.type() == BSONType::Object) {
- _hasNonEmptyArrayOrObject = true;
}
}
@@ -845,25 +795,6 @@ bool BitTestMatchExpression::matchesSingleElement(const BSONElement& e,
if (eDouble != static_cast<double>(static_cast<long long>(eDouble))) {
return false;
}
- } else if (e.type() == BSONType::NumberDecimal) {
- Decimal128 eDecimal = e.numberDecimal();
-
- // NaN NumberDecimals are rejected.
- if (eDecimal.isNaN()) {
- return false;
- }
-
- // NumberDecimals that are too large or small to be represented as a 64-bit signed
- // integer are treated as 0.
- if (eDecimal > Decimal128(std::numeric_limits<long long>::max()) ||
- eDecimal < Decimal128(std::numeric_limits<long long>::min())) {
- return false;
- }
-
- // This checks if e is an integral NumberDecimal.
- if (eDecimal != eDecimal.round(Decimal128::kRoundTowardZero)) {
- return false;
- }
}
long long eValue = e.numberLong();
@@ -908,9 +839,7 @@ void BitTestMatchExpression::debugString(StringBuilder& debug, int indentationLe
}
}
-void BitTestMatchExpression::appendSerializedRightHandSide(BSONObjBuilder* bob,
- const SerializationOptions& opts,
- bool includePath) const {
+BSONObj BitTestMatchExpression::getSerializedRightHandSide() const {
std::string opString = "";
switch (matchType()) {
@@ -935,10 +864,8 @@ void BitTestMatchExpression::appendSerializedRightHandSide(BSONObjBuilder* bob,
arrBob.append(static_cast<int32_t>(bitPosition));
}
arrBob.doneFast();
- // Unfortunately this cannot be done without copying the array into the BSONObjBuilder, since
- // `opts.appendLiteral` may choose to append this actual array, a representative empty array, or
- // a debug string.
- opts.appendLiteral(bob, opString, arrBob.arr());
+
+ return BSON(opString << arrBob.arr());
}
bool BitTestMatchExpression::equivalent(const MatchExpression* other) const {