summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Andrei <mihai.andrei@10gen.com>2022-05-17 02:12:58 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-05-17 02:38:30 +0000
commit7ed364e8922e42822c2d1bc2e41a66159eb7ddcb (patch)
tree02e786c32a59ea572097ab0e9269846dc1d664e1
parent252235fda4d45e85db342bb6437b1587b980b1ed (diff)
downloadmongo-7ed364e8922e42822c2d1bc2e41a66159eb7ddcb.tar.gz
SERVER-66445 Make the classic engine the default execution engine
(cherry picked from commit 40109e237a0ffaf41d26b5465920d12bc6a3f304)
-rw-r--r--buildscripts/resmokeconfig/suites/clustered_collection_passthrough.yml2
-rw-r--r--etc/evergreen.yml32
-rw-r--r--etc/generate_subtasks_config.yml4
-rw-r--r--jstests/concurrency/fsm_workloads/agg_lookup.js6
-rw-r--r--jstests/concurrency/fsm_workloads/find_flip_sbe_enabled.js56
-rw-r--r--jstests/libs/sbe_util.js15
-rw-r--r--jstests/multiVersion/targetedTestsLastContinuousFeatures/accumulator_fix_last_continuous.js30
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/accumulator_fix_last_lts.js13
-rw-r--r--jstests/noPassthrough/accumulator_bug_fix.js22
-rw-r--r--jstests/noPassthrough/agg_group.js8
-rw-r--r--jstests/noPassthrough/profile_operation_metrics.js10
-rw-r--r--jstests/noPassthrough/query_engine_stats.js6
-rw-r--r--jstests/noPassthrough/query_knobs_validation.js4
-rw-r--r--jstests/noPassthrough/sbe_multiplanner_trial_termination.js6
-rw-r--r--jstests/noPassthrough/sbe_plan_cache_key_reporting.js14
-rw-r--r--jstests/noPassthrough/sbe_plan_cache_memory_debug_info.js3
-rw-r--r--jstests/noPassthrough/sbe_plan_cache_size_metric.js5
-rw-r--r--jstests/noPassthrough/server_status_multiplanner.js5
-rw-r--r--jstests/noPassthroughWithMongod/group_pushdown.js18
-rw-r--r--jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js6
-rw-r--r--src/mongo/db/commands/plan_cache_clear_command.cpp2
-rw-r--r--src/mongo/db/pipeline/pipeline_d.cpp6
-rw-r--r--src/mongo/db/query/canonical_query.cpp4
-rw-r--r--src/mongo/db/query/canonical_query.h8
-rw-r--r--src/mongo/db/query/canonical_query_encoder.cpp2
-rw-r--r--src/mongo/db/query/canonical_query_encoder_test.cpp179
-rw-r--r--src/mongo/db/query/explain.cpp2
-rw-r--r--src/mongo/db/query/get_executor.cpp2
-rw-r--r--src/mongo/db/query/plan_cache_key_info_test.cpp8
-rw-r--r--src/mongo/db/query/query_knobs.idl8
-rw-r--r--src/mongo/db/query/query_planner.cpp2
-rw-r--r--src/mongo/db/query/query_planner_columnar_test.cpp7
-rw-r--r--src/mongo/dbtests/query_stage_multiplan.cpp3
-rw-r--r--src/mongo/shell/servers.js35
34 files changed, 322 insertions, 211 deletions
diff --git a/buildscripts/resmokeconfig/suites/clustered_collection_passthrough.yml b/buildscripts/resmokeconfig/suites/clustered_collection_passthrough.yml
index cb9f747aebb..b793210cb52 100644
--- a/buildscripts/resmokeconfig/suites/clustered_collection_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/clustered_collection_passthrough.yml
@@ -91,6 +91,6 @@ executor:
set_parameters:
enableTestCommands: 1
# SBE is not compatible with clustered collections
- internalQueryForceClassicEngine: 1
+ internalQueryEnableSlotBasedExecutionEngine: 0
failpoint.clusterAllCollectionsByDefault: "{mode: 'alwaysOn'}"
num_nodes: 2
diff --git a/etc/evergreen.yml b/etc/evergreen.yml
index 434bb4c7af6..9fc31a563f7 100644
--- a/etc/evergreen.yml
+++ b/etc/evergreen.yml
@@ -1613,16 +1613,16 @@ buildvariants:
# distros:
# - rhel80-large
-- &enterprise-rhel-80-64-bit-dynamic-classic-engine
- name: enterprise-rhel-80-64-bit-dynamic-classic-engine
- display_name: "Shared Library Enterprise RHEL 8.0 (Classic Engine)"
+- &enterprise-rhel-80-64-bit-dynamic-sbe-engine
+ name: enterprise-rhel-80-64-bit-dynamic-sbe-engine
+ display_name: "Shared Library Enterprise RHEL 8.0 (SBE Engine)"
cron: "0 4 * * *" # From the ${project_nightly_cron} parameter.
stepback: false
modules:
- enterprise
run_on:
- rhel80-small
- expansions: &enterprise-rhel-80-64-bit-dynamic-classic-engine-expansions
+ expansions: &enterprise-rhel-80-64-bit-dynamic-sbe-engine-expansions
additional_package_targets: archive-mongocryptd archive-mongocryptd-debug archive-mh archive-mh-debug
compile_flags: --ssl MONGO_DISTMOD=rhel80 -j$(grep -c ^processor /proc/cpuinfo) --variables-files=etc/scons/mongodbtoolchain_v3_gcc.vars --link-model=dynamic
multiversion_platform: rhel80
@@ -1638,7 +1638,7 @@ buildvariants:
burn_in_tag_buildvariants: enterprise-rhel-80-64-bit-inmem linux-64-duroff enterprise-rhel-80-64-bit-multiversion
num_scons_link_jobs_available: 0.99
test_flags: >-
- --mongodSetParameters="{internalQueryForceClassicEngine: true}"
+ --mongodSetParameters="{internalQueryEnableSlotBasedExecutionEngine: true}"
tasks:
- name: .aggfuzzer
- name: .aggregation
@@ -2350,8 +2350,8 @@ buildvariants:
# - name: server_discovery_and_monitoring_json_test_TG
# - name: server_selection_json_test_TG
-- name: rhel80-debug-asan-classic-engine
- display_name: ~ ASAN Enterprise RHEL 8.0 DEBUG (Classic Engine)
+- name: rhel80-debug-asan-sbe-engine
+ display_name: ~ ASAN Enterprise RHEL 8.0 DEBUG (SBE Engine)
cron: "0 4 * * *" # From the ${project_nightly_cron} parameter.
modules:
- enterprise
@@ -2366,7 +2366,7 @@ buildvariants:
san_options: LSAN_OPTIONS="suppressions=etc/lsan.suppressions:report_objects=1:external_symbolizer_path=/opt/mongodbtoolchain/v3/bin/llvm-symbolizer" ASAN_OPTIONS="detect_leaks=1:check_initialization_order=true:strict_init_order=true:abort_on_error=1:disable_coredump=0:handle_abort=1:external_symbolizer_path=/opt/mongodbtoolchain/v3/bin/llvm-symbolizer"
compile_flags: --variables-files=etc/scons/mongodbtoolchain_v3_clang.vars --dbg=on --opt=on --allocator=system --sanitize=address --ssl --ocsp-stapling=off --enable-free-mon=on -j$(grep -c ^processor /proc/cpuinfo)
test_flags: >-
- --mongodSetParameters="{internalQueryForceClassicEngine: true}"
+ --mongodSetParameters="{internalQueryEnableSlotBasedExecutionEngine: true}"
--excludeWithAnyTags=requires_fast_memory,requires_ocsp_stapling
multiversion_platform: rhel80
multiversion_edition: enterprise
@@ -2496,8 +2496,8 @@ buildvariants:
# - name: server_discovery_and_monitoring_json_test_TG
# - name: server_selection_json_test_TG
-- name: rhel80-debug-ubsan-classic-engine
- display_name: "~ UBSAN Enterprise RHEL 8.0 DEBUG (Classic Engine)"
+- name: rhel80-debug-ubsan-sbe-engine
+ display_name: "~ UBSAN Enterprise RHEL 8.0 DEBUG (SBE Engine)"
cron: "0 4 * * *" # From the ${project_nightly_cron} parameter.
modules:
- enterprise
@@ -2512,7 +2512,7 @@ buildvariants:
san_options: UBSAN_OPTIONS="print_stacktrace=1:external_symbolizer_path=/opt/mongodbtoolchain/v3/bin/llvm-symbolizer"
compile_flags: --variables-files=etc/scons/mongodbtoolchain_v3_clang.vars --dbg=on --opt=on --sanitize=undefined --ssl --ocsp-stapling=off --enable-free-mon=on -j$(grep -c ^processor /proc/cpuinfo)
test_flags: >-
- --mongodSetParameters="{internalQueryForceClassicEngine: true}"
+ --mongodSetParameters="{internalQueryEnableSlotBasedExecutionEngine: true}"
--excludeWithAnyTags=requires_ocsp_stapling
multiversion_platform: rhel80
multiversion_edition: enterprise
@@ -3050,18 +3050,18 @@ buildvariants:
- windows-vsCurrent-large
### QO & QE Patch-Specific Build Variants ###
-- <<: *enterprise-rhel-80-64-bit-dynamic-classic-engine
- name: enterprise-rhel-80-64-bit-dynamic-classic-engine-query-patch-only
- display_name: "~ Shared Library Enterprise RHEL 8.0 Query Patch Only (Classic Engine)"
+- <<: *enterprise-rhel-80-64-bit-dynamic-sbe-engine
+ name: enterprise-rhel-80-64-bit-dynamic-sbe-engine-query-patch-only
+ display_name: "~ Shared Library Enterprise RHEL 8.0 Query Patch Only (SBE Engine)"
cron: "0 4 * * 0" # From the ${project_weekly_cron} parameter # This is a patch-only variant but we run on mainline to pick up task history.
expansions:
- <<: *enterprise-rhel-80-64-bit-dynamic-classic-engine-expansions
+ <<: *enterprise-rhel-80-64-bit-dynamic-sbe-engine-expansions
jstestfuzz_num_generated_files: 20
jstestfuzz_concurrent_num_files: 5
target_resmoke_time: 30
max_sub_suites: 3
test_flags: >-
- --mongodSetParameters="{internalQueryForceClassicEngine: true}"
+ --mongodSetParameters="{internalQueryEnableSlotBasedExecutionEngine: true}"
--excludeWithAnyTags=resource_intensive
# Intentionally derive from SBE to run the SBE tests with all feature flags.
diff --git a/etc/generate_subtasks_config.yml b/etc/generate_subtasks_config.yml
index 2a2255148b8..d81d4c20681 100644
--- a/etc/generate_subtasks_config.yml
+++ b/etc/generate_subtasks_config.yml
@@ -47,8 +47,8 @@ build_variant_large_distro_exceptions:
- ubuntu1604-debug
- ubuntu1804-debug-asan
- ubuntu1804-debug-asan-all-feature-flags
- - ubuntu1804-debug-asan-classic-engine
+ - ubuntu1804-debug-asan-sbe-engine
- ubuntu1804-debug-aubsan-lite-required
- ubuntu1804-debug-ubsan
- ubuntu1804-debug-ubsan-all-feature-flags
- - ubuntu1804-debug-ubsan-classic-engine
+ - ubuntu1804-debug-ubsan-sbe-engine
diff --git a/jstests/concurrency/fsm_workloads/agg_lookup.js b/jstests/concurrency/fsm_workloads/agg_lookup.js
index 9395c503d3c..73a930eb35b 100644
--- a/jstests/concurrency/fsm_workloads/agg_lookup.js
+++ b/jstests/concurrency/fsm_workloads/agg_lookup.js
@@ -74,7 +74,7 @@ var $config = (function() {
getParameter: 1,
featureFlagShardedLookup: 1,
featureFlagSBELookupPushdown: 1,
- internalQueryForceClassicEngine: 1
+ internalQueryEnableSlotBasedExecutionEngine: 1
});
const isShardedLookupEnabled = getParam.hasOwnProperty("featureFlagShardedLookup") &&
getParam.featureFlagShardedLookup.value;
@@ -97,9 +97,9 @@ var $config = (function() {
assertWhenOwnColl.eq(this.numDocs, db[collName].find().itcount());
const isLookupPushdownEnabled = getParam.hasOwnProperty("featureFlagSBELookupPushdown") &&
- getParam.hasOwnProperty("internalQueryForceClassicEngine") &&
+ getParam.hasOwnProperty("internalQueryEnableSlotBasedExecutionEngine") &&
getParam.featureFlagSBELookupPushdown.value &&
- !getParam.internalQueryForceClassicEngine.value;
+ getParam.internalQueryEnableSlotBasedExecutionEngine.value;
this.allowDiskUse = true;
// If $lookup pushdown into SBE is enabled, we select a random join algorithm to use and
diff --git a/jstests/concurrency/fsm_workloads/find_flip_sbe_enabled.js b/jstests/concurrency/fsm_workloads/find_flip_sbe_enabled.js
index 67883f034cc..b284b75b9e8 100644
--- a/jstests/concurrency/fsm_workloads/find_flip_sbe_enabled.js
+++ b/jstests/concurrency/fsm_workloads/find_flip_sbe_enabled.js
@@ -1,12 +1,10 @@
'use strict';
/**
- * Sets the internalQueryForceClassicEngine flag to true and false, and
+ * Sets the internalQueryEnableSlotBasedExecutionEngine flag to true and false, and
* asserts that find queries using the plan cache produce the correct results.
*
* @tags: [
- * # Needed as the setParameter for ForceClassicEngine was introduced in 5.1.
- * requires_fcv_51,
* # Our test infrastructure prevents tests which use the 'setParameter' command from running in
* # stepdown suites, since parameters are local to each mongod in the replica set.
* does_not_support_stepdowns,
@@ -22,10 +20,10 @@ var $config = (function() {
function setup(db, collName, cluster) {
const originalParamValue =
- db.adminCommand({getParameter: 1, internalQueryForceClassicEngine: 1});
+ db.adminCommand({getParameter: 1, internalQueryEnableSlotBasedExecutionEngine: 1});
assertAlways.commandWorked(originalParamValue);
- assert(originalParamValue.hasOwnProperty("internalQueryForceClassicEngine"));
- this.originalParamValue = originalParamValue.internalQueryForceClassicEngine;
+ assert(originalParamValue.hasOwnProperty("internalQueryEnableSlotBasedExecutionEngine"));
+ this.originalParamValue = originalParamValue.internalQueryEnableSlotBasedExecutionEngine;
const coll = db.getCollection(getCollectionName(collName));
for (let i = 0; i < 10; ++i) {
assertAlways.commandWorked(
@@ -37,14 +35,14 @@ var $config = (function() {
}
let states = (function() {
- function setForceClassicEngineOn(db, collName) {
- assertAlways.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+ function setEnableSlotBasedExecutionEngineOn(db, collName) {
+ assertAlways.commandWorked(db.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
}
- function setForceClassicEngineOff(db, collName) {
- assertAlways.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
+ function setEnableSlotBasedExecutionEngineOff(db, collName) {
+ assertAlways.commandWorked(db.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
}
function runQueriesAndCheckResults(db, collName) {
@@ -79,8 +77,8 @@ var $config = (function() {
}
return {
- setForceClassicEngineOn: setForceClassicEngineOn,
- setForceClassicEngineOff: setForceClassicEngineOff,
+ setEnableSlotBasedExecutionEngineOn: setEnableSlotBasedExecutionEngineOn,
+ setEnableSlotBasedExecutionEngineOff: setEnableSlotBasedExecutionEngineOff,
runQueriesAndCheckResults: runQueriesAndCheckResults,
createIndex: createIndex,
dropIndex: dropIndex
@@ -88,36 +86,36 @@ var $config = (function() {
})();
let transitions = {
- setForceClassicEngineOn: {
- setForceClassicEngineOn: 0.1,
- setForceClassicEngineOff: 0.1,
+ setEnableSlotBasedExecutionEngineOn: {
+ setEnableSlotBasedExecutionEngineOn: 0.1,
+ setEnableSlotBasedExecutionEngineOff: 0.1,
runQueriesAndCheckResults: 0.8
},
- setForceClassicEngineOff: {
- setForceClassicEngineOn: 0.1,
- setForceClassicEngineOff: 0.1,
+ setEnableSlotBasedExecutionEngineOff: {
+ setEnableSlotBasedExecutionEngineOn: 0.1,
+ setEnableSlotBasedExecutionEngineOff: 0.1,
runQueriesAndCheckResults: 0.8
},
runQueriesAndCheckResults: {
- setForceClassicEngineOn: 0.1,
- setForceClassicEngineOff: 0.1,
+ setEnableSlotBasedExecutionEngineOn: 0.1,
+ setEnableSlotBasedExecutionEngineOff: 0.1,
runQueriesAndCheckResults: 0.78,
createIndex: 0.02,
},
createIndex: {
- setForceClassicEngineOn: 0.1,
- setForceClassicEngineOff: 0.1,
+ setEnableSlotBasedExecutionEngineOn: 0.1,
+ setEnableSlotBasedExecutionEngineOff: 0.1,
runQueriesAndCheckResults: 0.78,
createIndex: 0.01,
dropIndex: 0.01
},
dropIndex: {
- setForceClassicEngineOn: 0.1,
- setForceClassicEngineOff: 0.1,
+ setEnableSlotBasedExecutionEngineOn: 0.1,
+ setEnableSlotBasedExecutionEngineOff: 0.1,
runQueriesAndCheckResults: 0.78,
createIndex: 0.02,
}
@@ -127,15 +125,15 @@ var $config = (function() {
// Restore the original state of the ForceClassicEngine parameter.
const setParam = this.originalParamValue;
cluster.executeOnMongodNodes(function(db) {
- assertAlways.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: setParam}));
+ assertAlways.commandWorked(db.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: setParam}));
});
}
return {
threadCount: 10,
iterations: 100,
- startState: 'setForceClassicEngineOn',
+ startState: 'setEnableSlotBasedExecutionEngineOn',
states: states,
transitions: transitions,
setup: setup,
diff --git a/jstests/libs/sbe_util.js b/jstests/libs/sbe_util.js
index 2d85bbb4f79..fe623fe6d7e 100644
--- a/jstests/libs/sbe_util.js
+++ b/jstests/libs/sbe_util.js
@@ -24,8 +24,8 @@ function checkSBEEnabled(theDB, featureFlags = []) {
return false;
}
- // Find a non-mongos node and check whether its forceClassicEngine flag is on. We
- // assume either all nodes in the cluster have SBE disabled or none.
+ // Find a non-mongos node and check whether its SBE flag is on. We assume either
+ // all nodes in the cluster have SBE disabled or none.
for (const node of nodes) {
try {
const conn = new Mongo(node);
@@ -38,16 +38,17 @@ function checkSBEEnabled(theDB, featureFlags = []) {
internalQueryForceClassicEngine: 1,
internalQueryEnableSlotBasedExecutionEngine: 1
});
- if (getParam.hasOwnProperty("internalQueryForceClassicEngine") &&
- !getParam.internalQueryForceClassicEngine) {
- checkResult = true;
- }
- // Some versions use a different parameter to enable SBE instead of disabling it.
if (getParam.hasOwnProperty("internalQueryEnableSlotBasedExecutionEngine") &&
getParam.internalQueryEnableSlotBasedExecutionEngine) {
checkResult = true;
}
+ // Some versions use a different parameter to disable SBE instead of enabling it.
+ if (getParam.hasOwnProperty("internalQueryForceClassicEngine") &&
+ !getParam.internalQueryForceClassicEngine) {
+ checkResult = true;
+ }
+
featureFlags.forEach(function(featureFlag) {
const featureFlagParam = conn.adminCommand({getParameter: 1, [featureFlag]: 1});
checkResult = checkResult && featureFlagParam.hasOwnProperty(featureFlag) &&
diff --git a/jstests/multiVersion/targetedTestsLastContinuousFeatures/accumulator_fix_last_continuous.js b/jstests/multiVersion/targetedTestsLastContinuousFeatures/accumulator_fix_last_continuous.js
index e63b1d69b59..75699597ffa 100644
--- a/jstests/multiVersion/targetedTestsLastContinuousFeatures/accumulator_fix_last_continuous.js
+++ b/jstests/multiVersion/targetedTestsLastContinuousFeatures/accumulator_fix_last_continuous.js
@@ -33,19 +33,37 @@ load('jstests/multiVersion/libs/multi_cluster.js'); // For upgradeCluster()
st.rs1.getSecondary().getDB(jsTestName())
];
+ function setEngine(db, turnOnSBE) {
+ // Based on which version we are running, set the appropriate parameter which
+ // controls the execution engine.
+ const res = db.adminCommand({
+ getParameter: 1,
+ internalQueryEnableSlotBasedExecutionEngine: 1,
+ internalQueryForceClassicEngine: 1
+ });
+
+ if (res.hasOwnProperty("internalQueryEnableSlotBasedExecutionEngine")) {
+ assert.commandWorked(
+ db.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: turnOnSBE}),
+ `at node ${db.getMongo().host}`);
+ } else {
+ assert(res.hasOwnProperty("internalQueryForceClassicEngine"));
+ assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: !turnOnSBE}),
+ `at node ${db.getMongo().host}`);
+ }
+ }
+
// Turns to the classic engine at the shards.
- dbs.forEach((db) => assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}),
- `at node ${db.getMongo().host}`));
+ dbs.forEach((db) => setEngine(db, false /* turnOnSBE */));
// Verifies that the classic engine's results are same as the expected results.
const classicRes = coll.aggregate(pipeline).toArray();
verifyThis(classicRes);
// Turns to the SBE engine at the shards.
- dbs.forEach((db) => assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}),
- `at node ${db.getMongo().host}`));
+ dbs.forEach((db) => setEngine(db, true /* turnOnSBE */));
// Verifies that the SBE engine's results are same as the expected results.
const sbeRes = coll.aggregate(pipeline).toArray();
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/accumulator_fix_last_lts.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/accumulator_fix_last_lts.js
index e8d4bf71c14..8e8d6573796 100644
--- a/jstests/multiVersion/targetedTestsLastLtsFeatures/accumulator_fix_last_lts.js
+++ b/jstests/multiVersion/targetedTestsLastLtsFeatures/accumulator_fix_last_lts.js
@@ -34,12 +34,14 @@ load('jstests/multiVersion/libs/multi_cluster.js'); // For upgradeCluster()
st.rs1.getSecondary().getDB(jsTestName())
];
- // In the last-lts, we don't have the 'internalQueryForceClassicEngine' query knob.
+ // In the last-lts, we don't have the 'internalQueryEnableSlotBasedExecutionEngine'
+ // query knob.
if (isGreaterLastContinous) {
// Turns to the classic engine at the shards.
dbs.forEach(
(db) => assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}),
+ db.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}),
`at node ${db.getMongo().host}`));
}
@@ -47,13 +49,14 @@ load('jstests/multiVersion/libs/multi_cluster.js'); // For upgradeCluster()
const classicRes = coll.aggregate(pipeline).toArray();
verifyThis(classicRes);
- // In the last-lts, we have neither the 'internalQueryForceClassicEngine' query knob
- // nor the SBE $group pushdown feature.
+ // In the last-lts, we have neither the 'internalQueryEnableSlotBasedExecutionEngine'
+ // query knob nor the SBE $group pushdown feature.
if (isGreaterLastContinous) {
// Turns to the SBE engine at the shards.
dbs.forEach(
(db) => assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}),
+ db.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}),
`at node ${db.getMongo().host}`));
// Verifies that the SBE engine's results are same as the expected results.
diff --git a/jstests/noPassthrough/accumulator_bug_fix.js b/jstests/noPassthrough/accumulator_bug_fix.js
index be3347f6018..060b4a5fb7d 100644
--- a/jstests/noPassthrough/accumulator_bug_fix.js
+++ b/jstests/noPassthrough/accumulator_bug_fix.js
@@ -27,7 +27,7 @@
// Turns on the classical engine.
assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
const pipeline = [{$group: {_id: "$k", o: accSpec}}, {$group: {_id: "$o"}}];
@@ -76,13 +76,13 @@
// Turns on the classical engine.
assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
const classicRes = assert.commandWorked(db.runCommand(aggCmd)).cursor.firstBatch;
assert.eq(classicRes, expectedRes, testDesc);
// Turns off the classical engine.
assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
const sbeRes = assert.commandWorked(db.runCommand(aggCmd)).cursor.firstBatch;
assert.eq(sbeRes, expectedRes, testDesc);
};
@@ -240,20 +240,20 @@
let verifyShardedAccumulatorResultsOnBothEngine = (testDesc, coll, pipeline, expectedRes) => {
// Turns to the classic engine at the shards.
- assert.commandWorked(
- dbAtShard0.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
- assert.commandWorked(
- dbAtShard1.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+ assert.commandWorked(dbAtShard0.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
+ assert.commandWorked(dbAtShard1.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
// Verifies that the classic engine's results are same as the expected results.
const classicRes = coll.aggregate(pipeline).toArray();
assert.eq(classicRes, expectedRes, testDesc);
// Turns to the SBE engine at the shards.
- assert.commandWorked(
- dbAtShard0.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
- assert.commandWorked(
- dbAtShard1.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
+ assert.commandWorked(dbAtShard0.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
+ assert.commandWorked(dbAtShard1.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
// Verifies that the SBE engine's results are same as the expected results.
const sbeRes = coll.aggregate(pipeline).toArray();
diff --git a/jstests/noPassthrough/agg_group.js b/jstests/noPassthrough/agg_group.js
index 234237baf72..885c43852d2 100644
--- a/jstests/noPassthrough/agg_group.js
+++ b/jstests/noPassthrough/agg_group.js
@@ -42,8 +42,8 @@ st.ensurePrimaryShard(db.getName(), st.shard0.shardName);
let assertShardedGroupResultsMatch = (coll, pipeline) => {
// Turns to the classic engine at the shard before figuring out its result.
- assert.commandWorked(
- dbAtShard.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+ assert.commandWorked(dbAtShard.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
// Collects the classic engine's result as the expected result, executing the pipeline at the
// mongos.
@@ -52,8 +52,8 @@ let assertShardedGroupResultsMatch = (coll, pipeline) => {
.cursor.firstBatch;
// Turns to the SBE engine at the shard.
- assert.commandWorked(
- dbAtShard.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
+ assert.commandWorked(dbAtShard.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
// Verifies that the SBE engine's results are same as the expected results, executing the
// pipeline at the mongos.
diff --git a/jstests/noPassthrough/profile_operation_metrics.js b/jstests/noPassthrough/profile_operation_metrics.js
index 41da73e9e50..5ef83ba6d61 100644
--- a/jstests/noPassthrough/profile_operation_metrics.js
+++ b/jstests/noPassthrough/profile_operation_metrics.js
@@ -20,13 +20,15 @@ const isDebugBuild = (db) => {
return db.adminCommand('buildInfo').debug;
};
const isGroupPushdownEnabled = (db) => {
- const internalQueryForceClassicEngine =
- assert.commandWorked(db.adminCommand({getParameter: 1, internalQueryForceClassicEngine: 1}))
- .internalQueryForceClassicEngine;
+ const internalQueryEnableSlotBasedExecutionEngine =
+ assert
+ .commandWorked(
+ db.adminCommand({getParameter: 1, internalQueryEnableSlotBasedExecutionEngine: 1}))
+ .internalQueryEnableSlotBasedExecutionEngine;
const featureFlagSBEGroupPushdown =
assert.commandWorked(db.adminCommand({getParameter: 1, featureFlagSBEGroupPushdown: 1}))
.featureFlagSBEGroupPushdown.value;
- return !internalQueryForceClassicEngine && featureFlagSBEGroupPushdown;
+ return internalQueryEnableSlotBasedExecutionEngine && featureFlagSBEGroupPushdown;
};
const assertMetricsExist = (profilerEntry) => {
diff --git a/jstests/noPassthrough/query_engine_stats.js b/jstests/noPassthrough/query_engine_stats.js
index 492b4792efe..3e6b0ebe938 100644
--- a/jstests/noPassthrough/query_engine_stats.js
+++ b/jstests/noPassthrough/query_engine_stats.js
@@ -107,7 +107,8 @@ function compareQueryEngineCounters(expectedCounters) {
}
// Start with SBE off.
-assert.commandWorked(db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
// Run a find command.
let expectedCounters = generateExpectedCounters(engine.find.classic);
@@ -142,7 +143,8 @@ compareQueryEngineCounters(expectedCounters);
verifyProfiler(queryComment, engine.find.classic);
// Turn SBE on.
-assert.commandWorked(db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
+assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
// Run a find command.
expectedCounters = generateExpectedCounters(engine.find.sbe);
diff --git a/jstests/noPassthrough/query_knobs_validation.js b/jstests/noPassthrough/query_knobs_validation.js
index d5636ebadaf..cb76a691934 100644
--- a/jstests/noPassthrough/query_knobs_validation.js
+++ b/jstests/noPassthrough/query_knobs_validation.js
@@ -216,8 +216,8 @@ assertSetParameterSucceeds("internalQuerySlotBasedExecutionMaxStaticIndexScanInt
assertSetParameterFails("internalQuerySlotBasedExecutionMaxStaticIndexScanIntervals", 0);
assertSetParameterFails("internalQuerySlotBasedExecutionMaxStaticIndexScanIntervals", -1);
-assertSetParameterSucceeds("internalQueryForceClassicEngine", true);
-assertSetParameterSucceeds("internalQueryForceClassicEngine", false);
+assertSetParameterSucceeds("internalQueryEnableSlotBasedExecutionEngine", true);
+assertSetParameterSucceeds("internalQueryEnableSlotBasedExecutionEngine", false);
assertSetParameterSucceeds("internalQueryCollectionMaxNoOfDocumentsToChooseHashJoin", 1);
assertSetParameterFails("internalQueryCollectionMaxNoOfDocumentsToChooseHashJoin", 0);
diff --git a/jstests/noPassthrough/sbe_multiplanner_trial_termination.js b/jstests/noPassthrough/sbe_multiplanner_trial_termination.js
index 75739587a9f..2d77b962467 100644
--- a/jstests/noPassthrough/sbe_multiplanner_trial_termination.js
+++ b/jstests/noPassthrough/sbe_multiplanner_trial_termination.js
@@ -54,7 +54,8 @@ assert.commandWorked(db.adminCommand({setParameter: 1, [worksKnob]: trialLengthF
// Force the classic engine and run an "allPlansExecution" verbosity explain. Confirm that the trial
// period terminates based on the the "collection fraction" as opposed to
// 'internalQueryPlanEvaluationWorks'.
-assert.commandWorked(db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
let allPlans = getAllPlansExecution("1");
for (let plan of allPlans) {
assert(plan.hasOwnProperty("executionStages"), plan);
@@ -92,7 +93,8 @@ assert.gt(getParamRes[worksKnobSbe], numDocs);
// default value of SBE's works knob exceeds the size of the collection, we expect the number of
// reads to exceed the collection size as well. By construction of the test, this also means that
// the trial period length exceeds both 'trialLengthFromCollFrac' and 'trialLengthFromWorksKnob'.
-assert.commandWorked(db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
+assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
allPlans = getAllPlansExecution("2");
verifySbeNumReads(allPlans, numDocs, assert.gt);
diff --git a/jstests/noPassthrough/sbe_plan_cache_key_reporting.js b/jstests/noPassthrough/sbe_plan_cache_key_reporting.js
index 41e242e872b..5c39ec6362e 100644
--- a/jstests/noPassthrough/sbe_plan_cache_key_reporting.js
+++ b/jstests/noPassthrough/sbe_plan_cache_key_reporting.js
@@ -42,7 +42,7 @@ function runTestAgainstSbeAndClassicEngines(testToRun) {
return ["sbe", "classic"].map((engine) => {
setupCollection();
assert.commandWorked(db.adminCommand(
- {setParameter: 1, internalQueryForceClassicEngine: engine == "classic"}));
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: engine === "sbe"}));
return testToRun(engine);
});
}
@@ -193,9 +193,9 @@ function assertQueryHashAndPlanCacheKey(sbe, classic) {
assert.eq(classic.explainVersion, "1", classic);
// The query hashes and the plan cache keys ('the keys') are different now because
- // 'internalQueryForceClassicEngine' flag is encoded into query shape, once this flag is removed
- // from the query shape encoding the keys will be the same until SERVER-61507 is completed, then
- // the keys will be different forever.
+ // 'internalQueryEnableSlotBasedExecutionEngine' flag is encoded into query shape, once this
+ // flag is removed from the query shape encoding the keys will be the same until SERVER-61507
+ // is completed, then the keys will be different forever.
assertQueryHashAndPlanCacheKey(sbe.queryPlanner, classic.stages[0]["$cursor"].queryPlanner);
})();
@@ -219,9 +219,9 @@ function assertQueryHashAndPlanCacheKey(sbe, classic) {
assert.eq(classic.explainVersion, "1", classic);
// The query hashes and the plan cache keys ('the keys') are different now because
- // 'internalQueryForceClassicEngine' flag is encoded into query shape, once this flag is removed
- // from the query shape encoding the keys will be the same until SERVER-61507 is completed, then
- // the keys will be different forever.
+ // 'internalQueryEnableSlotBasedExecutionEngine' flag is encoded into query shape, once this
+ // flag is removed from the query shape encoding the keys will be the same until SERVER-61507
+ // is completed, then the keys will be different forever.
assertQueryHashAndPlanCacheKey(sbe.queryPlanner, classic.stages[0]["$cursor"].queryPlanner);
})();
diff --git a/jstests/noPassthrough/sbe_plan_cache_memory_debug_info.js b/jstests/noPassthrough/sbe_plan_cache_memory_debug_info.js
index df3ac0d3fd9..9c8f6fb5461 100644
--- a/jstests/noPassthrough/sbe_plan_cache_memory_debug_info.js
+++ b/jstests/noPassthrough/sbe_plan_cache_memory_debug_info.js
@@ -75,7 +75,8 @@ const planCacheSizeAfterSbeStep = getPlanCacheSize();
assert.lt(initialPlanCacheSize, planCacheSizeAfterSbeStep);
// Force classic plan cache.
-assert.commandWorked(db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
// Create a new collection for classic queries so we can easily assess its plan cache.
const classicColl = createTestCollection("classic");
diff --git a/jstests/noPassthrough/sbe_plan_cache_size_metric.js b/jstests/noPassthrough/sbe_plan_cache_size_metric.js
index 4cec6ba7f78..8e37ac8e26e 100644
--- a/jstests/noPassthrough/sbe_plan_cache_size_metric.js
+++ b/jstests/noPassthrough/sbe_plan_cache_size_metric.js
@@ -76,7 +76,8 @@ if (isSbePlanCacheEnabled) {
// Step 2. Insert an entry to Classic Plan Cache.
// Force classic plan cache.
- assert.commandWorked(db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+ assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
assert.eq(1, coll.find(classicQuery).itcount());
assertQueryInPlanCache(coll, classicQuery);
// Plan Cache must contain exactly 2 entries.
@@ -95,7 +96,7 @@ if (isSbePlanCacheEnabled) {
// Step 4. Remove the entry from SBE Plan Cache.
// Move back to SBE plan cache.
assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
// Clean up SBE Plan Cache
assert.commandWorked(db.runCommand({planCacheClear: collectionName, query: sbeQuery}));
// Assert metric is decremented back to initial value.
diff --git a/jstests/noPassthrough/server_status_multiplanner.js b/jstests/noPassthrough/server_status_multiplanner.js
index f185cdb7841..10ac1d67e0a 100644
--- a/jstests/noPassthrough/server_status_multiplanner.js
+++ b/jstests/noPassthrough/server_status_multiplanner.js
@@ -44,7 +44,8 @@ assert.eq(multiPlannerMetrics.histograms.classicMicros[0].lowerBound, 0);
// Run with classic engine and verify metrics.
{
- assert.commandWorked(db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}));
+ assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}));
assert.commandWorked(coll.find({a: 1, b: 1, c: 1}).explain());
multiPlannerMetrics = db.serverStatus().metrics.query.multiPlanner;
@@ -66,7 +67,7 @@ assert.eq(multiPlannerMetrics.histograms.classicMicros[0].lowerBound, 0);
// Run with SBE and verify metrics.
{
assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
assert.commandWorked(coll.find({a: 1, b: 1, c: 1}).explain());
multiPlannerMetrics = db.serverStatus().metrics.query.multiPlanner;
diff --git a/jstests/noPassthroughWithMongod/group_pushdown.js b/jstests/noPassthroughWithMongod/group_pushdown.js
index adfeda64b74..0b85a84b0eb 100644
--- a/jstests/noPassthroughWithMongod/group_pushdown.js
+++ b/jstests/noPassthroughWithMongod/group_pushdown.js
@@ -79,7 +79,7 @@ let assertResultsMatchWithAndWithoutGroupPushdown = function(
assertGroupPushdown(coll, pipeline, expectedResults, expectedGroupCountInExplain);
// Turn sbe off.
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true});
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false});
// Sanity check the results when no pushdown happens.
let resultNoGroupPushdown = coll.aggregate(pipeline).toArray();
@@ -87,7 +87,7 @@ let assertResultsMatchWithAndWithoutGroupPushdown = function(
// Turn sbe on which will allow $group stages that contain supported accumulators to be pushed
// down under certain conditions.
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false});
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true});
let resultWithGroupPushdown = coll.aggregate(pipeline).toArray();
assert.sameMembers(resultNoGroupPushdown, resultWithGroupPushdown);
@@ -100,7 +100,7 @@ let assertResultsMatchWithAndWithoutProjectPushdown = function(
{coll: coll, pipeline: pipeline, expectProjectToBePushedDown: expectProjectToBePushedDown});
// Turn sbe off.
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true});
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false});
// Sanity check the results when no project pushdown happens.
let resultNoProjectPushdown = coll.aggregate(pipeline).toArray();
@@ -108,17 +108,17 @@ let assertResultsMatchWithAndWithoutProjectPushdown = function(
// Turn sbe on which will allow $group stages that contain supported accumulators to be pushed
// down under certain conditions.
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false});
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true});
let resultWithProjectPushdown = coll.aggregate(pipeline).toArray();
assert.sameMembers(resultNoProjectPushdown, resultWithProjectPushdown);
};
let assertShardedGroupResultsMatch = function(coll, pipeline, expectedGroupCountInExplain = 1) {
- const originalClassicEngineStatus =
+ const originalSBEEngineStatus =
assert
- .commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: true}))
+ .commandWorked(db.adminCommand(
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: false}))
.was;
const cmd = {
@@ -131,7 +131,7 @@ let assertShardedGroupResultsMatch = function(coll, pipeline, expectedGroupCount
const classicalRes = coll.runCommand(cmd).cursor.firstBatch;
assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryForceClassicEngine: false}));
+ db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
const explainCmd = {
aggregate: coll.getName(),
pipeline: pipeline,
@@ -147,7 +147,7 @@ let assertShardedGroupResultsMatch = function(coll, pipeline, expectedGroupCount
assert.sameMembers(sbeRes, classicalRes);
assert.commandWorked(db.adminCommand(
- {setParameter: 1, internalQueryForceClassicEngine: originalClassicEngineStatus}));
+ {setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: originalSBEEngineStatus}));
};
// Try a pipeline with no group stage.
diff --git a/jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js b/jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js
index c3924654a74..2c799f31f88 100644
--- a/jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js
+++ b/jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js
@@ -117,11 +117,11 @@ const isShardedLookupEnabled = getShardedLookupParam.hasOwnProperty("featureFlag
let res = st.getPrimaryShard(jsTestName()).getDB("admin").adminCommand({
getParameter: 1,
featureFlagSBELookupPushdown: 1,
- internalQueryForceClassicEngine: 1
+ internalQueryEnableSlotBasedExecutionEngine: 1
});
let isSBELookupEnabled = res.ok && res.hasOwnProperty("featureFlagSBELookupPushdown") &&
- res.hasOwnProperty("internalQueryForceClassicEngine") &&
- res.featureFlagSBELookupPushdown.value && !res.internalQueryForceClassicEngine;
+ res.hasOwnProperty("internalQueryEnableSlotBasedExecutionEngine") &&
+ res.featureFlagSBELookupPushdown.value && res.internalQueryEnableSlotBasedExecutionEngine;
// Now run a getMore for each of the test cases. The collection has become sharded mid-iteration, so
// we should observe the error code associated with the test case.
diff --git a/src/mongo/db/commands/plan_cache_clear_command.cpp b/src/mongo/db/commands/plan_cache_clear_command.cpp
index 1609577347e..eb56632a9bd 100644
--- a/src/mongo/db/commands/plan_cache_clear_command.cpp
+++ b/src/mongo/db/commands/plan_cache_clear_command.cpp
@@ -90,7 +90,7 @@ Status clear(OperationContext* opCtx,
// sbe::isQuerySbeCompatible here.
const size_t plannerOptions = 0;
if (feature_flags::gFeatureFlagSbePlanCache.isEnabledAndIgnoreFCV() &&
- !cq->getForceClassicEngine() &&
+ cq->getEnableSlotBasedExecutionEngine() &&
sbe::isQuerySbeCompatible(&collection, cq.get(), plannerOptions)) {
cq->setSbeCompatible(true);
sbe::getPlanCache(opCtx).remove(
diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp
index 69d3711e080..c1d80e84ade 100644
--- a/src/mongo/db/pipeline/pipeline_d.cpp
+++ b/src/mongo/db/pipeline/pipeline_d.cpp
@@ -110,14 +110,14 @@ namespace {
* pipeline to prepare for pushdown of $group and $lookup into the inner query layer so that it
* can be executed using SBE.
* Group stages are extracted from the pipeline when all of the following conditions are met:
- * 0. When the 'internalQueryForceClassicEngine' feature flag is 'false'.
+ * 0. When the 'internalQueryEnableSlotBasedExecutionEngine' feature flag is 'true'.
* 1. When 'allowDiskUse' is false. We currently don't support spilling in the SBE HashAgg
* stage. This will change once that is supported when SERVER-58436 is complete.
* 2. When the DocumentSourceGroup has 'doingMerge=false', this will change when we implement
* hash table spilling in SERVER-58436.
*
* Lookup stages are extracted from the pipeline when all of the following conditions are met:
- * 0. When the 'internalQueryForceClassicEngine' feature flag is 'false'.
+ * 0. When the 'internalQueryEnableSlotBasedExecutionEngine' feature flag is 'true'.
* 1. When the 'featureFlagSBELookupPushdown' feature flag is 'true'.
* 2. The $lookup uses only the 'localField'/'foreignField' syntax (no pipelines).
* 3. The foreign collection is neither sharded nor a view.
@@ -138,7 +138,7 @@ std::vector<std::unique_ptr<InnerPipelineStageInterface>> extractSbeCompatibleSt
}
// No pushdown if we're using the classic engine.
- if (cq->getForceClassicEngine()) {
+ if (!cq->getEnableSlotBasedExecutionEngine()) {
return {};
}
diff --git a/src/mongo/db/query/canonical_query.cpp b/src/mongo/db/query/canonical_query.cpp
index 865cd10b245..f760e1f5be1 100644
--- a/src/mongo/db/query/canonical_query.cpp
+++ b/src/mongo/db/query/canonical_query.cpp
@@ -193,7 +193,7 @@ Status CanonicalQuery::init(OperationContext* opCtx,
_findCommand = std::move(findCommand);
_canHaveNoopMatchNodes = canHaveNoopMatchNodes;
- _forceClassicEngine = internalQueryForceClassicEngine.load();
+ _enableSlotBasedExecutionEngine = internalQueryEnableSlotBasedExecutionEngine.load();
auto validStatus = isValid(root.get(), *_findCommand);
if (!validStatus.isOK()) {
@@ -543,7 +543,7 @@ CanonicalQuery::QueryShapeString CanonicalQuery::encodeKey() const {
// TODO SERVER-61507: remove '_pipeline.empty()' check. Canonical queries with pushed down
// $group/$lookup stages are not SBE-compatible until SERVER-61507 is complete.
return (feature_flags::gFeatureFlagSbePlanCache.isEnabledAndIgnoreFCV() &&
- !_forceClassicEngine && _sbeCompatible && _pipeline.empty())
+ _enableSlotBasedExecutionEngine && _sbeCompatible && _pipeline.empty())
? canonical_query_encoder::encodeSBE(*this)
: canonical_query_encoder::encode(*this);
}
diff --git a/src/mongo/db/query/canonical_query.h b/src/mongo/db/query/canonical_query.h
index c06051347d6..3f997eb1f8b 100644
--- a/src/mongo/db/query/canonical_query.h
+++ b/src/mongo/db/query/canonical_query.h
@@ -221,8 +221,8 @@ public:
return _explain;
}
- bool getForceClassicEngine() const {
- return _forceClassicEngine;
+ bool getEnableSlotBasedExecutionEngine() const {
+ return _enableSlotBasedExecutionEngine;
}
void setSbeCompatible(bool sbeCompatible) {
@@ -302,8 +302,8 @@ private:
bool _explain = false;
- // Determines whether the classic engine must be used.
- bool _forceClassicEngine = false;
+ // Determines whether the SBE engine is enabled.
+ bool _enableSlotBasedExecutionEngine = false;
// True if this query can be executed by the SBE.
bool _sbeCompatible = false;
diff --git a/src/mongo/db/query/canonical_query_encoder.cpp b/src/mongo/db/query/canonical_query_encoder.cpp
index 303cdb6009a..aa65a0cf6ae 100644
--- a/src/mongo/db/query/canonical_query_encoder.cpp
+++ b/src/mongo/db/query/canonical_query_encoder.cpp
@@ -665,7 +665,7 @@ CanonicalQuery::QueryShapeString encode(const CanonicalQuery& cq) {
// This encoding can be removed once the classic query engine reaches EOL and SBE is used
// exclusively for all query execution.
- keyBuilder << kEncodeEngineSection << (cq.getForceClassicEngine() ? "f" : "t");
+ keyBuilder << kEncodeEngineSection << (cq.getEnableSlotBasedExecutionEngine() ? "t" : "f");
return keyBuilder.str();
}
diff --git a/src/mongo/db/query/canonical_query_encoder_test.cpp b/src/mongo/db/query/canonical_query_encoder_test.cpp
index 928fdbda8ee..27e8ae74707 100644
--- a/src/mongo/db/query/canonical_query_encoder_test.cpp
+++ b/src/mongo/db/query/canonical_query_encoder_test.cpp
@@ -40,7 +40,6 @@
#include "mongo/unittest/unittest.h"
#include "mongo/util/assert_util.h"
-
namespace mongo {
namespace {
@@ -147,103 +146,120 @@ void testComputeSBEKey(const char* queryStr,
TEST(CanonicalQueryEncoderTest, ComputeKey) {
// Generated cache keys should be treated as opaque to the user.
+ // 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
+ // 'internalQueryEnableSlotBasedExecutionEngine' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE(
+ "internalQueryEnableSlotBasedExecutionEngine", false);
+
// No sorts
- testComputeKey("{}", "{}", "{}", "an@t");
- testComputeKey("{$or: [{a: 1}, {b: 2}]}", "{}", "{}", "or[eqa,eqb]@t");
+ testComputeKey("{}", "{}", "{}", "an@f");
+ testComputeKey("{$or: [{a: 1}, {b: 2}]}", "{}", "{}", "or[eqa,eqb]@f");
testComputeKey(
- "{$or: [{a: 1}, {b: 1}, {c: 1}], d: 1}", "{}", "{}", "an[or[eqa,eqb,eqc],eqd]@t");
- testComputeKey("{$or: [{a: 1}, {b: 1}], c: 1, d: 1}", "{}", "{}", "an[or[eqa,eqb],eqc,eqd]@t");
- testComputeKey("{a: 1, b: 1, c: 1}", "{}", "{}", "an[eqa,eqb,eqc]@t");
- testComputeKey("{a: 1, beqc: 1}", "{}", "{}", "an[eqa,eqbeqc]@t");
- testComputeKey("{ap1a: 1}", "{}", "{}", "eqap1a@t");
- testComputeKey("{aab: 1}", "{}", "{}", "eqaab@t");
+ "{$or: [{a: 1}, {b: 1}, {c: 1}], d: 1}", "{}", "{}", "an[or[eqa,eqb,eqc],eqd]@f");
+ testComputeKey("{$or: [{a: 1}, {b: 1}], c: 1, d: 1}", "{}", "{}", "an[or[eqa,eqb],eqc,eqd]@f");
+ testComputeKey("{a: 1, b: 1, c: 1}", "{}", "{}", "an[eqa,eqb,eqc]@f");
+ testComputeKey("{a: 1, beqc: 1}", "{}", "{}", "an[eqa,eqbeqc]@f");
+ testComputeKey("{ap1a: 1}", "{}", "{}", "eqap1a@f");
+ testComputeKey("{aab: 1}", "{}", "{}", "eqaab@f");
// With sort
- testComputeKey("{}", "{a: 1}", "{}", "an~aa@t");
- testComputeKey("{}", "{a: -1}", "{}", "an~da@t");
+ testComputeKey("{}", "{a: 1}", "{}", "an~aa@f");
+ testComputeKey("{}", "{a: -1}", "{}", "an~da@f");
testComputeKey("{$text: {$search: 'search keywords'}}",
"{a: {$meta: 'textScore'}}",
"{a: {$meta: 'textScore'}}",
- "te_fts~ta@t");
- testComputeKey("{a: 1}", "{b: 1}", "{}", "eqa~ab@t");
+ "te_fts~ta@f");
+ testComputeKey("{a: 1}", "{b: 1}", "{}", "eqa~ab@f");
// With projection
- testComputeKey("{}", "{}", "{a: 1}", "an|_id-a@t");
- testComputeKey("{}", "{}", "{a: -1}", "an|_id-a@t");
- testComputeKey("{}", "{}", "{a: -1.0}", "an|_id-a@t");
- testComputeKey("{}", "{}", "{a: true}", "an|_id-a@t");
- testComputeKey("{}", "{}", "{a: 0}", "an@t");
- testComputeKey("{}", "{}", "{a: false}", "an@t");
- testComputeKey("{}", "{}", "{a: 99}", "an|_id-a@t");
- testComputeKey("{}", "{}", "{a: 'foo'}", "an|_id@t");
+ testComputeKey("{}", "{}", "{a: 1}", "an|_id-a@f");
+ testComputeKey("{}", "{}", "{a: -1}", "an|_id-a@f");
+ testComputeKey("{}", "{}", "{a: -1.0}", "an|_id-a@f");
+ testComputeKey("{}", "{}", "{a: true}", "an|_id-a@f");
+ testComputeKey("{}", "{}", "{a: 0}", "an@f");
+ testComputeKey("{}", "{}", "{a: false}", "an@f");
+ testComputeKey("{}", "{}", "{a: 99}", "an|_id-a@f");
+ testComputeKey("{}", "{}", "{a: 'foo'}", "an|_id@f");
// $slice defaults to exclusion.
- testComputeKey("{}", "{}", "{a: {$slice: [3, 5]}}", "an@t");
- testComputeKey("{}", "{}", "{a: {$slice: [3, 5]}, b: 0}", "an@t");
+ testComputeKey("{}", "{}", "{a: {$slice: [3, 5]}}", "an@f");
+ testComputeKey("{}", "{}", "{a: {$slice: [3, 5]}, b: 0}", "an@f");
// But even when using $slice in an inclusion, the entire document is needed.
- testComputeKey("{}", "{}", "{a: {$slice: [3, 5]}, b: 1}", "an@t");
+ testComputeKey("{}", "{}", "{a: {$slice: [3, 5]}, b: 1}", "an@f");
- testComputeKey("{}", "{}", "{a: {$elemMatch: {x: 2}}}", "an@t");
- testComputeKey("{}", "{}", "{a: {$elemMatch: {x: 2}}, b: 0}", "an@t");
- testComputeKey("{}", "{}", "{a: {$elemMatch: {x: 2}}, b: 1}", "an@t");
+ testComputeKey("{}", "{}", "{a: {$elemMatch: {x: 2}}}", "an@f");
+ testComputeKey("{}", "{}", "{a: {$elemMatch: {x: 2}}, b: 0}", "an@f");
+ testComputeKey("{}", "{}", "{a: {$elemMatch: {x: 2}}, b: 1}", "an@f");
- testComputeKey("{}", "{}", "{a: {$slice: [3, 5]}, b: {$elemMatch: {x: 2}}}", "an@t");
+ testComputeKey("{}", "{}", "{a: {$slice: [3, 5]}, b: {$elemMatch: {x: 2}}}", "an@f");
- testComputeKey("{}", "{}", "{a: ObjectId('507f191e810c19729de860ea')}", "an|_id@t");
+ testComputeKey("{}", "{}", "{a: ObjectId('507f191e810c19729de860ea')}", "an|_id@f");
// Since this projection overwrites the entire document, no fields are required.
testComputeKey(
- "{}", "{}", "{_id: 0, a: ObjectId('507f191e810c19729de860ea'), b: 'foo'}", "an|@t");
- testComputeKey("{a: 1}", "{}", "{'a.$': 1}", "eqa@t");
- testComputeKey("{a: 1}", "{}", "{a: 1}", "eqa|_id-a@t");
+ "{}", "{}", "{_id: 0, a: ObjectId('507f191e810c19729de860ea'), b: 'foo'}", "an|@f");
+ testComputeKey("{a: 1}", "{}", "{'a.$': 1}", "eqa@f");
+ testComputeKey("{a: 1}", "{}", "{a: 1}", "eqa|_id-a@f");
// Projection should be order-insensitive
- testComputeKey("{}", "{}", "{a: 1, b: 1}", "an|_id-a-b@t");
- testComputeKey("{}", "{}", "{b: 1, a: 1}", "an|_id-a-b@t");
+ testComputeKey("{}", "{}", "{a: 1, b: 1}", "an|_id-a-b@f");
+ testComputeKey("{}", "{}", "{b: 1, a: 1}", "an|_id-a-b@f");
// And should escape the separation character.
- testComputeKey("{}", "{}", "{'b-1': 1, 'a-2': 1}", "an|_id-a\\-2-b\\-1@t");
+ testComputeKey("{}", "{}", "{'b-1': 1, 'a-2': 1}", "an|_id-a\\-2-b\\-1@f");
// And should exclude $-prefixed fields which can be added internally.
- testComputeKey("{}", "{x: 1}", "{$sortKey: {$meta: 'sortKey'}}", "an~ax@t");
- testComputeKey("{}", "{}", "{}", "an@t");
+ testComputeKey("{}", "{x: 1}", "{$sortKey: {$meta: 'sortKey'}}", "an~ax@f");
+ testComputeKey("{}", "{}", "{}", "an@f");
- testComputeKey("{}", "{x: 1}", "{a: 1, $sortKey: {$meta: 'sortKey'}}", "an~ax|_id-a@t");
- testComputeKey("{}", "{}", "{a: 1}", "an|_id-a@t");
+ testComputeKey("{}", "{x: 1}", "{a: 1, $sortKey: {$meta: 'sortKey'}}", "an~ax|_id-a@f");
+ testComputeKey("{}", "{}", "{a: 1}", "an|_id-a@f");
// With or-elimination and projection
- testComputeKey("{$or: [{a: 1}]}", "{}", "{_id: 0, a: 1}", "eqa|a@t");
- testComputeKey("{$or: [{a: 1}]}", "{}", "{'a.$': 1}", "eqa@t");
+ testComputeKey("{$or: [{a: 1}]}", "{}", "{_id: 0, a: 1}", "eqa|a@f");
+ testComputeKey("{$or: [{a: 1}]}", "{}", "{'a.$': 1}", "eqa@f");
}
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
+ // 'internalQueryEnableSlotBasedExecutionEngine' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE(
+ "internalQueryEnableSlotBasedExecutionEngine", false);
+
// With '$eq', '$gte', and '$lte' negation comparison to 'null'.
- testComputeKey("{a: {$not: {$eq: null}}}", "{}", "{_id: 0, a: 1}", "ntnot_eq_null[eqa]|a@t");
+ testComputeKey("{a: {$not: {$eq: null}}}", "{}", "{_id: 0, a: 1}", "ntnot_eq_null[eqa]|a@f");
testComputeKey(
- "{a: {$not: {$eq: null}}}", "{a: 1}", "{_id: 0, a: 1}", "ntnot_eq_null[eqa]~aa|a@t");
+ "{a: {$not: {$eq: null}}}", "{a: 1}", "{_id: 0, a: 1}", "ntnot_eq_null[eqa]~aa|a@f");
testComputeKey(
- "{a: {$not: {$gte: null}}}", "{a: 1}", "{_id: 0, a: 1}", "ntnot_eq_null[gea]~aa|a@t");
+ "{a: {$not: {$gte: null}}}", "{a: 1}", "{_id: 0, a: 1}", "ntnot_eq_null[gea]~aa|a@f");
testComputeKey(
- "{a: {$not: {$lte: null}}}", "{a: 1}", "{_id: 0, a: 1}", "ntnot_eq_null[lea]~aa|a@t");
+ "{a: {$not: {$lte: null}}}", "{a: 1}", "{_id: 0, a: 1}", "ntnot_eq_null[lea]~aa|a@f");
// Same '$eq' negation query with non-'null' argument should have different key.
- testComputeKey("{a: {$not: {$eq: true}}}", "{a: 1}", "{_id: 0, a: 1}", "nt[eqa]~aa|a@t");
+ testComputeKey("{a: {$not: {$eq: true}}}", "{a: 1}", "{_id: 0, a: 1}", "nt[eqa]~aa|a@f");
}
// Delimiters found in user field names or non-standard projection field values
// must be escaped.
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
+ // 'internalQueryEnableSlotBasedExecutionEngine' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE(
+ "internalQueryEnableSlotBasedExecutionEngine", false);
// Field name in query.
- testComputeKey("{'a,[]~|-<>': 1}", "{}", "{}", "eqa\\,\\[\\]\\~\\|\\-<>@t");
+ testComputeKey("{'a,[]~|-<>': 1}", "{}", "{}", "eqa\\,\\[\\]\\~\\|\\-<>@f");
// Field name in sort.
- testComputeKey("{}", "{'a,[]~|-<>': 1}", "{}", "an~aa\\,\\[\\]\\~\\|\\-<>@t");
+ testComputeKey("{}", "{'a,[]~|-<>': 1}", "{}", "an~aa\\,\\[\\]\\~\\|\\-<>@f");
// Field name in projection.
- testComputeKey("{}", "{}", "{'a,[]~|-<>': 1}", "an|_id-a\\,\\[\\]\\~\\|\\-<>@t");
+ testComputeKey("{}", "{}", "{'a,[]~|-<>': 1}", "an|_id-a\\,\\[\\]\\~\\|\\-<>@f");
// String literal provided as value.
- testComputeKey("{}", "{}", "{a: 'foo,[]~|-<>'}", "an|_id@t");
+ testComputeKey("{}", "{}", "{a: 'foo,[]~|-<>'}", "an|_id@f");
}
// Cache keys for $geoWithin queries with legacy and GeoJSON coordinates should
@@ -266,17 +282,27 @@ TEST(CanonicalQueryEncoderTest, ComputeKeyGeoWithin) {
// GEO_NEAR cache keys should include information on geometry and CRS in addition
// to the match type and field name.
TEST(CanonicalQueryEncoderTest, ComputeKeyGeoNear) {
- testComputeKey("{a: {$near: [0,0], $maxDistance:0.3 }}", "{}", "{}", "gnanrfl@t");
- testComputeKey("{a: {$nearSphere: [0,0], $maxDistance: 0.31 }}", "{}", "{}", "gnanssp@t");
+ // 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
+ // 'internalQueryEnableSlotBasedExecutionEngine' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE(
+ "internalQueryEnableSlotBasedExecutionEngine", false);
+
+ testComputeKey("{a: {$near: [0,0], $maxDistance:0.3 }}", "{}", "{}", "gnanrfl@f");
+ testComputeKey("{a: {$nearSphere: [0,0], $maxDistance: 0.31 }}", "{}", "{}", "gnanssp@f");
testComputeKey(
"{a: {$geoNear: {$geometry: {type: 'Point', coordinates: [0,0]},"
"$maxDistance:100}}}",
"{}",
"{}",
- "gnanrsp@t");
+ "gnanrsp@f");
}
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(
+ "internalQueryEnableSlotBasedExecutionEngine", true);
testComputeKey("{a: {$regex: \"sometext\"}}", "{}", "{}", "rea@t");
testComputeKey("{a: {$regex: \"sometext\", $options: \"\"}}", "{}", "{}", "rea@t");
@@ -307,61 +333,76 @@ 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
+ // 'internalQueryEnableSlotBasedExecutionEngine' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE(
+ "internalQueryEnableSlotBasedExecutionEngine", false);
+
// Test that an $in containing a single regex is unwrapped to $regex.
- testComputeKey("{a: {$in: [/foo/]}}", "{}", "{}", "rea@t");
- testComputeKey("{a: {$in: [/foo/i]}}", "{}", "{}", "rea/i/@t");
+ testComputeKey("{a: {$in: [/foo/]}}", "{}", "{}", "rea@f");
+ testComputeKey("{a: {$in: [/foo/i]}}", "{}", "{}", "rea/i/@f");
// Test that an $in with no regexes does not include any regex information.
- testComputeKey("{a: {$in: [1, 'foo']}}", "{}", "{}", "ina@t");
+ testComputeKey("{a: {$in: [1, 'foo']}}", "{}", "{}", "ina@f");
// Test that an $in with a regex encodes the presence of the regex.
- testComputeKey("{a: {$in: [1, /foo/]}}", "{}", "{}", "ina_re@t");
+ testComputeKey("{a: {$in: [1, /foo/]}}", "{}", "{}", "ina_re@f");
// Test that an $in with a regex encodes the presence of the regex and its flags.
- testComputeKey("{a: {$in: [1, /foo/is]}}", "{}", "{}", "ina_re/is/@t");
+ testComputeKey("{a: {$in: [1, /foo/is]}}", "{}", "{}", "ina_re/is/@f");
// Test that the computed key is invariant to the order of the flags within each regex.
- testComputeKey("{a: {$in: [1, /foo/si]}}", "{}", "{}", "ina_re/is/@t");
+ testComputeKey("{a: {$in: [1, /foo/si]}}", "{}", "{}", "ina_re/is/@f");
// Test that an $in with multiple regexes encodes all unique flags.
- testComputeKey("{a: {$in: [1, /foo/i, /bar/m, /baz/s]}}", "{}", "{}", "ina_re/ims/@t");
+ testComputeKey("{a: {$in: [1, /foo/i, /bar/m, /baz/s]}}", "{}", "{}", "ina_re/ims/@f");
// Test that an $in with multiple regexes deduplicates identical flags.
testComputeKey(
- "{a: {$in: [1, /foo/i, /bar/m, /baz/s, /qux/i, /quux/s]}}", "{}", "{}", "ina_re/ims/@t");
+ "{a: {$in: [1, /foo/i, /bar/m, /baz/s, /qux/i, /quux/s]}}", "{}", "{}", "ina_re/ims/@f");
// Test that the computed key is invariant to the ordering of the flags across regexes.
testComputeKey("{a: {$in: [1, /foo/ism, /bar/msi, /baz/im, /qux/si, /quux/im]}}",
"{}",
"{}",
- "ina_re/ims/@t");
+ "ina_re/ims/@f");
testComputeKey("{a: {$in: [1, /foo/msi, /bar/ism, /baz/is, /qux/mi, /quux/im]}}",
"{}",
"{}",
- "ina_re/ims/@t");
+ "ina_re/ims/@f");
// Test that $not-$in-$regex similarly records the presence and flags of any regexes.
- testComputeKey("{a: {$not: {$in: [1, 'foo']}}}", "{}", "{}", "nt[ina]@t");
- testComputeKey("{a: {$not: {$in: [1, /foo/]}}}", "{}", "{}", "nt[ina_re]@t");
+ testComputeKey("{a: {$not: {$in: [1, 'foo']}}}", "{}", "{}", "nt[ina]@f");
+ testComputeKey("{a: {$not: {$in: [1, /foo/]}}}", "{}", "{}", "nt[ina_re]@f");
testComputeKey(
- "{a: {$not: {$in: [1, /foo/i, /bar/i, /baz/msi]}}}", "{}", "{}", "nt[ina_re/ims/]@t");
+ "{a: {$not: {$in: [1, /foo/i, /bar/i, /baz/msi]}}}", "{}", "{}", "nt[ina_re/ims/]@f");
// Test that a $not-$in containing a single regex is unwrapped to $not-$regex.
- testComputeKey("{a: {$not: {$in: [/foo/]}}}", "{}", "{}", "nt[rea]@t");
- testComputeKey("{a: {$not: {$in: [/foo/i]}}}", "{}", "{}", "nt[rea/i/]@t");
+ testComputeKey("{a: {$not: {$in: [/foo/]}}}", "{}", "{}", "nt[rea]@f");
+ testComputeKey("{a: {$not: {$in: [/foo/i]}}}", "{}", "{}", "nt[rea/i/]@f");
}
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
+ // 'internalQueryEnableSlotBasedExecutionEngine' change in the future.
+ RAIIServerParameterControllerForTest controllerSBE(
+ "internalQueryEnableSlotBasedExecutionEngine", false);
unique_ptr<CanonicalQuery> cq(canonicalize(
fromjson("{a: 1, b: 1}"), {}, {}, fromjson("{locale: 'mock_reverse_string'}")));
- testComputeKey(*cq, "an[eqa,eqb]#mock_reverse_string02300000@t");
+ testComputeKey(*cq, "an[eqa,eqb]#mock_reverse_string02300000@f");
}
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(
+ "internalQueryEnableSlotBasedExecutionEngine", true);
+
// TODO SERVER-61314: Remove when featureFlagSbePlanCache is removed.
RAIIServerParameterControllerForTest controllerSBEPlanCache("featureFlagSbePlanCache", true);
diff --git a/src/mongo/db/query/explain.cpp b/src/mongo/db/query/explain.cpp
index 414badb8332..4ec9e8d9e7d 100644
--- a/src/mongo/db/query/explain.cpp
+++ b/src/mongo/db/query/explain.cpp
@@ -96,7 +96,7 @@ void generatePlannerInfo(PlanExecutor* exec,
QuerySettingsDecoration::get(collection->getSharedDecorations());
if (exec->getCanonicalQuery()->isSbeCompatible() &&
feature_flags::gFeatureFlagSbePlanCache.isEnabledAndIgnoreFCV() &&
- !exec->getCanonicalQuery()->getForceClassicEngine() &&
+ exec->getCanonicalQuery()->getEnableSlotBasedExecutionEngine() &&
// TODO(SERVER-61507): Remove pipeline check once lowered pipelines are integrated with
// SBE plan cache.
exec->getCanonicalQuery()->pipeline().empty()) {
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp
index 8b801dcb33b..bfbfd63d08e 100644
--- a/src/mongo/db/query/get_executor.cpp
+++ b/src/mongo/db/query/get_executor.cpp
@@ -1374,7 +1374,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutor(
const auto& mainColl = collections.getMainCollection();
canonicalQuery->setSbeCompatible(
sbe::isQuerySbeCompatible(&mainColl, canonicalQuery.get(), plannerOptions));
- return !canonicalQuery->getForceClassicEngine() && canonicalQuery->isSbeCompatible()
+ return canonicalQuery->getEnableSlotBasedExecutionEngine() && canonicalQuery->isSbeCompatible()
? getSlotBasedExecutor(opCtx,
collections,
std::move(canonicalQuery),
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 13d37bd7b12..472b1f0ab9c 100644
--- a/src/mongo/db/query/plan_cache_key_info_test.cpp
+++ b/src/mongo/db/query/plan_cache_key_info_test.cpp
@@ -420,10 +420,10 @@ TEST(PlanCacheKeyInfoTest, DifferentQueryEngines) {
false, // sparse
IndexEntry::Identifier{""})}; // name
- // Helper to construct a plan cache key given the 'forceClassicEngine' flag.
- auto constructPlanCacheKey = [&](bool forceClassicEngine) {
- RAIIServerParameterControllerForTest controller{"internalQueryForceClassicEngine",
- forceClassicEngine};
+ // Helper to construct a plan cache key given the 'enableSlotBasedExecutionEngine' flag.
+ auto constructPlanCacheKey = [&](bool enableSlotBasedExecutionEngine) {
+ RAIIServerParameterControllerForTest controller{
+ "internalQueryEnableSlotBasedExecutionEngine", enableSlotBasedExecutionEngine};
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 4756981a4b9..c75f5beb09e 100644
--- a/src/mongo/db/query/query_knobs.idl
+++ b/src/mongo/db/query/query_knobs.idl
@@ -653,11 +653,11 @@ 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."
+ internalQueryEnableSlotBasedExecutionEngine:
+ description: "If true, the system will use the SBE execution engine for eligible queries,
+ otherwise all queries will execute using the classic execution engine."
set_at: [ startup, runtime ]
- cpp_varname: "internalQueryForceClassicEngine"
+ cpp_varname: "internalQueryEnableSlotBasedExecutionEngine"
cpp_vartype: AtomicWord<bool>
default: false
diff --git a/src/mongo/db/query/query_planner.cpp b/src/mongo/db/query/query_planner.cpp
index e1d9c5a2b00..34f9a9616c7 100644
--- a/src/mongo/db/query/query_planner.cpp
+++ b/src/mongo/db/query/query_planner.cpp
@@ -204,7 +204,7 @@ void tryToAddColumnScan(const QueryPlannerParams& params,
// We only want to use the columnar index if we can avoid fetching the whole document.
return;
}
- if (!query.isSbeCompatible() || query.getForceClassicEngine()) {
+ if (!query.isSbeCompatible() || !query.getEnableSlotBasedExecutionEngine()) {
// We only support column scans in SBE.
return;
}
diff --git a/src/mongo/db/query/query_planner_columnar_test.cpp b/src/mongo/db/query/query_planner_columnar_test.cpp
index 439715ee74c..930bf3055c9 100644
--- a/src/mongo/db/query/query_planner_columnar_test.cpp
+++ b/src/mongo/db/query/query_planner_columnar_test.cpp
@@ -32,6 +32,8 @@
#include "mongo/db/query/collation/collator_interface_mock.h"
#include "mongo/db/query/query_knobs_gen.h"
#include "mongo/db/query/query_planner_test_fixture.h"
+#include "mongo/db/query/query_planner_test_lib.h"
+#include "mongo/idl/server_parameter_test_util.h"
#include "mongo/unittest/death_test.h"
namespace mongo {
@@ -64,6 +66,11 @@ protected:
void addColumnarIndex() {
params.columnarIndexes.emplace_back(kIndexName);
}
+
+private:
+ // SBE must be enabled in order to test columnar indexes.
+ RAIIServerParameterControllerForTest _controllerSBE{
+ "internalQueryEnableSlotBasedExecutionEngine", true};
};
TEST_F(QueryPlannerColumnarTest, InclusionProjectionUsesColumnarIndex) {
diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp
index 3552cf095fd..ce40f343858 100644
--- a/src/mongo/dbtests/query_stage_multiplan.cpp
+++ b/src/mongo/dbtests/query_stage_multiplan.cpp
@@ -551,7 +551,8 @@ TEST_F(QueryStageMultiPlanTest, MPSExplainAllPlans) {
//
// This is a regression test for SERVER-20111.
TEST_F(QueryStageMultiPlanTest, MPSSummaryStats) {
- RAIIServerParameterControllerForTest controller("internalQueryForceClassicEngine", true);
+ RAIIServerParameterControllerForTest controller("internalQueryEnableSlotBasedExecutionEngine",
+ false);
const int N = 5000;
for (int i = 0; i < N; ++i) {
diff --git a/src/mongo/shell/servers.js b/src/mongo/shell/servers.js
index 165ee334be4..bf688fb06bd 100644
--- a/src/mongo/shell/servers.js
+++ b/src/mongo/shell/servers.js
@@ -643,6 +643,20 @@ var _isMongodVersionEqualOrAfter = function(version1, version2) {
return false;
};
+// Returns if version2 came before version 1.
+var _isMongodVersionBefore = function(version1, version2) {
+ var versionParts1 = _convertVersionToIntegerArray(version1);
+ var versionParts2 = _convertVersionToIntegerArray(version2);
+ if (versionParts2[0] < versionParts1[0] ||
+ (versionParts2[0] === versionParts1[0] && versionParts2[1] < versionParts1[1]) ||
+ (versionParts2[0] === versionParts1[0] && versionParts2[1] === versionParts1[1] &&
+ versionParts2[2] < versionParts1[2])) {
+ return true;
+ }
+
+ return false;
+};
+
// Removes a setParameter parameter from mongods or mongoses running a version that won't recognize
// them.
var _removeSetParameterIfBeforeVersion = function(
@@ -658,6 +672,24 @@ var _removeSetParameterIfBeforeVersion = function(
}
};
+// Similar to the function above, but accepts two versions such that if the configured binVersion is
+// between the specified versions, it removes the setParameter parameter.
+var _removeSetParameterIfBetweenSpecifiedVersions = function(
+ opts, parameterName, afterVersion, beforeVersion, isMongos = false) {
+ var processString = isMongos ? "mongos" : "mongod";
+ var versionCompatible = (opts.binVersion === "" || opts.binVersion === undefined ||
+ // For 'opts.binVersion' to be compatible with 'parameterName', it must
+ // be GTE 'afterVersion' or LT 'beforeVersion'.
+ _isMongodVersionEqualOrAfter(afterVersion, opts.binVersion) ||
+ _isMongodVersionBefore(beforeVersion, opts.binVersion));
+ if (!versionCompatible && opts.setParameter && opts.setParameter[parameterName] != undefined) {
+ print("Removing '" + parameterName + "' setParameter with value " +
+ opts.setParameter[parameterName] + " because it isn't compatible with " +
+ processString + " running version " + opts.binVersion);
+ delete opts.setParameter[parameterName];
+ }
+};
+
/**
* @option {object} opts
*
@@ -703,7 +735,8 @@ MongoRunner.mongodOptions = function(opts = {}) {
opts, "enableDefaultWriteConcernUpdatesForInitiate", "5.0.0");
_removeSetParameterIfBeforeVersion(opts, "enableReconfigRollbackCommittedWritesCheck", "5.0.0");
_removeSetParameterIfBeforeVersion(opts, "featureFlagRetryableFindAndModify", "5.0.0");
- _removeSetParameterIfBeforeVersion(opts, "internalQueryForceClassicEngine", "5.1.0");
+ _removeSetParameterIfBetweenSpecifiedVersions(
+ opts, "internalQueryEnableSlotBasedExecutionEngine", "6.0.0", "5.1.0");
_removeSetParameterIfBeforeVersion(opts, "allowMultipleArbiters", "5.3.0");
if (!opts.logFile && opts.useLogFiles) {