summaryrefslogtreecommitdiff
path: root/src/mongo/db/matcher/expression_algo_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/matcher/expression_algo_test.cpp')
-rw-r--r--src/mongo/db/matcher/expression_algo_test.cpp54
1 files changed, 49 insertions, 5 deletions
diff --git a/src/mongo/db/matcher/expression_algo_test.cpp b/src/mongo/db/matcher/expression_algo_test.cpp
index 95e7bcd62fc..ead421bc76e 100644
--- a/src/mongo/db/matcher/expression_algo_test.cpp
+++ b/src/mongo/db/matcher/expression_algo_test.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/matcher/expression_parser.h"
#include "mongo/db/matcher/extensions_callback_disallow_extensions.h"
#include "mongo/db/matcher/extensions_callback_noop.h"
+#include "mongo/db/query/collation/collator_interface_mock.h"
#include "mongo/platform/decimal128.h"
namespace mongo {
@@ -51,8 +52,8 @@ using std::unique_ptr;
*/
class ParsedMatchExpression {
public:
- ParsedMatchExpression(const std::string& str) : _obj(fromjson(str)) {
- const CollatorInterface* collator = nullptr;
+ ParsedMatchExpression(const std::string& str, const CollatorInterface* collator = nullptr)
+ : _obj(fromjson(str)) {
StatusWithMatchExpression result =
MatchExpressionParser::parse(_obj, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(result.getStatus());
@@ -489,9 +490,6 @@ TEST(ExpressionAlgoIsSubsetOf, RegexAndIn) {
ParsedMatchExpression inRegexAOrEq1("{x: {$in: [/a/, 1]}}");
ParsedMatchExpression inRegexAOrNull("{x: {$in: [/a/, null]}}");
- ASSERT_TRUE(expression::isSubsetOf(inRegexA.get(), inRegexA.get()));
- ASSERT_FALSE(expression::isSubsetOf(inRegexAbc.get(), inRegexA.get()));
- ASSERT_FALSE(expression::isSubsetOf(inRegexA.get(), inRegexAOrEq1.get()));
ASSERT_FALSE(expression::isSubsetOf(inRegexAOrEq1.get(), eq1.get()));
ASSERT_FALSE(expression::isSubsetOf(inRegexA.get(), eqA.get()));
ASSERT_FALSE(expression::isSubsetOf(inRegexAOrNull.get(), eqA.get()));
@@ -652,6 +650,52 @@ TEST(ExpressionAlgoIsSubsetOf, Compare_Exists_NE) {
ASSERT_TRUE(expression::isSubsetOf(aNotEqualNull.get(), aExists.get()));
}
+TEST(ExpressionAlgoIsSubsetOf, CollationAwareStringComparison) {
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
+ ParsedMatchExpression lhs("{a: {$gt: 'abc'}}", &collator);
+ ParsedMatchExpression rhs("{a: {$gt: 'cba'}}", &collator);
+
+ ASSERT_TRUE(expression::isSubsetOf(lhs.get(), rhs.get()));
+
+ ParsedMatchExpression lhsLT("{a: {$lt: 'abc'}}", &collator);
+ ParsedMatchExpression rhsLT("{a: {$lt: 'cba'}}", &collator);
+
+ ASSERT_FALSE(expression::isSubsetOf(lhsLT.get(), rhsLT.get()));
+}
+
+TEST(ExpressionAlgoIsSubsetOf, CollationAwareStringComparisonIn) {
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
+ ParsedMatchExpression lhsAllGTcba("{a: {$in: ['abc', 'cbc']}}", &collator);
+ ParsedMatchExpression lhsSomeGTcba("{a: {$in: ['abc', 'aba']}}", &collator);
+ ParsedMatchExpression rhs("{a: {$gt: 'cba'}}", &collator);
+
+ ASSERT_TRUE(expression::isSubsetOf(lhsAllGTcba.get(), rhs.get()));
+ ASSERT_FALSE(expression::isSubsetOf(lhsSomeGTcba.get(), rhs.get()));
+
+ ParsedMatchExpression rhsLT("{a: {$lt: 'cba'}}", &collator);
+
+ ASSERT_FALSE(expression::isSubsetOf(lhsAllGTcba.get(), rhsLT.get()));
+ ASSERT_FALSE(expression::isSubsetOf(lhsSomeGTcba.get(), rhsLT.get()));
+}
+
+TEST(ExpressionAlgoIsSubsetOf, NonMatchingCollationsNoStringComparisonLHS) {
+ CollatorInterfaceMock collatorAlwaysEqual(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ CollatorInterfaceMock collatorReverseString(CollatorInterfaceMock::MockType::kReverseString);
+ ParsedMatchExpression lhs("{a: {b: 1}}", &collatorAlwaysEqual);
+ ParsedMatchExpression rhs("{a: {$lt: {b: 'abc'}}}", &collatorReverseString);
+
+ ASSERT_TRUE(expression::isSubsetOf(lhs.get(), rhs.get()));
+}
+
+TEST(ExpressionAlgoIsSubsetOf, NonMatchingCollationsNoStringComparison) {
+ CollatorInterfaceMock collatorAlwaysEqual(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ CollatorInterfaceMock collatorReverseString(CollatorInterfaceMock::MockType::kReverseString);
+ ParsedMatchExpression lhs("{a: 1}", &collatorAlwaysEqual);
+ ParsedMatchExpression rhs("{a: {$gt: 0}}", &collatorReverseString);
+
+ ASSERT_TRUE(expression::isSubsetOf(lhs.get(), rhs.get()));
+}
+
TEST(IsIndependent, AndIsIndependentOnlyIfChildrenAre) {
BSONObj matchPredicate = fromjson("{$and: [{a: 1}, {b: 1}]}");
const CollatorInterface* collator = nullptr;