| 661 | } |
| 662 | |
| 663 | bool GroupingSet::getDefaultGlobalGroupingSetOutput( |
| 664 | RowContainerIterator& iterator, |
| 665 | RowVectorPtr& result) { |
| 666 | BOLT_CHECK(hasDefaultGlobalGroupingSetOutput()); |
| 667 | |
| 668 | if (iterator.allocationIndex != 0) { |
| 669 | return false; |
| 670 | } |
| 671 | // Global aggregates don't have grouping keys. But global grouping sets |
| 672 | // have null values in grouping keys and a groupId column as well. These |
| 673 | // key fields precede the aggregate columns in the result. |
| 674 | // This logic builds a row with just aggregate fields to reuse the global |
| 675 | // aggregate computation from the regular GroupingSet code-path. |
| 676 | auto outputType = asRowType(result->type()); |
| 677 | auto firstAggregateCol = outputType->size() - aggregates_.size(); |
| 678 | std::vector<std::string> names; |
| 679 | std::vector<TypePtr> types; |
| 680 | names.reserve(aggregates_.size()); |
| 681 | types.reserve(aggregates_.size()); |
| 682 | for (auto i = firstAggregateCol; i < outputType->size(); i++) { |
| 683 | names.push_back(outputType->nameOf(i)); |
| 684 | types.push_back(outputType->childAt(i)); |
| 685 | } |
| 686 | auto aggregatesType = ROW(std::move(names), std::move(types)); |
| 687 | auto globalAggregatesRow = |
| 688 | BaseVector::create<RowVector>(aggregatesType, 1, &pool_); |
| 689 | |
| 690 | BOLT_CHECK(getGlobalAggregationOutput(iterator, globalAggregatesRow)); |
| 691 | |
| 692 | // There is one output row for each global GroupingSet. |
| 693 | const auto numGroupingSets = globalGroupingSets_.size(); |
| 694 | result->resize(numGroupingSets); |
| 695 | BOLT_CHECK(groupIdChannel_.has_value()); |
| 696 | // These first columns are for grouping keys (which could include the |
| 697 | // GroupId column). For a global grouping set row : |
| 698 | // i) Non-groupId grouping keys are null. |
| 699 | // ii) GroupId column is populated with the global grouping set number. |
| 700 | for (auto i = 0; i < firstAggregateCol; i++) { |
| 701 | auto column = result->childAt(i); |
| 702 | if (i == groupIdChannel_.value()) { |
| 703 | column->resize(numGroupingSets); |
| 704 | auto* groupIdVector = column->asFlatVector<int64_t>(); |
| 705 | for (auto j = 0; j < numGroupingSets; j++) { |
| 706 | groupIdVector->set(j, globalGroupingSets_.at(j)); |
| 707 | } |
| 708 | } else { |
| 709 | column->resize(numGroupingSets, false); |
| 710 | for (auto j = 0; j < numGroupingSets; j++) { |
| 711 | column->setNull(j, true); |
| 712 | } |
| 713 | } |
| 714 | } |
| 715 | |
| 716 | // The remaining aggregate columns are filled from the computed global |
| 717 | // aggregates. |
| 718 | for (auto i = firstAggregateCol; i < outputType->size(); i++) { |
| 719 | auto resultAggregateColumn = result->childAt(i); |
| 720 | resultAggregateColumn->resize(numGroupingSets); |
no test coverage detected