Esempio n. 1
0
    UpdateResult UpdateExecutor::execute(Database* db) {
        uassertStatusOK(prepare());

        LOG(3) << "processing update : " << *_request;

        // If we've already done the in-lock preparation, this is a no-op.
        Status status = prepareInLock(db);
        uassert(17243,
                "could not get executor " + _request->getQuery().toString()
                                         + "; " + causedBy(status),
                status.isOK());

        // Run the plan (don't need to collect results because UpdateStage always returns
        // NEED_TIME).
        uassertStatusOK(_exec->executePlan());

        // Get stats from the root stage.
        invariant(_exec->getRootStage()->stageType() == STAGE_UPDATE);
        UpdateStage* updateStage = static_cast<UpdateStage*>(_exec->getRootStage());
        const UpdateStats* updateStats =
            static_cast<const UpdateStats*>(updateStage->getSpecificStats());

        // Use stats from the root stage to fill out opDebug.
        _opDebug->nMatched = updateStats->nMatched;
        _opDebug->nModified = updateStats->nModified;
        _opDebug->upsert = updateStats->inserted;
        _opDebug->fastmodinsert = updateStats->fastmodinsert;
        _opDebug->fastmod = updateStats->fastmod;

        // Historically, 'opDebug' considers 'nMatched' and 'nModified' to be 1 (rather than 0) if
        // there is an upsert that inserts a document. The UpdateStage does not participate in this
        // madness in order to have saner stats reporting for explain. This means that we have to
        // set these values "manually" in the case of an insert.
        if (updateStats->inserted) {
            _opDebug->nMatched = 1;
            _opDebug->nModified = 1;
        }

        // Get summary information about the plan.
        PlanSummaryStats stats;
        Explain::getSummaryStats(_exec.get(), &stats);
        _opDebug->nscanned = stats.totalKeysExamined;
        _opDebug->nscannedObjects = stats.totalDocsExamined;

        return UpdateResult(updateStats->nMatched > 0 /* Did we update at least one obj? */,
                            !_driver.isDocReplacement() /* $mod or obj replacement */,
                            _opDebug->nModified /* number of modified docs, no no-ops */,
                            _opDebug->nMatched /* # of docs matched/updated, even no-ops */,
                            updateStats->objInserted);
    }
Esempio n. 2
0
long long DeleteExecutor::execute(Database* db) {
    uassertStatusOK(prepare());

    // If we've already done the in-lock preparation, this is a no-op.
    uassertStatusOK(prepareInLock(db));
    invariant(_exec.get());

    uassertStatusOK(_exec->executePlan());

    // Extract the number of documents deleted from the DeleteStage stats.
    invariant(_exec->getRootStage()->stageType() == STAGE_DELETE);
    DeleteStage* deleteStage = static_cast<DeleteStage*>(_exec->getRootStage());
    const DeleteStats* deleteStats =
        static_cast<const DeleteStats*>(deleteStage->getSpecificStats());
    return deleteStats->docsDeleted;
}