void run() {
        OldClientWriteContext ctx(&_txn, nss.ns());

        addIndex(BSON("a" << 1 << "b" << 1));
        addIndex(BSON("a" << 1 << "c" << 1));
        addIndex(BSON("d" << 1));

        for (int i = 0; i < 10; i++) {
            insert(BSON("a" << 1 << "e" << 1 << "d" << 1));
        }

        // Running this query should not create any cache entries. For the first branch, it's
        // because plans using the {a: 1, b: 1} and {a: 1, c: 1} indices should tie during plan
        // ranking. For the second branch it's because there is only one relevant index.
        BSONObj query = fromjson("{$or: [{a: 1, e: 1}, {d: 1}]}");

        Collection* collection = ctx.getCollection();

        auto qr = stdx::make_unique<QueryRequest>(nss);
        qr->setFilter(query);
        auto statusWithCQ = CanonicalQuery::canonicalize(
            txn(), std::move(qr), ExtensionsCallbackDisallowExtensions());
        ASSERT_OK(statusWithCQ.getStatus());
        std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue());

        // Get planner params.
        QueryPlannerParams plannerParams;
        fillOutPlannerParams(&_txn, collection, cq.get(), &plannerParams);

        WorkingSet ws;
        std::unique_ptr<SubplanStage> subplan(
            new SubplanStage(&_txn, collection, &ws, plannerParams, cq.get()));

        PlanYieldPolicy yieldPolicy(PlanExecutor::YIELD_MANUAL, _clock);
        ASSERT_OK(subplan->pickBestPlan(&yieldPolicy));

        // Nothing is in the cache yet, so neither branch should have been planned from
        // the plan cache.
        ASSERT_FALSE(subplan->branchPlannedFromCache(0));
        ASSERT_FALSE(subplan->branchPlannedFromCache(1));

        // If we run the query again, it should again be the case that neither branch gets planned
        // from the cache (because the first call to pickBestPlan() refrained from creating any
        // cache entries).
        ws.clear();
        subplan.reset(new SubplanStage(&_txn, collection, &ws, plannerParams, cq.get()));

        ASSERT_OK(subplan->pickBestPlan(&yieldPolicy));

        ASSERT_FALSE(subplan->branchPlannedFromCache(0));
        ASSERT_FALSE(subplan->branchPlannedFromCache(1));
    }
    void run() {
        OldClientWriteContext ctx(&_txn, nss.ns());

        addIndex(BSON("a" << 1));
        addIndex(BSON("a" << 1 << "b" << 1));
        addIndex(BSON("c" << 1));

        for (int i = 0; i < 10; i++) {
            insert(BSON("a" << 1 << "b" << i << "c" << i));
        }

        // This query should result in a plan cache entry for the first $or branch, because
        // there are two competing indices. The second branch has only one relevant index, so
        // its winning plan should not be cached.
        BSONObj query = fromjson("{$or: [{a: 1, b: 3}, {c: 1}]}");

        Collection* collection = ctx.getCollection();

        auto qr = stdx::make_unique<QueryRequest>(nss);
        qr->setFilter(query);
        auto statusWithCQ = CanonicalQuery::canonicalize(
            txn(), std::move(qr), ExtensionsCallbackDisallowExtensions());
        ASSERT_OK(statusWithCQ.getStatus());
        std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue());

        // Get planner params.
        QueryPlannerParams plannerParams;
        fillOutPlannerParams(&_txn, collection, cq.get(), &plannerParams);

        WorkingSet ws;
        std::unique_ptr<SubplanStage> subplan(
            new SubplanStage(&_txn, collection, &ws, plannerParams, cq.get()));

        PlanYieldPolicy yieldPolicy(PlanExecutor::YIELD_MANUAL, _clock);
        ASSERT_OK(subplan->pickBestPlan(&yieldPolicy));

        // Nothing is in the cache yet, so neither branch should have been planned from
        // the plan cache.
        ASSERT_FALSE(subplan->branchPlannedFromCache(0));
        ASSERT_FALSE(subplan->branchPlannedFromCache(1));

        // If we repeat the same query, the plan for the first branch should have come from
        // the cache.
        ws.clear();
        subplan.reset(new SubplanStage(&_txn, collection, &ws, plannerParams, cq.get()));

        ASSERT_OK(subplan->pickBestPlan(&yieldPolicy));

        ASSERT_TRUE(subplan->branchPlannedFromCache(0));
        ASSERT_FALSE(subplan->branchPlannedFromCache(1));
    }
    void run() {
        OldClientWriteContext ctx(&_txn, nss.ns());

        addIndex(BSON("a" << 1 << "b" << 1));
        addIndex(BSON("a" << 1));
        addIndex(BSON("c" << 1));

        for (int i = 0; i < 10; i++) {
            insert(BSON("a" << 1 << "b" << i << "c" << i));
        }

        // Running this query should not create any cache entries. For the first branch, it's
        // because there are no matching results. For the second branch it's because there is only
        // one relevant index.
        BSONObj query = fromjson("{$or: [{a: 1, b: 15}, {c: 1}]}");

        Collection* collection = ctx.getCollection();

        auto statusWithCQ = CanonicalQuery::canonicalize(nss, query);
        ASSERT_OK(statusWithCQ.getStatus());
        std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue());

        // Get planner params.
        QueryPlannerParams plannerParams;
        fillOutPlannerParams(&_txn, collection, cq.get(), &plannerParams);

        WorkingSet ws;
        std::unique_ptr<SubplanStage> subplan(
            new SubplanStage(&_txn, collection, &ws, plannerParams, cq.get()));

        PlanYieldPolicy yieldPolicy(nullptr, PlanExecutor::YIELD_MANUAL);
        ASSERT_OK(subplan->pickBestPlan(&yieldPolicy));

        // Nothing is in the cache yet, so neither branch should have been planned from
        // the plan cache.
        ASSERT_FALSE(subplan->branchPlannedFromCache(0));
        ASSERT_FALSE(subplan->branchPlannedFromCache(1));

        // If we run the query again, it should again be the case that neither branch gets planned
        // from the cache (because the first call to pickBestPlan() refrained from creating any
        // cache entries).
        ws.clear();
        subplan.reset(new SubplanStage(&_txn, collection, &ws, plannerParams, cq.get()));

        ASSERT_OK(subplan->pickBestPlan(&yieldPolicy));

        ASSERT_FALSE(subplan->branchPlannedFromCache(0));
        ASSERT_FALSE(subplan->branchPlannedFromCache(1));
    }
        void run() {
            OldClientWriteContext ctx(&_txn, ns());

            addIndex(BSON("a" << 1 << "b" << 1));
            addIndex(BSON("a" << 1 << "c" << 1));

            for (int i = 0; i < 10; i++) {
                insert(BSON("a" << 1 << "b" << i << "c" << i));
            }

            // This query should result in a plan cache entry for the first branch. The second
            // branch should tie, meaning that nothing is inserted into the plan cache.
            BSONObj query = fromjson("{$or: [{a: 1, b: 3}, {a: 1}]}");

            Collection* collection = ctx.getCollection();

            CanonicalQuery* rawCq;
            ASSERT_OK(CanonicalQuery::canonicalize(ns(), query, &rawCq));
            boost::scoped_ptr<CanonicalQuery> cq(rawCq);

            // Get planner params.
            QueryPlannerParams plannerParams;
            fillOutPlannerParams(&_txn, collection, cq.get(), &plannerParams);

            WorkingSet ws;
            boost::scoped_ptr<SubplanStage> subplan(new SubplanStage(&_txn, collection, &ws,
                                                                     plannerParams, cq.get()));

            PlanYieldPolicy yieldPolicy(NULL, PlanExecutor::YIELD_MANUAL);
            ASSERT_OK(subplan->pickBestPlan(&yieldPolicy));

            // Nothing is in the cache yet, so neither branch should have been planned from
            // the plan cache.
            ASSERT_FALSE(subplan->branchPlannedFromCache(0));
            ASSERT_FALSE(subplan->branchPlannedFromCache(1));

            // If we repeat the same query, then the first branch should come from the cache,
            // but the second is re-planned due to tying on the first run.
            ws.clear();
            subplan.reset(new SubplanStage(&_txn, collection, &ws, plannerParams, cq.get()));

            ASSERT_OK(subplan->pickBestPlan(&yieldPolicy));

            ASSERT_TRUE(subplan->branchPlannedFromCache(0));
            ASSERT_FALSE(subplan->branchPlannedFromCache(1));
        }