| 161 | } |
| 162 | |
| 163 | Result<ExecNode*> ScalarAggregateNode::Make(ExecPlan* plan, std::vector<ExecNode*> inputs, |
| 164 | const ExecNodeOptions& options) { |
| 165 | RETURN_NOT_OK(ValidateExecNodeInputs(plan, inputs, 1, "ScalarAggregateNode")); |
| 166 | |
| 167 | const auto& aggregate_options = checked_cast<const AggregateNodeOptions&>(options); |
| 168 | auto aggregates = aggregate_options.aggregates; |
| 169 | const auto& keys = aggregate_options.keys; |
| 170 | const auto& segment_keys = aggregate_options.segment_keys; |
| 171 | const auto concurrency = plan->query_context()->max_concurrency(); |
| 172 | // We can't use concurrency == 1 because that include I/O concurrency |
| 173 | const bool is_cpu_parallel = plan->query_context()->executor()->GetCapacity() > 1; |
| 174 | |
| 175 | if (keys.size() > 0) { |
| 176 | return Status::Invalid("Scalar aggregation with some key"); |
| 177 | } |
| 178 | if (is_cpu_parallel && segment_keys.size() > 0) { |
| 179 | return Status::NotImplemented("Segmented aggregation in a multi-threaded plan"); |
| 180 | } |
| 181 | |
| 182 | const auto& input_schema = inputs[0]->output_schema(); |
| 183 | auto exec_ctx = plan->query_context()->exec_context(); |
| 184 | |
| 185 | ARROW_ASSIGN_OR_RAISE( |
| 186 | auto args, MakeAggregateNodeArgs(input_schema, keys, segment_keys, aggregates, |
| 187 | exec_ctx, concurrency, is_cpu_parallel)); |
| 188 | |
| 189 | if (is_cpu_parallel) { |
| 190 | for (auto& kernel : args.kernels) { |
| 191 | if (kernel->ordered) { |
| 192 | return Status::NotImplemented( |
| 193 | "Using ordered aggregator in multiple threaded execution is not supported"); |
| 194 | } |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | return plan->EmplaceNode<ScalarAggregateNode>( |
| 199 | plan, std::move(inputs), std::move(args.output_schema), std::move(args.segmenter), |
| 200 | std::move(args.segment_key_field_ids), std::move(args.target_fieldsets), |
| 201 | std::move(args.aggregates), std::move(args.kernels), std::move(args.kernel_intypes), |
| 202 | std::move(args.states)); |
| 203 | } |
| 204 | |
| 205 | Status ScalarAggregateNode::DoConsume(const ExecSpan& batch, size_t thread_index) { |
| 206 | for (size_t i = 0; i < kernels_.size(); ++i) { |
nothing calls this directly
no test coverage detected