Add extra argument to function 'nothing' only in QueryAnalysisPass

This commit is contained in:
vdimir 2023-11-27 17:37:31 +00:00
parent 04baafccba
commit 1f474a870a
No known key found for this signature in database
GPG Key ID: 6EE4CE2BEDC51862
4 changed files with 10 additions and 18 deletions

View File

@ -14,7 +14,8 @@ void registerAggregateFunctionNothing(AggregateFunctionFactory & factory)
{ {
assertNoParameters(name, parameters); assertNoParameters(name, parameters);
return std::make_shared<AggregateFunctionNothing>(argument_types, parameters); auto result_type = argument_types.empty() ? std::make_shared<DataTypeNullable>(std::make_shared<DataTypeNothing>()) : argument_types.front();
return std::make_shared<AggregateFunctionNothing>(argument_types, parameters, result_type);
}); });
} }

View File

@ -24,13 +24,8 @@ namespace ErrorCodes
class AggregateFunctionNothing final : public IAggregateFunctionHelper<AggregateFunctionNothing> class AggregateFunctionNothing final : public IAggregateFunctionHelper<AggregateFunctionNothing>
{ {
public: public:
AggregateFunctionNothing(const DataTypes & arguments, const Array & params) AggregateFunctionNothing(const DataTypes & arguments, const Array & params, const DataTypePtr & result_type_)
: IAggregateFunctionHelper<AggregateFunctionNothing>( : IAggregateFunctionHelper<AggregateFunctionNothing>(arguments, params, result_type_) {}
arguments,
params,
arguments.empty() ? std::make_shared<DataTypeNullable>(std::make_shared<DataTypeNothing>()) : arguments.front())
{
}
String getName() const override String getName() const override
{ {

View File

@ -101,14 +101,10 @@ public:
if (has_null_types) if (has_null_types)
{ {
/// Currently the only functions that returns not-NULL on all NULL arguments are count and uniq, and they returns UInt64. /// Currently the only functions that returns not-NULL on all NULL arguments are count and uniq, and they returns UInt64.
/// In that case we need to set type of first argument to UInt64 to have in as a result type.
if (properties.returns_default_when_only_null) if (properties.returns_default_when_only_null)
{ return std::make_shared<AggregateFunctionNothing>(arguments, params, std::make_shared<DataTypeUInt64>());
DataTypes new_arguments = {std::make_shared<DataTypeUInt64>()}; else
std::copy(arguments.begin(), arguments.end(), std::back_inserter(new_arguments)); return std::make_shared<AggregateFunctionNothing>(arguments, params, std::make_shared<DataTypeNullable>(std::make_shared<DataTypeNothing>()));
return std::make_shared<AggregateFunctionNothing>(new_arguments, params);
}
return std::make_shared<AggregateFunctionNothing>(arguments, params);
} }
assert(nested_function); assert(nested_function);

View File

@ -5194,11 +5194,11 @@ ProjectionNames QueryAnalyzer::resolveFunction(QueryTreeNodePtr & node, Identifi
* Also we don't want to replace first argument, but just prepend it because it may have aliases, for example * Also we don't want to replace first argument, but just prepend it because it may have aliases, for example
* SELECT count(NULL AS a), sum(a) FROM table * SELECT count(NULL AS a), sum(a) FROM table
*/ */
const auto & actual_argument_types = aggregate_function->getArgumentTypes(); const auto & actual_result_type = aggregate_function->getResultType();
if (!actual_argument_types.empty() && !argument_types.empty() && !argument_types[0]->equals(*actual_argument_types[0])) if (!argument_types.empty() && !argument_types.front()->equals(*actual_result_type))
{ {
QueryTreeNodes & nodes = function_node.getArguments().getNodes(); QueryTreeNodes & nodes = function_node.getArguments().getNodes();
QueryTreeNodes new_nodes = {std::make_shared<ConstantNode>(actual_argument_types[0]->getDefault(), actual_argument_types[0])}; QueryTreeNodes new_nodes = {std::make_shared<ConstantNode>(actual_result_type->getDefault(), actual_result_type)};
std::move(nodes.begin(), nodes.end(), std::back_inserter(new_nodes)); std::move(nodes.begin(), nodes.end(), std::back_inserter(new_nodes));
nodes = std::move(new_nodes); nodes = std::move(new_nodes);
} }