| 581 | } |
| 582 | |
| 583 | TypePtr resolveAggregateType( |
| 584 | const std::string& aggregateName, |
| 585 | core::AggregationNode::Step step, |
| 586 | const std::vector<TypePtr>& rawInputTypes, |
| 587 | bool nullOnFailure) { |
| 588 | if (auto signatures = exec::getAggregateFunctionSignatures(aggregateName)) { |
| 589 | for (const auto& signature : signatures.value()) { |
| 590 | exec::SignatureBinder binder(*signature, rawInputTypes); |
| 591 | if (binder.tryBind()) { |
| 592 | return binder.tryResolveType( |
| 593 | exec::isPartialOutput(step) ? signature->intermediateType() |
| 594 | : signature->returnType()); |
| 595 | } |
| 596 | } |
| 597 | |
| 598 | if (nullOnFailure) { |
| 599 | return nullptr; |
| 600 | } |
| 601 | |
| 602 | throwAggregateFunctionSignatureNotSupported( |
| 603 | aggregateName, rawInputTypes, signatures.value()); |
| 604 | } |
| 605 | |
| 606 | // We may be parsing lambda expression used in a lambda aggregate function. In |
| 607 | // this case, 'aggregateName' would refer to a scalar function. |
| 608 | // |
| 609 | // TODO Enhance the parser to allow for specifying separate resolver for |
| 610 | // lambda expressions. |
| 611 | if (auto type = |
| 612 | exec::resolveTypeForSpecialForm(aggregateName, rawInputTypes)) { |
| 613 | return type; |
| 614 | } |
| 615 | |
| 616 | if (auto type = parse::resolveScalarFunctionType( |
| 617 | aggregateName, rawInputTypes, true)) { |
| 618 | return type; |
| 619 | } |
| 620 | |
| 621 | if (nullOnFailure) { |
| 622 | return nullptr; |
| 623 | } |
| 624 | |
| 625 | throwAggregateFunctionDoesntExist(aggregateName); |
| 626 | return nullptr; |
| 627 | } |
| 628 | |
| 629 | class AggregateTypeResolver { |
| 630 | public: |
no test coverage detected