/**
* Copyright (c) 2011 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
#include "pch.h"
#include "accumulator.h"
#include "db/pipeline/value.h"
namespace mongo {
intrusive_ptr AccumulatorSum::evaluate(
const intrusive_ptr &pDocument) const {
assert(vpOperand.size() == 1);
intrusive_ptr prhs(vpOperand[0]->evaluate(pDocument));
/* upgrade to the widest type required to hold the result */
totalType = Value::getWidestNumeric(totalType, prhs->getType());
if (totalType == NumberInt) {
int v = prhs->coerceToInt();
longTotal += v;
doubleTotal += v;
}
else if (totalType == NumberLong) {
long long v = prhs->coerceToLong();
longTotal += v;
doubleTotal += v;
}
else { /* (totalType == NumberDouble) */
double v = prhs->coerceToDouble();
doubleTotal += v;
}
return Value::getZero();
}
intrusive_ptr AccumulatorSum::create(
const intrusive_ptr &pCtx) {
intrusive_ptr pSummer(new AccumulatorSum());
return pSummer;
}
intrusive_ptr AccumulatorSum::getValue() const {
if (totalType == NumberInt)
return Value::createInt((int)longTotal);
if (totalType == NumberLong)
return Value::createLong(longTotal);
return Value::createDouble(doubleTotal);
}
AccumulatorSum::AccumulatorSum():
Accumulator(),
totalType(NumberInt),
longTotal(0),
doubleTotal(0) {
}
const char *AccumulatorSum::getOpName() const {
return "$sum";
}
}