2014-02-17 23:56:45 +00:00
# pragma once
# include <DB/Core/Field.h>
2014-10-06 02:01:41 +00:00
# include <DB/IO/WriteHelpers.h>
2014-02-17 23:56:45 +00:00
# include <Poco/Timespan.h>
2015-02-22 10:53:09 +00:00
# include <cpuid/libcpuid.h>
2015-05-21 09:38:02 +00:00
# include <DB/IO/CompressedStream.h>
2014-02-17 23:56:45 +00:00
namespace DB
{
/** Одна настройка какого-либо типа.
* Х р а н и т в н у т р и с е б я з н а ч е н и е , а т а к ж е ф л а г - б ы л о л и з н а ч е н и е и з м е н е н о .
* Э т о с д е л а н о , ч т о б ы м о ж н о б ы л о о т п р а в л я т ь н а у д а л ё н н ы е с е р в е р ы т о л ь к о и з м е н ё н н ы е ( и л и я в н о у к а з а н н ы е в к о н ф и г е ) з н а ч е н и я .
* Т о е с т ь , е с л и н а с т р о й к а н е б ы л а у к а з а н а в к о н ф и г е и н е б ы л а и з м е н е н а д и н а м и ч е с к и , т о о н а н е о т п р а в л я е т с я н а у д а л ё н н ы й с е р в е р ,
* и у д а л ё н н ы й с е р в е р б у д е т и с п о л ь з о в а т ь с в о ё з н а ч е н и е п о - у м о л ч а н и ю .
*/
struct SettingUInt64
{
UInt64 value ;
bool changed = false ;
SettingUInt64 ( UInt64 x = 0 ) : value ( x ) { }
operator UInt64 ( ) const { return value ; }
SettingUInt64 & operator = ( UInt64 x ) { set ( x ) ; return * this ; }
2014-10-06 02:01:41 +00:00
String toString ( ) const
{
return DB : : toString ( value ) ;
}
2014-02-17 23:56:45 +00:00
void set ( UInt64 x )
{
value = x ;
changed = true ;
}
void set ( const Field & x )
{
set ( safeGet < UInt64 > ( x ) ) ;
}
void set ( const String & x )
{
set ( parse < UInt64 > ( x ) ) ;
}
void set ( ReadBuffer & buf )
{
UInt64 x = 0 ;
readVarUInt ( x , buf ) ;
set ( x ) ;
}
void write ( WriteBuffer & buf ) const
{
writeVarUInt ( value , buf ) ;
}
} ;
typedef SettingUInt64 SettingBool ;
2015-02-22 10:50:36 +00:00
/** В отличие от SettingUInt64, поддерживает значение 'auto' - количество процессорных ядер без учёта SMT.
* З н а ч е н и е 0 т а к ж е в о с п р и н и м а е т с я к а к auto .
* П р и с е р и а л и з а ц и и , auto з а п и с ы в а е т с я т а к ж е , к а к 0.
*/
struct SettingMaxThreads
{
UInt64 value ;
bool is_auto ;
bool changed = false ;
SettingMaxThreads ( UInt64 x = 0 ) : value ( x ? x : getAutoValue ( ) ) , is_auto ( x = = 0 ) { }
operator UInt64 ( ) const { return value ; }
SettingMaxThreads & operator = ( UInt64 x ) { set ( x ) ; return * this ; }
String toString ( ) const
{
/// Вместо значения auto выводим актуальное значение, чтобы е г о было легче посмотреть.
return DB : : toString ( value ) ;
}
void set ( UInt64 x )
{
value = x ? x : getAutoValue ( ) ;
is_auto = x = = 0 ;
changed = true ;
}
void set ( const Field & x )
{
if ( x . getType ( ) = = Field : : Types : : String )
set ( safeGet < const String & > ( x ) ) ;
else
set ( safeGet < UInt64 > ( x ) ) ;
}
void set ( const String & x )
{
if ( x = = " auto " )
setAuto ( ) ;
else
set ( parse < UInt64 > ( x ) ) ;
}
void set ( ReadBuffer & buf )
{
UInt64 x = 0 ;
readVarUInt ( x , buf ) ;
set ( x ) ;
}
void write ( WriteBuffer & buf ) const
{
writeVarUInt ( is_auto ? 0 : value , buf ) ;
}
void setAuto ( )
{
value = getAutoValue ( ) ;
is_auto = true ;
}
UInt64 getAutoValue ( ) const
{
static auto res = getAutoValueImpl ( ) ;
return res ;
}
/// Выполняется один раз за всё время. Выполняется из одного потока.
UInt64 getAutoValueImpl ( ) const
{
cpu_raw_data_t raw_data ;
if ( 0 ! = cpuid_get_raw_data ( & raw_data ) )
throw Exception ( " Cannot cpuid_get_raw_data: " + String ( cpuid_error ( ) ) , ErrorCodes : : CPUID_ERROR ) ;
cpu_id_t data ;
if ( 0 ! = cpu_identify ( & raw_data , & data ) )
throw Exception ( " Cannot cpu_identify: " + String ( cpuid_error ( ) ) , ErrorCodes : : CPUID_ERROR ) ;
2015-02-22 11:25:26 +00:00
return data . num_cores * data . total_logical_cpus / data . num_logical_cpus ;
2015-02-22 10:50:36 +00:00
}
} ;
2014-02-17 23:56:45 +00:00
struct SettingSeconds
{
Poco : : Timespan value ;
bool changed = false ;
SettingSeconds ( UInt64 seconds = 0 ) : value ( seconds , 0 ) { }
operator Poco : : Timespan ( ) const { return value ; }
SettingSeconds & operator = ( Poco : : Timespan x ) { set ( x ) ; return * this ; }
Poco : : Timespan : : TimeDiff totalSeconds ( ) const { return value . totalSeconds ( ) ; }
2014-10-06 02:01:41 +00:00
String toString ( ) const
{
return DB : : toString ( totalSeconds ( ) ) ;
}
2014-02-17 23:56:45 +00:00
void set ( Poco : : Timespan x )
{
value = x ;
changed = true ;
}
void set ( UInt64 x )
{
set ( Poco : : Timespan ( x , 0 ) ) ;
}
void set ( const Field & x )
{
set ( safeGet < UInt64 > ( x ) ) ;
}
void set ( const String & x )
{
set ( parse < UInt64 > ( x ) ) ;
}
void set ( ReadBuffer & buf )
{
UInt64 x = 0 ;
readVarUInt ( x , buf ) ;
set ( x ) ;
}
void write ( WriteBuffer & buf ) const
{
writeVarUInt ( value . totalSeconds ( ) , buf ) ;
}
} ;
struct SettingMilliseconds
{
Poco : : Timespan value ;
bool changed = false ;
SettingMilliseconds ( UInt64 milliseconds = 0 ) : value ( milliseconds * 1000 ) { }
operator Poco : : Timespan ( ) const { return value ; }
SettingMilliseconds & operator = ( Poco : : Timespan x ) { set ( x ) ; return * this ; }
Poco : : Timespan : : TimeDiff totalMilliseconds ( ) const { return value . totalMilliseconds ( ) ; }
2014-10-06 02:01:41 +00:00
String toString ( ) const
{
return DB : : toString ( totalMilliseconds ( ) ) ;
}
2014-02-17 23:56:45 +00:00
void set ( Poco : : Timespan x )
{
value = x ;
changed = true ;
}
void set ( UInt64 x )
{
set ( Poco : : Timespan ( x * 1000 ) ) ;
}
void set ( const Field & x )
{
set ( safeGet < UInt64 > ( x ) ) ;
}
void set ( const String & x )
{
set ( parse < UInt64 > ( x ) ) ;
}
void set ( ReadBuffer & buf )
{
UInt64 x = 0 ;
readVarUInt ( x , buf ) ;
set ( x ) ;
}
void write ( WriteBuffer & buf ) const
{
writeVarUInt ( value . totalMilliseconds ( ) , buf ) ;
}
} ;
struct SettingFloat
{
float value ;
bool changed = false ;
SettingFloat ( float x = 0 ) : value ( x ) { }
operator float ( ) const { return value ; }
SettingFloat & operator = ( float x ) { set ( x ) ; return * this ; }
2014-10-06 02:01:41 +00:00
String toString ( ) const
{
return DB : : toString ( value ) ;
}
2014-02-17 23:56:45 +00:00
void set ( float x )
{
value = x ;
changed = true ;
}
void set ( const Field & x )
{
if ( x . getType ( ) = = Field : : Types : : UInt64 )
{
set ( safeGet < UInt64 > ( x ) ) ;
}
else if ( x . getType ( ) = = Field : : Types : : Int64 )
{
set ( safeGet < Int64 > ( x ) ) ;
}
else if ( x . getType ( ) = = Field : : Types : : Float64 )
{
set ( safeGet < Float64 > ( x ) ) ;
}
else
throw Exception ( std : : string ( " Bad type of setting. Expected UInt64, Int64 or Float64, got " ) + x . getTypeName ( ) , ErrorCodes : : TYPE_MISMATCH ) ;
}
void set ( const String & x )
{
set ( parse < float > ( x ) ) ;
}
void set ( ReadBuffer & buf )
{
String x ;
readBinary ( x , buf ) ;
set ( x ) ;
}
void write ( WriteBuffer & buf ) const
{
2014-10-06 02:01:41 +00:00
writeBinary ( toString ( ) , buf ) ;
2014-02-17 23:56:45 +00:00
}
} ;
enum class LoadBalancing
{
/// среди реплик с минимальным количеством ошибок выбирается случайная
RANDOM = 0 ,
/// среди реплик с минимальным количеством ошибок выбирается реплика
/// с минимальным количеством отличающихся символов в имени реплики и имени локального хоста
2015-01-26 19:55:10 +00:00
NEAREST_HOSTNAME ,
/// реплики перебираются строго по порядку; количество ошибок не имеет значение
IN_ORDER ,
2014-02-17 23:56:45 +00:00
} ;
struct SettingLoadBalancing
{
LoadBalancing value ;
bool changed = false ;
SettingLoadBalancing ( LoadBalancing x ) : value ( x ) { }
operator LoadBalancing ( ) const { return value ; }
SettingLoadBalancing & operator = ( LoadBalancing x ) { set ( x ) ; return * this ; }
static LoadBalancing getLoadBalancing ( const String & s )
{
if ( s = = " random " ) return LoadBalancing : : RANDOM ;
if ( s = = " nearest_hostname " ) return LoadBalancing : : NEAREST_HOSTNAME ;
2015-01-26 19:55:10 +00:00
if ( s = = " in_order " ) return LoadBalancing : : IN_ORDER ;
2014-02-17 23:56:45 +00:00
2015-01-26 19:55:10 +00:00
throw Exception ( " Unknown load balancing mode: ' " + s + " ', must be one of 'random', 'nearest_hostname', 'in_order' " ,
ErrorCodes : : UNKNOWN_LOAD_BALANCING ) ;
2014-02-17 23:56:45 +00:00
}
String toString ( ) const
{
2015-01-26 19:55:10 +00:00
const char * strings [ ] = { " random " , " nearest_hostname " , " in_order " } ;
if ( value < LoadBalancing : : RANDOM | | value > LoadBalancing : : IN_ORDER )
2014-02-17 23:56:45 +00:00
throw Exception ( " Unknown load balancing mode " , ErrorCodes : : UNKNOWN_OVERFLOW_MODE ) ;
return strings [ static_cast < size_t > ( value ) ] ;
}
void set ( LoadBalancing x )
{
value = x ;
changed = true ;
}
void set ( const Field & x )
{
set ( safeGet < const String & > ( x ) ) ;
}
void set ( const String & x )
{
set ( getLoadBalancing ( x ) ) ;
}
void set ( ReadBuffer & buf )
{
String x ;
readBinary ( x , buf ) ;
set ( x ) ;
}
void write ( WriteBuffer & buf ) const
{
writeBinary ( toString ( ) , buf ) ;
}
} ;
2014-02-18 09:02:35 +00:00
/// Какие строки включать в TOTALS.
enum class TotalsMode
{
BEFORE_HAVING = 0 , /// Считать HAVING по всем прочитанным строкам;
/// включая не попавшие в max_rows_to_group_by
/// и не прошедшие HAVING после группировки.
AFTER_HAVING_INCLUSIVE = 1 , /// Считать по всем строкам, кроме не прошедших HAVING;
/// то есть, включать в TOTALS все строки, не прошедшие max_rows_to_group_by.
AFTER_HAVING_EXCLUSIVE = 2 , /// Включать только строки, прошедшие и max_rows_to_group_by, и HAVING.
AFTER_HAVING_AUTO = 3 , /// Автоматически выбирать между INCLUSIVE и EXCLUSIVE,
} ;
struct SettingTotalsMode
{
TotalsMode value ;
bool changed = false ;
SettingTotalsMode ( TotalsMode x ) : value ( x ) { }
operator TotalsMode ( ) const { return value ; }
SettingTotalsMode & operator = ( TotalsMode x ) { set ( x ) ; return * this ; }
static TotalsMode getTotalsMode ( const String & s )
{
if ( s = = " before_having " ) return TotalsMode : : BEFORE_HAVING ;
if ( s = = " after_having_exclusive " ) return TotalsMode : : AFTER_HAVING_EXCLUSIVE ;
if ( s = = " after_having_inclusive " ) return TotalsMode : : AFTER_HAVING_INCLUSIVE ;
if ( s = = " after_having_auto " ) return TotalsMode : : AFTER_HAVING_AUTO ;
throw Exception ( " Unknown totals mode: ' " + s + " ', must be one of 'before_having', 'after_having_exclusive', 'after_having_inclusive', 'after_having_auto' " , ErrorCodes : : UNKNOWN_TOTALS_MODE ) ;
}
String toString ( ) const
{
switch ( value )
{
case TotalsMode : : BEFORE_HAVING : return " before_having " ;
case TotalsMode : : AFTER_HAVING_EXCLUSIVE : return " after_having_exclusive " ;
case TotalsMode : : AFTER_HAVING_INCLUSIVE : return " after_having_inclusive " ;
case TotalsMode : : AFTER_HAVING_AUTO : return " after_having_auto " ;
default :
2014-02-27 12:49:21 +00:00
throw Exception ( " Unknown TotalsMode enum value " , ErrorCodes : : ARGUMENT_OUT_OF_BOUND ) ;
2014-02-18 09:02:35 +00:00
}
}
void set ( TotalsMode x )
{
value = x ;
changed = true ;
}
void set ( const Field & x )
{
set ( safeGet < const String & > ( x ) ) ;
}
void set ( const String & x )
{
set ( getTotalsMode ( x ) ) ;
}
void set ( ReadBuffer & buf )
{
String x ;
readBinary ( x , buf ) ;
set ( x ) ;
}
void write ( WriteBuffer & buf ) const
{
writeBinary ( toString ( ) , buf ) ;
}
} ;
2014-02-17 23:56:45 +00:00
/// Что делать, если ограничение превышено.
enum class OverflowMode
{
THROW = 0 , /// Кинуть исключение.
BREAK = 1 , /// Прервать выполнение запроса, вернуть что есть.
ANY = 2 , /** Только для GROUP BY: не добавлять новые строки в набор,
* н о п р о д о л ж а т ь а г р е г и р о в а т ь д л я к л ю ч е й , у с п е в ш и х п о п а с т ь в н а б о р .
*/
} ;
template < bool enable_mode_any >
struct SettingOverflowMode
{
OverflowMode value ;
bool changed = false ;
SettingOverflowMode ( OverflowMode x = OverflowMode : : THROW ) : value ( x ) { }
operator OverflowMode ( ) const { return value ; }
SettingOverflowMode & operator = ( OverflowMode x ) { set ( x ) ; return * this ; }
static OverflowMode getOverflowModeForGroupBy ( const String & s )
{
if ( s = = " throw " ) return OverflowMode : : THROW ;
if ( s = = " break " ) return OverflowMode : : BREAK ;
if ( s = = " any " ) return OverflowMode : : ANY ;
throw Exception ( " Unknown overflow mode: ' " + s + " ', must be one of 'throw', 'break', 'any' " , ErrorCodes : : UNKNOWN_OVERFLOW_MODE ) ;
}
static OverflowMode getOverflowMode ( const String & s )
{
OverflowMode mode = getOverflowModeForGroupBy ( s ) ;
if ( mode = = OverflowMode : : ANY & & ! enable_mode_any )
throw Exception ( " Illegal overflow mode: 'any' is only for 'group_by_overflow_mode' " , ErrorCodes : : ILLEGAL_OVERFLOW_MODE ) ;
return mode ;
}
String toString ( ) const
{
const char * strings [ ] = { " throw " , " break " , " any " } ;
if ( value < OverflowMode : : THROW | | value > OverflowMode : : ANY )
throw Exception ( " Unknown overflow mode " , ErrorCodes : : UNKNOWN_OVERFLOW_MODE ) ;
return strings [ static_cast < size_t > ( value ) ] ;
}
void set ( OverflowMode x )
{
value = x ;
changed = true ;
}
void set ( const Field & x )
{
set ( safeGet < const String & > ( x ) ) ;
}
void set ( const String & x )
{
set ( getOverflowMode ( x ) ) ;
}
void set ( ReadBuffer & buf )
{
String x ;
readBinary ( x , buf ) ;
set ( x ) ;
}
void write ( WriteBuffer & buf ) const
{
writeBinary ( toString ( ) , buf ) ;
}
} ;
2015-05-21 16:05:02 +00:00
struct SettingCompressionMethod
2015-05-21 09:38:02 +00:00
{
CompressionMethod value ;
bool changed = false ;
2015-05-21 16:05:02 +00:00
SettingCompressionMethod ( CompressionMethod x = CompressionMethod : : LZ4 ) : value ( x ) { }
2015-05-21 09:38:02 +00:00
operator CompressionMethod ( ) const { return value ; }
2015-05-21 16:05:02 +00:00
SettingCompressionMethod & operator = ( CompressionMethod x ) { set ( x ) ; return * this ; }
2015-05-21 09:38:02 +00:00
static CompressionMethod getCompressionMethod ( const String & s )
{
if ( s = = " quicklz " )
return CompressionMethod : : QuickLZ ;
if ( s = = " lz4 " )
return CompressionMethod : : LZ4 ;
if ( s = = " lz4hc " )
return CompressionMethod : : LZ4HC ;
if ( s = = " zstd " )
return CompressionMethod : : ZSTD ;
throw Exception ( " Unknown network compression method: ' " + s + " ', must be one of 'quicklz', 'lz4', 'lz4hc', 'zstd' " , ErrorCodes : : UNKNOWN_COMPRESSION_METHOD ) ;
}
String toString ( ) const
{
const char * strings [ ] = { " quicklz " , " lz4 " , " lz4hc " , " zstd " } ;
if ( value < CompressionMethod : : QuickLZ | | value > CompressionMethod : : ZSTD )
throw Exception ( " Unknown compression method " , ErrorCodes : : UNKNOWN_COMPRESSION_METHOD ) ;
return strings [ static_cast < size_t > ( value ) ] ;
}
void set ( CompressionMethod x )
{
value = x ;
changed = true ;
}
void set ( const Field & x )
{
set ( safeGet < const String & > ( x ) ) ;
}
2014-02-17 23:56:45 +00:00
2015-05-21 09:38:02 +00:00
void set ( const String & x )
{
set ( getCompressionMethod ( x ) ) ;
}
void set ( ReadBuffer & buf )
{
String x ;
readBinary ( x , buf ) ;
set ( x ) ;
}
void write ( WriteBuffer & buf ) const
{
writeBinary ( toString ( ) , buf ) ;
}
} ;
2014-02-17 23:56:45 +00:00
}