| 865 | NanosecondTimer timer(&stats_.aggExtractGroupsTimeNs); |
| 866 | if (groups.empty()) { |
| 867 | return; |
| 868 | } |
| 869 | // 4 bytes for rowSize |
| 870 | static constexpr int32_t headerSize = sizeof(RowSizeType); |
| 871 | const auto& rowInfo = rowInfo_.value(); |
| 872 | char *rowStart = nullptr, *newRow = nullptr; |
| 873 | RowSizeType rowSize = 0, actualRowSize = 0; |
| 874 | const auto& compositeResult = |
| 875 | std::dynamic_pointer_cast<CompositeRowVector>(result); |
| 876 | BOLT_CHECK(compositeResult); |
| 877 | compositeResult->setRowOffset(sizeof(RowSizeType)); |
| 878 | |
| 879 | convertRowsFromContainerRows(compositeResult, groups, resultRanges); |
| 880 | } |
| 881 | |
| 882 | void GroupingSet::extractGroups( |
| 883 | folly::Range<char**> groups, |
| 884 | const RowVectorPtr& result, |
| 885 | bool excludeKey) { |
| 886 | NanosecondTimer timer(&stats_.aggExtractGroupsTimeNs); |
| 887 | result->resize(groups.size()); |
| 888 | if (groups.empty()) { |
| 889 | return; |
| 890 | } |
| 891 | RowContainer& rows = *table_->rows(); |
| 892 | auto totalKeys = rows.keyTypes().size(); |
| 893 | if (!excludeKey) { |
| 894 | for (int32_t i = 0; i < totalKeys; ++i) { |
| 895 | auto keyVector = result->childAt(i); |
| 896 | rows.extractColumn(groups.data(), groups.size(), i, keyVector); |
| 897 | } |
| 898 | } |
| 899 | for (int32_t i = 0; i < aggregates_.size(); ++i) { |
| 900 | if (!aggregates_[i].sortingKeys.empty()) { |
| 901 | continue; |
| 902 | } |
| 903 | |
| 904 | auto& function = aggregates_[i].function; |
| 905 | auto& aggregateVector = result->childAt(i + totalKeys); |
| 906 | if (isPartial_) { |
| 907 | function->extractAccumulators( |
| 908 | groups.data(), groups.size(), &aggregateVector); |
| 909 | } else { |
| 910 | function->extractValues(groups.data(), groups.size(), &aggregateVector); |
| 911 | } |
nothing calls this directly
no test coverage detected