dbms: support for argMinIf and argMaxIf functions [#METR-9001]

This commit is contained in:
Sergey Fedorov 2013-10-28 16:13:19 +00:00
parent f7a6316abd
commit ff61e2cbc8
2 changed files with 11 additions and 11 deletions

View File

@ -19,6 +19,7 @@ class AggregateFunctionIf : public IAggregateFunction
private:
AggregateFunctionPtr nested_func_owner;
IAggregateFunction * nested_func;
int num_agruments;
public:
AggregateFunctionIf(AggregateFunctionPtr nested_) : nested_func_owner(nested_), nested_func(nested_func_owner.get()) {}
@ -34,15 +35,15 @@ public:
void setArguments(const DataTypes & arguments)
{
if (arguments.size() != 2)
throw Exception("Aggregate function " + getName() + " requires exactly two arguments.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
num_agruments = arguments.size();
if (!dynamic_cast<const DataTypeUInt8 *>(&*arguments[1]))
throw Exception("Illegal type " + arguments[1]->getName() + " of second argument for aggregate function " + getName() + ". Must be UInt8.",
if (!dynamic_cast<const DataTypeUInt8 *>(&*arguments[num_agruments - 1]))
throw Exception("Illegal type " + arguments[num_agruments - 1]->getName() + " of second argument for aggregate function " + getName() + ". Must be UInt8.",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
DataTypes nested_arguments;
nested_arguments.push_back(arguments[0]);
for (int i = 0; i < num_agruments - 1; i ++)
nested_arguments.push_back(arguments[i]);
nested_func->setArguments(nested_arguments);
}
@ -73,7 +74,7 @@ public:
void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num) const
{
if (static_cast<const ColumnUInt8 &>(*columns[1]).getData()[row_num])
if (static_cast<const ColumnUInt8 &>(*columns[num_agruments - 1]).getData()[row_num])
nested_func->add(place, columns, row_num);
}

View File

@ -278,10 +278,9 @@ AggregateFunctionPtr AggregateFunctionFactory::get(const String & name, const Da
else if (recursion_level == 0 && name.size() >= 3 && name[name.size() - 2] == 'I' && name[name.size() - 1] == 'f')
{
/// Для агрегатных функций вида aggIf, где agg - имя другой агрегатной функции.
if (argument_types.size() != 2)
throw Exception("Incorrect number of arguments for aggregate function " + name, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
AggregateFunctionPtr nested = get(String(name.data(), name.size() - 2), DataTypes(1, argument_types[0]), 1);
DataTypes nested_dt = argument_types;
nested_dt.pop_back();
AggregateFunctionPtr nested = get(String(name.data(), name.size() - 2), nested_dt);
return new AggregateFunctionIf(nested);
}
else