| 394 | } |
| 395 | |
| 396 | void SortedAggregations::extractValues( |
| 397 | folly::Range<char**> groups, |
| 398 | const RowVectorPtr& result) { |
| 399 | raw_vector<int32_t> temp; |
| 400 | SelectivityVector rows; |
| 401 | std::vector<char*> groupRows; |
| 402 | for (const auto& [sortingSpec, aggregates] : aggregates_) { |
| 403 | std::vector<VectorPtr> inputVectors; |
| 404 | size_t numInputColumns = 0; |
| 405 | for (const auto& aggregate : aggregates) { |
| 406 | numInputColumns += aggregate->inputs.size(); |
| 407 | } |
| 408 | inputVectors.resize(numInputColumns); |
| 409 | |
| 410 | // For each group, sort inputs, add them to aggregate. |
| 411 | for (auto* group : groups) { |
| 412 | auto* accumulator = reinterpret_cast<RowPointers*>(group + offset_); |
| 413 | groupRows.resize(accumulator->size); |
| 414 | accumulator->read(folly::Range(groupRows.data(), groupRows.size())); |
| 415 | |
| 416 | sortSingleGroup(groupRows, sortingSpec); |
| 417 | |
| 418 | size_t firstInputColumn = 0; |
| 419 | for (const auto& aggregate : aggregates) { |
| 420 | std::vector<VectorPtr> aggregateInputs; |
| 421 | aggregateInputs.reserve(aggregate->inputs.size()); |
| 422 | for (auto i = 0; i < aggregate->inputs.size(); ++i) { |
| 423 | aggregateInputs.push_back( |
| 424 | std::move(inputVectors[firstInputColumn + i])); |
| 425 | } |
| 426 | |
| 427 | // TODO Process group rows in batches to avoid creating very large |
| 428 | // input vectors. |
| 429 | const auto numRows = |
| 430 | extractSingleGroup(groupRows, *aggregate, aggregateInputs); |
| 431 | if (numRows == 0) { |
| 432 | // Mask must be false for all 'groupRows'. |
| 433 | continue; |
| 434 | } |
| 435 | |
| 436 | rows.resize(numRows); |
| 437 | aggregate->function->addSingleGroupRawInput( |
| 438 | group, rows, aggregateInputs, false); |
| 439 | |
| 440 | for (auto i = 0; i < aggregate->inputs.size(); ++i) { |
| 441 | inputVectors[firstInputColumn + i] = std::move(aggregateInputs[i]); |
| 442 | } |
| 443 | |
| 444 | firstInputColumn += aggregateInputs.size(); |
| 445 | } |
| 446 | } |
| 447 | |
| 448 | for (const auto& aggregate : aggregates) { |
| 449 | aggregate->function->extractValues( |
| 450 | groups.data(), groups.size(), &result->childAt(aggregate->output)); |
| 451 | |
| 452 | // Release memory back to HashStringAllocator to allow next aggregate to |
| 453 | // reuse it. |
no test coverage detected