2014-03-27 12:48:09 +00:00
# pragma once
# include <DB/Columns/ColumnArray.h>
# include <DB/DataTypes/DataTypeArray.h>
# include <DB/AggregateFunctions/IAggregateFunction.h>
2017-03-12 10:13:45 +00:00
# include <DB/IO/WriteHelpers.h>
2014-03-27 12:48:09 +00:00
namespace DB
{
2017-03-09 00:56:38 +00:00
/** Not an aggregate function, but an adapter of aggregate functions,
* which any aggregate function ` agg ( x ) ` makes an aggregate function of the form ` aggArray ( x ) ` .
* The adapted aggregate function calculates nested aggregate function for each element of the array .
2014-03-27 12:48:09 +00:00
*/
2014-06-04 01:00:09 +00:00
class AggregateFunctionArray final : public IAggregateFunction
2014-03-27 12:48:09 +00:00
{
private :
AggregateFunctionPtr nested_func_owner ;
IAggregateFunction * nested_func ;
2016-07-10 17:19:35 +00:00
size_t num_agruments ;
2014-03-27 12:48:09 +00:00
public :
AggregateFunctionArray ( AggregateFunctionPtr nested_ ) : nested_func_owner ( nested_ ) , nested_func ( nested_func_owner . get ( ) ) { }
2015-11-11 02:04:23 +00:00
String getName ( ) const override
2014-03-27 12:48:09 +00:00
{
return nested_func - > getName ( ) + " Array " ;
}
2015-11-11 02:04:23 +00:00
DataTypePtr getReturnType ( ) const override
2014-03-27 12:48:09 +00:00
{
return nested_func - > getReturnType ( ) ;
}
2015-11-11 02:04:23 +00:00
void setArguments ( const DataTypes & arguments ) override
2014-03-27 12:48:09 +00:00
{
num_agruments = arguments . size ( ) ;
2016-01-13 00:47:12 +00:00
if ( 0 = = num_agruments )
throw Exception ( " Array aggregate functions requires at least one argument " , ErrorCodes : : NUMBER_OF_ARGUMENTS_DOESNT_MATCH ) ;
2014-03-27 12:48:09 +00:00
DataTypes nested_arguments ;
2016-07-10 17:19:35 +00:00
for ( size_t i = 0 ; i < num_agruments ; + + i )
2014-03-27 12:48:09 +00:00
{
2014-06-26 00:58:14 +00:00
if ( const DataTypeArray * array = typeid_cast < const DataTypeArray * > ( & * arguments [ i ] ) )
2014-03-27 12:48:09 +00:00
nested_arguments . push_back ( array - > getNestedType ( ) ) ;
else
throw Exception ( " Illegal type " + arguments [ i ] - > getName ( ) + " of argument # " + toString ( i + 1 ) + " for aggregate function " + getName ( ) + " . Must be array. " , ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
}
2016-01-13 00:47:12 +00:00
2014-03-27 12:48:09 +00:00
nested_func - > setArguments ( nested_arguments ) ;
}
2015-11-11 02:04:23 +00:00
void setParameters ( const Array & params ) override
2014-03-27 12:48:09 +00:00
{
nested_func - > setParameters ( params ) ;
}
2015-11-11 02:04:23 +00:00
void create ( AggregateDataPtr place ) const override
2014-03-27 12:48:09 +00:00
{
nested_func - > create ( place ) ;
}
2015-11-11 02:04:23 +00:00
void destroy ( AggregateDataPtr place ) const noexcept override
2014-03-27 12:48:09 +00:00
{
nested_func - > destroy ( place ) ;
}
2015-11-11 02:04:23 +00:00
bool hasTrivialDestructor ( ) const override
2014-03-27 12:48:09 +00:00
{
return nested_func - > hasTrivialDestructor ( ) ;
}
2015-11-11 02:04:23 +00:00
size_t sizeOfData ( ) const override
2014-03-27 12:48:09 +00:00
{
return nested_func - > sizeOfData ( ) ;
}
2015-11-11 02:04:23 +00:00
size_t alignOfData ( ) const override
2014-03-27 12:48:09 +00:00
{
return nested_func - > alignOfData ( ) ;
}
2017-01-09 12:26:32 +00:00
void add ( AggregateDataPtr place , const IColumn * * columns , size_t row_num , Arena * arena ) const override
2014-03-27 12:48:09 +00:00
{
2014-03-27 20:32:12 +00:00
const IColumn * nested [ num_agruments ] ;
2016-07-10 17:19:35 +00:00
for ( size_t i = 0 ; i < num_agruments ; + + i )
2014-03-27 20:32:12 +00:00
nested [ i ] = & static_cast < const ColumnArray & > ( * columns [ i ] ) . getData ( ) ;
const ColumnArray & first_array_column = static_cast < const ColumnArray & > ( * columns [ 0 ] ) ;
const IColumn : : Offsets_t & offsets = first_array_column . getOffsets ( ) ;
size_t begin = row_num = = 0 ? 0 : offsets [ row_num - 1 ] ;
size_t end = offsets [ row_num ] ;
for ( size_t i = begin ; i < end ; + + i )
2017-01-09 12:26:32 +00:00
nested_func - > add ( place , nested , i , arena ) ;
2014-03-27 12:48:09 +00:00
}
2016-09-23 23:33:17 +00:00
void merge ( AggregateDataPtr place , ConstAggregateDataPtr rhs , Arena * arena ) const override
2014-03-27 12:48:09 +00:00
{
2016-09-23 23:33:17 +00:00
nested_func - > merge ( place , rhs , arena ) ;
2014-03-27 12:48:09 +00:00
}
2015-11-11 02:04:23 +00:00
void serialize ( ConstAggregateDataPtr place , WriteBuffer & buf ) const override
2014-03-27 12:48:09 +00:00
{
nested_func - > serialize ( place , buf ) ;
}
2016-09-22 23:26:08 +00:00
void deserialize ( AggregateDataPtr place , ReadBuffer & buf , Arena * arena ) const override
2014-03-27 12:48:09 +00:00
{
2016-09-22 23:26:08 +00:00
nested_func - > deserialize ( place , buf , arena ) ;
2014-03-27 12:48:09 +00:00
}
2015-11-11 02:04:23 +00:00
void insertResultInto ( ConstAggregateDataPtr place , IColumn & to ) const override
2014-03-27 12:48:09 +00:00
{
nested_func - > insertResultInto ( place , to ) ;
}
2015-11-21 19:46:27 +00:00
2017-02-15 11:23:38 +00:00
bool allocatesMemoryInArena ( ) const override
{
return nested_func - > allocatesMemoryInArena ( ) ;
}
2016-09-19 22:30:40 +00:00
static void addFree ( const IAggregateFunction * that , AggregateDataPtr place , const IColumn * * columns , size_t row_num , Arena * arena )
2015-11-21 19:46:27 +00:00
{
2016-09-19 22:30:40 +00:00
static_cast < const AggregateFunctionArray & > ( * that ) . add ( place , columns , row_num , arena ) ;
2015-11-21 19:46:27 +00:00
}
IAggregateFunction : : AddFunc getAddressOfAddFunction ( ) const override final { return & addFree ; }
2014-03-27 12:48:09 +00:00
} ;
}