@ -2,12 +2,18 @@
# include <Poco/NumberFormatter.h>
# include <DB/Columns/ColumnsNumber.h>
# include <DB/Columns/ColumnConst.h>
# include <DB/Columns/ColumnString.h>
# include <DB/Columns/ColumnFixedString.h>
# include <DB/DataTypes/DataTypesNumberFixed.h>
# include <DB/DataTypes/DataTypesNumberVariable.h>
# include <DB/DataTypes/DataTypeDateTime.h>
# include <DB/DataTypes/DataTypeDate.h>
# include <DB/DataTypes/DataTypeString.h>
# include <DB/DataTypes/DataTypeFixedString.h>
# include <DB/Functions/IFunction.h>
@ -25,42 +31,50 @@ namespace DB
* в н у т р и к а ж д о й г р у п п ы , н о н е и з р а з н ы х г р у п п .
*/
/** Игнорируем warning о сравнении signed и unsigned.
* ( Р е з у л ь т а т м о ж е т б ы т ь н е к о р р е к т н ы м . )
*/
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wsign-compare"
template < typename A , typename B >
struct EqualsNumImpl
{
typedef UInt8 ResultType ;
static void vector_vector ( const std : : vector < A > & a , const std : : vector < B > & b , std : : vector < ResultType > & c )
static void vector_vector ( const std : : vector < A > & a , const std : : vector < B > & b , std : : vector < UInt8 > & c )
{
size_t size = a . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
c [ i ] = a [ i ] = = b [ i ] ;
}
static void vector_constant ( const std : : vector < A > & a , B b , std : : vector < ResultType > & c )
static void vector_constant ( const std : : vector < A > & a , B b , std : : vector < UInt8 > & c )
{
size_t size = a . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
c [ i ] = a [ i ] = = b ;
}
static void constant_constant ( A a , B b , ResultType & c )
static void constant_vector ( A a , const std : : vector < B > & b , std : : vector < UInt8 > & c )
{
size_t size = b . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
c [ i ] = a = = b [ i ] ;
}
static void constant_constant ( A a , B b , UInt8 & c )
{
c = a = = b ;
}
} ;
template < typename A , typename B >
struct EqualsStringImpl
{
typedef UInt8 ResultType ;
static void string_vector_string_vector (
const std : : vector < UInt8 > & a_data , const std : : vector < size_t > & a_offsets ,
const std : : vector < UInt8 > & b_data , const std : : vector < size_t > & b_offsets ,
std : : vector < ResultType > & c )
std : : vector < UInt8 > & c )
{
size_t size = a_ data . size ( ) ;
size_t size = a_ offsets . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
c [ i ] = ( i = = 0 )
? ( a_offsets [ 0 ] = = b_offsets [ 0 ] & & ! memcmp ( & a_data [ 0 ] , & b_data [ 0 ] , a_offsets [ 0 ] ) )
@ -71,130 +85,135 @@ struct EqualsStringImpl
static void string_vector_fixed_string_vector (
const std : : vector < UInt8 > & a_data , const std : : vector < size_t > & a_offsets ,
const std : : vector < UInt8 > & b_data , size_t b_n ,
std : : vector < ResultType > & c )
std : : vector < UInt8 > & c )
{
size_t size = a_ data . size ( ) ;
size_t size = a_ offsets . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
c [ i ] = ( i = = 0 )
? ( a_offsets [ 0 ] = = b_n && ! memcmp ( & a_data [ 0 ] , & b_data [ 0 ] , b_n ) )
: ( a_offsets [ i ] - a_offsets [ i - 1 ] = = b_n
? ( a_offsets [ 0 ] = = b_n + 1 && ! memcmp ( & a_data [ 0 ] , & b_data [ 0 ] , b_n ) )
: ( a_offsets [ i ] - a_offsets [ i - 1 ] = = b_n + 1
& & ! memcmp ( & a_data [ a_offsets [ i - 1 ] ] , & b_data [ b_n * i ] , b_n ) ) ;
}
static void string_vector_constant (
const std : : vector < UInt8 > & a_data , const std : : vector < size_t > & a_offsets ,
const std : : string & b ,
std : : vector < ResultType > & c )
std : : vector < UInt8 > & c )
{
size_t size = a_ data . size ( ) ;
size_t size = a_ offsets . size ( ) ;
size_t b_n = b . size ( ) ;
const UInt8 * b_data = reinterpret_cast < const UInt8 * > ( b . data ( ) )
const UInt8 * b_data = reinterpret_cast < const UInt8 * > ( b . data ( ) ) ;
for ( size_t i = 0 ; i < size ; + + i )
c [ i ] = ( i = = 0 )
? ( a_offsets [ 0 ] = = b_n && ! memcmp ( & a_data [ 0 ] , b_data , b_n ) )
: ( a_offsets [ i ] - a_offsets [ i - 1 ] = = b_n
? ( a_offsets [ 0 ] = = b_n + 1 && ! memcmp ( & a_data [ 0 ] , b_data , b_n ) )
: ( a_offsets [ i ] - a_offsets [ i - 1 ] = = b_n + 1
& & ! memcmp ( & a_data [ a_offsets [ i - 1 ] ] , b_data , b_n ) ) ;
}
static void fixed_string_vector_string_vector (
const std : : vector < UInt8 > & a_data , size_t a_n ,
const std : : vector < UInt8 > & b_data , const std : : vector < size_t > & b_offsets ,
std : : vector < UInt8 > & c )
{
size_t size = b_offsets . size ( ) ;
for ( size_t i = 0 ; i < size ; + + i )
c [ i ] = ( i = = 0 )
? ( b_offsets [ 0 ] = = a_n + 1 & & ! memcmp ( & b_data [ 0 ] , & a_data [ 0 ] , a_n ) )
: ( b_offsets [ i ] - b_offsets [ i - 1 ] = = a_n + 1
& & ! memcmp ( & b_data [ b_offsets [ i - 1 ] ] , & a_data [ a_n * i ] , a_n ) ) ;
}
static void fixed_string_vector_fixed_string_vector (
const std : : vector < UInt8 > & a_data , size_t a_n ,
const std : : vector < UInt8 > & b_data , size_t b_n ,
std : : vector < ResultType > & c )
std : : vector < UInt8 > & c )
{
size_t size = a_data . size ( ) ;
for ( size_t i = 0 ; i < size ; i + = n )
c [ i ] = a_n = = b_n & & ! memcmp ( & a_data [ i ] , & b_data [ i ] , n ) ;
for ( size_t i = 0 ; i < size ; i + = a_ n)
c [ i ] = a_n = = b_n & & ! memcmp ( & a_data [ i ] , & b_data [ i ] , a_ n) ;
}
static void fixed_string_vector_constant (
const std : : vector < UInt8 > & a_data , size_t a_n ,
const std : : string & b ,
std : : vector < ResultType > & c )
std : : vector < UInt8 > & c )
{
size_t size = a_data . size ( ) ;
for ( size_t i = 0 ; i < size ; i + = n )
c [ i ] = ! memcmp ( & a_data [ i ] , & b_data [ i ] , n ) ;
const UInt8 * b_data = reinterpret_cast < const UInt8 * > ( b . data ( ) ) ;
size_t b_n = b . size ( ) ;
for ( size_t i = 0 ; i < size ; i + = a_n )
c [ i ] = a_n = = b_n & & ! memcmp ( & a_data [ i ] , b_data , a_n ) ;
}
static void constant_string_vector (
const std : : string & a ,
const std : : vector < UInt8 > & b_data , const std : : vector < size_t > & b_offsets ,
std : : vector < UInt8 > & c )
{
size_t size = b_offsets . size ( ) ;
size_t a_n = a . size ( ) ;
const UInt8 * a_data = reinterpret_cast < const UInt8 * > ( a . data ( ) ) ;
for ( size_t i = 0 ; i < size ; + + i )
c [ i ] = ( i = = 0 )
? ( b_offsets [ 0 ] = = a_n + 1 & & ! memcmp ( & b_data [ 0 ] , a_data , a_n ) )
: ( b_offsets [ i ] - b_offsets [ i - 1 ] = = a_n + 1
& & ! memcmp ( & b_data [ b_offsets [ i - 1 ] ] , a_data , a_n ) ) ;
}
static void constant_fixed_string_vector (
const std : : string & a ,
const std : : vector < UInt8 > & b_data , size_t b_n ,
std : : vector < UInt8 > & c )
{
size_t size = b_data . size ( ) ;
const UInt8 * a_data = reinterpret_cast < const UInt8 * > ( a . data ( ) ) ;
size_t a_n = a . size ( ) ;
for ( size_t i = 0 ; i < size ; i + = b_n )
c [ i ] = a_n = = b_n & & ! memcmp ( & b_data [ i ] , a_data , b_n ) ;
}
static void constant_constant (
const std : : string & a ,
const std : : string & b ,
std : : string & c )
UInt8 & c )
{
c = a = = b ;
}
} ;
# pragma GCC diagnostic pop
template < template < typename , typename > class Impl , typename Name >
template <
template < typename , typename > class NumImpl ,
typename StringImpl ,
typename Name >
class FunctionComparison : public IFunction
{
private :
template < typename T0 , typename T1 >
bool checkRightType ( const DataTypes & arguments , DataTypes & types_res ) const
{
if ( dynamic_cast < const T1 * > ( & * arguments [ 1 ] ) )
{
types_res . push_back ( new typename DataTypeFromFieldType <
typename Impl < typename T0 : : FieldType , typename T1 : : FieldType > : : ResultType > : : Type ) ;
return true ;
}
return false ;
}
template < typename T0 >
bool checkLeftType ( const DataTypes & arguments , DataTypes & types_res ) const
{
if ( dynamic_cast < const T0 * > ( & * arguments [ 0 ] ) )
{
if ( checkRightType < T0 , DataTypeUInt8 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeUInt16 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeUInt32 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeUInt64 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeInt8 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeInt16 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeInt32 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeInt64 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeFloat32 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeFloat64 > ( arguments , types_res )
| | checkRightType < T0 , DataTypeVarUInt > ( arguments , types_res )
| | checkRightType < T0 , DataTypeVarInt > ( arguments , types_res ) )
return true ;
else
throw Exception ( " Illegal type " + arguments [ 1 ] - > getName ( ) + " of second argument of function " + getName ( ) ,
ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
}
return false ;
}
template < typename T0 , typename T1 >
bool execute RightType( Block & block , const ColumnNumbers & arguments , const ColumnNumbers & result , const ColumnVector < T0 > * col_left )
bool executeNumRightType ( Block & block , const ColumnNumbers & arguments , const ColumnNumbers & result , const ColumnVector < T0 > * col_left )
{
if ( ColumnVector < T1 > * col_right = dynamic_cast < ColumnVector < T1 > * > ( & * block . getByPosition ( arguments [ 1 ] ) . column ) )
{
typedef typename Impl < T0 , T1 > : : ResultType ResultType ;
ColumnVector < ResultType > * col_res = new ColumnVector < ResultType > ;
ColumnUInt8 * col_res = new ColumnUInt8 ;
block . getByPosition ( result [ 0 ] ) . column = col_res ;
typename ColumnVector < ResultType > : : Container_t & vec_res = col_res - > getData ( ) ;
ColumnUInt8 : : Container_t & vec_res = col_res - > getData ( ) ;
vec_res . resize ( col_left - > getData ( ) . size ( ) ) ;
Impl< T0 , T1 > : : vector_vector ( col_left - > getData ( ) , col_right - > getData ( ) , vec_res ) ;
NumImpl < T0 , T1 > : : vector_vector ( col_left - > getData ( ) , col_right - > getData ( ) , vec_res ) ;
return true ;
}
else if ( ColumnConst < T1 > * col_right = dynamic_cast < ColumnConst < T1 > * > ( & * block . getByPosition ( arguments [ 1 ] ) . column ) )
{
typedef typename Impl < T0 , T1 > : : ResultType ResultType ;
ColumnVector < ResultType > * col_res = new ColumnVector < ResultType > ;
ColumnUInt8 * col_res = new ColumnUInt8 ;
block . getByPosition ( result [ 0 ] ) . column = col_res ;
typename ColumnVector < ResultType > : : Container_t & vec_res = col_res - > getData ( ) ;
ColumnUInt8 : : Container_t & vec_res = col_res - > getData ( ) ;
vec_res . resize ( col_left - > getData ( ) . size ( ) ) ;
Impl< T0 , T1 > : : vector_constant ( col_left - > getData ( ) , col_right - > getData ( ) , vec_res ) ;
NumImpl < T0 , T1 > : : vector_constant ( col_left - > getData ( ) , col_right - > getData ( ) , vec_res ) ;
return true ;
}
@ -203,29 +222,25 @@ private:
}
template < typename T0 , typename T1 >
bool execute ConstRightType( Block & block , const ColumnNumbers & arguments , const ColumnNumbers & result , const ColumnConst < T0 > * col_left )
bool execute Num ConstRightType( Block & block , const ColumnNumbers & arguments , const ColumnNumbers & result , const ColumnConst < T0 > * col_left )
{
if ( ColumnVector < T1 > * col_right = dynamic_cast < ColumnVector < T1 > * > ( & * block . getByPosition ( arguments [ 1 ] ) . column ) )
{
typedef typename Impl < T0 , T1 > : : ResultType ResultType ;
ColumnVector < ResultType > * col_res = new ColumnVector < ResultType > ;
ColumnUInt8 * col_res = new ColumnUInt8 ;
block . getByPosition ( result [ 0 ] ) . column = col_res ;
typename ColumnVector < ResultType > : : Container_t & vec_res = col_res - > getData ( ) ;
ColumnUInt8 : : Container_t & vec_res = col_res - > getData ( ) ;
vec_res . resize ( col_left - > size ( ) ) ;
Impl< T0 , T1 > : : constant_vector ( col_left - > getData ( ) , col_right - > getData ( ) , vec_res ) ;
Num Impl< T0 , T1 > : : constant_vector ( col_left - > getData ( ) , col_right - > getData ( ) , vec_res ) ;
return true ;
}
else if ( ColumnConst < T1 > * col_right = dynamic_cast < ColumnConst < T1 > * > ( & * block . getByPosition ( arguments [ 1 ] ) . column ) )
{
typedef typename Impl < T0 , T1 > : : ResultType ResultType ;
ResultType res = 0 ;
Impl < T0 , T1 > : : constant_constant ( col_left - > getData ( ) , col_right - > getData ( ) , res ) ;
UInt8 res = 0 ;
NumImpl < T0 , T1 > : : constant_constant ( col_left - > getData ( ) , col_right - > getData ( ) , res ) ;
ColumnConst < ResultType > * col_res = new ColumnConst < ResultType > ( col_left - > size ( ) , res ) ;
ColumnConstUInt8 * col_res = new ColumnConstUInt8 ( col_left - > size ( ) , res ) ;
block . getByPosition ( result [ 0 ] ) . column = col_res ;
return true ;
@ -235,20 +250,20 @@ private:
}
template < typename T0 >
bool execute LeftType( Block & block , const ColumnNumbers & arguments , const ColumnNumbers & result )
bool execute Num LeftType( Block & block , const ColumnNumbers & arguments , const ColumnNumbers & result )
{
if ( ColumnVector < T0 > * col_left = dynamic_cast < ColumnVector < T0 > * > ( & * block . getByPosition ( arguments [ 0 ] ) . column ) )
{
if ( execute RightType< T0 , UInt8 > ( block , arguments , result , col_left )
| | execute RightType< T0 , UInt16 > ( block , arguments , result , col_left )
| | execute RightType< T0 , UInt32 > ( block , arguments , result , col_left )
| | execute RightType< T0 , UInt64 > ( block , arguments , result , col_left )
| | execute RightType< T0 , Int8 > ( block , arguments , result , col_left )
| | execute RightType< T0 , Int16 > ( block , arguments , result , col_left )
| | execute RightType< T0 , Int32 > ( block , arguments , result , col_left )
| | execute RightType< T0 , Int64 > ( block , arguments , result , col_left )
| | execute RightType< T0 , Float32 > ( block , arguments , result , col_left )
| | execute RightType< T0 , Float64 > ( block , arguments , result , col_left ) )
if ( execute Num RightType< T0 , UInt8 > ( block , arguments , result , col_left )
| | execute Num RightType< T0 , UInt16 > ( block , arguments , result , col_left )
| | execute Num RightType< T0 , UInt32 > ( block , arguments , result , col_left )
| | execute Num RightType< T0 , UInt64 > ( block , arguments , result , col_left )
| | execute Num RightType< T0 , Int8 > ( block , arguments , result , col_left )
| | execute Num RightType< T0 , Int16 > ( block , arguments , result , col_left )
| | execute Num RightType< T0 , Int32 > ( block , arguments , result , col_left )
| | execute Num RightType< T0 , Int64 > ( block , arguments , result , col_left )
| | execute Num RightType< T0 , Float32 > ( block , arguments , result , col_left )
| | execute Num RightType< T0 , Float64 > ( block , arguments , result , col_left ) )
return true ;
else
throw Exception ( " Illegal column of second argument of function " + getName ( ) ,
@ -256,16 +271,16 @@ private:
}
else if ( ColumnConst < T0 > * col_left = dynamic_cast < ColumnConst < T0 > * > ( & * block . getByPosition ( arguments [ 0 ] ) . column ) )
{
if ( execute ConstRightType< T0 , UInt8 > ( block , arguments , result , col_left )
| | execute ConstRightType< T0 , UInt16 > ( block , arguments , result , col_left )
| | execute ConstRightType< T0 , UInt32 > ( block , arguments , result , col_left )
| | execute ConstRightType< T0 , UInt64 > ( block , arguments , result , col_left )
| | execute ConstRightType< T0 , Int8 > ( block , arguments , result , col_left )
| | execute ConstRightType< T0 , Int16 > ( block , arguments , result , col_left )
| | execute ConstRightType< T0 , Int32 > ( block , arguments , result , col_left )
| | execute ConstRightType< T0 , Int64 > ( block , arguments , result , col_left )
| | execute ConstRightType< T0 , Float32 > ( block , arguments , result , col_left )
| | execute ConstRightType< T0 , Float64 > ( block , arguments , result , col_left ) )
if ( execute Num ConstRightType< T0 , UInt8 > ( block , arguments , result , col_left )
| | execute Num ConstRightType< T0 , UInt16 > ( block , arguments , result , col_left )
| | execute Num ConstRightType< T0 , UInt32 > ( block , arguments , result , col_left )
| | execute Num ConstRightType< T0 , UInt64 > ( block , arguments , result , col_left )
| | execute Num ConstRightType< T0 , Int8 > ( block , arguments , result , col_left )
| | execute Num ConstRightType< T0 , Int16 > ( block , arguments , result , col_left )
| | execute Num ConstRightType< T0 , Int32 > ( block , arguments , result , col_left )
| | execute Num ConstRightType< T0 , Int64 > ( block , arguments , result , col_left )
| | execute Num ConstRightType< T0 , Float32 > ( block , arguments , result , col_left )
| | execute Num ConstRightType< T0 , Float64 > ( block , arguments , result , col_left ) )
return true ;
else
throw Exception ( " Illegal column of second argument of function " + getName ( ) ,
@ -274,9 +289,80 @@ private:
return false ;
}
void executeString ( Block & block , const ColumnNumbers & arguments , const ColumnNumbers & result )
{
IColumn * c0 = & * block . getByPosition ( arguments [ 0 ] ) . column ;
IColumn * c1 = & * block . getByPosition ( arguments [ 1 ] ) . column ;
ColumnString * c0_string = dynamic_cast < ColumnString * > ( c0 ) ;
ColumnString * c1_string = dynamic_cast < ColumnString * > ( c1 ) ;
ColumnFixedString * c0_fixed_string = dynamic_cast < ColumnFixedString * > ( c0 ) ;
ColumnFixedString * c1_fixed_string = dynamic_cast < ColumnFixedString * > ( c1 ) ;
ColumnConstString * c0_const = dynamic_cast < ColumnConstString * > ( c0 ) ;
ColumnConstString * c1_const = dynamic_cast < ColumnConstString * > ( c1 ) ;
if ( c0_const & & c1_const )
{
ColumnConstUInt8 * c_res = new ColumnConstUInt8 ( c0_const - > size ( ) , 0 ) ;
block . getByPosition ( result [ 0 ] ) . column = c_res ;
StringImpl : : constant_constant ( c0_const - > getData ( ) , c1_const - > getData ( ) , c_res - > getData ( ) ) ;
}
else
{
ColumnUInt8 * c_res = new ColumnUInt8 ;
block . getByPosition ( result [ 0 ] ) . column = c_res ;
ColumnUInt8 : : Container_t & vec_res = c_res - > getData ( ) ;
vec_res . resize ( c0 - > size ( ) ) ;
if ( c0_string & & c1_string )
StringImpl : : string_vector_string_vector (
dynamic_cast < ColumnUInt8 & > ( c0_string - > getData ( ) ) . getData ( ) , c0_string - > getOffsets ( ) ,
dynamic_cast < ColumnUInt8 & > ( c1_string - > getData ( ) ) . getData ( ) , c1_string - > getOffsets ( ) ,
c_res - > getData ( ) ) ;
else if ( c0_string & & c1_fixed_string )
StringImpl : : string_vector_fixed_string_vector (
dynamic_cast < ColumnUInt8 & > ( c0_string - > getData ( ) ) . getData ( ) , c0_string - > getOffsets ( ) ,
dynamic_cast < ColumnUInt8 & > ( c1_fixed_string - > getData ( ) ) . getData ( ) , c1_fixed_string - > getN ( ) ,
c_res - > getData ( ) ) ;
else if ( c0_string & & c1_const )
StringImpl : : string_vector_constant (
dynamic_cast < ColumnUInt8 & > ( c0_string - > getData ( ) ) . getData ( ) , c0_string - > getOffsets ( ) ,
c1_const - > getData ( ) ,
c_res - > getData ( ) ) ;
else if ( c0_fixed_string & & c1_string )
StringImpl : : fixed_string_vector_string_vector (
dynamic_cast < ColumnUInt8 & > ( c0_fixed_string - > getData ( ) ) . getData ( ) , c0_fixed_string - > getN ( ) ,
dynamic_cast < ColumnUInt8 & > ( c1_string - > getData ( ) ) . getData ( ) , c1_string - > getOffsets ( ) ,
c_res - > getData ( ) ) ;
else if ( c0_fixed_string & & c1_fixed_string )
StringImpl : : fixed_string_vector_fixed_string_vector (
dynamic_cast < ColumnUInt8 & > ( c0_fixed_string - > getData ( ) ) . getData ( ) , c0_fixed_string - > getN ( ) ,
dynamic_cast < ColumnUInt8 & > ( c1_fixed_string - > getData ( ) ) . getData ( ) , c1_fixed_string - > getN ( ) ,
c_res - > getData ( ) ) ;
else if ( c0_fixed_string & & c1_const )
StringImpl : : fixed_string_vector_constant (
dynamic_cast < ColumnUInt8 & > ( c0_fixed_string - > getData ( ) ) . getData ( ) , c0_fixed_string - > getN ( ) ,
c1_const - > getData ( ) ,
c_res - > getData ( ) ) ;
else if ( c0_const & & c1_string )
StringImpl : : constant_string_vector (
c0_const - > getData ( ) ,
dynamic_cast < ColumnUInt8 & > ( c1_string - > getData ( ) ) . getData ( ) , c1_string - > getOffsets ( ) ,
c_res - > getData ( ) ) ;
else if ( c0_const & & c1_fixed_string )
StringImpl : : constant_fixed_string_vector (
c0_const - > getData ( ) ,
dynamic_cast < ColumnUInt8 & > ( c1_fixed_string - > getData ( ) ) . getData ( ) , c1_fixed_string - > getN ( ) ,
c_res - > getData ( ) ) ;
else
throw Exception ( " Illegal columns of arguments of function " + getName ( ) ,
ErrorCodes : : ILLEGAL_COLUMN ) ;
}
}
public :
/// Получить все имена функции.
/// Получить имя функции.
String getName ( ) const
{
return Name : : get ( ) ;
@ -290,23 +376,16 @@ public:
+ Poco : : NumberFormatter : : format ( arguments . size ( ) ) + " , should be 2. " ,
ErrorCodes : : NUMBER_OF_ARGUMENTS_DOESNT_MATCH ) ;
if ( ! ( ( arguments [ 0 ] - > isNumeric ( ) & & arguments [ 1 ] - > isNumeric ( ) )
| | ( ( arguments [ 0 ] - > getName ( ) = = " String " | | arguments [ 0 ] - > getName ( ) . substr ( 0 , 11 ) = = " FixedString " )
& & ( arguments [ 1 ] - > getName ( ) = = " String " | | arguments [ 1 ] - > getName ( ) . substr ( 0 , 11 ) = = " FixedString " ) )
| | ( arguments [ 0 ] - > getName ( ) = = " Date " & & arguments [ 1 ] - > getName ( ) = = " Date " )
| | ( arguments [ 0 ] - > getName ( ) = = " DateTime " & & arguments [ 1 ] - > getName ( ) = = " DateTime " ) ) )
throw Exception ( " Illegal types of arguments ( " + arguments [ 0 ] - > getName ( ) + " , " + arguments [ 1 ] - > getName ( ) + " ) "
" of function " + getName ( ) , ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
DataTypes types_res ;
if ( ! ( checkLeftType < DataTypeUInt8 > ( arguments , types_res )
| | checkLeftType < DataTypeUInt16 > ( arguments , types_res )
| | checkLeftType < DataTypeUInt32 > ( arguments , types_res )
| | checkLeftType < DataTypeUInt64 > ( arguments , types_res )
| | checkLeftType < DataTypeInt8 > ( arguments , types_res )
| | checkLeftType < DataTypeInt16 > ( arguments , types_res )
| | checkLeftType < DataTypeInt32 > ( arguments , types_res )
| | checkLeftType < DataTypeInt64 > ( arguments , types_res )
| | checkLeftType < DataTypeFloat32 > ( arguments , types_res )
| | checkLeftType < DataTypeFloat64 > ( arguments , types_res )
| | checkLeftType < DataTypeVarUInt > ( arguments , types_res )
| | checkLeftType < DataTypeVarInt > ( arguments , types_res ) ) )
throw Exception ( " Illegal type " + arguments [ 0 ] - > getName ( ) + " of first argument of function " + getName ( ) ,
ErrorCodes : : ILLEGAL_TYPE_OF_ARGUMENT ) ;
types_res . push_back ( new DataTypeUInt8 ) ;
return types_res ;
}
@ -317,35 +396,29 @@ public:
throw Exception ( " Wrong number of result columns in function " + getName ( ) + " , should be 1. " ,
ErrorCodes : : ILLEGAL_NUMBER_OF_RESULT_COLUMNS ) ;
if ( ! ( executeLeftType < UInt8 > ( block , arguments , result )
| | executeLeftType < UInt16 > ( block , arguments , result )
| | executeLeftType < UInt32 > ( block , arguments , result )
| | executeLeftType < UInt64 > ( block , arguments , result )
| | executeLeftType < Int8 > ( block , arguments , result )
| | executeLeftType < Int16 > ( block , arguments , result )
| | executeLeftType < Int32 > ( block , arguments , result )
| | executeLeftType < Int64 > ( block , arguments , result )
| | executeLeftType < Float32 > ( block , arguments , result )
| | executeLeftType < Float64 > ( block , arguments , result ) ) )
throw Exception ( " Illegal column of first argument of function " + getName ( ) ,
ErrorCodes : : ILLEGAL_COLUMN ) ;
if ( block . getByPosition ( arguments [ 0 ] ) . column - > isNumeric ( ) )
{
if ( ! ( executeNumLeftType < UInt8 > ( block , arguments , result )
| | executeNumLeftType < UInt16 > ( block , arguments , result )
| | executeNumLeftType < UInt32 > ( block , arguments , result )
| | executeNumLeftType < UInt64 > ( block , arguments , result )
| | executeNumLeftType < Int8 > ( block , arguments , result )
| | executeNumLeftType < Int16 > ( block , arguments , result )
| | executeNumLeftType < Int32 > ( block , arguments , result )
| | executeNumLeftType < Int64 > ( block , arguments , result )
| | executeNumLeftType < Float32 > ( block , arguments , result )
| | executeNumLeftType < Float64 > ( block , arguments , result ) ) )
throw Exception ( " Illegal column of first argument of function " + getName ( ) ,
ErrorCodes : : ILLEGAL_COLUMN ) ;
}
else
executeString ( block , arguments , result ) ;
}
} ;
struct NamePlus { static const char * get ( ) { return " plus " ; } } ;
struct NameMinus { static const char * get ( ) { return " minus " ; } } ;
struct NameMultiply { static const char * get ( ) { return " multiply " ; } } ;
struct NameDivideFloating { static const char * get ( ) { return " divide " ; } } ;
struct NameDivideIntegral { static const char * get ( ) { return " div " ; } } ;
struct NameModulo { static const char * get ( ) { return " modulo " ; } } ;
typedef FunctionBinaryArithmetic < PlusImpl , NamePlus > FunctionPlus ;
typedef FunctionBinaryArithmetic < MinusImpl , NameMinus > FunctionMinus ;
typedef FunctionBinaryArithmetic < MultiplyImpl , NameMultiply > FunctionMultiply ;
typedef FunctionBinaryArithmetic < DivideFloatingImpl , NameDivideFloating > FunctionDivideFloating ;
typedef FunctionBinaryArithmetic < DivideIntegralImpl , NameDivideIntegral > FunctionDivideIntegral ;
typedef FunctionBinaryArithmetic < ModuloImpl , NameModulo > FunctionModulo ;
struct NameEquals { static const char * get ( ) { return " equals " ; } } ;
typedef FunctionComparison < EqualsNumImpl , EqualsStringImpl , NameEquals > FunctionEquals ;
}