mongo/jstests/aggregation/optimization/agg_optimize_empty_add_fiel...

51 lines
1.7 KiB
JavaScript

/**
* SERVER-111948 Simplify vacuous $addFields stages
*
* @tags: [
* # Required to optimize $addFields
* requires_pipeline_optimization,
* # Facets break the checks on explain()
* do_not_wrap_aggregations_in_facets,
* # Run against mongod for the explain()
* assumes_against_mongod_not_mongos
* ]
*/
import {isAggregationPlan} from "jstests/libs/query/analyze_plan.js";
const coll = db[jsTestName()];
coll.drop();
assert.commandWorked(
coll.insertMany([
{_id: 1, a: "foo"},
{_id: 2, a: "bar"},
{_id: 3, a: "baz"},
]),
);
function explainPipeline(pipeline) {
// Add $_internalInhibitOptimization to prevent the pipeline from being optimized away
const explain = coll.explain().aggregate([{$_internalInhibitOptimization: {}}, ...pipeline]);
assert.eq(true, isAggregationPlan(explain), "Pipeline should not be optimized away");
jsTest.log.info("Stages for pipeline", {input: pipeline, stages: explain.stages, explain});
return explain;
}
const emptyAddFields = explainPipeline([{$addFields: {}}]);
// Allow the .stages to be undefined, which occurs when the pipeline is optimized to a find
assert.doesNotContain({$addFields: {}}, emptyAddFields.stages || [], "The empty $addFields stage should be removed");
const nonEmptyAddFields = explainPipeline([{$addFields: {b: 1}}]);
assert.contains(
{$addFields: {b: {$const: 1}}},
nonEmptyAddFields.stages,
"Non-empty $addFields stage remains in the pipeline",
);
const removeAddFields = explainPipeline([{$addFields: {b: "$$REMOVE"}}]);
assert.contains(
{$addFields: {b: "$$REMOVE"}},
removeAddFields.stages,
"$addFields which only removes fields is not optimized away",
);