Sums up the specified item(s). @param avg calculate average @param qc query context @return summed up item @throws QueryException query exception
(final boolean avg, final QueryContext qc)
| 149 | * @throws QueryException query exception |
| 150 | */ |
| 151 | final Item sum(final boolean avg, final QueryContext qc) throws QueryException { |
| 152 | final Expr values = arg(0); |
| 153 | if(values instanceof Range) return range(values.value(qc), avg); |
| 154 | |
| 155 | final Iter iter = values.atomIter(qc, info); |
| 156 | final Item item = iter.next(); |
| 157 | if(item == null) return null; |
| 158 | |
| 159 | Item result = item.type.isUntyped() ? Dbl.get(item.dbl(info)) : item; |
| 160 | final Type type = result.type; |
| 161 | final boolean num = result instanceof ANum; |
| 162 | final boolean dtd = type == DAY_TIME_DURATION, ymd = type == YEAR_MONTH_DURATION; |
| 163 | if(!num && !dtd && !ymd) throw NUMDUR_X_X.get(info, type, result); |
| 164 | |
| 165 | int c = 1; |
| 166 | for(Item it; (it = qc.next(iter)) != null;) { |
| 167 | final Type tp = it.type; |
| 168 | Type t = null; |
| 169 | if(tp.isNumberOrUntyped()) { |
| 170 | if(!num) t = DURATION; |
| 171 | } else if(num) { |
| 172 | t = NUMERIC; |
| 173 | } else if(dtd && tp != DAY_TIME_DURATION || ymd && tp != YEAR_MONTH_DURATION) { |
| 174 | t = DURATION; |
| 175 | } |
| 176 | if(t != null) throw ARGTYPE_X_X_X.get(info, t, tp, it); |
| 177 | result = Calc.ADD.eval(result, it, info); |
| 178 | c++; |
| 179 | } |
| 180 | return avg ? Calc.DIVIDE.eval(result, Itr.get(c), info) : result; |
| 181 | } |
| 182 | } |