1#include <AggregateFunctions/parseAggregateFunctionParameters.h>
2#include <Parsers/ExpressionListParsers.h>
3#include <Parsers/parseQuery.h>
4#include <Common/typeid_cast.h>
5
6
7namespace DB
8{
9
10namespace ErrorCodes
11{
12 extern const int BAD_ARGUMENTS;
13 extern const int PARAMETERS_TO_AGGREGATE_FUNCTIONS_MUST_BE_LITERALS;
14}
15
16Array getAggregateFunctionParametersArray(const ASTPtr & expression_list, const std::string & error_context)
17{
18 const ASTs & parameters = expression_list->children;
19 if (parameters.empty())
20 throw Exception("Parameters list to aggregate functions cannot be empty", ErrorCodes::BAD_ARGUMENTS);
21
22 Array params_row(parameters.size());
23
24 for (size_t i = 0; i < parameters.size(); ++i)
25 {
26 const auto * literal = parameters[i]->as<ASTLiteral>();
27 if (!literal)
28 {
29 throw Exception("Parameters to aggregate functions must be literals" + (error_context.empty() ? "" : " (in " + error_context +")"),
30 ErrorCodes::PARAMETERS_TO_AGGREGATE_FUNCTIONS_MUST_BE_LITERALS);
31 }
32
33 params_row[i] = literal->value;
34 }
35
36 return params_row;
37}
38
39
40void getAggregateFunctionNameAndParametersArray(
41 const std::string & aggregate_function_name_with_params,
42 std::string & aggregate_function_name,
43 Array & aggregate_function_parameters,
44 const std::string & error_context)
45{
46 if (aggregate_function_name_with_params.back() != ')')
47 {
48 aggregate_function_name = aggregate_function_name_with_params;
49 aggregate_function_parameters = Array();
50 return;
51 }
52
53 size_t pos = aggregate_function_name_with_params.find('(');
54 if (pos == std::string::npos || pos + 2 >= aggregate_function_name_with_params.size())
55 throw Exception(aggregate_function_name_with_params + " doesn't look like aggregate function name in " + error_context + ".",
56 ErrorCodes::BAD_ARGUMENTS);
57
58 aggregate_function_name = aggregate_function_name_with_params.substr(0, pos);
59 std::string parameters_str = aggregate_function_name_with_params.substr(pos + 1, aggregate_function_name_with_params.size() - pos - 2);
60
61 if (aggregate_function_name.empty())
62 throw Exception(aggregate_function_name_with_params + " doesn't look like aggregate function name in " + error_context + ".",
63 ErrorCodes::BAD_ARGUMENTS);
64
65 ParserExpressionList params_parser(false);
66 ASTPtr args_ast = parseQuery(params_parser,
67 parameters_str.data(), parameters_str.data() + parameters_str.size(),
68 "parameters of aggregate function in " + error_context, 0);
69
70 if (args_ast->children.empty())
71 throw Exception("Incorrect list of parameters to aggregate function "
72 + aggregate_function_name, ErrorCodes::BAD_ARGUMENTS);
73
74 aggregate_function_parameters = getAggregateFunctionParametersArray(args_ast);
75}
76
77}
78