summaryrefslogtreecommitdiff
path: root/src/mongo/db/query
diff options
context:
space:
mode:
authorNicholas Zolnierz <nicholas.zolnierz@mongodb.com>2022-08-03 16:08:42 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-08-03 17:22:30 +0000
commitc9bbd1cfae470f2b3229e69957f512d2a2db6663 (patch)
tree1176c9ce875b1abfd346b1614c96608d6a7ee434 /src/mongo/db/query
parent970a89221d0520693bc64bb33df6b1bf66d7c56d (diff)
downloadmongo-c9bbd1cfae470f2b3229e69957f512d2a2db6663.tar.gz
SERVER-62042 Consolidate query optimization and execution control into a single knob
Diffstat (limited to 'src/mongo/db/query')
-rw-r--r--src/mongo/db/query/SConscript1
-rw-r--r--src/mongo/db/query/canonical_query.cpp4
-rw-r--r--src/mongo/db/query/canonical_query_encoder_test.cpp42
-rw-r--r--src/mongo/db/query/framework_control.cpp45
-rw-r--r--src/mongo/db/query/plan_cache_key_info_test.cpp5
-rw-r--r--src/mongo/db/query/query_knobs.idl44
-rw-r--r--src/mongo/db/query/query_planner_columnar_test.cpp3
7 files changed, 102 insertions, 42 deletions
diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript
index f25c387d64f..bb5e3047085 100644
--- a/src/mongo/db/query/SConscript
+++ b/src/mongo/db/query/SConscript
@@ -261,6 +261,7 @@ env.Library(
target="query_knobs",
source=[
'ce_mode_parameter.cpp',
+ 'framework_control.cpp',
'plan_cache_size_parameter.cpp',
'query_feature_flags.idl',
'query_knobs.idl',
diff --git a/src/mongo/db/query/canonical_query.cpp b/src/mongo/db/query/canonical_query.cpp
index f6f69af1605..bbd7c68a21b 100644
--- a/src/mongo/db/query/canonical_query.cpp
+++ b/src/mongo/db/query/canonical_query.cpp
@@ -191,7 +191,9 @@ Status CanonicalQuery::init(OperationContext* opCtx,
_findCommand = std::move(findCommand);
_canHaveNoopMatchNodes = canHaveNoopMatchNodes;
- _forceClassicEngine = internalQueryForceClassicEngine.load();
+ _forceClassicEngine = ServerParameterSet::getNodeParameterSet()
+ ->get<QueryFrameworkControl>("internalQueryFrameworkControl")
+ ->_data.get() == QueryFrameworkControlEnum::kForceClassicEngine;
auto validStatus = isValid(root.get(), *_findCommand);
if (!validStatus.isOK()) {
diff --git a/src/mongo/db/query/canonical_query_encoder_test.cpp b/src/mongo/db/query/canonical_query_encoder_test.cpp
index 359a50ab625..6b814fd91b9 100644
--- a/src/mongo/db/query/canonical_query_encoder_test.cpp
+++ b/src/mongo/db/query/canonical_query_encoder_test.cpp
@@ -172,8 +172,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKey) {
// The computed key depends on which execution engine is enabled. As such, we disable SBE for
// this test so that the test doesn't break should the default value of
- // 'internalQueryForceClassicEngine' change in the future.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true);
+ // 'internalQueryFrameworkControl' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "forceClassicEngine");
// No sorts
testComputeKey("{}", "{}", "{}", "an@f");
@@ -247,8 +248,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKey) {
TEST(CanonicalQueryEncoderTest, EncodeNotEqualNullPredicates) {
// The computed key depends on which execution engine is enabled. As such, we disable SBE for
// this test so that the test doesn't break should the default value of
- // 'internalQueryForceClassicEngine' change in the future.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true);
+ // 'internalQueryFrameworkControl' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "forceClassicEngine");
// With '$eq', '$gte', and '$lte' negation comparison to 'null'.
testComputeKey("{a: {$not: {$eq: null}}}", "{}", "{_id: 0, a: 1}", "ntnot_eq_null[eqa]|a@f");
@@ -268,8 +270,9 @@ TEST(CanonicalQueryEncoderTest, EncodeNotEqualNullPredicates) {
TEST(CanonicalQueryEncoderTest, ComputeKeyEscaped) {
// The computed key depends on which execution engine is enabled. As such, we disable SBE for
// this test so that the test doesn't break should the default value of
- // 'internalQueryForceClassicEngine' change in the future.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true);
+ // 'internalQueryFrameworkControl' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "forceClassicEngine");
// Field name in query.
testComputeKey("{'a,[]~|-<>': 1}", "{}", "{}", "eqa\\,\\[\\]\\~\\|\\-<>@f");
@@ -304,8 +307,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKeyGeoWithin) {
TEST(CanonicalQueryEncoderTest, ComputeKeyGeoNear) {
// The computed key depends on which execution engine is enabled. As such, we disable SBE for
// this test so that the test doesn't break should the default value of
- // 'internalQueryForceClassicEngine' change in the future.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true);
+ // 'internalQueryFrameworkControl' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "forceClassicEngine");
testComputeKey("{a: {$near: [0,0], $maxDistance:0.3 }}", "{}", "{}", "gnanrfl@f");
testComputeKey("{a: {$nearSphere: [0,0], $maxDistance: 0.31 }}", "{}", "{}", "gnanssp@f");
@@ -320,7 +324,8 @@ TEST(CanonicalQueryEncoderTest, ComputeKeyGeoNear) {
TEST(CanonicalQueryEncoderTest, ComputeKeyRegexDependsOnFlags) {
// The computed key depends on which execution engine is enabled. As such, we enable SBE for
// this test in order to ensure that we have coverage for both SBE and the classic engine.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", false);
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "trySbeEngine");
testComputeKey("{a: {$regex: \"sometext\"}}", "{}", "{}", "rea@t");
testComputeKey("{a: {$regex: \"sometext\", $options: \"\"}}", "{}", "{}", "rea@t");
@@ -353,8 +358,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKeyRegexDependsOnFlags) {
TEST(CanonicalQueryEncoderTest, ComputeKeyMatchInDependsOnPresenceOfRegexAndFlags) {
// The computed key depends on which execution engine is enabled. As such, we disable SBE for
// this test so that the test doesn't break should the default value of
- // 'internalQueryForceClassicEngine' change in the future.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true);
+ // 'internalQueryFrameworkControl' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "forceClassicEngine");
// Test that an $in containing a single regex is unwrapped to $regex.
testComputeKey("{a: {$in: [/foo/]}}", "{}", "{}", "rea@f");
@@ -403,8 +409,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKeyMatchInDependsOnPresenceOfRegexAndFlag
TEST(CanonicalQueryEncoderTest, CheckCollationIsEncoded) {
// The computed key depends on which execution engine is enabled. As such, we disable SBE for
// this test so that the test doesn't break should the default value of
- // 'internalQueryForceClassicEngine' change in the future.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true);
+ // 'internalQueryFrameworkControl' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "forceClassicEngine");
unique_ptr<CanonicalQuery> cq(canonicalize(
fromjson("{a: 1, b: 1}"), {}, {}, fromjson("{locale: 'mock_reverse_string'}")));
@@ -416,7 +423,8 @@ TEST(CanonicalQueryEncoderTest, ComputeKeySBE) {
// Generated cache keys should be treated as opaque to the user.
// SBE must be enabled in order to generate SBE plan cache keys.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", false);
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "trySbeEngine");
RAIIServerParameterControllerForTest controllerSBEPlanCache("featureFlagSbeFull", true);
@@ -534,7 +542,8 @@ TEST(CanonicalQueryEncoderTest, ComputeKeySBE) {
TEST(CanonicalQueryEncoderTest, ComputeKeySBEWithPipeline) {
// SBE must be enabled in order to generate SBE plan cache keys.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", false);
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "trySbeEngine");
RAIIServerParameterControllerForTest controllerSBEPlanCache("featureFlagSbeFull", true);
@@ -595,7 +604,8 @@ TEST(CanonicalQueryEncoderTest, ComputeKeySBEWithPipeline) {
TEST(CanonicalQueryEncoderTest, ComputeKeySBEWithReadConcern) {
// SBE must be enabled in order to generate SBE plan cache keys.
- RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", false);
+ RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl",
+ "trySbeEngine");
RAIIServerParameterControllerForTest controllerSBEPlanCache("featureFlagSbeFull", true);
const auto sbeEncodingWithoutReadConcernAvailable =
diff --git a/src/mongo/db/query/framework_control.cpp b/src/mongo/db/query/framework_control.cpp
new file mode 100644
index 00000000000..cd35264a9b3
--- /dev/null
+++ b/src/mongo/db/query/framework_control.cpp
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2022-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/query/query_knobs_gen.h"
+
+namespace mongo {
+
+void QueryFrameworkControl::append(OperationContext*, BSONObjBuilder& b, const std::string& name) {
+ b << name << QueryFrameworkControl_serializer(_data.get());
+}
+
+Status QueryFrameworkControl::setFromString(const std::string& value) {
+ _data = QueryFrameworkControl_parse(IDLParserContext("internalQueryFrameworkControl"), value);
+ return Status::OK();
+}
+
+} // namespace mongo
diff --git a/src/mongo/db/query/plan_cache_key_info_test.cpp b/src/mongo/db/query/plan_cache_key_info_test.cpp
index 7235386e7f4..824fdf9dc37 100644
--- a/src/mongo/db/query/plan_cache_key_info_test.cpp
+++ b/src/mongo/db/query/plan_cache_key_info_test.cpp
@@ -422,8 +422,9 @@ TEST(PlanCacheKeyInfoTest, DifferentQueryEngines) {
// Helper to construct a plan cache key given the 'forceClassicEngine' flag.
auto constructPlanCacheKey = [&](bool forceClassicEngine) {
- RAIIServerParameterControllerForTest controller{"internalQueryForceClassicEngine",
- forceClassicEngine};
+ RAIIServerParameterControllerForTest controller{"internalQueryFrameworkControl",
+ forceClassicEngine ? "forceClassicEngine"
+ : "trySbeEngine"};
const auto queryStr = "{a: 0}";
unique_ptr<CanonicalQuery> cq(canonicalize(queryStr));
return makeKey(*cq, indexCores);
diff --git a/src/mongo/db/query/query_knobs.idl b/src/mongo/db/query/query_knobs.idl
index 831334ed790..422ffea63ff 100644
--- a/src/mongo/db/query/query_knobs.idl
+++ b/src/mongo/db/query/query_knobs.idl
@@ -35,6 +35,21 @@ global:
- "mongo/platform/atomic_proxy.h"
- "mongo/platform/atomic_word.h"
+enums:
+ QueryFrameworkControl:
+ description: "Enum for possible values of internalQueryFrameworkControl."
+ type: string
+ values:
+ # Force the classic query engine for all queries.
+ kForceClassicEngine: "forceClassicEngine"
+ # Attempt to use SBE for eligible queries, otherwise fallback to the classic engine.
+ kTrySbeEngine: "trySbeEngine"
+ # Attempt to use the Bonsai optimizer and lower to SBE for eligible queries, otherwise
+ # fallback to "trySbeEngine".
+ kTryBonsai: "tryBonsai"
+ # Force the Bonsai optimizer for all queries.
+ kForceBonsai: "forceBonsai"
+
server_parameters:
#
@@ -656,14 +671,6 @@ server_parameters:
default: false
on_update: plan_cache_util::clearSbeCacheOnParameterChange
- internalQueryForceClassicEngine:
- description: "If true, the system will use the classic execution engine for all queries,
- otherwise eligible queries will execute using the SBE execution engine."
- set_at: [ startup, runtime ]
- cpp_varname: "internalQueryForceClassicEngine"
- cpp_vartype: AtomicWord<bool>
- default: false
-
internalQueryAppendIdToSetWindowFieldsSort:
description: "If true, appends _id to the sort stage generated by desugaring $setWindowFields to
ensure deterministic sort order."
@@ -726,14 +733,6 @@ server_parameters:
validator:
callback: ce::validateCEMode
- internalQueryEnableCascadesOptimizer:
- description: "Set to use the new optimizer path, must be used in conjunction with the feature
- flag."
- set_at: [ startup, runtime ]
- cpp_varname: "internalQueryEnableCascadesOptimizer"
- cpp_vartype: AtomicWord<bool>
- default: true
-
internalCascadesOptimizerDisableScan:
description: "Disable full collection scans in the Cascades optimizer."
set_at: [ startup, runtime ]
@@ -784,13 +783,14 @@ server_parameters:
cpp_vartype: AtomicWord<bool>
default: false
- internalQueryForceCommonQueryFramework:
- description: "Set to always use the bonsai optimizer, regardless of the query."
+ internalQueryFrameworkControl:
+ description: "Knob to control the optimizer/execution engine to use."
set_at: [ startup, runtime ]
- cpp_varname: "internalQueryForceCommonQueryFramework"
- cpp_vartype: AtomicWord<bool>
- test_only: true
- default: false
+ cpp_class:
+ name: QueryFrameworkControl
+ data: synchronized_value<QueryFrameworkControlEnum>
+ default:
+ expr: QueryFrameworkControlEnum::kTryBonsai
internalQueryCollectionMaxNoOfDocumentsToChooseHashJoin:
description: "Up to what number of documents do we choose the hash join algorithm when $lookup
diff --git a/src/mongo/db/query/query_planner_columnar_test.cpp b/src/mongo/db/query/query_planner_columnar_test.cpp
index aeb3f26b69f..f576e8f6cd5 100644
--- a/src/mongo/db/query/query_planner_columnar_test.cpp
+++ b/src/mongo/db/query/query_planner_columnar_test.cpp
@@ -85,7 +85,8 @@ protected:
private:
// SBE must be enabled in order to test columnar indexes.
- RAIIServerParameterControllerForTest _controllerSBE{"internalQueryForceClassicEngine", false};
+ RAIIServerParameterControllerForTest _controllerSBE{"internalQueryFrameworkControl",
+ "trySbeEngine"};
};
TEST_F(QueryPlannerColumnarTest, InclusionProjectionUsesColumnarIndex) {