TEST_F(OptimizePipeline, ProjectThenMixedMatchPushedDown) {
    auto pipeline = Pipeline::parse(
        makeVector(fromjson("{$_internalUnpackBucket: { exclude: [], timeField: 'time', metaField: "
                            "'myMeta', bucketMaxSpanSeconds: 3600}}"),
                   fromjson("{$project: {a: 1, myMeta: 1, x: 1}}"),
                   fromjson("{$match: {myMeta: {$eq: 'abc'}, a: {$lte: 4}}}")),
        getExpCtx());
    ASSERT_EQ(3u, pipeline->getSources().size());

    pipeline->optimizePipeline();

    // We should push down part of the $match and do dependency analysis on the rest.
    auto stages = pipeline->writeExplainOps(ExplainOptions::Verbosity::kQueryPlanner);
    ASSERT_EQ(4u, stages.size());
    ASSERT_BSONOBJ_EQ(
        fromjson(
            "{$match: {$and: [{meta: {$eq: 'abc'}}, {'control.min.a': {$_internalExprLte: 4}}]}}"),
        stages[0].getDocument().toBson());
    ASSERT_BSONOBJ_EQ(
        fromjson("{$_internalUnpackBucket: { include: ['_id', 'a', 'x', 'myMeta'], timeField: "
                 "'time', metaField: 'myMeta', bucketMaxSpanSeconds: 3600}}"),
        stages[1].getDocument().toBson());
    ASSERT_BSONOBJ_EQ(fromjson("{$match: {a: {$lte: 4}}}"), stages[2].getDocument().toBson());
    const UnorderedFieldsBSONObjComparator kComparator;
    ASSERT_EQ(
        kComparator.compare(fromjson("{$project: {_id: true, a: true, myMeta: true, x: true}}"),
                            stages[3].getDocument().toBson()),
        0);
}
TEST_F(OptimizePipeline, ProjectThenMixedMatchPushedDown) {
    auto pipeline = Pipeline::parse(
        makeVector(fromjson("{$_internalUnpackBucket: { exclude: [], timeField: 'time', metaField: "
                            "'myMeta', bucketMaxSpanSeconds: 3600}}"),
                   fromjson("{$project: {a: 1, myMeta: 1, x: 1}}"),
                   fromjson("{$match: {myMeta: {$eq: 'abc'}, a: {$lte: 4}}}")),
        getExpCtx());
    ASSERT_EQ(3u, pipeline->getSources().size());

    pipeline->optimizePipeline();

     
    auto stages = pipeline->writeExplainOps(ExplainOptions::Verbosity::kQueryPlanner);
    ASSERT_EQ(4u, stages.size());
    ASSERT_BSONOBJ_EQ(
        fromjson(
            "{$match: {$and: [{meta: {$eq: 'abc'}}, {'control.min.a': {$_internalExprLte: 4}}]}}"),
        stages[0].getDocument().toBson());
    ASSERT_BSONOBJ_EQ(
        fromjson("{$_internalUnpackBucket: { include: ['_id', 'a', 'x', 'myMeta'], timeField: "
                 "'time', metaField: 'myMeta', bucketMaxSpanSeconds: 3600}}"),
        stages[1].getDocument().toBson());
    ASSERT_BSONOBJ_EQ(fromjson("{$match: {a: {$lte: 4}}}"), stages[2].getDocument().toBson());
    const UnorderedFieldsBSONObjComparator kComparator;
    ASSERT_EQ(
        kComparator.compare(fromjson("{$project: {_id: true, a: true, myMeta: true, x: true}}"),
                            stages[3].getDocument().toBson()),
        0);
}