Analyzer UniqInjectiveFunctionsEliminationPass

This commit is contained in:
Maksim Kita 2022-11-23 12:35:14 +01:00
parent 0076109654
commit 0bc3ff1ba3
3 changed files with 47 additions and 0 deletions

View File

@ -2,9 +2,13 @@
#include <Functions/IFunction.h> #include <Functions/IFunction.h>
#include <AggregateFunctions/AggregateFunctionFactory.h>
#include <AggregateFunctions/IAggregateFunction.h>
#include <Analyzer/InDepthQueryTreeVisitor.h> #include <Analyzer/InDepthQueryTreeVisitor.h>
#include <Analyzer/FunctionNode.h> #include <Analyzer/FunctionNode.h>
namespace DB namespace DB
{ {
@ -30,7 +34,9 @@ public:
if (!function_node || !function_node->isAggregateFunction() || !isUniqFunction(function_node->getFunctionName())) if (!function_node || !function_node->isAggregateFunction() || !isUniqFunction(function_node->getFunctionName()))
return; return;
bool replaced_argument = false;
auto & uniq_function_arguments_nodes = function_node->getArguments().getNodes(); auto & uniq_function_arguments_nodes = function_node->getArguments().getNodes();
for (auto & uniq_function_argument_node : uniq_function_arguments_nodes) for (auto & uniq_function_argument_node : uniq_function_arguments_nodes)
{ {
auto * uniq_function_argument_node_typed = uniq_function_argument_node->as<FunctionNode>(); auto * uniq_function_argument_node_typed = uniq_function_argument_node->as<FunctionNode>();
@ -49,7 +55,28 @@ public:
/// Replace injective function with its single argument /// Replace injective function with its single argument
uniq_function_argument_node = uniq_function_argument_node_argument_nodes[0]; uniq_function_argument_node = uniq_function_argument_node_argument_nodes[0];
replaced_argument = true;
} }
if (!replaced_argument)
return;
const auto & function_node_argument_nodes = function_node->getArguments().getNodes();
DataTypes argument_types;
argument_types.reserve(function_node_argument_nodes.size());
for (const auto & function_node_argument : function_node_argument_nodes)
argument_types.emplace_back(function_node_argument->getResultType());
AggregateFunctionProperties properties;
auto aggregate_function = AggregateFunctionFactory::instance().get(function_node->getFunctionName(),
argument_types,
function_node->getAggregateFunction()->getParameters(),
properties);
auto function_result_type = function_node->getResultType();
function_node->resolveAsAggregateFunction(std::move(aggregate_function), std::move(function_result_type));
} }
}; };

View File

@ -0,0 +1,15 @@
QUERY id: 0
PROJECTION COLUMNS
uniqCombined(tuple(\'\')) UInt64
PROJECTION
LIST id: 1, nodes: 1
FUNCTION id: 2, function_name: uniqCombined, function_type: aggregate, result_type: UInt64
ARGUMENTS
LIST id: 3, nodes: 1
CONSTANT id: 4, constant_value: \'\', constant_value_type: String
JOIN TREE
TABLE_FUNCTION id: 5, table_function_name: numbers
ARGUMENTS
LIST id: 6, nodes: 1
CONSTANT id: 7, constant_value: UInt64_1, constant_value_type: UInt8
1

View File

@ -0,0 +1,5 @@
SET allow_experimental_analyzer = 1;
EXPLAIN QUERY TREE SELECT uniqCombined(tuple('')) FROM numbers(1);
SELECT uniqCombined(tuple('')) FROM numbers(1);