summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorAlexander Ignatyev <alexander.ignatyev@mongodb.com>2022-04-26 18:01:18 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-26 19:47:33 +0000
commit9ca1d39e1ad5317bf3e8dcbef937f165f991d74c (patch)
treea794ee1bea2a3dde24b3e1001dd5932f49dec560 /src/mongo/db
parent220004ef366d4ac10fc05a9c4a09224008889198 (diff)
downloadmongo-9ca1d39e1ad5317bf3e8dcbef937f165f991d74c.tar.gz
SERVER-65793 Do not parameterize queries with TEXT match expression node
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/query/canonical_query.cpp18
-rw-r--r--src/mongo/db/query/canonical_query_encoder.cpp52
-rw-r--r--src/mongo/db/query/canonical_query_test.cpp14
3 files changed, 68 insertions, 16 deletions
diff --git a/src/mongo/db/query/canonical_query.cpp b/src/mongo/db/query/canonical_query.cpp
index 7c4830be8ca..f3d5c53c483 100644
--- a/src/mongo/db/query/canonical_query.cpp
+++ b/src/mongo/db/query/canonical_query.cpp
@@ -47,6 +47,7 @@
#include "mongo/db/query/indexability.h"
#include "mongo/db/query/projection_parser.h"
#include "mongo/db/query/query_planner_common.h"
+#include "mongo/logv2/log.h"
namespace mongo {
namespace {
@@ -201,10 +202,19 @@ Status CanonicalQuery::init(OperationContext* opCtx,
auto unavailableMetadata = validStatus.getValue();
_root = MatchExpression::normalize(std::move(root));
if (feature_flags::gFeatureFlagSbePlanCache.isEnabledAndIgnoreFCV()) {
- // When the SBE plan cache is enabled, we auto-parameterize queries in the hopes of caching
- // a parameterized plan. Here we add parameter markers to the appropriate match expression
- // leaf nodes.
- _inputParamIdToExpressionMap = MatchExpression::parameterize(_root.get());
+ const bool hasNoTextNodes =
+ !QueryPlannerCommon::hasNode(_root.get(), MatchExpression::TEXT);
+ if (hasNoTextNodes) {
+ // When the SBE plan cache is enabled, we auto-parameterize queries in the hopes of
+ // caching a parameterized plan. Here we add parameter markers to the appropriate match
+ // expression leaf nodes.
+ _inputParamIdToExpressionMap = MatchExpression::parameterize(_root.get());
+ } else {
+ LOGV2_DEBUG(6579310,
+ 5,
+ "The query was not auto-parameterized since its match expression tree "
+ "contains TEXT nodes");
+ }
}
// The tree must always be valid after normalization.
dassert(isValid(_root.get(), *_findCommand).isOK());
diff --git a/src/mongo/db/query/canonical_query_encoder.cpp b/src/mongo/db/query/canonical_query_encoder.cpp
index ee6efa914b1..c03d5ee2e88 100644
--- a/src/mongo/db/query/canonical_query_encoder.cpp
+++ b/src/mongo/db/query/canonical_query_encoder.cpp
@@ -724,21 +724,39 @@ public:
void visit(const ModMatchExpression* expr) final {
auto divisorParam = expr->getDivisorInputParamId();
auto remainderParam = expr->getRemainderInputParamId();
- tassert(6512901, "$mod expression should have divisor param", divisorParam);
- tassert(6512902, "$mod expression should have remainder param", remainderParam);
+ if (divisorParam) {
+ tassert(6512902,
+ "$mod expression should have divisor and remainder params",
+ remainderParam);
- encodeParamMarker(*divisorParam);
- encodeParamMarker(*remainderParam);
+ encodeParamMarker(*divisorParam);
+ encodeParamMarker(*remainderParam);
+ } else {
+ tassert(6579300,
+ "If divisor param is not set in $mod expression reminder param must be unset "
+ "as well",
+ !remainderParam);
+ encodeFull(expr);
+ }
}
void visit(const RegexMatchExpression* expr) final {
auto sourceRegexParam = expr->getSourceRegexInputParamId();
auto compiledRegexParam = expr->getCompiledRegexInputParamId();
- tassert(6512903, "regex expression should have source param", sourceRegexParam);
- tassert(6512904, "regex expression should have compiled param", compiledRegexParam);
+ if (sourceRegexParam) {
+ tassert(6512904,
+ "regex expression should have source and compiled params",
+ compiledRegexParam);
- encodeParamMarker(*sourceRegexParam);
- encodeParamMarker(*compiledRegexParam);
+ encodeParamMarker(*sourceRegexParam);
+ encodeParamMarker(*compiledRegexParam);
+ } else {
+ tassert(6579301,
+ "If source param is not set in $regex expression compiled param must be unset "
+ "as well",
+ !compiledRegexParam);
+ encodeFull(expr);
+ }
}
void visit(const SizeMatchExpression* expr) final {
@@ -898,11 +916,21 @@ private:
void encodeBitTestExpression(const BitTestMatchExpression* expr) {
auto bitPositionsParam = expr->getBitPositionsParamId();
auto bitMaskParam = expr->getBitMaskParamId();
- tassert(6512905, "bit-test expression should have bit positions param", bitPositionsParam);
- tassert(6512906, "$mod expression should have bitmask param", bitMaskParam);
+ if (bitPositionsParam) {
+
+ tassert(6512906,
+ "bit-test expression should have bit positions and bitmask params",
+ bitMaskParam);
- encodeParamMarker(*bitPositionsParam);
- encodeParamMarker(*bitMaskParam);
+ encodeParamMarker(*bitPositionsParam);
+ encodeParamMarker(*bitMaskParam);
+ } else {
+ tassert(6579302,
+ "If positions param is not set in a bit-test expression bitmask param must be "
+ "unset as well",
+ !bitMaskParam);
+ encodeFull(expr);
+ }
}
/**
diff --git a/src/mongo/db/query/canonical_query_test.cpp b/src/mongo/db/query/canonical_query_test.cpp
index 3d5f27431a9..dbb2fd929da 100644
--- a/src/mongo/db/query/canonical_query_test.cpp
+++ b/src/mongo/db/query/canonical_query_test.cpp
@@ -34,6 +34,7 @@
#include "mongo/db/query/collation/collator_factory_interface.h"
#include "mongo/db/query/collation/collator_interface_mock.h"
#include "mongo/db/query/query_test_service_context.h"
+#include "mongo/idl/server_parameter_test_util.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
@@ -454,5 +455,18 @@ TEST(CanonicalQueryTest, InvalidSortOrdersFailToCanonicalize) {
assertInvalidSortOrder(fromjson("{'': -1}"));
}
+TEST(CanonicalQueryTest, DoNotParameterizeTextExpressions) {
+ RAIIServerParameterControllerForTest controllerSBEPlanCache("featureFlagSbePlanCache", true);
+ auto cq =
+ canonicalize("{$text: {$search: \"Hello World!\"}}",
+ MatchExpressionParser::kDefaultSpecialFeatures | MatchExpressionParser::kText);
+ ASSERT_FALSE(cq->isParameterized());
+}
+
+TEST(CanonicalQueryTest, DoParameterizeRegularExpressions) {
+ RAIIServerParameterControllerForTest controllerSBEPlanCache("featureFlagSbePlanCache", true);
+ auto cq = canonicalize("{a: 1, b: {$lt: 5}}");
+ ASSERT_TRUE(cq->isParameterized());
+}
} // namespace
} // namespace mongo