| 191 | } |
| 192 | |
| 193 | Tuple* Aggregator::GetOutputTuple( |
| 194 | const vector<AggFnEvaluator*>& agg_fn_evals, Tuple* tuple, MemPool* pool) { |
| 195 | DCHECK(tuple != nullptr || agg_fn_evals.empty()) << tuple; |
| 196 | Tuple* dst = tuple; |
| 197 | if (needs_finalize_ && intermediate_tuple_id_ != output_tuple_id_) { |
| 198 | dst = Tuple::Create(output_tuple_desc_->byte_size(), pool); |
| 199 | } |
| 200 | if (needs_finalize_) { |
| 201 | AggFnEvaluator::Finalize(agg_fn_evals, tuple, dst); |
| 202 | } else { |
| 203 | AggFnEvaluator::Serialize(agg_fn_evals, tuple); |
| 204 | } |
| 205 | // Copy grouping values from tuple to dst. |
| 206 | // TODO: Codegen this. |
| 207 | if (dst != tuple) { |
| 208 | int num_grouping_slots = GetNumGroupingExprs(); |
| 209 | for (int i = 0; i < num_grouping_slots; ++i) { |
| 210 | SlotDescriptor* src_slot_desc = intermediate_tuple_desc_->slots()[i]; |
| 211 | SlotDescriptor* dst_slot_desc = output_tuple_desc_->slots()[i]; |
| 212 | bool src_slot_null = tuple->IsNull(src_slot_desc->null_indicator_offset()); |
| 213 | void* src_slot = nullptr; |
| 214 | if (!src_slot_null) src_slot = tuple->GetSlot(src_slot_desc->tuple_offset()); |
| 215 | RawValue::Write(src_slot, dst, dst_slot_desc, nullptr); |
| 216 | } |
| 217 | } |
| 218 | return dst; |
| 219 | } |
| 220 | |
| 221 | Status Aggregator::QueryMaintenance(RuntimeState* state) { |
| 222 | expr_results_pool_->Clear(); |