Merge branch 'master' of https://github.com/yandex/ClickHouse into CLICKHOUSE-2720

This commit is contained in:
Ivan Blinkov 2017-09-18 14:55:27 +03:00
commit ef074a9649
139 changed files with 3457 additions and 3496 deletions

View File

@ -1,3 +1,41 @@
# ClickHouse release 1.1.54289
## New features:
* `SYSTEM` queries for server administration: `SYSTEM RELOAD DICTIONARY`, `SYSTEM RELOAD DICTIONARIES`, `SYSTEM DROP DNS CACHE`, `SYSTEM SHUTDOWN`, `SYSTEM KILL`.
* Added functions for working with arrays: `concat`, `arraySlice`, `arrayPushBack`, `arrayPushFront`, `arrayPopBack`, `arrayPopFront`.
* Added the `root` and `identity` parameters for the ZooKeeper configuration. This allows you to isolate individual users on the same ZooKeeper cluster.
* Added the aggregate functions `groupBitAnd`, `groupBitOr`, and `groupBitXor` (for compatibility, they can also be accessed with the names `BIT_AND`, `BIT_OR`, and `BIT_XOR`).
* External dictionaries can be loaded from MySQL by specifying a socket in the filesystem.
* External dictionaries can be loaded from MySQL over SSL (the `ssl_cert`, `ssl_key`, and `ssl_ca` parameters).
* Added the `max_network_bandwidth_for_user` setting to restrict the overall bandwidth use for queries per user.
* Support for `DROP TABLE` for temporary tables.
* Support for reading `DateTime` values in Unix timestamp format from the `CSV` and `JSONEachRow` formats.
* Lagging replicas in distributed queries are now excluded by default (the default threshold is 5 minutes).
* FIFO locking is used during ALTER: an ALTER query isn't blocked indefinitely for continuously running queries.
* Option to set `umask` in the config file.
* Improved performance for queries with `DISTINCT`.
## Bug fixes:
* Improved the process for deleting old nodes in ZooKeeper. Previously, old nodes sometimes didn't get deleted if there were very frequent inserts, which caused the server to be slow to shut down, among other things.
* Fixed randomization when choosing hosts for the connection to ZooKeeper.
* Fixed the exclusion of lagging replicas in distributed queries if the replica is localhost.
* Fixed an error where a data part in a `ReplicatedMergeTree` table could be broken after running `ALTER MODIFY` on an element in a `Nested` structure.
* Fixed an error that could cause SELECT queries to "hang".
* Improvements to distributed DDL queries.
* Fixed the query `CREATE TABLE ... AS <materialized view>`.
* Resolved the deadlock in the `ALTER ... CLEAR COLUMN IN PARTITION` query for `Buffer` tables.
* Fixed the invalid default value for `Enum`s (0 instead of the minimum) when using the `JSONEachRow` and `TSKV` formats.
* Resolved the appearance of zombie processes when using a dictionary with an `executable` source.
* Fixed segfault for the HEAD query.
## Improvements to development workflow and ClickHouse build:
* You can use `pbuilder` to build ClickHouse.
* You can use `libc++` instead of `libstdc++` for builds on Linux.
* Added instructions for using static code analysis tools: `Coverity`, `clang-tidy`, and `cppcheck`.
## Please note when upgrading:
* There is now a higher default value for the MergeTree setting `max_bytes_to_merge_at_max_space_in_pool` (the maximum total size of data parts to merge, in bytes): it has increased from 100 GiB to 150 GiB. This might result in large merges running after the server upgrade, which could cause an increased load on the disk subsystem. If the free space available on the server is less than twice the total amount of the merges that are running, this will cause all other merges to stop running, including merges of small data parts. As a result, INSERT requests will fail with the message "Merges are processing significantly slower than inserts." Use the `SELECT * FROM system.merges` request to monitor the situation. You can also check the `DiskSpaceReservedForMerge` metric in the `system.metrics` table, or in Graphite. You don't need to do anything to fix this, since the issue will resolve itself once the large merges finish. If you find this unacceptable, you can restore the previous value for the `max_bytes_to_merge_at_max_space_in_pool` setting (to do this, go to the `<merge_tree>` section in config.xml, set `<max_bytes_to_merge_at_max_space_in_pool>107374182400</max_bytes_to_merge_at_max_space_in_pool>` and restart the server).
# ClickHouse release 1.1.54284 # ClickHouse release 1.1.54284
* This is bugfix release for previous 1.1.54282 release. It fixes ZooKeeper nodes leak in `parts/` directory. * This is bugfix release for previous 1.1.54282 release. It fixes ZooKeeper nodes leak in `parts/` directory.

View File

@ -1,3 +1,41 @@
# Релиз ClickHouse 1.1.54289
## Новые возможности:
* Запросы `SYSTEM` для административных действий с сервером: `SYSTEM RELOAD DICTIONARY`, `SYSTEM RELOAD DICTIONARIES`, `SYSTEM DROP DNS CACHE`, `SYSTEM SHUTDOWN`, `SYSTEM KILL`.
* Добавлены функции для работы с массивами: `concat`, `arraySlice`, `arrayPushBack`, `arrayPushFront`, `arrayPopBack`, `arrayPopFront`.
* Добавлены параметры `root` и `identity` для конфигурации ZooKeeper. Это позволяет изолировать разных пользователей одного ZooKeeper кластера.
* Добавлены агрегатные функции `groupBitAnd`, `groupBitOr`, `groupBitXor` (для совместимости доступны также под именами `BIT_AND`, `BIT_OR`, `BIT_XOR`).
* Возможность загрузки внешних словарей из MySQL с указанием сокета на файловой системе.
* Возможность загрузки внешних словарей из MySQL через SSL соединение (параметры `ssl_cert`, `ssl_key`, `ssl_ca`).
* Добавлена настройка `max_network_bandwidth_for_user` для ограничения общего потребления сети для всех запросов одного пользователя.
* Поддержка `DROP TABLE` для временных таблиц.
* Поддержка чтения значений типа `DateTime` в формате unix timestamp из форматов `CSV` и `JSONEachRow`.
* Включено по-умолчанию отключение отстающих реплик при распределённых запросах (по-умолчанию порог равен 5 минутам).
* Используются FIFO блокировки при ALTER: выполнение ALTER не будет неограниченно блокироваться при непрерывно выполняющихся запросах.
* Возможность задать `umask` в конфигурационном файле.
* Увеличена производительность запросов с `DISTINCT`.
## Исправления ошибок:
* Более оптимальная процедура удаления старых нод в ZooKeeper. Ранее в случае очень частых вставок, старые ноды могли не успевать удаляться, что приводило, в том числе, к очень долгому завершению сервера.
* Исправлена рандомизация при выборе хостов для соединения с ZooKeeper.
* Исправлено отключение отстающей реплики при распределённых запросах, если реплика является localhost.
* Исправлена ошибка, в связи с которой кусок данных таблицы типа `ReplicatedMergeTree` мог становиться битым после выполнения `ALTER MODIFY` элемента `Nested` структуры.
* Исправлена ошибка приводящая к возможному зависанию SELECT запросов.
* Доработки распределённых DDL запросов.
* Исправлен запрос `CREATE TABLE ... AS <materialized view>`.
* Исправлен дедлок при запросе `ALTER ... CLEAR COLUMN IN PARTITION` для `Buffer` таблиц.
* Исправлено использование неправильного значения по-умолчанию для `Enum`-ов (0 вместо минимального) при использовании форматов `JSONEachRow` и `TSKV`.
* Исправлено появление zombie процессов при работе со словарём с источником `executable`.
* Исправлен segfault при запросе HEAD.
## Улучшения процесса разработки и сборки ClickHouse:
* Возможность сборки с помощью `pbuilder`.
* Возможность сборки с использованием `libc++` вместо `libstdc++` под Linux.
* Добавлены инструкции для использования статических анализаторов кода `Coverity`, `clang-tidy`, `cppcheck`.
## На что обратить внимание при обновлении:
* Увеличено значение по-умолчанию для настройки MergeTree `max_bytes_to_merge_at_max_space_in_pool` (максимальный суммарный размер кусков в байтах для мержа) со 100 GiB до 150 GiB. Это может привести к запуску больших мержей после обновления сервера, что может вызвать повышенную нагрузку на дисковую подсистему. Если же на серверах, где это происходит, количество свободного места менее чем в два раза больше суммарного объёма выполняющихся мержей, то в связи с этим перестанут выполняться какие-либо другие мержи, включая мержи мелких кусков. Это приведёт к тому, что INSERT-ы будут отклоняться с сообщением "Merges are processing significantly slower than inserts". Для наблюдения, используйте запрос `SELECT * FROM system.merges`. Вы также можете смотреть на метрику `DiskSpaceReservedForMerge` в таблице `system.metrics` или в Graphite. Для исправления этой ситуации можно ничего не делать, так как она нормализуется сама после завершения больших мержей. Если же вас это не устраивает, вы можете вернуть настройку `max_bytes_to_merge_at_max_space_in_pool` в старое значение, прописав в config.xml в секции `<merge_tree>` `<max_bytes_to_merge_at_max_space_in_pool>107374182400</max_bytes_to_merge_at_max_space_in_pool>` и перезапустить сервер.
# Релиз ClickHouse 1.1.54284 # Релиз ClickHouse 1.1.54284
* Релиз содержит изменения к предыдущему релизу 1.1.54282, которые исправляют утечку записей о кусках в ZooKeeper * Релиз содержит изменения к предыдущему релизу 1.1.54282, которые исправляют утечку записей о кусках в ZooKeeper

View File

@ -71,11 +71,16 @@ if (USE_STATIC_LIBRARIES)
list(REVERSE CMAKE_FIND_LIBRARY_SUFFIXES) list(REVERSE CMAKE_FIND_LIBRARY_SUFFIXES)
endif () endif ()
option (GLIBC_COMPATIBILITY "Set to TRUE to enable compatibility with older glibc libraries. Note that it is not compatible with ASan." OFF) if (CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
option (USE_INTERNAL_MEMCPY "Use internal implementation of 'memcpy' function instead of provided by libc. Only for x86_64." ON)
if (CMAKE_SYSTEM MATCHES "Linux")
option (GLIBC_COMPATIBILITY "Set to TRUE to enable compatibility with older glibc libraries. Only for x86_64, Linux. Implies USE_INTERNAL_MEMCPY." ON)
endif()
endif ()
if (GLIBC_COMPATIBILITY) if (GLIBC_COMPATIBILITY)
set (GLIBC_COMPATIBILITY_COMPILE_FLAGS "-include ${ClickHouse_SOURCE_DIR}/libs/libcommon/include/common/glibc_compatibility.h") set (USE_INTERNAL_MEMCPY ON)
set (GLIBC_COMPATIBILITY_LINK_FLAGS "-Wl,--wrap=memcpy")
endif () endif ()
if (CXX11_ABI STREQUAL ENABLE) if (CXX11_ABI STREQUAL ENABLE)
@ -107,6 +112,11 @@ if (USE_LIBCXX)
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_LIBCPP_DEBUG=1") # More checks in debug build. set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_LIBCPP_DEBUG=1") # More checks in debug build.
endif () endif ()
# Special options for better optimized code with clang
#if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -Wno-unused-command-line-argument -mllvm -inline-threshold=10000")
#endif ()
set (CMAKE_BUILD_COLOR_MAKEFILE ON) set (CMAKE_BUILD_COLOR_MAKEFILE ON)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS} -std=gnu++1z ${PLATFORM_EXTRA_CXX_FLAG} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${CXX_WARNING_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS} -std=gnu++1z ${PLATFORM_EXTRA_CXX_FLAG} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${CXX_WARNING_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS}")
#set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") #set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")

View File

@ -2394,7 +2394,12 @@ namespace detail
&& (filename.size()== 1 && (filename.size()== 1
|| (filename[1] == dot || (filename[1] == dot
&& filename.size()== 2))) && filename.size()== 2)))
{ it.increment(*ec); } {
if (ec)
it.increment(*ec);
else
it.increment();
}
} }
} }

View File

@ -489,39 +489,15 @@ if(MINGW OR MSYS)
set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
endif(MINGW OR MSYS) endif(MINGW OR MSYS)
add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_GZFILE_SRCS} ${ZLIB_ARCH_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_GZFILE_SRCS} ${ZLIB_ARCH_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_GZFILE_SRCS} ${ZLIB_ARCH_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
set_target_properties(zlib PROPERTIES SOVERSION 1)
if(NOT CYGWIN)
# This property causes shared libraries on Linux to have the full version
# encoded into their final filename. We disable this on Cygwin because
# it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll
# seems to be the default.
#
# This has no effect with MSVC, on that platform the version info for
# the DLL comes from the resource file win32/zlib1.rc
set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
endif()
if(UNIX) if(UNIX)
# On unix-like platforms the library is almost always called libz # On unix-like platforms the library is almost always called libz
set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) set_target_properties(zlibstatic PROPERTIES OUTPUT_NAME z)
if(NOT APPLE)
set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
endif()
elseif(MSYS)
# Suppress version number from shared library name
set(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 0)
elseif(BUILD_SHARED_LIBS AND WIN32)
# Creates zlib1.dll when building shared library version
set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
endif() endif()
if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
install(TARGETS zlib zlibstatic install(TARGETS zlibstatic
RUNTIME DESTINATION "${INSTALL_BIN_DIR}" RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"
LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) LIBRARY DESTINATION "${INSTALL_LIB_DIR}" )
@ -529,35 +505,6 @@ endif()
if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}") install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}")
endif() endif()
if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3")
endif()
if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}") install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}")
endif() endif()
#============================================================================
# Example binaries
#============================================================================
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set (CMAKE_EXE_LINKER_FLAGS "")
endif ()
add_executable(example test/example.c)
target_link_libraries(example zlib)
add_test(example example)
add_executable(minigzip test/minigzip.c)
target_link_libraries(minigzip zlib)
if(HAVE_OFF64_T)
add_executable(example64 test/example.c)
target_link_libraries(example64 zlib)
set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
add_test(example64 example64)
add_executable(minigzip64 test/minigzip.c)
target_link_libraries(minigzip64 zlib)
set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
endif()

View File

@ -16,7 +16,8 @@
# sudo ./copy_headers.sh . /usr/share/clickhouse/headers/ # sudo ./copy_headers.sh . /usr/share/clickhouse/headers/
SOURCE_PATH=${1:-.} SOURCE_PATH=${1:-.}
DST=${2:-$SOURCE_PATH/../headers}; DST=${2:-$SOURCE_PATH/../headers}
BUILD_PATH=${3:-$SOURCE_PATH/build}
PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:$PATH" PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:$PATH"
@ -24,14 +25,19 @@ if [[ -z $CLANG ]]; then
CLANG="clang" CLANG="clang"
fi fi
START_HEADERS=$(echo \
$BUILD_PATH/dbms/src/Common/config_version.h \
$SOURCE_PATH/dbms/src/Interpreters/SpecializedAggregator.h \
$SOURCE_PATH/dbms/src/AggregateFunctions/AggregateFunction*.h)
# Опция -mcx16 для того, чтобы выбиралось больше заголовочных файлов (с запасом). # Опция -mcx16 для того, чтобы выбиралось больше заголовочных файлов (с запасом).
for src_file in $($CLANG -M -xc++ -std=gnu++1z -Wall -Werror -msse4 -mcx16 -mpopcnt -O3 -g -fPIC \ for src_file in $(echo | $CLANG -M -xc++ -std=gnu++1z -Wall -Werror -msse4 -mcx16 -mpopcnt -O3 -g -fPIC \
$(cat "$SOURCE_PATH/build/include_directories.txt") \ $(cat "$BUILD_PATH/include_directories.txt") \
"$SOURCE_PATH/build/dbms/src/Common/config_version.h" \ $(echo $START_HEADERS | sed -r -e 's/[^ ]+/-include \0/g') \
"$SOURCE_PATH/dbms/src/Interpreters/SpecializedAggregator.h" | - |
tr -d '\\' | tr -d '\\' |
sed -r -e 's/^\w+\.o://'); sed -r -e 's/^-\.o://');
do do
dst_file=$src_file; dst_file=$src_file;
dst_file=$(echo $dst_file | sed -r -e 's/build\///') # for simplicity reasons, will put generated headers near the rest. dst_file=$(echo $dst_file | sed -r -e 's/build\///') # for simplicity reasons, will put generated headers near the rest.

View File

@ -69,6 +69,8 @@ public:
{ {
this->data(place).result.insertResultInto(to); this->data(place).result.insertResultInto(to);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -132,6 +132,8 @@ public:
} }
IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; } IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -70,6 +70,8 @@ public:
static_cast<ColumnFloat64 &>(to).getData().push_back( static_cast<ColumnFloat64 &>(to).getData().push_back(
static_cast<Float64>(this->data(place).sum) / this->data(place).count); static_cast<Float64>(this->data(place).sum) / this->data(place).count);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -81,6 +81,8 @@ public:
{ {
static_cast<ColumnVector<T> &>(to).getData().push_back(this->data(place).value); static_cast<ColumnVector<T> &>(to).getData().push_back(this->data(place).value);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -70,6 +70,8 @@ public:
{ {
data(place).count += x; data(place).count += x;
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -114,6 +116,8 @@ public:
{ {
static_cast<ColumnUInt64 &>(to).getData().push_back(data(place).count); static_cast<ColumnUInt64 &>(to).getData().push_back(data(place).count);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -183,6 +187,8 @@ public:
static_cast<ColumnUInt64 &>(to).getData().push_back(data(place).count); static_cast<ColumnUInt64 &>(to).getData().push_back(data(place).count);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
private: private:
enum { MAX_ARGS = 8 }; enum { MAX_ARGS = 8 };
size_t number_of_arguments = 0; size_t number_of_arguments = 0;

View File

@ -1,92 +0,0 @@
#include <AggregateFunctions/INullaryAggregateFunction.h>
#include <AggregateFunctions/AggregateFunctionFactory.h>
#include <DataTypes/DataTypesNumber.h>
#include <Columns/ColumnsNumber.h>
#include <IO/ReadHelpers.h>
#include <IO/WriteHelpers.h>
namespace DB
{
/** State management of aggregate functions is done in a non-trivial way:
* - the memory for them needs to be allocated in the pool,
* pointers to these states can be passed between different data structures,
* herewith, you can not make RAII wrappers for each individual state.
* For more information, see Aggregator.h.
*
* In this regard, there are difficult-debugging bugs.
* To simplify the playback of bugs, an aggregate `debug` function was written,
* and its source code is decided not to delete after debugging.
*
* This aggregate function takes zero arguments and does nothing.
* But it has a state that is non-trivially created and destroyed.
*/
struct AggregateFunctionDebugData
{
std::unique_ptr<size_t> ptr { new size_t(0xABCDEF01DEADBEEF) };
AggregateFunctionDebugData() {}
~AggregateFunctionDebugData()
{
if (*ptr != 0xABCDEF01DEADBEEF)
{
std::cerr << "Bug!";
abort();
}
ptr.reset();
}
};
class AggregateFunctionDebug final : public INullaryAggregateFunction<AggregateFunctionDebugData, AggregateFunctionDebug>
{
public:
String getName() const override { return "debug"; }
DataTypePtr getReturnType() const override
{
return std::make_shared<DataTypeUInt8>();
}
void addImpl(AggregateDataPtr place) const
{
}
void merge(AggregateDataPtr place, ConstAggregateDataPtr rhs, Arena * arena) const override
{
}
void serialize(ConstAggregateDataPtr place, WriteBuffer & buf) const override
{
writeBinary(UInt8(0), buf);
}
void deserialize(AggregateDataPtr place, ReadBuffer & buf, Arena *) const override
{
UInt8 tmp;
readBinary(tmp, buf);
}
void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const override
{
static_cast<ColumnUInt8 &>(to).getData().push_back(0);
}
};
AggregateFunctionPtr createAggregateFunctionDebug(const std::string & name, const DataTypes & argument_types, const Array & parameters)
{
return std::make_shared<AggregateFunctionDebug>();
}
void registerAggregateFunctionDebug(AggregateFunctionFactory & factory)
{
factory.registerFunction("debug", createAggregateFunctionDebug);
}
}

View File

@ -245,6 +245,8 @@ public:
} }
IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; } IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -8,7 +8,7 @@ namespace DB
namespace namespace
{ {
template <template <typename, typename> class AggregateFunctionTemplate, class Data, typename ... TArgs> template <template <typename, typename> class AggregateFunctionTemplate, typename Data, typename ... TArgs>
static IAggregateFunction * createWithNumericOrTimeType(const IDataType & argument_type, TArgs && ... args) static IAggregateFunction * createWithNumericOrTimeType(const IDataType & argument_type, TArgs && ... args)
{ {
if (typeid_cast<const DataTypeDate *>(&argument_type)) return new AggregateFunctionTemplate<UInt16, Data>(std::forward<TArgs>(args)...); if (typeid_cast<const DataTypeDate *>(&argument_type)) return new AggregateFunctionTemplate<UInt16, Data>(std::forward<TArgs>(args)...);

View File

@ -137,6 +137,8 @@ public:
{ {
return true; return true;
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -408,6 +410,8 @@ public:
{ {
return true; return true;
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
#undef AGGREGATE_FUNCTION_GROUP_ARRAY_MAX_ARRAY_SIZE #undef AGGREGATE_FUNCTION_GROUP_ARRAY_MAX_ARRAY_SIZE

View File

@ -202,6 +202,8 @@ public:
to_offsets.push_back((to_offsets.empty() ? 0 : to_offsets.back()) + result_array_size); to_offsets.push_back((to_offsets.empty() ? 0 : to_offsets.back()) + result_array_size);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -98,6 +98,8 @@ public:
for (auto it = set.begin(); it != set.end(); ++it, ++i) for (auto it = set.begin(); it != set.end(); ++it, ++i)
data_to[old_size + i] = *it; data_to[old_size + i] = *it;
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -219,6 +221,8 @@ public:
deserializeAndInsert(elem, data_to); deserializeAndInsert(elem, data_to);
} }
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -121,6 +121,8 @@ public:
} }
IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; } IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -121,6 +121,8 @@ public:
} }
IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; } IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -726,6 +726,8 @@ public:
{ {
this->data(place).insertResultInto(to); this->data(place).insertResultInto(to);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -157,6 +157,8 @@ public:
{ {
return nested_function->isState(); return nested_function->isState();
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -99,6 +99,8 @@ public:
else else
static_cast<ColumnVector<ArgumentFieldType> &>(to).getData().push_back(sample.quantileInterpolated(level)); static_cast<ColumnVector<ArgumentFieldType> &>(to).getData().push_back(sample.quantileInterpolated(level));
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -192,6 +194,8 @@ public:
data_to.push_back(sample.quantileInterpolated(levels[i])); data_to.push_back(sample.quantileInterpolated(levels[i]));
} }
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -105,6 +105,8 @@ public:
else else
static_cast<ColumnVector<ArgumentFieldType> &>(to).getData().push_back(sample.quantileInterpolated(level)); static_cast<ColumnVector<ArgumentFieldType> &>(to).getData().push_back(sample.quantileInterpolated(level));
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -204,6 +206,8 @@ public:
data_to.push_back(sample.quantileInterpolated(levels[i])); data_to.push_back(sample.quantileInterpolated(levels[i]));
} }
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -117,6 +117,8 @@ public:
static_cast<ColumnVector<T> &>(to).getData().push_back(quantile); static_cast<ColumnVector<T> &>(to).getData().push_back(quantile);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -217,6 +219,8 @@ public:
data_to[old_size + i] = T(); data_to[old_size + i] = T();
} }
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -154,6 +154,8 @@ public:
static_cast<ColumnVector<ValueType> &>(to).getData().push_back(it->first); static_cast<ColumnVector<ValueType> &>(to).getData().push_back(it->first);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -296,6 +298,8 @@ public:
++level_index; ++level_index;
} }
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -411,6 +411,8 @@ public:
else else
static_cast<ColumnVector<T> &>(to).getData().push_back(quantile); static_cast<ColumnVector<T> &>(to).getData().push_back(quantile);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -480,6 +482,8 @@ public:
else else
static_cast<ColumnVector<T> &>(to).getData().push_back(quantile); static_cast<ColumnVector<T> &>(to).getData().push_back(quantile);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -563,6 +567,8 @@ public:
params, &levels.levels[0], &levels.permutation[0], size, &data_to[old_size]); params, &levels.levels[0], &levels.permutation[0], size, &data_to[old_size]);
} }
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -648,6 +654,8 @@ public:
params, &levels.levels[0], &levels.permutation[0], size, &data_to[old_size]); params, &levels.levels[0], &levels.permutation[0], size, &data_to[old_size]);
} }
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -843,6 +843,8 @@ public:
{ {
static_cast<ColumnFloat32 &>(to).getData().push_back(this->data(place).getFloat(level)); static_cast<ColumnFloat32 &>(to).getData().push_back(this->data(place).getFloat(level));
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -903,6 +905,8 @@ public:
{ {
static_cast<ColumnFloat32 &>(to).getData().push_back(this->data(place).getFloat(level)); static_cast<ColumnFloat32 &>(to).getData().push_back(this->data(place).getFloat(level));
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -971,6 +975,8 @@ public:
this->data(place).getManyFloat(&levels.levels[0], &levels.permutation[0], size, &data_to[old_size]); this->data(place).getManyFloat(&levels.levels[0], &levels.permutation[0], size, &data_to[old_size]);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -1037,6 +1043,8 @@ public:
this->data(place).getManyFloat(&levels.levels[0], &levels.permutation[0], size, &data_to[old_size]); this->data(place).getManyFloat(&levels.levels[0], &levels.permutation[0], size, &data_to[old_size]);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -238,6 +238,8 @@ public:
IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; } IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; }
const char * getHeaderFilePath() const override { return __FILE__; }
private: private:
enum class PatternActionType enum class PatternActionType
{ {

View File

@ -111,6 +111,8 @@ public:
} }
IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; } IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
} }

View File

@ -153,6 +153,8 @@ public:
{ {
this->data(place).publish(to); this->data(place).publish(to);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
/** Implementing the varSamp function. /** Implementing the varSamp function.
@ -416,6 +418,8 @@ public:
{ {
this->data(place).publish(to); this->data(place).publish(to);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
/** Implementing the covarSamp function. /** Implementing the covarSamp function.

View File

@ -63,6 +63,8 @@ public:
{ {
static_cast<ColumnVector<typename NearestFieldType<T>::Type> &>(to).getData().push_back(this->data(place).sum); static_cast<ColumnVector<typename NearestFieldType<T>::Type> &>(to).getData().push_back(this->data(place).sum);
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -120,6 +120,8 @@ public:
for (auto it = resultVec.begin(); it != resultVec.end(); ++it, ++i) for (auto it = resultVec.begin(); it != resultVec.end(); ++it, ++i)
data_to[old_size + i] = it->key; data_to[old_size + i] = it->key;
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -236,6 +238,8 @@ public:
deserializeAndInsert(elem.key, data_to); deserializeAndInsert(elem.key, data_to);
} }
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -255,7 +255,7 @@ struct OneAdder<T, Data, typename std::enable_if<
std::is_same<Data, AggregateFunctionUniqHLL12Data<T>>::value>::type> std::is_same<Data, AggregateFunctionUniqHLL12Data<T>>::value>::type>
{ {
template <typename T2 = T> template <typename T2 = T>
static void addImpl(Data & data, const IColumn & column, size_t row_num, static void ALWAYS_INLINE addImpl(Data & data, const IColumn & column, size_t row_num,
typename std::enable_if<!std::is_same<T2, String>::value>::type * = nullptr) typename std::enable_if<!std::is_same<T2, String>::value>::type * = nullptr)
{ {
const auto & value = static_cast<const ColumnVector<T2> &>(column).getData()[row_num]; const auto & value = static_cast<const ColumnVector<T2> &>(column).getData()[row_num];
@ -263,7 +263,7 @@ struct OneAdder<T, Data, typename std::enable_if<
} }
template <typename T2 = T> template <typename T2 = T>
static void addImpl(Data & data, const IColumn & column, size_t row_num, static void ALWAYS_INLINE addImpl(Data & data, const IColumn & column, size_t row_num,
typename std::enable_if<std::is_same<T2, String>::value>::type * = nullptr) typename std::enable_if<std::is_same<T2, String>::value>::type * = nullptr)
{ {
StringRef value = column.getDataAt(row_num); StringRef value = column.getDataAt(row_num);
@ -279,7 +279,7 @@ struct OneAdder<T, Data, typename std::enable_if<
std::is_same<Data, AggregateFunctionUniqCombinedData<T>>::value>::type> std::is_same<Data, AggregateFunctionUniqCombinedData<T>>::value>::type>
{ {
template <typename T2 = T> template <typename T2 = T>
static void addImpl(Data & data, const IColumn & column, size_t row_num, static void ALWAYS_INLINE addImpl(Data & data, const IColumn & column, size_t row_num,
typename std::enable_if<!std::is_same<T2, String>::value>::type * = nullptr) typename std::enable_if<!std::is_same<T2, String>::value>::type * = nullptr)
{ {
const auto & value = static_cast<const ColumnVector<T2> &>(column).getData()[row_num]; const auto & value = static_cast<const ColumnVector<T2> &>(column).getData()[row_num];
@ -287,7 +287,7 @@ struct OneAdder<T, Data, typename std::enable_if<
} }
template <typename T2 = T> template <typename T2 = T>
static void addImpl(Data & data, const IColumn & column, size_t row_num, static void ALWAYS_INLINE addImpl(Data & data, const IColumn & column, size_t row_num,
typename std::enable_if<std::is_same<T2, String>::value>::type * = nullptr) typename std::enable_if<std::is_same<T2, String>::value>::type * = nullptr)
{ {
StringRef value = column.getDataAt(row_num); StringRef value = column.getDataAt(row_num);
@ -300,14 +300,14 @@ struct OneAdder<T, Data, typename std::enable_if<
std::is_same<Data, AggregateFunctionUniqExactData<T>>::value>::type> std::is_same<Data, AggregateFunctionUniqExactData<T>>::value>::type>
{ {
template <typename T2 = T> template <typename T2 = T>
static void addImpl(Data & data, const IColumn & column, size_t row_num, static void ALWAYS_INLINE addImpl(Data & data, const IColumn & column, size_t row_num,
typename std::enable_if<!std::is_same<T2, String>::value>::type * = nullptr) typename std::enable_if<!std::is_same<T2, String>::value>::type * = nullptr)
{ {
data.set.insert(static_cast<const ColumnVector<T2> &>(column).getData()[row_num]); data.set.insert(static_cast<const ColumnVector<T2> &>(column).getData()[row_num]);
} }
template <typename T2 = T> template <typename T2 = T>
static void addImpl(Data & data, const IColumn & column, size_t row_num, static void ALWAYS_INLINE addImpl(Data & data, const IColumn & column, size_t row_num,
typename std::enable_if<std::is_same<T2, String>::value>::type * = nullptr) typename std::enable_if<std::is_same<T2, String>::value>::type * = nullptr)
{ {
StringRef value = column.getDataAt(row_num); StringRef value = column.getDataAt(row_num);
@ -364,6 +364,8 @@ public:
{ {
static_cast<ColumnUInt64 &>(to).getData().push_back(this->data(place).set.size()); static_cast<ColumnUInt64 &>(to).getData().push_back(this->data(place).set.size());
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -426,6 +428,8 @@ public:
} }
IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; } IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -176,6 +176,8 @@ public:
{ {
static_cast<ColumnUInt64 &>(to).getData().push_back(this->data(place).size()); static_cast<ColumnUInt64 &>(to).getData().push_back(this->data(place).size());
} }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };
@ -256,6 +258,8 @@ public:
} }
IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; } IAggregateFunction::AddFunc getAddressOfAddFunction() const override final { return &addFree; }
const char * getHeaderFilePath() const override { return __FILE__; }
}; };

View File

@ -34,7 +34,7 @@ static IAggregateFunction * createWithNumericType(const IDataType & argument_typ
return nullptr; return nullptr;
} }
template <template <typename, typename> class AggregateFunctionTemplate, class Data> template <template <typename, typename> class AggregateFunctionTemplate, typename Data>
static IAggregateFunction * createWithNumericType(const IDataType & argument_type) static IAggregateFunction * createWithNumericType(const IDataType & argument_type)
{ {
if (typeid_cast<const DataTypeUInt8 *>(&argument_type)) return new AggregateFunctionTemplate<UInt8, Data>; if (typeid_cast<const DataTypeUInt8 *>(&argument_type)) return new AggregateFunctionTemplate<UInt8, Data>;
@ -53,7 +53,7 @@ static IAggregateFunction * createWithNumericType(const IDataType & argument_typ
return nullptr; return nullptr;
} }
template <template <typename, typename> class AggregateFunctionTemplate, class Data, typename ... TArgs> template <template <typename, typename> class AggregateFunctionTemplate, typename Data, typename ... TArgs>
static IAggregateFunction * createWithNumericType(const IDataType & argument_type, TArgs && ... args) static IAggregateFunction * createWithNumericType(const IDataType & argument_type, TArgs && ... args)
{ {
if (typeid_cast<const DataTypeUInt8 *>(&argument_type)) return new AggregateFunctionTemplate<UInt8, Data>(std::forward<TArgs>(args)...); if (typeid_cast<const DataTypeUInt8 *>(&argument_type)) return new AggregateFunctionTemplate<UInt8, Data>(std::forward<TArgs>(args)...);

View File

@ -121,7 +121,6 @@ public:
*/ */
virtual bool isState() const { return false; } virtual bool isState() const { return false; }
/** The inner loop that uses the function pointer is better than using the virtual function. /** The inner loop that uses the function pointer is better than using the virtual function.
* The reason is that in the case of virtual functions GCC 5.1.2 generates code, * The reason is that in the case of virtual functions GCC 5.1.2 generates code,
* which, at each iteration of the loop, reloads the function address (the offset value in the virtual function table) from memory to the register. * which, at each iteration of the loop, reloads the function address (the offset value in the virtual function table) from memory to the register.
@ -130,6 +129,12 @@ public:
*/ */
using AddFunc = void (*)(const IAggregateFunction *, AggregateDataPtr, const IColumn **, size_t, Arena *); using AddFunc = void (*)(const IAggregateFunction *, AggregateDataPtr, const IColumn **, size_t, Arena *);
virtual AddFunc getAddressOfAddFunction() const = 0; virtual AddFunc getAddressOfAddFunction() const = 0;
/** This is used for runtime code generation to determine, which header files to include in generated source.
* Always implement it as
* const char * getHeaderFilePath() const override { return __FILE__; }
*/
virtual const char * getHeaderFilePath() const = 0;
}; };

View File

@ -24,7 +24,6 @@ void registerAggregateFunctionsUniq(AggregateFunctionFactory & factory);
void registerAggregateFunctionUniqUpTo(AggregateFunctionFactory & factory); void registerAggregateFunctionUniqUpTo(AggregateFunctionFactory & factory);
void registerAggregateFunctionTopK(AggregateFunctionFactory & factory); void registerAggregateFunctionTopK(AggregateFunctionFactory & factory);
void registerAggregateFunctionsBitwise(AggregateFunctionFactory & factory); void registerAggregateFunctionsBitwise(AggregateFunctionFactory & factory);
void registerAggregateFunctionDebug(AggregateFunctionFactory & factory);
void registerAggregateFunctions() void registerAggregateFunctions()
@ -50,7 +49,6 @@ void registerAggregateFunctions()
registerAggregateFunctionUniqUpTo(factory); registerAggregateFunctionUniqUpTo(factory);
registerAggregateFunctionTopK(factory); registerAggregateFunctionTopK(factory);
registerAggregateFunctionsBitwise(factory); registerAggregateFunctionsBitwise(factory);
registerAggregateFunctionDebug(factory);
} }
} }

View File

@ -19,7 +19,7 @@ namespace ErrorCodes
/** ColumnConst contains another column with single element, /** ColumnConst contains another column with single element,
* but looks like a column with arbitary amount of same elements. * but looks like a column with arbitary amount of same elements.
*/ */
class ColumnConst : public IColumn class ColumnConst final : public IColumn
{ {
private: private:
ColumnPtr data; ColumnPtr data;

View File

@ -11,10 +11,10 @@
namespace detail namespace detail
{ {
template <class T, bool is_nothrow_move_assignable = std::is_nothrow_move_assignable<T>::value> template <typename T, bool is_nothrow_move_assignable = std::is_nothrow_move_assignable<T>::value>
struct MoveOrCopyIfThrow; struct MoveOrCopyIfThrow;
template <class T> template <typename T>
struct MoveOrCopyIfThrow<T, true> struct MoveOrCopyIfThrow<T, true>
{ {
void operator()(T && src, T & dst) const void operator()(T && src, T & dst) const
@ -23,7 +23,7 @@ namespace detail
} }
}; };
template <class T> template <typename T>
struct MoveOrCopyIfThrow<T, false> struct MoveOrCopyIfThrow<T, false>
{ {
void operator()(T && src, T & dst) const void operator()(T && src, T & dst) const
@ -32,14 +32,14 @@ namespace detail
} }
}; };
template <class T> template <typename T>
void moveOrCopyIfThrow(T && src, T & dst) void moveOrCopyIfThrow(T && src, T & dst)
{ {
MoveOrCopyIfThrow<T>()(std::forward<T>(src), dst); MoveOrCopyIfThrow<T>()(std::forward<T>(src), dst);
} }
}; };
/** A very simple thread-safe queue of limited length. /** A very simple thread-safe queue of limited size.
* If you try to pop an item from an empty queue, the thread is blocked until the queue becomes nonempty. * If you try to pop an item from an empty queue, the thread is blocked until the queue becomes nonempty.
* If you try to push an element into an overflowed queue, the thread is blocked until space appears in the queue. * If you try to push an element into an overflowed queue, the thread is blocked until space appears in the queue.
*/ */
@ -47,7 +47,6 @@ template <typename T>
class ConcurrentBoundedQueue class ConcurrentBoundedQueue
{ {
private: private:
size_t max_fill;
std::queue<T> queue; std::queue<T> queue;
Poco::FastMutex mutex; Poco::FastMutex mutex;
Poco::Semaphore fill_count; Poco::Semaphore fill_count;

View File

@ -36,13 +36,13 @@ namespace CurrentMetrics
/// Set value of specified metric. /// Set value of specified metric.
inline void set(Metric metric, Value value) inline void set(Metric metric, Value value)
{ {
values[metric] = value; values[metric].store(value, std::memory_order_relaxed);
} }
/// Add value for specified metric. You must subtract value later; or see class Increment below. /// Add value for specified metric. You must subtract value later; or see class Increment below.
inline void add(Metric metric, Value value = 1) inline void add(Metric metric, Value value = 1)
{ {
values[metric] += value; values[metric].fetch_add(value, std::memory_order_relaxed);
} }
inline void sub(Metric metric, Value value = 1) inline void sub(Metric metric, Value value = 1)
@ -70,7 +70,7 @@ namespace CurrentMetrics
~Increment() ~Increment()
{ {
if (what) if (what)
*what -= amount; what->fetch_sub(amount, std::memory_order_relaxed);
} }
Increment(Increment && old) Increment(Increment && old)
@ -88,14 +88,14 @@ namespace CurrentMetrics
void changeTo(Value new_amount) void changeTo(Value new_amount)
{ {
*what += new_amount - amount; what->fetch_add(new_amount - amount, std::memory_order_relaxed);
amount = new_amount; amount = new_amount;
} }
/// Subtract value before destructor. /// Subtract value before destructor.
void destroy() void destroy()
{ {
*what -= amount; what->fetch_sub(amount, std::memory_order_relaxed);
what = nullptr; what = nullptr;
} }
}; };

View File

@ -32,8 +32,8 @@ MemoryTracker::~MemoryTracker()
* then memory usage of 'next' memory trackers will be underestimated, * then memory usage of 'next' memory trackers will be underestimated,
* because amount will be decreased twice (first - here, second - when real 'free' happens). * because amount will be decreased twice (first - here, second - when real 'free' happens).
*/ */
if (amount) if (auto value = amount.load(std::memory_order_relaxed))
free(amount); free(value);
} }
@ -47,7 +47,11 @@ void MemoryTracker::logPeakMemoryUsage() const
void MemoryTracker::alloc(Int64 size) void MemoryTracker::alloc(Int64 size)
{ {
Int64 will_be = amount += size; /** Using memory_order_relaxed means that if allocations are done simultaneously,
* we allow exception about memory limit exceeded to be thrown only on next allocation.
* So, we allow over-allocations.
*/
Int64 will_be = size + amount.fetch_add(size, std::memory_order_relaxed);
if (!next.load(std::memory_order_relaxed)) if (!next.load(std::memory_order_relaxed))
CurrentMetrics::add(metric, size); CurrentMetrics::add(metric, size);
@ -96,29 +100,31 @@ void MemoryTracker::alloc(Int64 size)
void MemoryTracker::free(Int64 size) void MemoryTracker::free(Int64 size)
{ {
Int64 new_amount = amount.fetch_sub(size, std::memory_order_relaxed) - size;
/** Sometimes, query could free some data, that was allocated outside of query context. /** Sometimes, query could free some data, that was allocated outside of query context.
* Example: cache eviction. * Example: cache eviction.
* To avoid negative memory usage, we "saturate" amount. * To avoid negative memory usage, we "saturate" amount.
* Memory usage will be calculated with some error. * Memory usage will be calculated with some error.
* NOTE The code is not atomic. Not worth to fix.
*/ */
Int64 size_to_subtract = size; if (new_amount < 0)
if (size_to_subtract > amount) {
size_to_subtract = amount; amount.fetch_sub(new_amount);
size += new_amount;
amount -= size_to_subtract; }
/// NOTE above code is not atomic. It's easy to fix.
if (auto loaded_next = next.load(std::memory_order_relaxed)) if (auto loaded_next = next.load(std::memory_order_relaxed))
loaded_next->free(size); loaded_next->free(size);
else else
CurrentMetrics::sub(metric, size_to_subtract); CurrentMetrics::sub(metric, size);
} }
void MemoryTracker::reset() void MemoryTracker::reset()
{ {
if (!next.load(std::memory_order_relaxed)) if (!next.load(std::memory_order_relaxed))
CurrentMetrics::sub(metric, amount); CurrentMetrics::sub(metric, amount.load(std::memory_order_relaxed));
amount.store(0, std::memory_order_relaxed); amount.store(0, std::memory_order_relaxed);
peak.store(0, std::memory_order_relaxed); peak.store(0, std::memory_order_relaxed);

View File

@ -24,7 +24,7 @@ namespace ProfileEvents
/// Increment a counter for event. Thread-safe. /// Increment a counter for event. Thread-safe.
inline void increment(Event event, Count amount = 1) inline void increment(Event event, Count amount = 1)
{ {
counters[event] += amount; counters[event].fetch_add(amount, std::memory_order_relaxed);
} }
/// Get index just after last event identifier. /// Get index just after last event identifier.

View File

@ -185,6 +185,7 @@ public:
Element * swap_buffer = reinterpret_cast<Element *>(allocator.allocate(size * sizeof(Element))); Element * swap_buffer = reinterpret_cast<Element *>(allocator.allocate(size * sizeof(Element)));
/// Transform the array and calculate the histogram. /// Transform the array and calculate the histogram.
/// NOTE This is slightly suboptimal. Look at https://github.com/powturbo/TurboHist
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
{ {
if (!Traits::Transform::transform_is_simple) if (!Traits::Transform::transform_is_simple)

View File

@ -19,7 +19,7 @@ public:
ZooKeeperHolder() = default; ZooKeeperHolder() = default;
/// вызывать из одного потока - не thread safe /// вызывать из одного потока - не thread safe
template <class... Args> template <typename... Args>
void init(Args&&... args); void init(Args&&... args);
/// был ли класс инициализирован /// был ли класс инициализирован
bool isInitialized() const { return ptr != nullptr; } bool isInitialized() const { return ptr != nullptr; }
@ -75,7 +75,7 @@ private:
static std::string nullptr_exception_message; static std::string nullptr_exception_message;
}; };
template <class... Args> template <typename... Args>
void ZooKeeperHolder::init(Args&&... args) void ZooKeeperHolder::init(Args&&... args)
{ {
ptr = std::make_shared<ZooKeeper>(std::forward<Args>(args)...); ptr = std::make_shared<ZooKeeper>(std::forward<Args>(args)...);

View File

@ -146,7 +146,7 @@ private:
* Grow the map by GrowthFactor::num/GrowthFactor::den and use a modulo to map a hash * Grow the map by GrowthFactor::num/GrowthFactor::den and use a modulo to map a hash
* to a bucket. Slower but it can be usefull if you want a slower growth. * to a bucket. Slower but it can be usefull if you want a slower growth.
*/ */
template<class GrowthFactor = std::ratio<3, 2>> template <typename GrowthFactor = std::ratio<3, 2>>
class mod_growth_policy { class mod_growth_policy {
public: public:
mod_growth_policy(std::size_t& min_bucket_count_in_out) { mod_growth_policy(std::size_t& min_bucket_count_in_out) {
@ -617,7 +617,7 @@ private:
* OverflowContainer will be used as containers for overflown elements. Usually it should be a list<ValueType> * OverflowContainer will be used as containers for overflown elements. Usually it should be a list<ValueType>
* or a set<Key>/map<Key, T>. * or a set<Key>/map<Key, T>.
*/ */
template<class ValueType, template <typename ValueType,
class KeySelect, class KeySelect,
class ValueSelect, class ValueSelect,
class Hash, class Hash,
@ -724,7 +724,7 @@ public:
return KeySelect()(*m_overflow_iterator); return KeySelect()(*m_overflow_iterator);
} }
template<class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr> template <typename U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
typename std::conditional< typename std::conditional<
is_const, is_const,
const typename U::value_type&, const typename U::value_type&,
@ -791,7 +791,7 @@ public:
public: public:
template<class OC = OverflowContainer, typename std::enable_if<!has_key_compare<OC>::value>::type* = nullptr> template <typename OC = OverflowContainer, typename std::enable_if<!has_key_compare<OC>::value>::type* = nullptr>
hopscotch_hash(size_type bucket_count, hopscotch_hash(size_type bucket_count,
const Hash& hash, const Hash& hash,
const KeyEqual& equal, const KeyEqual& equal,
@ -814,7 +814,7 @@ public:
this->max_load_factor(max_load_factor); this->max_load_factor(max_load_factor);
} }
template<class OC = OverflowContainer, typename std::enable_if<has_key_compare<OC>::value>::type* = nullptr> template <typename OC = OverflowContainer, typename std::enable_if<has_key_compare<OC>::value>::type* = nullptr>
hopscotch_hash(size_type bucket_count, hopscotch_hash(size_type bucket_count,
const Hash& hash, const Hash& hash,
const KeyEqual& equal, const KeyEqual& equal,
@ -949,7 +949,7 @@ public:
return insert_impl(value); return insert_impl(value);
} }
template<class P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr> template <typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr>
std::pair<iterator, bool> insert(P&& value) { std::pair<iterator, bool> insert(P&& value) {
return emplace(std::forward<P>(value)); return emplace(std::forward<P>(value));
} }
@ -967,7 +967,7 @@ public:
return insert(value).first; return insert(value).first;
} }
template<class P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr> template <typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr>
iterator insert(const_iterator hint, P&& value) { iterator insert(const_iterator hint, P&& value) {
return emplace_hint(hint, std::forward<P>(value)); return emplace_hint(hint, std::forward<P>(value));
} }
@ -981,7 +981,7 @@ public:
} }
template<class InputIt> template <typename InputIt>
void insert(InputIt first, InputIt last) { void insert(InputIt first, InputIt last) {
if(std::is_base_of<std::forward_iterator_tag, if(std::is_base_of<std::forward_iterator_tag,
typename std::iterator_traits<InputIt>::iterator_category>::value) typename std::iterator_traits<InputIt>::iterator_category>::value)
@ -1003,18 +1003,18 @@ public:
} }
template<class M> template <typename M>
std::pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj) { std::pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj) {
return insert_or_assign_impl(k, std::forward<M>(obj)); return insert_or_assign_impl(k, std::forward<M>(obj));
} }
template<class M> template <typename M>
std::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj) { std::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj) {
return insert_or_assign_impl(std::move(k), std::forward<M>(obj)); return insert_or_assign_impl(std::move(k), std::forward<M>(obj));
} }
template<class M> template <typename M>
iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj) { iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj) {
if(hint != cend() && compare_keys(KeySelect()(*hint), k)) { if(hint != cend() && compare_keys(KeySelect()(*hint), k)) {
auto it = mutable_iterator(hint); auto it = mutable_iterator(hint);
@ -1026,7 +1026,7 @@ public:
return insert_or_assign(k, std::forward<M>(obj)).first; return insert_or_assign(k, std::forward<M>(obj)).first;
} }
template<class M> template <typename M>
iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj) { iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj) {
if(hint != cend() && compare_keys(KeySelect()(*hint), k)) { if(hint != cend() && compare_keys(KeySelect()(*hint), k)) {
auto it = mutable_iterator(hint); auto it = mutable_iterator(hint);
@ -1039,27 +1039,27 @@ public:
} }
template<class... Args> template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) { std::pair<iterator, bool> emplace(Args&&... args) {
return insert(value_type(std::forward<Args>(args)...)); return insert(value_type(std::forward<Args>(args)...));
} }
template<class... Args> template <typename... Args>
iterator emplace_hint(const_iterator hint, Args&&... args) { iterator emplace_hint(const_iterator hint, Args&&... args) {
return insert(hint, value_type(std::forward<Args>(args)...)); return insert(hint, value_type(std::forward<Args>(args)...));
} }
template<class... Args> template <typename... Args>
std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args) { std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args) {
return try_emplace_impl(k, std::forward<Args>(args)...); return try_emplace_impl(k, std::forward<Args>(args)...);
} }
template<class... Args> template <typename... Args>
std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args) { std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args) {
return try_emplace_impl(std::move(k), std::forward<Args>(args)...); return try_emplace_impl(std::move(k), std::forward<Args>(args)...);
} }
template<class... Args> template <typename... Args>
iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args) { iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args) {
if(hint != cend() && compare_keys(KeySelect()(*hint), k)) { if(hint != cend() && compare_keys(KeySelect()(*hint), k)) {
return mutable_iterator(hint); return mutable_iterator(hint);
@ -1068,7 +1068,7 @@ public:
return try_emplace(k, std::forward<Args>(args)...).first; return try_emplace(k, std::forward<Args>(args)...).first;
} }
template<class... Args> template <typename... Args>
iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args) { iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args) {
if(hint != cend() && compare_keys(KeySelect()(*hint), k)) { if(hint != cend() && compare_keys(KeySelect()(*hint), k)) {
return mutable_iterator(hint); return mutable_iterator(hint);
@ -1111,12 +1111,12 @@ public:
return to_delete; return to_delete;
} }
template<class K> template <typename K>
size_type erase(const K& key) { size_type erase(const K& key) {
return erase(key, hash_key(key)); return erase(key, hash_key(key));
} }
template<class K> template <typename K>
size_type erase(const K& key, std::size_t hash) { size_type erase(const K& key, std::size_t hash) {
const std::size_t ibucket_for_hash = bucket_for_hash(hash); const std::size_t ibucket_for_hash = bucket_for_hash(hash);
@ -1157,23 +1157,23 @@ public:
/* /*
* Lookup * Lookup
*/ */
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr> template <typename K, typename U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
typename U::value_type& at(const K& key) { typename U::value_type& at(const K& key) {
return at(key, hash_key(key)); return at(key, hash_key(key));
} }
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr> template <typename K, typename U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
typename U::value_type& at(const K& key, std::size_t hash) { typename U::value_type& at(const K& key, std::size_t hash) {
return const_cast<typename U::value_type&>(static_cast<const hopscotch_hash*>(this)->at(key, hash)); return const_cast<typename U::value_type&>(static_cast<const hopscotch_hash*>(this)->at(key, hash));
} }
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr> template <typename K, typename U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
const typename U::value_type& at(const K& key) const { const typename U::value_type& at(const K& key) const {
return at(key, hash_key(key)); return at(key, hash_key(key));
} }
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr> template <typename K, typename U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
const typename U::value_type& at(const K& key, std::size_t hash) const { const typename U::value_type& at(const K& key, std::size_t hash) const {
using T = typename U::value_type; using T = typename U::value_type;
@ -1187,7 +1187,7 @@ public:
} }
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr> template <typename K, typename U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
typename U::value_type& operator[](K&& key) { typename U::value_type& operator[](K&& key) {
using T = typename U::value_type; using T = typename U::value_type;
@ -1206,57 +1206,57 @@ public:
} }
template<class K> template <typename K>
size_type count(const K& key) const { size_type count(const K& key) const {
return count(key, hash_key(key)); return count(key, hash_key(key));
} }
template<class K> template <typename K>
size_type count(const K& key, std::size_t hash) const { size_type count(const K& key, std::size_t hash) const {
return count_impl(key, hash, m_buckets.cbegin() + bucket_for_hash(hash)); return count_impl(key, hash, m_buckets.cbegin() + bucket_for_hash(hash));
} }
template<class K> template <typename K>
iterator find(const K& key) { iterator find(const K& key) {
return find(key, hash_key(key)); return find(key, hash_key(key));
} }
template<class K> template <typename K>
iterator find(const K& key, std::size_t hash) { iterator find(const K& key, std::size_t hash) {
return find_impl(key, hash, m_buckets.begin() + bucket_for_hash(hash)); return find_impl(key, hash, m_buckets.begin() + bucket_for_hash(hash));
} }
template<class K> template <typename K>
const_iterator find(const K& key) const { const_iterator find(const K& key) const {
return find(key, hash_key(key)); return find(key, hash_key(key));
} }
template<class K> template <typename K>
const_iterator find(const K& key, std::size_t hash) const { const_iterator find(const K& key, std::size_t hash) const {
return find_impl(key, hash, m_buckets.begin() + bucket_for_hash(hash)); return find_impl(key, hash, m_buckets.begin() + bucket_for_hash(hash));
} }
template<class K> template <typename K>
std::pair<iterator, iterator> equal_range(const K& key) { std::pair<iterator, iterator> equal_range(const K& key) {
return equal_range(key, hash_key(key)); return equal_range(key, hash_key(key));
} }
template<class K> template <typename K>
std::pair<iterator, iterator> equal_range(const K& key, std::size_t hash) { std::pair<iterator, iterator> equal_range(const K& key, std::size_t hash) {
iterator it = find(key, hash); iterator it = find(key, hash);
return std::make_pair(it, (it == end())?it:std::next(it)); return std::make_pair(it, (it == end())?it:std::next(it));
} }
template<class K> template <typename K>
std::pair<const_iterator, const_iterator> equal_range(const K& key) const { std::pair<const_iterator, const_iterator> equal_range(const K& key) const {
return equal_range(key, hash_key(key)); return equal_range(key, hash_key(key));
} }
template<class K> template <typename K>
std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t hash) const { std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t hash) const {
const_iterator it = find(key, hash); const_iterator it = find(key, hash);
return std::make_pair(it, (it == cend())?it:std::next(it)); return std::make_pair(it, (it == cend())?it:std::next(it));
@ -1339,19 +1339,19 @@ public:
return m_overflow_elements.size(); return m_overflow_elements.size();
} }
template<class U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr> template <typename U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr>
typename U::key_compare key_comp() const { typename U::key_compare key_comp() const {
return m_overflow_elements.key_comp(); return m_overflow_elements.key_comp();
} }
private: private:
template<class K> template <typename K>
std::size_t hash_key(const K& key) const { std::size_t hash_key(const K& key) const {
return Hash::operator()(key); return Hash::operator()(key);
} }
template<class K1, class K2> template <typename K1, typename K2>
bool compare_keys(const K1& key1, const K2& key2) const { bool compare_keys(const K1& key1, const K2& key2) const {
return KeyEqual::operator()(key1, key2); return KeyEqual::operator()(key1, key2);
} }
@ -1499,7 +1499,7 @@ private:
template<class K, class M> template <typename K, typename M>
std::pair<iterator, bool> insert_or_assign_impl(K&& key, M&& obj) { std::pair<iterator, bool> insert_or_assign_impl(K&& key, M&& obj) {
auto it = try_emplace_impl(std::forward<K>(key), std::forward<M>(obj)); auto it = try_emplace_impl(std::forward<K>(key), std::forward<M>(obj));
if(!it.second) { if(!it.second) {
@ -1509,7 +1509,7 @@ private:
return it; return it;
} }
template<typename P, class... Args> template <typename P, typename... Args>
std::pair<iterator, bool> try_emplace_impl(P&& key, Args&&... args_value) { std::pair<iterator, bool> try_emplace_impl(P&& key, Args&&... args_value) {
const std::size_t hash = hash_key(key); const std::size_t hash = hash_key(key);
const std::size_t ibucket_for_hash = bucket_for_hash(hash); const std::size_t ibucket_for_hash = bucket_for_hash(hash);
@ -1682,7 +1682,7 @@ private:
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr> template <typename K, typename U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
typename U::value_type* find_value_impl(const K& key, std::size_t hash, iterator_buckets it_bucket) { typename U::value_type* find_value_impl(const K& key, std::size_t hash, iterator_buckets it_bucket) {
return const_cast<typename U::value_type*>( return const_cast<typename U::value_type*>(
static_cast<const hopscotch_hash*>(this)->find_value_impl(key, hash, it_bucket)); static_cast<const hopscotch_hash*>(this)->find_value_impl(key, hash, it_bucket));
@ -1693,7 +1693,7 @@ private:
* *
* Return null if no value for key (TODO use std::optional when available). * Return null if no value for key (TODO use std::optional when available).
*/ */
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr> template <typename K, typename U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
const typename U::value_type* find_value_impl(const K& key, std::size_t hash, const typename U::value_type* find_value_impl(const K& key, std::size_t hash,
const_iterator_buckets it_bucket) const const_iterator_buckets it_bucket) const
{ {
@ -1712,7 +1712,7 @@ private:
return nullptr; return nullptr;
} }
template<class K> template <typename K>
size_type count_impl(const K& key, std::size_t hash, const_iterator_buckets it_bucket) const { size_type count_impl(const K& key, std::size_t hash, const_iterator_buckets it_bucket) const {
if(find_in_buckets(key, hash, it_bucket) != m_buckets.cend()) { if(find_in_buckets(key, hash, it_bucket) != m_buckets.cend()) {
return 1; return 1;
@ -1725,7 +1725,7 @@ private:
} }
} }
template<class K> template <typename K>
iterator find_impl(const K& key, std::size_t hash, iterator_buckets it_bucket) { iterator find_impl(const K& key, std::size_t hash, iterator_buckets it_bucket) {
auto it = find_in_buckets(key, hash, it_bucket); auto it = find_in_buckets(key, hash, it_bucket);
if(it != m_buckets.end()) { if(it != m_buckets.end()) {
@ -1739,7 +1739,7 @@ private:
return iterator(m_buckets.end(), m_buckets.end(), find_in_overflow(key)); return iterator(m_buckets.end(), m_buckets.end(), find_in_overflow(key));
} }
template<class K> template <typename K>
const_iterator find_impl(const K& key, std::size_t hash, const_iterator_buckets it_bucket) const { const_iterator find_impl(const K& key, std::size_t hash, const_iterator_buckets it_bucket) const {
auto it = find_in_buckets(key, hash, it_bucket); auto it = find_in_buckets(key, hash, it_bucket);
if(it != m_buckets.cend()) { if(it != m_buckets.cend()) {
@ -1754,14 +1754,14 @@ private:
return const_iterator(m_buckets.cend(), m_buckets.cend(), find_in_overflow(key)); return const_iterator(m_buckets.cend(), m_buckets.cend(), find_in_overflow(key));
} }
template<class K> template <typename K>
iterator_buckets find_in_buckets(const K& key, std::size_t hash, iterator_buckets it_bucket) { iterator_buckets find_in_buckets(const K& key, std::size_t hash, iterator_buckets it_bucket) {
auto it_find = static_cast<const hopscotch_hash*>(this)->find_in_buckets(key, hash, it_bucket); auto it_find = static_cast<const hopscotch_hash*>(this)->find_in_buckets(key, hash, it_bucket);
return m_buckets.begin() + std::distance(m_buckets.cbegin(), it_find); return m_buckets.begin() + std::distance(m_buckets.cbegin(), it_find);
} }
template<class K> template <typename K>
const_iterator_buckets find_in_buckets(const K& key, std::size_t hash, const_iterator_buckets it_bucket) const { const_iterator_buckets find_in_buckets(const K& key, std::size_t hash, const_iterator_buckets it_bucket) const {
(void) hash; // Avoid warning of unused variable when StoreHash is false; (void) hash; // Avoid warning of unused variable when StoreHash is false;
@ -1791,7 +1791,7 @@ private:
template<class K, class U = OverflowContainer, typename std::enable_if<!has_key_compare<U>::value>::type* = nullptr> template <typename K, typename U = OverflowContainer, typename std::enable_if<!has_key_compare<U>::value>::type* = nullptr>
iterator_overflow find_in_overflow(const K& key) { iterator_overflow find_in_overflow(const K& key) {
return std::find_if(m_overflow_elements.begin(), m_overflow_elements.end(), return std::find_if(m_overflow_elements.begin(), m_overflow_elements.end(),
[&](const value_type& value) { [&](const value_type& value) {
@ -1799,7 +1799,7 @@ private:
}); });
} }
template<class K, class U = OverflowContainer, typename std::enable_if<!has_key_compare<U>::value>::type* = nullptr> template <typename K, typename U = OverflowContainer, typename std::enable_if<!has_key_compare<U>::value>::type* = nullptr>
const_iterator_overflow find_in_overflow(const K& key) const { const_iterator_overflow find_in_overflow(const K& key) const {
return std::find_if(m_overflow_elements.cbegin(), m_overflow_elements.cend(), return std::find_if(m_overflow_elements.cbegin(), m_overflow_elements.cend(),
[&](const value_type& value) { [&](const value_type& value) {
@ -1807,37 +1807,37 @@ private:
}); });
} }
template<class K, class U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr> template <typename K, typename U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr>
iterator_overflow find_in_overflow(const K& key) { iterator_overflow find_in_overflow(const K& key) {
return m_overflow_elements.find(key); return m_overflow_elements.find(key);
} }
template<class K, class U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr> template <typename K, typename U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr>
const_iterator_overflow find_in_overflow(const K& key) const { const_iterator_overflow find_in_overflow(const K& key) const {
return m_overflow_elements.find(key); return m_overflow_elements.find(key);
} }
template<class... Args, class U = OverflowContainer, typename std::enable_if<!has_key_compare<U>::value>::type* = nullptr> template <typename... Args, typename U = OverflowContainer, typename std::enable_if<!has_key_compare<U>::value>::type* = nullptr>
iterator_overflow insert_in_overflow(Args&&... value_type_args) { iterator_overflow insert_in_overflow(Args&&... value_type_args) {
return m_overflow_elements.emplace(m_overflow_elements.end(), std::forward<Args>(value_type_args)...); return m_overflow_elements.emplace(m_overflow_elements.end(), std::forward<Args>(value_type_args)...);
} }
template<class... Args, class U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr> template <typename... Args, typename U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr>
iterator_overflow insert_in_overflow(Args&&... value_type_args) { iterator_overflow insert_in_overflow(Args&&... value_type_args) {
return m_overflow_elements.emplace(std::forward<Args>(value_type_args)...).first; return m_overflow_elements.emplace(std::forward<Args>(value_type_args)...).first;
} }
template<class U = OverflowContainer, typename std::enable_if<!has_key_compare<U>::value>::type* = nullptr> template <typename U = OverflowContainer, typename std::enable_if<!has_key_compare<U>::value>::type* = nullptr>
hopscotch_hash new_hopscotch_hash(size_type bucket_count) { hopscotch_hash new_hopscotch_hash(size_type bucket_count) {
return hopscotch_hash(bucket_count, static_cast<Hash&>(*this), static_cast<KeyEqual&>(*this), return hopscotch_hash(bucket_count, static_cast<Hash&>(*this), static_cast<KeyEqual&>(*this),
get_allocator(), m_max_load_factor); get_allocator(), m_max_load_factor);
} }
template<class U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr> template <typename U = OverflowContainer, typename std::enable_if<has_key_compare<U>::value>::type* = nullptr>
hopscotch_hash new_hopscotch_hash(size_type bucket_count) { hopscotch_hash new_hopscotch_hash(size_type bucket_count) {
return hopscotch_hash(bucket_count, static_cast<Hash&>(*this), static_cast<KeyEqual&>(*this), return hopscotch_hash(bucket_count, static_cast<Hash&>(*this), static_cast<KeyEqual&>(*this),
get_allocator(), m_max_load_factor, m_overflow_elements.key_comp()); get_allocator(), m_max_load_factor, m_overflow_elements.key_comp());

View File

@ -68,7 +68,7 @@ namespace tsl {
* insert will invalidate the iterators). Or if there is a rehash. * insert will invalidate the iterators). Or if there is a rehash.
* - erase: iterator on the erased element is the only one which become invalid. * - erase: iterator on the erased element is the only one which become invalid.
*/ */
template<class Key, template <typename Key,
class T, class T,
class Hash = std::hash<Key>, class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>, class KeyEqual = std::equal_to<Key>,
@ -161,7 +161,7 @@ public:
explicit hopscotch_map(const Allocator& alloc) : hopscotch_map(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) { explicit hopscotch_map(const Allocator& alloc) : hopscotch_map(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) {
} }
template<class InputIt> template <typename InputIt>
hopscotch_map(InputIt first, InputIt last, hopscotch_map(InputIt first, InputIt last,
size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE, size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
const Hash& hash = Hash(), const Hash& hash = Hash(),
@ -171,14 +171,14 @@ public:
insert(first, last); insert(first, last);
} }
template<class InputIt> template <typename InputIt>
hopscotch_map(InputIt first, InputIt last, hopscotch_map(InputIt first, InputIt last,
size_type bucket_count, size_type bucket_count,
const Allocator& alloc) : hopscotch_map(first, last, bucket_count, Hash(), KeyEqual(), alloc) const Allocator& alloc) : hopscotch_map(first, last, bucket_count, Hash(), KeyEqual(), alloc)
{ {
} }
template<class InputIt> template <typename InputIt>
hopscotch_map(InputIt first, InputIt last, hopscotch_map(InputIt first, InputIt last,
size_type bucket_count, size_type bucket_count,
const Hash& hash, const Hash& hash,
@ -254,7 +254,7 @@ public:
return m_ht.insert(value); return m_ht.insert(value);
} }
template<class P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr> template <typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr>
std::pair<iterator, bool> insert(P&& value) { std::pair<iterator, bool> insert(P&& value) {
return m_ht.insert(std::forward<P>(value)); return m_ht.insert(std::forward<P>(value));
} }
@ -268,7 +268,7 @@ public:
return m_ht.insert(hint, value); return m_ht.insert(hint, value);
} }
template<class P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr> template <typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr>
iterator insert(const_iterator hint, P&& value) { iterator insert(const_iterator hint, P&& value) {
return m_ht.insert(hint, std::forward<P>(value)); return m_ht.insert(hint, std::forward<P>(value));
} }
@ -278,7 +278,7 @@ public:
} }
template<class InputIt> template <typename InputIt>
void insert(InputIt first, InputIt last) { void insert(InputIt first, InputIt last) {
m_ht.insert(first, last); m_ht.insert(first, last);
} }
@ -290,22 +290,22 @@ public:
template<class M> template <typename M>
std::pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj) { std::pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj) {
return m_ht.insert_or_assign(k, std::forward<M>(obj)); return m_ht.insert_or_assign(k, std::forward<M>(obj));
} }
template<class M> template <typename M>
std::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj) { std::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj) {
return m_ht.insert_or_assign(std::move(k), std::forward<M>(obj)); return m_ht.insert_or_assign(std::move(k), std::forward<M>(obj));
} }
template<class M> template <typename M>
iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj) { iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj) {
return m_ht.insert_or_assign(hint, k, std::forward<M>(obj)); return m_ht.insert_or_assign(hint, k, std::forward<M>(obj));
} }
template<class M> template <typename M>
iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj) { iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj) {
return m_ht.insert_or_assign(hint, std::move(k), std::forward<M>(obj)); return m_ht.insert_or_assign(hint, std::move(k), std::forward<M>(obj));
} }
@ -319,7 +319,7 @@ public:
* *
* Mainly here for compatibility with the std::unordered_map interface. * Mainly here for compatibility with the std::unordered_map interface.
*/ */
template<class... Args> template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) { std::pair<iterator, bool> emplace(Args&&... args) {
return m_ht.emplace(std::forward<Args>(args)...); return m_ht.emplace(std::forward<Args>(args)...);
} }
@ -333,7 +333,7 @@ public:
* *
* Mainly here for compatibility with the std::unordered_map interface. * Mainly here for compatibility with the std::unordered_map interface.
*/ */
template<class... Args> template <typename... Args>
iterator emplace_hint(const_iterator hint, Args&&... args) { iterator emplace_hint(const_iterator hint, Args&&... args) {
return m_ht.emplace_hint(hint, std::forward<Args>(args)...); return m_ht.emplace_hint(hint, std::forward<Args>(args)...);
} }
@ -341,22 +341,22 @@ public:
template<class... Args> template <typename... Args>
std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args) { std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args) {
return m_ht.try_emplace(k, std::forward<Args>(args)...); return m_ht.try_emplace(k, std::forward<Args>(args)...);
} }
template<class... Args> template <typename... Args>
std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args) { std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args) {
return m_ht.try_emplace(std::move(k), std::forward<Args>(args)...); return m_ht.try_emplace(std::move(k), std::forward<Args>(args)...);
} }
template<class... Args> template <typename... Args>
iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args) { iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args) {
return m_ht.try_emplace(hint, k, std::forward<Args>(args)...); return m_ht.try_emplace(hint, k, std::forward<Args>(args)...);
} }
template<class... Args> template <typename... Args>
iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args) { iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args) {
return m_ht.try_emplace(hint, std::move(k), std::forward<Args>(args)...); return m_ht.try_emplace(hint, std::move(k), std::forward<Args>(args)...);
} }
@ -381,7 +381,7 @@ public:
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type erase(const K& key) { return m_ht.erase(key); } size_type erase(const K& key) { return m_ht.erase(key); }
/** /**
@ -390,7 +390,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type erase(const K& key, std::size_t precalculated_hash) { size_type erase(const K& key, std::size_t precalculated_hash) {
return m_ht.erase(key, precalculated_hash); return m_ht.erase(key, precalculated_hash);
} }
@ -424,7 +424,7 @@ public:
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
T& at(const K& key) { return m_ht.at(key); } T& at(const K& key) { return m_ht.at(key); }
/** /**
@ -433,20 +433,20 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
T& at(const K& key, std::size_t precalculated_hash) { return m_ht.at(key, precalculated_hash); } T& at(const K& key, std::size_t precalculated_hash) { return m_ht.at(key, precalculated_hash); }
/** /**
* @copydoc at(const K& key) * @copydoc at(const K& key)
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const T& at(const K& key) const { return m_ht.at(key); } const T& at(const K& key) const { return m_ht.at(key); }
/** /**
* @copydoc at(const K& key, std::size_t precalculated_hash) * @copydoc at(const K& key, std::size_t precalculated_hash)
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const T& at(const K& key, std::size_t precalculated_hash) const { return m_ht.at(key, precalculated_hash); } const T& at(const K& key, std::size_t precalculated_hash) const { return m_ht.at(key, precalculated_hash); }
@ -472,7 +472,7 @@ public:
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type count(const K& key) const { return m_ht.count(key); } size_type count(const K& key) const { return m_ht.count(key); }
/** /**
@ -481,7 +481,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); } size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); }
@ -508,7 +508,7 @@ public:
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
iterator find(const K& key) { return m_ht.find(key); } iterator find(const K& key) { return m_ht.find(key); }
/** /**
@ -517,13 +517,13 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
/** /**
* @copydoc find(const K& key) * @copydoc find(const K& key)
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const_iterator find(const K& key) const { return m_ht.find(key); } const_iterator find(const K& key) const { return m_ht.find(key); }
/** /**
@ -532,7 +532,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const_iterator find(const K& key, std::size_t precalculated_hash) const { const_iterator find(const K& key, std::size_t precalculated_hash) const {
return m_ht.find(key, precalculated_hash); return m_ht.find(key, precalculated_hash);
} }
@ -563,7 +563,7 @@ public:
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
std::pair<iterator, iterator> equal_range(const K& key) { return m_ht.equal_range(key); } std::pair<iterator, iterator> equal_range(const K& key) { return m_ht.equal_range(key); }
@ -573,7 +573,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
std::pair<iterator, iterator> equal_range(const K& key, std::size_t precalculated_hash) { std::pair<iterator, iterator> equal_range(const K& key, std::size_t precalculated_hash) {
return m_ht.equal_range(key, precalculated_hash); return m_ht.equal_range(key, precalculated_hash);
} }
@ -581,13 +581,13 @@ public:
/** /**
* @copydoc equal_range(const K& key) * @copydoc equal_range(const K& key)
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
std::pair<const_iterator, const_iterator> equal_range(const K& key) const { return m_ht.equal_range(key); } std::pair<const_iterator, const_iterator> equal_range(const K& key) const { return m_ht.equal_range(key); }
/** /**
* @copydoc equal_range(const K& key, std::size_t precalculated_hash) * @copydoc equal_range(const K& key, std::size_t precalculated_hash)
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t precalculated_hash) const { std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t precalculated_hash) const {
return m_ht.equal_range(key, precalculated_hash); return m_ht.equal_range(key, precalculated_hash);
} }

View File

@ -53,7 +53,7 @@ namespace tsl {
* *
* @copydoc hopscotch_map * @copydoc hopscotch_map
*/ */
template<class Key, template <typename Key,
class T, class T,
class Hash = std::hash<Key>, class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>, class KeyEqual = std::equal_to<Key>,
@ -150,7 +150,7 @@ public:
explicit hopscotch_sc_map(const Allocator& alloc) : hopscotch_sc_map(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) { explicit hopscotch_sc_map(const Allocator& alloc) : hopscotch_sc_map(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) {
} }
template<class InputIt> template <typename InputIt>
hopscotch_sc_map(InputIt first, InputIt last, hopscotch_sc_map(InputIt first, InputIt last,
size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE, size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
const Hash& hash = Hash(), const Hash& hash = Hash(),
@ -160,14 +160,14 @@ public:
insert(first, last); insert(first, last);
} }
template<class InputIt> template <typename InputIt>
hopscotch_sc_map(InputIt first, InputIt last, hopscotch_sc_map(InputIt first, InputIt last,
size_type bucket_count, size_type bucket_count,
const Allocator& alloc) : hopscotch_sc_map(first, last, bucket_count, Hash(), KeyEqual(), alloc) const Allocator& alloc) : hopscotch_sc_map(first, last, bucket_count, Hash(), KeyEqual(), alloc)
{ {
} }
template<class InputIt> template <typename InputIt>
hopscotch_sc_map(InputIt first, InputIt last, hopscotch_sc_map(InputIt first, InputIt last,
size_type bucket_count, size_type bucket_count,
const Hash& hash, const Hash& hash,
@ -243,7 +243,7 @@ public:
return m_ht.insert(value); return m_ht.insert(value);
} }
template<class P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr> template <typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr>
std::pair<iterator, bool> insert(P&& value) { std::pair<iterator, bool> insert(P&& value) {
return m_ht.insert(std::forward<P>(value)); return m_ht.insert(std::forward<P>(value));
} }
@ -257,7 +257,7 @@ public:
return m_ht.insert(hint, value); return m_ht.insert(hint, value);
} }
template<class P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr> template <typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr>
iterator insert(const_iterator hint, P&& value) { iterator insert(const_iterator hint, P&& value) {
return m_ht.insert(hint, std::forward<P>(value)); return m_ht.insert(hint, std::forward<P>(value));
} }
@ -267,7 +267,7 @@ public:
} }
template<class InputIt> template <typename InputIt>
void insert(InputIt first, InputIt last) { void insert(InputIt first, InputIt last) {
m_ht.insert(first, last); m_ht.insert(first, last);
} }
@ -279,22 +279,22 @@ public:
template<class M> template <typename M>
std::pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj) { std::pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj) {
return m_ht.insert_or_assign(k, std::forward<M>(obj)); return m_ht.insert_or_assign(k, std::forward<M>(obj));
} }
template<class M> template <typename M>
std::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj) { std::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj) {
return m_ht.insert_or_assign(std::move(k), std::forward<M>(obj)); return m_ht.insert_or_assign(std::move(k), std::forward<M>(obj));
} }
template<class M> template <typename M>
iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj) { iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj) {
return m_ht.insert_or_assign(hint, k, std::forward<M>(obj)); return m_ht.insert_or_assign(hint, k, std::forward<M>(obj));
} }
template<class M> template <typename M>
iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj) { iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj) {
return m_ht.insert_or_assign(hint, std::move(k), std::forward<M>(obj)); return m_ht.insert_or_assign(hint, std::move(k), std::forward<M>(obj));
} }
@ -307,7 +307,7 @@ public:
* *
* Mainly here for compatibility with the std::unordered_map interface. * Mainly here for compatibility with the std::unordered_map interface.
*/ */
template<class... Args> template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) { std::pair<iterator, bool> emplace(Args&&... args) {
return m_ht.emplace(std::forward<Args>(args)...); return m_ht.emplace(std::forward<Args>(args)...);
} }
@ -321,7 +321,7 @@ public:
* *
* Mainly here for compatibility with the std::unordered_map interface. * Mainly here for compatibility with the std::unordered_map interface.
*/ */
template<class... Args> template <typename... Args>
iterator emplace_hint(const_iterator hint, Args&&... args) { iterator emplace_hint(const_iterator hint, Args&&... args) {
return m_ht.emplace_hint(hint, std::forward<Args>(args)...); return m_ht.emplace_hint(hint, std::forward<Args>(args)...);
} }
@ -329,22 +329,22 @@ public:
template<class... Args> template <typename... Args>
std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args) { std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args) {
return m_ht.try_emplace(k, std::forward<Args>(args)...); return m_ht.try_emplace(k, std::forward<Args>(args)...);
} }
template<class... Args> template <typename... Args>
std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args) { std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args) {
return m_ht.try_emplace(std::move(k), std::forward<Args>(args)...); return m_ht.try_emplace(std::move(k), std::forward<Args>(args)...);
} }
template<class... Args> template <typename... Args>
iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args) { iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args) {
return m_ht.try_emplace(hint, k, std::forward<Args>(args)...); return m_ht.try_emplace(hint, k, std::forward<Args>(args)...);
} }
template<class... Args> template <typename... Args>
iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args) { iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args) {
return m_ht.try_emplace(hint, std::move(k), std::forward<Args>(args)...); return m_ht.try_emplace(hint, std::move(k), std::forward<Args>(args)...);
} }
@ -370,7 +370,7 @@ public:
* and Compare::is_transparent exist. * and Compare::is_transparent exist.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
size_type erase(const K& key) { return m_ht.erase(key); } size_type erase(const K& key) { return m_ht.erase(key); }
@ -380,7 +380,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
size_type erase(const K& key, std::size_t precalculated_hash) { return m_ht.erase(key, precalculated_hash); } size_type erase(const K& key, std::size_t precalculated_hash) { return m_ht.erase(key, precalculated_hash); }
@ -412,7 +412,7 @@ public:
* and Compare::is_transparent exist. * and Compare::is_transparent exist.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
T& at(const K& key) { return m_ht.at(key); } T& at(const K& key) { return m_ht.at(key); }
@ -422,21 +422,21 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
T& at(const K& key, std::size_t precalculated_hash) { return m_ht.at(key, precalculated_hash); } T& at(const K& key, std::size_t precalculated_hash) { return m_ht.at(key, precalculated_hash); }
/** /**
* @copydoc at(const K& key) * @copydoc at(const K& key)
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
const T& at(const K& key) const { return m_ht.at(key); } const T& at(const K& key) const { return m_ht.at(key); }
/** /**
* @copydoc at(const K& key, std::size_t precalculated_hash) * @copydoc at(const K& key, std::size_t precalculated_hash)
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
const T& at(const K& key, std::size_t precalculated_hash) const { return m_ht.at(key, precalculated_hash); } const T& at(const K& key, std::size_t precalculated_hash) const { return m_ht.at(key, precalculated_hash); }
@ -462,7 +462,7 @@ public:
* and Compare::is_transparent exist. * and Compare::is_transparent exist.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
size_type count(const K& key) const { return m_ht.count(key); } size_type count(const K& key) const { return m_ht.count(key); }
@ -472,7 +472,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); } size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); }
@ -499,7 +499,7 @@ public:
* and Compare::is_transparent exist. * and Compare::is_transparent exist.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
iterator find(const K& key) { return m_ht.find(key); } iterator find(const K& key) { return m_ht.find(key); }
@ -509,21 +509,21 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
/** /**
* @copydoc find(const K& key) * @copydoc find(const K& key)
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
const_iterator find(const K& key) const { return m_ht.find(key); } const_iterator find(const K& key) const { return m_ht.find(key); }
/** /**
* @copydoc find(const K& key, std::size_t precalculated_hash) * @copydoc find(const K& key, std::size_t precalculated_hash)
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
const_iterator find(const K& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); } const_iterator find(const K& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); }
@ -554,7 +554,7 @@ public:
* and Compare::is_transparent exist. * and Compare::is_transparent exist.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
std::pair<iterator, iterator> equal_range(const K& key) { return m_ht.equal_range(key); } std::pair<iterator, iterator> equal_range(const K& key) { return m_ht.equal_range(key); }
@ -564,7 +564,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
std::pair<iterator, iterator> equal_range(const K& key, std::size_t precalculated_hash) { std::pair<iterator, iterator> equal_range(const K& key, std::size_t precalculated_hash) {
return m_ht.equal_range(key, precalculated_hash); return m_ht.equal_range(key, precalculated_hash);
@ -573,14 +573,14 @@ public:
/** /**
* @copydoc equal_range(const K& key) * @copydoc equal_range(const K& key)
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
std::pair<const_iterator, const_iterator> equal_range(const K& key) const { return m_ht.equal_range(key); } std::pair<const_iterator, const_iterator> equal_range(const K& key) const { return m_ht.equal_range(key); }
/** /**
* @copydoc equal_range(const K& key, std::size_t precalculated_hash) * @copydoc equal_range(const K& key, std::size_t precalculated_hash)
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t precalculated_hash) const { std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t precalculated_hash) const {
return m_ht.equal_range(key, precalculated_hash); return m_ht.equal_range(key, precalculated_hash);

View File

@ -53,7 +53,7 @@ namespace tsl {
* *
* @copydoc hopscotch_set * @copydoc hopscotch_set
*/ */
template<class Key, template <typename Key,
class Hash = std::hash<Key>, class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>, class KeyEqual = std::equal_to<Key>,
class Compare = std::less<Key>, class Compare = std::less<Key>,
@ -133,7 +133,7 @@ public:
explicit hopscotch_sc_set(const Allocator& alloc) : hopscotch_sc_set(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) { explicit hopscotch_sc_set(const Allocator& alloc) : hopscotch_sc_set(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) {
} }
template<class InputIt> template <typename InputIt>
hopscotch_sc_set(InputIt first, InputIt last, hopscotch_sc_set(InputIt first, InputIt last,
size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE, size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
const Hash& hash = Hash(), const Hash& hash = Hash(),
@ -143,14 +143,14 @@ public:
insert(first, last); insert(first, last);
} }
template<class InputIt> template <typename InputIt>
hopscotch_sc_set(InputIt first, InputIt last, hopscotch_sc_set(InputIt first, InputIt last,
size_type bucket_count, size_type bucket_count,
const Allocator& alloc) : hopscotch_sc_set(first, last, bucket_count, Hash(), KeyEqual(), alloc) const Allocator& alloc) : hopscotch_sc_set(first, last, bucket_count, Hash(), KeyEqual(), alloc)
{ {
} }
template<class InputIt> template <typename InputIt>
hopscotch_sc_set(InputIt first, InputIt last, hopscotch_sc_set(InputIt first, InputIt last,
size_type bucket_count, size_type bucket_count,
const Hash& hash, const Hash& hash,
@ -228,7 +228,7 @@ public:
iterator insert(const_iterator hint, const value_type& value) { return m_ht.insert(hint, value); } iterator insert(const_iterator hint, const value_type& value) { return m_ht.insert(hint, value); }
iterator insert(const_iterator hint, value_type&& value) { return m_ht.insert(hint, std::move(value)); } iterator insert(const_iterator hint, value_type&& value) { return m_ht.insert(hint, std::move(value)); }
template<class InputIt> template <typename InputIt>
void insert(InputIt first, InputIt last) { m_ht.insert(first, last); } void insert(InputIt first, InputIt last) { m_ht.insert(first, last); }
void insert(std::initializer_list<value_type> ilist) { m_ht.insert(ilist.begin(), ilist.end()); } void insert(std::initializer_list<value_type> ilist) { m_ht.insert(ilist.begin(), ilist.end()); }
@ -241,7 +241,7 @@ public:
* *
* Mainly here for compatibility with the std::unordered_map interface. * Mainly here for compatibility with the std::unordered_map interface.
*/ */
template<class... Args> template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) { return m_ht.emplace(std::forward<Args>(args)...); } std::pair<iterator, bool> emplace(Args&&... args) { return m_ht.emplace(std::forward<Args>(args)...); }
@ -253,7 +253,7 @@ public:
* *
* Mainly here for compatibility with the std::unordered_map interface. * Mainly here for compatibility with the std::unordered_map interface.
*/ */
template<class... Args> template <typename... Args>
iterator emplace_hint(const_iterator hint, Args&&... args) { iterator emplace_hint(const_iterator hint, Args&&... args) {
return m_ht.emplace_hint(hint, std::forward<Args>(args)...); return m_ht.emplace_hint(hint, std::forward<Args>(args)...);
} }
@ -279,7 +279,7 @@ public:
* and Compare::is_transparent exist. * and Compare::is_transparent exist.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
size_type erase(const K& key) { return m_ht.erase(key); } size_type erase(const K& key) { return m_ht.erase(key); }
@ -289,7 +289,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
size_type erase(const K& key, std::size_t precalculated_hash) { return m_ht.erase(key, precalculated_hash); } size_type erase(const K& key, std::size_t precalculated_hash) { return m_ht.erase(key, precalculated_hash); }
@ -315,7 +315,7 @@ public:
* and Compare::is_transparent exist. * and Compare::is_transparent exist.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
size_type count(const K& key) const { return m_ht.count(key); } size_type count(const K& key) const { return m_ht.count(key); }
@ -325,7 +325,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); } size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); }
@ -352,7 +352,7 @@ public:
* and Compare::is_transparent exist. * and Compare::is_transparent exist.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
iterator find(const K& key) { return m_ht.find(key); } iterator find(const K& key) { return m_ht.find(key); }
@ -362,14 +362,14 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
/** /**
* @copydoc find(const K& key) * @copydoc find(const K& key)
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
const_iterator find(const K& key) const { return m_ht.find(key); } const_iterator find(const K& key) const { return m_ht.find(key); }
@ -379,7 +379,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
const_iterator find(const K& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); } const_iterator find(const K& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); }
@ -410,7 +410,7 @@ public:
* and Compare::is_transparent exist. * and Compare::is_transparent exist.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
std::pair<iterator, iterator> equal_range(const K& key) { return m_ht.equal_range(key); } std::pair<iterator, iterator> equal_range(const K& key) { return m_ht.equal_range(key); }
@ -420,7 +420,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
std::pair<iterator, iterator> equal_range(const K& key, std::size_t precalculated_hash) { std::pair<iterator, iterator> equal_range(const K& key, std::size_t precalculated_hash) {
return m_ht.equal_range(key, precalculated_hash); return m_ht.equal_range(key, precalculated_hash);
@ -429,14 +429,14 @@ public:
/** /**
* @copydoc equal_range(const K& key) * @copydoc equal_range(const K& key)
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
std::pair<const_iterator, const_iterator> equal_range(const K& key) const { return m_ht.equal_range(key); } std::pair<const_iterator, const_iterator> equal_range(const K& key) const { return m_ht.equal_range(key); }
/** /**
* @copydoc equal_range(const K& key, std::size_t precalculated_hash) * @copydoc equal_range(const K& key, std::size_t precalculated_hash)
*/ */
template<class K, class KE = KeyEqual, class CP = Compare, template <typename K, typename KE = KeyEqual, typename CP = Compare,
typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr> typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t precalculated_hash) const { std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t precalculated_hash) const {
return m_ht.equal_range(key, precalculated_hash); return m_ht.equal_range(key, precalculated_hash);

View File

@ -68,7 +68,7 @@ namespace tsl {
* insert will invalidate the iterators). Or if there is a rehash. * insert will invalidate the iterators). Or if there is a rehash.
* - erase: iterator on the erased element is the only one which become invalid. * - erase: iterator on the erased element is the only one which become invalid.
*/ */
template<class Key, template <typename Key,
class Hash = std::hash<Key>, class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>, class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<Key>, class Allocator = std::allocator<Key>,
@ -145,7 +145,7 @@ public:
explicit hopscotch_set(const Allocator& alloc) : hopscotch_set(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) { explicit hopscotch_set(const Allocator& alloc) : hopscotch_set(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) {
} }
template<class InputIt> template <typename InputIt>
hopscotch_set(InputIt first, InputIt last, hopscotch_set(InputIt first, InputIt last,
size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE, size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
const Hash& hash = Hash(), const Hash& hash = Hash(),
@ -155,14 +155,14 @@ public:
insert(first, last); insert(first, last);
} }
template<class InputIt> template <typename InputIt>
hopscotch_set(InputIt first, InputIt last, hopscotch_set(InputIt first, InputIt last,
size_type bucket_count, size_type bucket_count,
const Allocator& alloc) : hopscotch_set(first, last, bucket_count, Hash(), KeyEqual(), alloc) const Allocator& alloc) : hopscotch_set(first, last, bucket_count, Hash(), KeyEqual(), alloc)
{ {
} }
template<class InputIt> template <typename InputIt>
hopscotch_set(InputIt first, InputIt last, hopscotch_set(InputIt first, InputIt last,
size_type bucket_count, size_type bucket_count,
const Hash& hash, const Hash& hash,
@ -240,7 +240,7 @@ public:
iterator insert(const_iterator hint, const value_type& value) { return m_ht.insert(hint, value); } iterator insert(const_iterator hint, const value_type& value) { return m_ht.insert(hint, value); }
iterator insert(const_iterator hint, value_type&& value) { return m_ht.insert(hint, std::move(value)); } iterator insert(const_iterator hint, value_type&& value) { return m_ht.insert(hint, std::move(value)); }
template<class InputIt> template <typename InputIt>
void insert(InputIt first, InputIt last) { m_ht.insert(first, last); } void insert(InputIt first, InputIt last) { m_ht.insert(first, last); }
void insert(std::initializer_list<value_type> ilist) { m_ht.insert(ilist.begin(), ilist.end()); } void insert(std::initializer_list<value_type> ilist) { m_ht.insert(ilist.begin(), ilist.end()); }
@ -253,7 +253,7 @@ public:
* *
* Mainly here for compatibility with the std::unordered_map interface. * Mainly here for compatibility with the std::unordered_map interface.
*/ */
template<class... Args> template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) { return m_ht.emplace(std::forward<Args>(args)...); } std::pair<iterator, bool> emplace(Args&&... args) { return m_ht.emplace(std::forward<Args>(args)...); }
@ -265,7 +265,7 @@ public:
* *
* Mainly here for compatibility with the std::unordered_map interface. * Mainly here for compatibility with the std::unordered_map interface.
*/ */
template<class... Args> template <typename... Args>
iterator emplace_hint(const_iterator hint, Args&&... args) { iterator emplace_hint(const_iterator hint, Args&&... args) {
return m_ht.emplace_hint(hint, std::forward<Args>(args)...); return m_ht.emplace_hint(hint, std::forward<Args>(args)...);
} }
@ -290,7 +290,7 @@ public:
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type erase(const K& key) { return m_ht.erase(key); } size_type erase(const K& key) { return m_ht.erase(key); }
/** /**
@ -299,7 +299,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type erase(const K& key, std::size_t precalculated_hash) { size_type erase(const K& key, std::size_t precalculated_hash) {
return m_ht.erase(key, precalculated_hash); return m_ht.erase(key, precalculated_hash);
} }
@ -325,7 +325,7 @@ public:
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type count(const K& key) const { return m_ht.count(key); } size_type count(const K& key) const { return m_ht.count(key); }
/** /**
@ -334,7 +334,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); } size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); }
@ -359,7 +359,7 @@ public:
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
iterator find(const K& key) { return m_ht.find(key); } iterator find(const K& key) { return m_ht.find(key); }
/** /**
@ -368,13 +368,13 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
/** /**
* @copydoc find(const K& key) * @copydoc find(const K& key)
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const_iterator find(const K& key) const { return m_ht.find(key); } const_iterator find(const K& key) const { return m_ht.find(key); }
/** /**
@ -383,7 +383,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const_iterator find(const K& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); } const_iterator find(const K& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); }
@ -412,7 +412,7 @@ public:
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key. * If so, K must be hashable and comparable to Key.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
std::pair<iterator, iterator> equal_range(const K& key) { return m_ht.equal_range(key); } std::pair<iterator, iterator> equal_range(const K& key) { return m_ht.equal_range(key); }
/** /**
@ -421,7 +421,7 @@ public:
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
std::pair<iterator, iterator> equal_range(const K& key, std::size_t precalculated_hash) { std::pair<iterator, iterator> equal_range(const K& key, std::size_t precalculated_hash) {
return m_ht.equal_range(key, precalculated_hash); return m_ht.equal_range(key, precalculated_hash);
} }
@ -429,13 +429,13 @@ public:
/** /**
* @copydoc equal_range(const K& key) * @copydoc equal_range(const K& key)
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
std::pair<const_iterator, const_iterator> equal_range(const K& key) const { return m_ht.equal_range(key); } std::pair<const_iterator, const_iterator> equal_range(const K& key) const { return m_ht.equal_range(key); }
/** /**
* @copydoc equal_range(const K& key, std::size_t precalculated_hash) * @copydoc equal_range(const K& key, std::size_t precalculated_hash)
*/ */
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr> template <typename K, typename KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t precalculated_hash) const { std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t precalculated_hash) const {
return m_ht.equal_range(key, precalculated_hash); return m_ht.equal_range(key, precalculated_hash);
} }

View File

@ -68,7 +68,7 @@ Block AggregatingSortedBlockInputStream::readImpl()
} }
template<class TSortCursor> template <typename TSortCursor>
void AggregatingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue) void AggregatingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
{ {
size_t merged_rows = 0; size_t merged_rows = 0;
@ -133,7 +133,7 @@ void AggregatingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns,
} }
template <class TSortCursor> template <typename TSortCursor>
void AggregatingSortedBlockInputStream::addRow(TSortCursor & cursor) void AggregatingSortedBlockInputStream::addRow(TSortCursor & cursor)
{ {
for (size_t i = 0, size = column_numbers_to_aggregate.size(); i < size; ++i) for (size_t i = 0, size = column_numbers_to_aggregate.size(); i < size; ++i)

View File

@ -70,12 +70,12 @@ private:
/** We support two different cursors - with Collation and without. /** We support two different cursors - with Collation and without.
* Templates are used instead of polymorphic SortCursor and calls to virtual functions. * Templates are used instead of polymorphic SortCursor and calls to virtual functions.
*/ */
template <class TSortCursor> template <typename TSortCursor>
void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue); void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
/** Extract all states of aggregate functions and merge them with the current group. /** Extract all states of aggregate functions and merge them with the current group.
*/ */
template <class TSortCursor> template <typename TSortCursor>
void addRow(TSortCursor & cursor); void addRow(TSortCursor & cursor);
}; };

View File

@ -57,7 +57,10 @@ public:
if (started) if (started)
{ {
pool.wait(); pool.wait();
if (exception)
std::rethrow_exception(exception);
children.back()->readSuffix(); children.back()->readSuffix();
started = false;
} }
} }
@ -79,23 +82,18 @@ public:
~AsynchronousBlockInputStream() override ~AsynchronousBlockInputStream() override
{ {
try if (started)
{ pool.wait();
pool.wait(); /// It's ok to call wait even if there is no active threads.
}
catch (...)
{
tryLogCurrentException(__PRETTY_FUNCTION__);
}
} }
protected: protected:
ThreadPool pool{1}; /// Rethrows exceptions automatically on wait. ThreadPool pool{1};
Poco::Event ready; Poco::Event ready;
bool started = false; bool started = false;
bool first = true; bool first = true;
Block block; Block block;
std::exception_ptr exception;
Block readImpl() override Block readImpl() override
@ -103,12 +101,15 @@ protected:
/// If there were no calculations yet, calculate the first block synchronously /// If there were no calculations yet, calculate the first block synchronously
if (!started) if (!started)
{ {
started = true;
calculate(current_memory_tracker); calculate(current_memory_tracker);
started = true;
} }
else /// If the calculations are already in progress - wait for the result else /// If the calculations are already in progress - wait for the result
pool.wait(); pool.wait();
if (exception)
std::rethrow_exception(exception);
Block res = block; Block res = block;
if (!res) if (!res)
return res; return res;
@ -133,6 +134,8 @@ protected:
{ {
CurrentMetrics::Increment metric_increment{CurrentMetrics::QueryThread}; CurrentMetrics::Increment metric_increment{CurrentMetrics::QueryThread};
try
{
if (first) if (first)
{ {
first = false; first = false;
@ -142,6 +145,11 @@ protected:
} }
block = children.back()->read(); block = children.back()->read();
}
catch (...)
{
exception = std::current_exception();
}
ready.set(); ready.set();
} }

View File

@ -136,7 +136,7 @@ Block CollapsingSortedBlockInputStream::readImpl()
} }
template<class TSortCursor> template <typename TSortCursor>
void CollapsingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue) void CollapsingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
{ {
size_t merged_rows = 0; size_t merged_rows = 0;

View File

@ -90,7 +90,7 @@ private:
/** We support two different cursors - with Collation and without. /** We support two different cursors - with Collation and without.
* Templates are used instead of polymorphic SortCursors and calls to virtual functions. * Templates are used instead of polymorphic SortCursors and calls to virtual functions.
*/ */
template<class TSortCursor> template <typename TSortCursor>
void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue); void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
/// Output to result rows for the current primary key. /// Output to result rows for the current primary key.

View File

@ -118,8 +118,13 @@ void ColumnGathererStream::fetchNewBlock(Source & source, size_t source_num)
void ColumnGathererStream::readSuffixImpl() void ColumnGathererStream::readSuffixImpl()
{ {
const BlockStreamProfileInfo & profile_info = getProfileInfo(); const BlockStreamProfileInfo & profile_info = getProfileInfo();
/// Don't print info for small parts (< 10M rows)
if (profile_info.rows < 10000000)
return;
double seconds = profile_info.total_stopwatch.elapsedSeconds(); double seconds = profile_info.total_stopwatch.elapsedSeconds();
LOG_DEBUG(log, std::fixed << std::setprecision(2) LOG_TRACE(log, std::fixed << std::setprecision(2)
<< "Gathered column " << name << "Gathered column " << name
<< " (" << static_cast<double>(profile_info.bytes) / profile_info.rows << " bytes/elem.)" << " (" << static_cast<double>(profile_info.bytes) / profile_info.rows << " bytes/elem.)"
<< " in " << seconds << " sec., " << " in " << seconds << " sec., "

View File

@ -218,7 +218,7 @@ void GraphiteRollupSortedBlockInputStream::merge(ColumnPlainPtrs & merged_column
} }
template <class TSortCursor> template <typename TSortCursor>
void GraphiteRollupSortedBlockInputStream::startNextRow(ColumnPlainPtrs & merged_columns, TSortCursor & cursor, const Graphite::Pattern * next_pattern) void GraphiteRollupSortedBlockInputStream::startNextRow(ColumnPlainPtrs & merged_columns, TSortCursor & cursor, const Graphite::Pattern * next_pattern)
{ {
/// Copy unmodified column values. /// Copy unmodified column values.

View File

@ -199,7 +199,7 @@ private:
void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue); void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
/// Insert the values into the resulting columns, which will not be changed in the future. /// Insert the values into the resulting columns, which will not be changed in the future.
template <class TSortCursor> template <typename TSortCursor>
void startNextRow(ColumnPlainPtrs & merged_columns, TSortCursor & cursor, const Graphite::Pattern * next_pattern); void startNextRow(ColumnPlainPtrs & merged_columns, TSortCursor & cursor, const Graphite::Pattern * next_pattern);
/// Insert the calculated `time`, `value`, `version` values into the resulting columns by the last group of rows. /// Insert the calculated `time`, `value`, `version` values into the resulting columns by the last group of rows.

View File

@ -174,6 +174,38 @@ Block MergingSortedBlockInputStream::readImpl()
return merged_block; return merged_block;
} }
template <typename TSortCursor>
void MergingSortedBlockInputStream::fetchNextBlock(const TSortCursor & current, std::priority_queue<TSortCursor> & queue)
{
size_t i = 0;
size_t size = cursors.size();
for (; i < size; ++i)
{
if (&cursors[i] == current.impl)
{
source_blocks[i] = new detail::SharedBlock(children[i]->read());
if (*source_blocks[i])
{
cursors[i].reset(*source_blocks[i]);
queue.push(TSortCursor(&cursors[i]));
}
break;
}
}
if (i == size)
throw Exception("Logical error in MergingSortedBlockInputStream", ErrorCodes::LOGICAL_ERROR);
}
template
void MergingSortedBlockInputStream::fetchNextBlock<SortCursor>(const SortCursor & current, std::priority_queue<SortCursor> & queue);
template
void MergingSortedBlockInputStream::fetchNextBlock<SortCursorWithCollation>(const SortCursorWithCollation & current, std::priority_queue<SortCursorWithCollation> & queue);
template <typename TSortCursor> template <typename TSortCursor>
void MergingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue) void MergingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
{ {
@ -321,31 +353,6 @@ void MergingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs
} }
template <typename TSortCursor>
void MergingSortedBlockInputStream::fetchNextBlock(const TSortCursor & current, std::priority_queue<TSortCursor> & queue)
{
size_t i = 0;
size_t size = cursors.size();
for (; i < size; ++i)
{
if (&cursors[i] == current.impl)
{
source_blocks[i] = new detail::SharedBlock(children[i]->read());
if (*source_blocks[i])
{
cursors[i].reset(*source_blocks[i]);
queue.push(TSortCursor(&cursors[i]));
}
break;
}
}
if (i == size)
throw Exception("Logical error in MergingSortedBlockInputStream", ErrorCodes::LOGICAL_ERROR);
}
void MergingSortedBlockInputStream::readSuffixImpl() void MergingSortedBlockInputStream::readSuffixImpl()
{ {
if (quiet) if (quiet)

View File

@ -153,7 +153,7 @@ protected:
/// These methods are used in Collapsing/Summing/Aggregating... SortedBlockInputStream-s. /// These methods are used in Collapsing/Summing/Aggregating... SortedBlockInputStream-s.
/// Save the row pointed to by cursor in `row`. /// Save the row pointed to by cursor in `row`.
template <class TSortCursor> template <typename TSortCursor>
void setRow(Row & row, TSortCursor & cursor) void setRow(Row & row, TSortCursor & cursor)
{ {
for (size_t i = 0; i < num_columns; ++i) for (size_t i = 0; i < num_columns; ++i)
@ -185,7 +185,7 @@ protected:
} }
} }
template <class TSortCursor> template <typename TSortCursor>
void setRowRef(RowRef & row_ref, TSortCursor & cursor) void setRowRef(RowRef & row_ref, TSortCursor & cursor)
{ {
row_ref.row_num = cursor.impl->pos; row_ref.row_num = cursor.impl->pos;
@ -195,7 +195,7 @@ protected:
row_ref.columns[i] = cursor->all_columns[i]; row_ref.columns[i] = cursor->all_columns[i];
} }
template <class TSortCursor> template <typename TSortCursor>
void setPrimaryKeyRef(RowRef & row_ref, TSortCursor & cursor) void setPrimaryKeyRef(RowRef & row_ref, TSortCursor & cursor)
{ {
row_ref.row_num = cursor.impl->pos; row_ref.row_num = cursor.impl->pos;

View File

@ -58,7 +58,7 @@ Block ReplacingSortedBlockInputStream::readImpl()
} }
template<class TSortCursor> template <typename TSortCursor>
void ReplacingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue) void ReplacingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
{ {
size_t merged_rows = 0; size_t merged_rows = 0;

View File

@ -63,7 +63,7 @@ private:
PODArray<RowSourcePart> current_row_sources; /// Sources of rows with the current primary key PODArray<RowSourcePart> current_row_sources; /// Sources of rows with the current primary key
template<class TSortCursor> template <typename TSortCursor>
void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue); void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
/// Output into result the rows for current primary key. /// Output into result the rows for current primary key.

View File

@ -176,7 +176,7 @@ Block SummingSortedBlockInputStream::readImpl()
} }
template <class TSortCursor> template <typename TSortCursor>
void SummingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue) void SummingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
{ {
size_t merged_rows = 0; size_t merged_rows = 0;
@ -269,7 +269,7 @@ public:
}; };
template <class TSortCursor> template <typename TSortCursor>
bool SummingSortedBlockInputStream::mergeMaps(Row & row, TSortCursor & cursor) bool SummingSortedBlockInputStream::mergeMaps(Row & row, TSortCursor & cursor)
{ {
bool non_empty_map_present = false; bool non_empty_map_present = false;
@ -283,7 +283,7 @@ bool SummingSortedBlockInputStream::mergeMaps(Row & row, TSortCursor & cursor)
} }
template <class TSortCursor> template <typename TSortCursor>
bool SummingSortedBlockInputStream::mergeMap(const MapDescription & desc, Row & row, TSortCursor & cursor) bool SummingSortedBlockInputStream::mergeMap(const MapDescription & desc, Row & row, TSortCursor & cursor)
{ {
/// Strongly non-optimal. /// Strongly non-optimal.
@ -367,7 +367,7 @@ bool SummingSortedBlockInputStream::mergeMap(const MapDescription & desc, Row &
} }
template <class TSortCursor> template <typename TSortCursor>
bool SummingSortedBlockInputStream::addRow(Row & row, TSortCursor & cursor) bool SummingSortedBlockInputStream::addRow(Row & row, TSortCursor & cursor)
{ {
bool res = mergeMaps(row, cursor); /// Is there at least one non-zero number or non-empty array bool res = mergeMaps(row, cursor); /// Is there at least one non-zero number or non-empty array

View File

@ -90,7 +90,7 @@ private:
/** We support two different cursors - with Collation and without. /** We support two different cursors - with Collation and without.
* Templates are used instead of polymorphic SortCursor and calls to virtual functions. * Templates are used instead of polymorphic SortCursor and calls to virtual functions.
*/ */
template <class TSortCursor> template <typename TSortCursor>
void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue); void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
/// Insert the summed row for the current group into the result. /// Insert the summed row for the current group into the result.
@ -99,16 +99,16 @@ private:
/** For nested Map, a merge by key is performed with the ejection of rows of nested arrays, in which /** For nested Map, a merge by key is performed with the ejection of rows of nested arrays, in which
* all items are zero. * all items are zero.
*/ */
template <class TSortCursor> template <typename TSortCursor>
bool mergeMaps(Row & row, TSortCursor & cursor); bool mergeMaps(Row & row, TSortCursor & cursor);
template <class TSortCursor> template <typename TSortCursor>
bool mergeMap(const MapDescription & map, Row & row, TSortCursor & cursor); bool mergeMap(const MapDescription & map, Row & row, TSortCursor & cursor);
/** Add the row under the cursor to the `row`. /** Add the row under the cursor to the `row`.
* Returns false if the result is zero. * Returns false if the result is zero.
*/ */
template <class TSortCursor> template <typename TSortCursor>
bool addRow(Row & row, TSortCursor & cursor); bool addRow(Row & row, TSortCursor & cursor);
}; };

View File

@ -466,6 +466,17 @@ StringRef ComplexKeyCacheDictionary::placeKeysInPool(
return { place, sum_keys_size }; return { place, sum_keys_size };
} }
/// Explicit instantiations.
template StringRef ComplexKeyCacheDictionary::placeKeysInPool<Arena>(
const size_t row, const Columns & key_columns, StringRefs & keys,
const std::vector<DictionaryAttribute> & key_attributes, Arena & pool);
template StringRef ComplexKeyCacheDictionary::placeKeysInPool<ArenaWithFreeLists>(
const size_t row, const Columns & key_columns, StringRefs & keys,
const std::vector<DictionaryAttribute> & key_attributes, ArenaWithFreeLists & pool);
StringRef ComplexKeyCacheDictionary::placeKeysInFixedSizePool( StringRef ComplexKeyCacheDictionary::placeKeysInFixedSizePool(
const size_t row, const Columns & key_columns) const const size_t row, const Columns & key_columns) const
{ {

View File

@ -19,7 +19,7 @@ namespace DB
* BlockInputStream implementation for external dictionaries * BlockInputStream implementation for external dictionaries
* read() returns single block consisting of the in-memory contents of the dictionaries * read() returns single block consisting of the in-memory contents of the dictionaries
*/ */
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
class DictionaryBlockInputStream : public DictionaryBlockInputStreamBase class DictionaryBlockInputStream : public DictionaryBlockInputStreamBase
{ {
public: public:
@ -51,13 +51,13 @@ protected:
private: private:
// pointer types to getXXX functions // pointer types to getXXX functions
// for single key dictionaries // for single key dictionaries
template <class Type> template <typename Type>
using DictionaryGetter = void (DictionaryType::*)( using DictionaryGetter = void (DictionaryType::*)(
const std::string &, const PaddedPODArray<Key> &, PaddedPODArray<Type> &) const; const std::string &, const PaddedPODArray<Key> &, PaddedPODArray<Type> &) const;
using DictionaryStringGetter = void (DictionaryType::*)( using DictionaryStringGetter = void (DictionaryType::*)(
const std::string &, const PaddedPODArray<Key> &, ColumnString *) const; const std::string &, const PaddedPODArray<Key> &, ColumnString *) const;
// for complex complex key dictionaries // for complex complex key dictionaries
template <class Type> template <typename Type>
using GetterByKey = void (DictionaryType::*)( using GetterByKey = void (DictionaryType::*)(
const std::string &, const Columns &, const DataTypes &, PaddedPODArray<Type> & out) const; const std::string &, const Columns &, const DataTypes &, PaddedPODArray<Type> & out) const;
using StringGetterByKey = void (DictionaryType::*)( using StringGetterByKey = void (DictionaryType::*)(
@ -65,34 +65,34 @@ private:
// call getXXX // call getXXX
// for single key dictionaries // for single key dictionaries
template <class Type, class Container> template <typename Type, typename Container>
void callGetter(DictionaryGetter<Type> getter, const PaddedPODArray<Key> & ids, void callGetter(DictionaryGetter<Type> getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
Container & container, const DictionaryAttribute & attribute, const DictionaryType & dictionary) const; Container & container, const DictionaryAttribute & attribute, const DictionaryType & dictionary) const;
template <class Container> template <typename Container>
void callGetter(DictionaryStringGetter getter, const PaddedPODArray<Key> & ids, void callGetter(DictionaryStringGetter getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
Container & container, const DictionaryAttribute & attribute, const DictionaryType & dictionary) const; Container & container, const DictionaryAttribute & attribute, const DictionaryType & dictionary) const;
// for complex complex key dictionaries // for complex complex key dictionaries
template <class Type, class Container> template <typename Type, typename Container>
void callGetter(GetterByKey<Type> getter, const PaddedPODArray<Key> & ids, void callGetter(GetterByKey<Type> getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
Container & container, const DictionaryAttribute & attribute, const DictionaryType & dictionary) const; Container & container, const DictionaryAttribute & attribute, const DictionaryType & dictionary) const;
template <class Container> template <typename Container>
void callGetter(StringGetterByKey getter, const PaddedPODArray<Key> & ids, void callGetter(StringGetterByKey getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
Container & container, const DictionaryAttribute & attribute, const DictionaryType & dictionary) const; Container & container, const DictionaryAttribute & attribute, const DictionaryType & dictionary) const;
template <template <class> class Getter, class StringGetter> template <template <typename> class Getter, typename StringGetter>
Block fillBlock(const PaddedPODArray<Key> & ids, const Columns & keys, Block fillBlock(const PaddedPODArray<Key> & ids, const Columns & keys,
const DataTypes & types, ColumnsWithTypeAndName && view) const; const DataTypes & types, ColumnsWithTypeAndName && view) const;
template <class AttributeType, class Getter> template <typename AttributeType, typename Getter>
ColumnPtr getColumnFromAttribute(Getter getter, const PaddedPODArray<Key> & ids, ColumnPtr getColumnFromAttribute(Getter getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
const DictionaryAttribute & attribute, const DictionaryType & dictionary) const; const DictionaryAttribute & attribute, const DictionaryType & dictionary) const;
template <class Getter> template <typename Getter>
ColumnPtr getColumnFromStringAttribute(Getter getter, const PaddedPODArray<Key> & ids, ColumnPtr getColumnFromStringAttribute(Getter getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
const DictionaryAttribute& attribute, const DictionaryType& dictionary) const; const DictionaryAttribute& attribute, const DictionaryType& dictionary) const;
@ -115,7 +115,7 @@ private:
GetColumnsFunction get_view_columns_function; GetColumnsFunction get_view_columns_function;
}; };
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream( DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream(
std::shared_ptr<const IDictionaryBase> dictionary, size_t max_block_size, std::shared_ptr<const IDictionaryBase> dictionary, size_t max_block_size,
PaddedPODArray<Key> && ids, const Names& column_names) PaddedPODArray<Key> && ids, const Names& column_names)
@ -127,7 +127,7 @@ DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream(
{ {
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream( DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream(
std::shared_ptr<const IDictionaryBase> dictionary, size_t max_block_size, std::shared_ptr<const IDictionaryBase> dictionary, size_t max_block_size,
const std::vector<StringRef> & keys, const Names& column_names) const std::vector<StringRef> & keys, const Names& column_names)
@ -140,7 +140,7 @@ DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream(
fillKeyColumns(keys, 0, keys.size(), dictionaty_structure, key_columns); fillKeyColumns(keys, 0, keys.size(), dictionaty_structure, key_columns);
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream( DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream(
std::shared_ptr<const IDictionaryBase> dictionary, size_t max_block_size, std::shared_ptr<const IDictionaryBase> dictionary, size_t max_block_size,
const Columns & data_columns, const Names & column_names, const Columns & data_columns, const Names & column_names,
@ -155,7 +155,7 @@ DictionaryBlockInputStream<DictionaryType, Key>::DictionaryBlockInputStream(
{ {
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
Block DictionaryBlockInputStream<DictionaryType, Key>::getBlock(size_t start, size_t length) const Block DictionaryBlockInputStream<DictionaryType, Key>::getBlock(size_t start, size_t length) const
{ {
if (!key_columns.empty()) if (!key_columns.empty())
@ -197,8 +197,8 @@ Block DictionaryBlockInputStream<DictionaryType, Key>::getBlock(size_t start, si
} }
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <class Type, class Container> template <typename Type, typename Container>
void DictionaryBlockInputStream<DictionaryType, Key>::callGetter( void DictionaryBlockInputStream<DictionaryType, Key>::callGetter(
DictionaryGetter<Type> getter, const PaddedPODArray<Key> & ids, DictionaryGetter<Type> getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
@ -207,8 +207,8 @@ void DictionaryBlockInputStream<DictionaryType, Key>::callGetter(
(dictionary.*getter)(attribute.name, ids, container); (dictionary.*getter)(attribute.name, ids, container);
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <class Container> template <typename Container>
void DictionaryBlockInputStream<DictionaryType, Key>::callGetter( void DictionaryBlockInputStream<DictionaryType, Key>::callGetter(
DictionaryStringGetter getter, const PaddedPODArray<Key> & ids, DictionaryStringGetter getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
@ -217,8 +217,8 @@ void DictionaryBlockInputStream<DictionaryType, Key>::callGetter(
(dictionary.*getter)(attribute.name, ids, container); (dictionary.*getter)(attribute.name, ids, container);
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <class Type, class Container> template <typename Type, typename Container>
void DictionaryBlockInputStream<DictionaryType, Key>::callGetter( void DictionaryBlockInputStream<DictionaryType, Key>::callGetter(
GetterByKey<Type> getter, const PaddedPODArray<Key> & ids, GetterByKey<Type> getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
@ -227,8 +227,8 @@ void DictionaryBlockInputStream<DictionaryType, Key>::callGetter(
(dictionary.*getter)(attribute.name, keys, data_types, container); (dictionary.*getter)(attribute.name, keys, data_types, container);
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <class Container> template <typename Container>
void DictionaryBlockInputStream<DictionaryType, Key>::callGetter( void DictionaryBlockInputStream<DictionaryType, Key>::callGetter(
StringGetterByKey getter, const PaddedPODArray<Key> & ids, StringGetterByKey getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
@ -237,8 +237,8 @@ void DictionaryBlockInputStream<DictionaryType, Key>::callGetter(
(dictionary.*getter)(attribute.name, keys, data_types, container); (dictionary.*getter)(attribute.name, keys, data_types, container);
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <template <class> class Getter, class StringGetter> template <template <typename> class Getter, typename StringGetter>
Block DictionaryBlockInputStream<DictionaryType, Key>::fillBlock( Block DictionaryBlockInputStream<DictionaryType, Key>::fillBlock(
const PaddedPODArray<Key>& ids, const Columns& keys, const DataTypes & types, ColumnsWithTypeAndName && view) const const PaddedPODArray<Key>& ids, const Columns& keys, const DataTypes & types, ColumnsWithTypeAndName && view) const
{ {
@ -317,8 +317,8 @@ Block DictionaryBlockInputStream<DictionaryType, Key>::fillBlock(
return Block(block_columns); return Block(block_columns);
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <class AttributeType, class Getter> template <typename AttributeType, typename Getter>
ColumnPtr DictionaryBlockInputStream<DictionaryType, Key>::getColumnFromAttribute( ColumnPtr DictionaryBlockInputStream<DictionaryType, Key>::getColumnFromAttribute(
Getter getter, const PaddedPODArray<Key> & ids, Getter getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
@ -332,8 +332,8 @@ ColumnPtr DictionaryBlockInputStream<DictionaryType, Key>::getColumnFromAttribut
return ColumnPtr(std::move(column_vector)); return ColumnPtr(std::move(column_vector));
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <class Getter> template <typename Getter>
ColumnPtr DictionaryBlockInputStream<DictionaryType, Key>::getColumnFromStringAttribute( ColumnPtr DictionaryBlockInputStream<DictionaryType, Key>::getColumnFromStringAttribute(
Getter getter, const PaddedPODArray<Key> & ids, Getter getter, const PaddedPODArray<Key> & ids,
const Columns & keys, const DataTypes & data_types, const Columns & keys, const DataTypes & data_types,
@ -345,7 +345,7 @@ ColumnPtr DictionaryBlockInputStream<DictionaryType, Key>::getColumnFromStringAt
return column_string; return column_string;
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
ColumnPtr DictionaryBlockInputStream<DictionaryType, Key>::getColumnFromIds(const PaddedPODArray<Key>& ids) const ColumnPtr DictionaryBlockInputStream<DictionaryType, Key>::getColumnFromIds(const PaddedPODArray<Key>& ids) const
{ {
auto column_vector = std::make_shared<ColumnVector<UInt64>>(); auto column_vector = std::make_shared<ColumnVector<UInt64>>();
@ -357,7 +357,7 @@ ColumnPtr DictionaryBlockInputStream<DictionaryType, Key>::getColumnFromIds(cons
return column_vector; return column_vector;
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
void DictionaryBlockInputStream<DictionaryType, Key>::fillKeyColumns( void DictionaryBlockInputStream<DictionaryType, Key>::fillKeyColumns(
const std::vector<StringRef> & keys, size_t start, size_t size, const std::vector<StringRef> & keys, size_t start, size_t size,
const DictionaryStructure& dictionary_structure, ColumnsWithTypeAndName & columns) const const DictionaryStructure& dictionary_structure, ColumnsWithTypeAndName & columns) const

View File

@ -17,7 +17,7 @@ namespace DB
* BlockInputStream implementation for external dictionaries * BlockInputStream implementation for external dictionaries
* read() returns single block consisting of the in-memory contents of the dictionaries * read() returns single block consisting of the in-memory contents of the dictionaries
*/ */
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
class RangeDictionaryBlockInputStream : public DictionaryBlockInputStreamBase class RangeDictionaryBlockInputStream : public DictionaryBlockInputStreamBase
{ {
public: public:
@ -35,20 +35,20 @@ protected:
Block getBlock(size_t start, size_t length) const override; Block getBlock(size_t start, size_t length) const override;
private: private:
template <class Type> template <typename Type>
using DictionaryGetter = void (DictionaryType::*)(const std::string &, const PaddedPODArray<Key> &, using DictionaryGetter = void (DictionaryType::*)(const std::string &, const PaddedPODArray<Key> &,
const PaddedPODArray<UInt16> &, PaddedPODArray<Type> &) const; const PaddedPODArray<UInt16> &, PaddedPODArray<Type> &) const;
template <class AttributeType> template <typename AttributeType>
ColumnPtr getColumnFromAttribute(DictionaryGetter<AttributeType> getter, ColumnPtr getColumnFromAttribute(DictionaryGetter<AttributeType> getter,
const PaddedPODArray<Key>& ids, const PaddedPODArray<UInt16> & dates, const PaddedPODArray<Key>& ids, const PaddedPODArray<UInt16> & dates,
const DictionaryAttribute& attribute, const DictionaryType& dictionary) const; const DictionaryAttribute& attribute, const DictionaryType& dictionary) const;
ColumnPtr getColumnFromAttributeString(const PaddedPODArray<Key>& ids, const PaddedPODArray<UInt16> & dates, ColumnPtr getColumnFromAttributeString(const PaddedPODArray<Key>& ids, const PaddedPODArray<UInt16> & dates,
const DictionaryAttribute& attribute, const DictionaryType& dictionary) const; const DictionaryAttribute& attribute, const DictionaryType& dictionary) const;
template <class T> template <typename T>
ColumnPtr getColumnFromPODArray(const PaddedPODArray<T>& array) const; ColumnPtr getColumnFromPODArray(const PaddedPODArray<T>& array) const;
template <class T> template <typename T>
void addSpecialColumn( void addSpecialColumn(
const std::experimental::optional<DictionarySpecialAttribute>& attribute, DataTypePtr type, const std::experimental::optional<DictionarySpecialAttribute>& attribute, DataTypePtr type,
const std::string & default_name, const std::unordered_set<std::string> & column_names, const std::string & default_name, const std::unordered_set<std::string> & column_names,
@ -65,7 +65,7 @@ private:
}; };
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
RangeDictionaryBlockInputStream<DictionaryType, Key>::RangeDictionaryBlockInputStream( RangeDictionaryBlockInputStream<DictionaryType, Key>::RangeDictionaryBlockInputStream(
DictionatyPtr dictionary, size_t max_column_size, const Names & column_names, PaddedPODArray<Key> && ids, DictionatyPtr dictionary, size_t max_column_size, const Names & column_names, PaddedPODArray<Key> && ids,
PaddedPODArray<UInt16> && start_dates, PaddedPODArray<UInt16> && end_dates) PaddedPODArray<UInt16> && start_dates, PaddedPODArray<UInt16> && end_dates)
@ -75,7 +75,7 @@ RangeDictionaryBlockInputStream<DictionaryType, Key>::RangeDictionaryBlockInputS
{ {
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
Block RangeDictionaryBlockInputStream<DictionaryType, Key>::getBlock(size_t start, size_t length) const Block RangeDictionaryBlockInputStream<DictionaryType, Key>::getBlock(size_t start, size_t length) const
{ {
PaddedPODArray<Key> block_ids; PaddedPODArray<Key> block_ids;
@ -95,8 +95,8 @@ Block RangeDictionaryBlockInputStream<DictionaryType, Key>::getBlock(size_t star
return fillBlock(block_ids, block_start_dates, block_end_dates); return fillBlock(block_ids, block_start_dates, block_end_dates);
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <class AttributeType> template <typename AttributeType>
ColumnPtr RangeDictionaryBlockInputStream<DictionaryType, Key>::getColumnFromAttribute( ColumnPtr RangeDictionaryBlockInputStream<DictionaryType, Key>::getColumnFromAttribute(
DictionaryGetter<AttributeType> getter, const PaddedPODArray<Key>& ids, DictionaryGetter<AttributeType> getter, const PaddedPODArray<Key>& ids,
const PaddedPODArray<UInt16> & dates, const DictionaryAttribute& attribute, const DictionaryType& dictionary) const const PaddedPODArray<UInt16> & dates, const DictionaryAttribute& attribute, const DictionaryType& dictionary) const
@ -106,7 +106,7 @@ ColumnPtr RangeDictionaryBlockInputStream<DictionaryType, Key>::getColumnFromAtt
return ColumnPtr(std::move(column_vector)); return ColumnPtr(std::move(column_vector));
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
ColumnPtr RangeDictionaryBlockInputStream<DictionaryType, Key>::getColumnFromAttributeString( ColumnPtr RangeDictionaryBlockInputStream<DictionaryType, Key>::getColumnFromAttributeString(
const PaddedPODArray<Key>& ids, const PaddedPODArray<UInt16> & dates, const PaddedPODArray<Key>& ids, const PaddedPODArray<UInt16> & dates,
const DictionaryAttribute& attribute, const DictionaryType& dictionary) const const DictionaryAttribute& attribute, const DictionaryType& dictionary) const
@ -116,8 +116,8 @@ ColumnPtr RangeDictionaryBlockInputStream<DictionaryType, Key>::getColumnFromAtt
return ColumnPtr(std::move(column_string)); return ColumnPtr(std::move(column_string));
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <class T> template <typename T>
ColumnPtr RangeDictionaryBlockInputStream<DictionaryType, Key>::getColumnFromPODArray(const PaddedPODArray<T>& array) const ColumnPtr RangeDictionaryBlockInputStream<DictionaryType, Key>::getColumnFromPODArray(const PaddedPODArray<T>& array) const
{ {
auto column_vector = std::make_unique<ColumnVector<T>>(); auto column_vector = std::make_unique<ColumnVector<T>>();
@ -130,8 +130,8 @@ ColumnPtr RangeDictionaryBlockInputStream<DictionaryType, Key>::getColumnFromPOD
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
template <class T> template <typename T>
void RangeDictionaryBlockInputStream<DictionaryType, Key>::addSpecialColumn( void RangeDictionaryBlockInputStream<DictionaryType, Key>::addSpecialColumn(
const std::experimental::optional<DictionarySpecialAttribute> & attribute, DataTypePtr type, const std::experimental::optional<DictionarySpecialAttribute> & attribute, DataTypePtr type,
const std::string& default_name, const std::unordered_set<std::string> & column_names, const std::string& default_name, const std::unordered_set<std::string> & column_names,
@ -146,7 +146,7 @@ void RangeDictionaryBlockInputStream<DictionaryType, Key>::addSpecialColumn(
} }
} }
template <class DictionaryType, class Key> template <typename DictionaryType, typename Key>
Block RangeDictionaryBlockInputStream<DictionaryType, Key>::fillBlock( Block RangeDictionaryBlockInputStream<DictionaryType, Key>::fillBlock(
const PaddedPODArray<Key>& ids, const PaddedPODArray<Key>& ids,
const PaddedPODArray<UInt16> & start_dates, const PaddedPODArray<UInt16> & end_dates) const const PaddedPODArray<UInt16> & start_dates, const PaddedPODArray<UInt16> & end_dates) const

View File

@ -38,21 +38,21 @@ struct BinaryOperationImplBase
{ {
using ResultType = ResultType_; using ResultType = ResultType_;
static void vector_vector(const PaddedPODArray<A> & a, const PaddedPODArray<B> & b, PaddedPODArray<ResultType> & c) static void NO_INLINE vector_vector(const PaddedPODArray<A> & a, const PaddedPODArray<B> & b, PaddedPODArray<ResultType> & c)
{ {
size_t size = a.size(); size_t size = a.size();
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
c[i] = Op::template apply<ResultType>(a[i], b[i]); c[i] = Op::template apply<ResultType>(a[i], b[i]);
} }
static void vector_constant(const PaddedPODArray<A> & a, B b, PaddedPODArray<ResultType> & c) static void NO_INLINE vector_constant(const PaddedPODArray<A> & a, B b, PaddedPODArray<ResultType> & c)
{ {
size_t size = a.size(); size_t size = a.size();
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
c[i] = Op::template apply<ResultType>(a[i], b); c[i] = Op::template apply<ResultType>(a[i], b);
} }
static void constant_vector(A a, const PaddedPODArray<B> & b, PaddedPODArray<ResultType> & c) static void NO_INLINE constant_vector(A a, const PaddedPODArray<B> & b, PaddedPODArray<ResultType> & c)
{ {
size_t size = b.size(); size_t size = b.size();
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
@ -76,7 +76,7 @@ struct UnaryOperationImpl
{ {
using ResultType = typename Op::ResultType; using ResultType = typename Op::ResultType;
static void vector(const PaddedPODArray<A> & a, PaddedPODArray<ResultType> & c) static void NO_INLINE vector(const PaddedPODArray<A> & a, PaddedPODArray<ResultType> & c)
{ {
size_t size = a.size(); size_t size = a.size();
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)

View File

@ -331,7 +331,7 @@ struct ArraySumImpl
throw Exception("arraySum cannot add values of type " + expression_return->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); throw Exception("arraySum cannot add values of type " + expression_return->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
} }
template <class Element, class Result> template <typename Element, typename Result>
static bool executeType(const ColumnPtr & mapped, const ColumnArray::Offsets_t & offsets, ColumnPtr & res_ptr) static bool executeType(const ColumnPtr & mapped, const ColumnArray::Offsets_t & offsets, ColumnPtr & res_ptr)
{ {
const ColumnVector<Element> * column = checkAndGetColumn<ColumnVector<Element>>(&*mapped); const ColumnVector<Element> * column = checkAndGetColumn<ColumnVector<Element>>(&*mapped);

View File

@ -101,7 +101,7 @@ template <typename Op, size_t N>
struct AssociativeOperationImpl struct AssociativeOperationImpl
{ {
/// Erases the N last columns from `in` (if there are less, then all) and puts into `result` their combination. /// Erases the N last columns from `in` (if there are less, then all) and puts into `result` their combination.
static void execute(UInt8ColumnPtrs & in, UInt8Container & result) static void NO_INLINE execute(UInt8ColumnPtrs & in, UInt8Container & result)
{ {
if (N > in.size()) if (N > in.size())
{ {

View File

@ -9,9 +9,15 @@ void registerFunctionsRound(FunctionFactory & factory)
factory.registerFunction<FunctionRoundToExp2>(); factory.registerFunction<FunctionRoundToExp2>();
factory.registerFunction<FunctionRoundDuration>(); factory.registerFunction<FunctionRoundDuration>();
factory.registerFunction<FunctionRoundAge>(); factory.registerFunction<FunctionRoundAge>();
factory.registerFunction<FunctionRound>();
factory.registerFunction<FunctionCeil>(); factory.registerFunction("round", FunctionRound::create, FunctionFactory::CaseInsensitive);
factory.registerFunction<FunctionFloor>(); factory.registerFunction("floor", FunctionFloor::create, FunctionFactory::CaseInsensitive);
factory.registerFunction("ceil", FunctionCeil::create, FunctionFactory::CaseInsensitive);
factory.registerFunction("trunc", FunctionTrunc::create, FunctionFactory::CaseInsensitive);
/// Compatibility aliases.
factory.registerFunction("ceiling", FunctionCeil::create, FunctionFactory::CaseInsensitive);
factory.registerFunction("truncate", FunctionTrunc::create, FunctionFactory::CaseInsensitive);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -705,7 +705,7 @@ public:
void executeImpl(Block & block, const ColumnNumbers & arguments, const size_t result) override void executeImpl(Block & block, const ColumnNumbers & arguments, const size_t result) override
{ {
if (!is_injective && !arguments.empty() && checkDataType<DataTypeArray>(block.getByPosition(0).type.get())) if (!is_injective && !arguments.empty() && checkDataType<DataTypeArray>(block.getByPosition(arguments[0]).type.get()))
return FunctionArrayConcat().executeImpl(block, arguments, result); return FunctionArrayConcat().executeImpl(block, arguments, result);
if (arguments.size() == 2) if (arguments.size() == 2)

View File

@ -7,7 +7,7 @@ namespace DB
/// computation of the hash depends on the partitioning of blocks /// computation of the hash depends on the partitioning of blocks
/// so you need to compute a hash of n complete pieces and one incomplete /// so you need to compute a hash of n complete pieces and one incomplete
template <class Buffer> template <typename Buffer>
void IHashingBuffer<Buffer>::calculateHash(DB::BufferBase::Position data, size_t len) void IHashingBuffer<Buffer>::calculateHash(DB::BufferBase::Position data, size_t len)
{ {
if (len) if (len)

View File

@ -11,7 +11,7 @@
namespace DB namespace DB
{ {
template <class Buffer> template <typename Buffer>
class IHashingBuffer : public BufferWithOwnMemory<Buffer> class IHashingBuffer : public BufferWithOwnMemory<Buffer>
{ {
public: public:

View File

@ -19,7 +19,7 @@ namespace ErrorCodes
extern const int INCORRECT_DATA; extern const int INCORRECT_DATA;
} }
template <class IteratorSrc, class IteratorDst> template <typename IteratorSrc, typename IteratorDst>
void parseHex(IteratorSrc src, IteratorDst dst, const size_t num_bytes) void parseHex(IteratorSrc src, IteratorDst dst, const size_t num_bytes)
{ {
size_t src_pos = 0; size_t src_pos = 0;

View File

@ -351,7 +351,7 @@ void tryReadIntTextUnsafe(T & x, ReadBuffer & buf)
} }
template <bool throw_exception, class ExcepFun, class NoExcepFun, class... Args> template <bool throw_exception, typename ExcepFun, typename NoExcepFun, typename... Args>
bool exceptionPolicySelector(ExcepFun && excep_f, NoExcepFun && no_excep_f, Args &&... args) bool exceptionPolicySelector(ExcepFun && excep_f, NoExcepFun && no_excep_f, Args &&... args)
{ {
if (throw_exception) if (throw_exception)
@ -482,13 +482,13 @@ ReturnType readFloatTextImpl(T & x, ReadBuffer & buf)
return ReturnType(true); return ReturnType(true);
} }
template <class T> template <typename T>
inline bool tryReadFloatText(T & x, ReadBuffer & buf) inline bool tryReadFloatText(T & x, ReadBuffer & buf)
{ {
return readFloatTextImpl<T, bool>(x, buf); return readFloatTextImpl<T, bool>(x, buf);
} }
template <class T> template <typename T>
inline void readFloatText(T & x, ReadBuffer & buf) inline void readFloatText(T & x, ReadBuffer & buf)
{ {
readFloatTextImpl<T, void>(x, buf); readFloatTextImpl<T, void>(x, buf);
@ -569,7 +569,7 @@ struct NullSink
void parseUUID(const UInt8 * src36, UInt8 * dst16); void parseUUID(const UInt8 * src36, UInt8 * dst16);
void parseUUID(const UInt8 * src36, std::reverse_iterator<UInt8 *> dst16); void parseUUID(const UInt8 * src36, std::reverse_iterator<UInt8 *> dst16);
template<class IteratorSrc, class IteratorDst> template <typename IteratorSrc, typename IteratorDst>
void formatHex(IteratorSrc src, IteratorDst dst, const size_t num_bytes); void formatHex(IteratorSrc src, IteratorDst dst, const size_t num_bytes);
/// In YYYY-MM-DD format /// In YYYY-MM-DD format

View File

@ -223,6 +223,7 @@ void Aggregator::compileIfPossible(AggregatedDataVariants::Type type)
/// List of types of aggregate functions. /// List of types of aggregate functions.
std::stringstream aggregate_functions_typenames_str; std::stringstream aggregate_functions_typenames_str;
std::stringstream aggregate_functions_headers_args;
for (size_t i = 0; i < params.aggregates_size; ++i) for (size_t i = 0; i < params.aggregates_size; ++i)
{ {
IAggregateFunction & func = *aggregate_functions[i]; IAggregateFunction & func = *aggregate_functions[i];
@ -237,8 +238,21 @@ void Aggregator::compileIfPossible(AggregatedDataVariants::Type type)
+ ", status: " + toString(status), ErrorCodes::CANNOT_COMPILE_CODE); + ", status: " + toString(status), ErrorCodes::CANNOT_COMPILE_CODE);
aggregate_functions_typenames_str << ((i != 0) ? ", " : "") << type_name; aggregate_functions_typenames_str << ((i != 0) ? ", " : "") << type_name;
std::string header_path = func.getHeaderFilePath();
auto pos = header_path.find("/AggregateFunctions/");
if (pos == std::string::npos)
throw Exception("Cannot compile code: unusual path of header file for aggregate function: " + header_path,
ErrorCodes::CANNOT_COMPILE_CODE);
aggregate_functions_headers_args << "-include '" INTERNAL_COMPILER_HEADERS "/dbms/src";
aggregate_functions_headers_args.write(&header_path[pos], header_path.size() - pos);
aggregate_functions_headers_args << "' ";
} }
aggregate_functions_headers_args << "-include '" INTERNAL_COMPILER_HEADERS "/dbms/src/Interpreters/SpecializedAggregator.h'";
std::string aggregate_functions_typenames = aggregate_functions_typenames_str.str(); std::string aggregate_functions_typenames = aggregate_functions_typenames_str.str();
std::stringstream key_str; std::stringstream key_str;
@ -355,9 +369,9 @@ void Aggregator::compileIfPossible(AggregatedDataVariants::Type type)
* If the counter has reached the value min_count_to_compile, then the compilation starts asynchronously (in a separate thread) * If the counter has reached the value min_count_to_compile, then the compilation starts asynchronously (in a separate thread)
* at the end of which `on_ready` callback is called. * at the end of which `on_ready` callback is called.
*/ */
aggregate_functions_headers_args << " -Wno-unused-function";
SharedLibraryPtr lib = params.compiler->getOrCount(key, params.min_count_to_compile, SharedLibraryPtr lib = params.compiler->getOrCount(key, params.min_count_to_compile,
"-include " INTERNAL_COMPILER_HEADERS "/dbms/src/Interpreters/SpecializedAggregator.h " aggregate_functions_headers_args.str(),
"-Wno-unused-function",
get_code, on_ready); get_code, on_ready);
/// If the result is already ready. /// If the result is already ready.

View File

@ -215,7 +215,7 @@ void Compiler::compile(
std::stringstream command; std::stringstream command;
/// Slightly uncomfortable. /// Slightly unconvenient.
command << command <<
"LD_LIBRARY_PATH=" PATH_SHARE "/clickhouse/bin/" "LD_LIBRARY_PATH=" PATH_SHARE "/clickhouse/bin/"
" " INTERNAL_COMPILER_EXECUTABLE " " INTERNAL_COMPILER_EXECUTABLE
@ -231,6 +231,7 @@ void Compiler::compile(
#endif #endif
" -I " INTERNAL_COMPILER_HEADERS "/dbms/src/" " -I " INTERNAL_COMPILER_HEADERS "/dbms/src/"
" -I " INTERNAL_COMPILER_HEADERS "/contrib/libcityhash/include/" " -I " INTERNAL_COMPILER_HEADERS "/contrib/libcityhash/include/"
" -I " INTERNAL_COMPILER_HEADERS "/contrib/libpcg-random/include/"
" -I " INTERNAL_DOUBLE_CONVERSION_INCLUDE_DIR " -I " INTERNAL_DOUBLE_CONVERSION_INCLUDE_DIR
" -I " INTERNAL_Poco_Foundation_INCLUDE_DIR " -I " INTERNAL_Poco_Foundation_INCLUDE_DIR
" -I " INTERNAL_Boost_INCLUDE_DIRS " -I " INTERNAL_Boost_INCLUDE_DIRS

View File

@ -1,39 +1,14 @@
#include <Common/TypeList.h> #include <Common/TypeList.h>
#include <Common/typeid_cast.h>
#include <Interpreters/Aggregator.h> #include <Interpreters/Aggregator.h>
#include <AggregateFunctions/AggregateFunctionArgMinMax.h>
#include <AggregateFunctions/AggregateFunctionArray.h>
#include <AggregateFunctions/AggregateFunctionAvg.h>
#include <AggregateFunctions/AggregateFunctionCount.h>
#include <AggregateFunctions/AggregateFunctionForEach.h>
#include <AggregateFunctions/AggregateFunctionGroupArray.h>
#include <AggregateFunctions/AggregateFunctionGroupArrayInsertAt.h>
#include <AggregateFunctions/AggregateFunctionGroupUniqArray.h>
#include <AggregateFunctions/AggregateFunctionIf.h>
#include <AggregateFunctions/AggregateFunctionMerge.h>
#include <AggregateFunctions/AggregateFunctionMinMaxAny.h>
#include <AggregateFunctions/AggregateFunctionNull.h>
#include <AggregateFunctions/AggregateFunctionQuantileDeterministic.h>
#include <AggregateFunctions/AggregateFunctionQuantileExact.h>
#include <AggregateFunctions/AggregateFunctionQuantileExactWeighted.h>
#include <AggregateFunctions/AggregateFunctionQuantile.h>
#include <AggregateFunctions/AggregateFunctionQuantileTDigest.h>
#include <AggregateFunctions/AggregateFunctionQuantileTiming.h>
#include <AggregateFunctions/AggregateFunctionSequenceMatch.h>
#include <AggregateFunctions/AggregateFunctionState.h>
#include <AggregateFunctions/AggregateFunctionStatistics.h>
#include <AggregateFunctions/AggregateFunctionSum.h>
#include <AggregateFunctions/AggregateFunctionTopK.h>
#include <AggregateFunctions/AggregateFunctionUniq.h>
#include <AggregateFunctions/AggregateFunctionUniqUpTo.h>
namespace DB namespace DB
{ {
/** An aggregation cycle template that allows you to generate a custom variant for a specific combination of aggregate functions. /** An aggregation loop template that allows you to generate a custom variant for a specific combination of aggregate functions.
* It differs from the usual one in that calls to aggregate functions should be inlined, and the update cycle of the aggregate functions should be unfold. * It differs from the usual one in that calls to aggregate functions should be inlined, and the update loop of the aggregate functions should be unrolled.
* *
* Since there are too many possible combinations, it is not possible to generate them all in advance. * Since there are too many possible combinations, it is not possible to generate them all in advance.
* This template is intended to instantiate it in runtime, * This template is intended to instantiate it in runtime,
@ -263,8 +238,8 @@ void NO_INLINE Aggregator::executeSpecializedWithoutKey(
} }
/** The main code is compiled with gcc 5. /** The main code is compiled with gcc 7.
* But SpecializedAggregator is compiled using clang 3.6 into the .so file. * But SpecializedAggregator is compiled using clang 6 into the .so file.
* This is done because gcc can not get functions inlined, * This is done because gcc can not get functions inlined,
* which were de-virtualized, in a particular case, and the performance is lower. * which were de-virtualized, in a particular case, and the performance is lower.
* And also it's easier to distribute clang for deploy to the servers. * And also it's easier to distribute clang for deploy to the servers.

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <Parsers/IAST.h> #include <Parsers/IAST.h>
#include <AggregateFunctions/AggregateFunctionCount.h>
namespace DB namespace DB

View File

@ -56,7 +56,7 @@ protected:
}; };
template <class NameParser> template <typename NameParser>
class IParserNameTypePair : public IParserBase class IParserNameTypePair : public IParserBase
{ {
protected: protected:
@ -69,7 +69,7 @@ using ParserNameTypePair = IParserNameTypePair<ParserIdentifier>;
/** Name and type separated by a space. The name can contain a dot. For example, Hits.URL String. */ /** Name and type separated by a space. The name can contain a dot. For example, Hits.URL String. */
using ParserCompoundNameTypePair = IParserNameTypePair<ParserCompoundIdentifier>; using ParserCompoundNameTypePair = IParserNameTypePair<ParserCompoundIdentifier>;
template <class NameParser> template <typename NameParser>
bool IParserNameTypePair<NameParser>::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) bool IParserNameTypePair<NameParser>::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{ {
NameParser name_parser; NameParser name_parser;
@ -101,7 +101,7 @@ protected:
}; };
template <class NameParser> template <typename NameParser>
class IParserColumnDeclaration : public IParserBase class IParserColumnDeclaration : public IParserBase
{ {
protected: protected:
@ -112,7 +112,7 @@ protected:
using ParserColumnDeclaration = IParserColumnDeclaration<ParserIdentifier>; using ParserColumnDeclaration = IParserColumnDeclaration<ParserIdentifier>;
using ParserCompoundColumnDeclaration = IParserColumnDeclaration<ParserCompoundIdentifier>; using ParserCompoundColumnDeclaration = IParserColumnDeclaration<ParserCompoundIdentifier>;
template <class NameParser> template <typename NameParser>
bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{ {
NameParser name_parser; NameParser name_parser;

View File

@ -386,7 +386,7 @@ public:
* - amount of merged rows and their size (PK columns subset is used in case of Vertical merge) * - amount of merged rows and their size (PK columns subset is used in case of Vertical merge)
* - time elapsed for current merge. * - time elapsed for current merge.
*/ */
class MergeProgressCallback : public ProgressCallback class MergeProgressCallback
{ {
public: public:
MergeProgressCallback(MergeList::Entry & merge_entry_, UInt64 & watch_prev_elapsed_) MergeProgressCallback(MergeList::Entry & merge_entry_, UInt64 & watch_prev_elapsed_)
@ -540,14 +540,14 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMerger::mergePartsToTemporaryPart
BlockInputStreams src_streams; BlockInputStreams src_streams;
UInt64 watch_prev_elapsed = 0; UInt64 watch_prev_elapsed = 0;
for (size_t i = 0; i < parts.size(); ++i) for (const auto & part : parts)
{ {
auto input = std::make_unique<MergeTreeBlockInputStream>( auto input = std::make_unique<MergeTreeBlockInputStream>(
data, parts[i], DEFAULT_MERGE_BLOCK_SIZE, 0, 0, merging_column_names, MarkRanges(1, MarkRange(0, parts[i]->size)), data, part, DEFAULT_MERGE_BLOCK_SIZE, 0, 0, merging_column_names, MarkRanges(1, MarkRange(0, part->size)),
false, nullptr, "", true, aio_threshold, DBMS_DEFAULT_BUFFER_SIZE, false); false, nullptr, "", true, aio_threshold, DBMS_DEFAULT_BUFFER_SIZE, false);
input->setProgressCallback( input->setProgressCallback(MergeProgressCallback(
MergeProgressCallback{merge_entry, sum_input_rows_upper_bound, column_sizes, watch_prev_elapsed, merge_alg}); merge_entry, sum_input_rows_upper_bound, column_sizes, watch_prev_elapsed, merge_alg));
if (data.merging_params.mode != MergeTreeData::MergingParams::Unsorted) if (data.merging_params.mode != MergeTreeData::MergingParams::Unsorted)
src_streams.emplace_back(std::make_shared<MaterializingBlockInputStream>( src_streams.emplace_back(std::make_shared<MaterializingBlockInputStream>(
@ -680,8 +680,8 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMerger::mergePartsToTemporaryPart
data, parts[part_num], DEFAULT_MERGE_BLOCK_SIZE, 0, 0, column_name_, MarkRanges{MarkRange(0, parts[part_num]->size)}, data, parts[part_num], DEFAULT_MERGE_BLOCK_SIZE, 0, 0, column_name_, MarkRanges{MarkRange(0, parts[part_num]->size)},
false, nullptr, "", true, aio_threshold, DBMS_DEFAULT_BUFFER_SIZE, false, Names{}, 0, true); false, nullptr, "", true, aio_threshold, DBMS_DEFAULT_BUFFER_SIZE, false, Names{}, 0, true);
column_part_stream->setProgressCallback( column_part_stream->setProgressCallback(MergeProgressCallbackVerticalStep(
MergeProgressCallbackVerticalStep{merge_entry, sum_input_rows_exact, column_sizes, column_name, watch_prev_elapsed}); merge_entry, sum_input_rows_exact, column_sizes, column_name, watch_prev_elapsed));
column_part_streams[part_num] = std::move(column_part_stream); column_part_streams[part_num] = std::move(column_part_stream);
} }

View File

@ -69,7 +69,7 @@ private:
void checkNamesAndTypesCompatibleWithDictionary(const DictionaryStructure & dictionaryStructure) const; void checkNamesAndTypesCompatibleWithDictionary(const DictionaryStructure & dictionaryStructure) const;
template <class ForwardIterator> template <typename ForwardIterator>
std::string generateNamesAndTypesDescription(ForwardIterator begin, ForwardIterator end) const std::string generateNamesAndTypesDescription(ForwardIterator begin, ForwardIterator end) const
{ {
if (begin == end) if (begin == end)

View File

@ -54,7 +54,7 @@ BlockInputStreams StorageSystemMerges::read(
block.getByPosition(i++).column->insert(merge.database); block.getByPosition(i++).column->insert(merge.database);
block.getByPosition(i++).column->insert(merge.table); block.getByPosition(i++).column->insert(merge.table);
block.getByPosition(i++).column->insert(merge.elapsed); block.getByPosition(i++).column->insert(merge.elapsed);
block.getByPosition(i++).column->insert(std::min(1., merge.progress)); /// little cheat block.getByPosition(i++).column->insert(merge.progress);
block.getByPosition(i++).column->insert(merge.num_parts); block.getByPosition(i++).column->insert(merge.num_parts);
block.getByPosition(i++).column->insert(merge.source_part_names); block.getByPosition(i++).column->insert(merge.source_part_names);
block.getByPosition(i++).column->insert(merge.result_part_name); block.getByPosition(i++).column->insert(merge.result_part_name);

View File

@ -29,6 +29,19 @@ MSG_OK = OP_SQUARE_BRACKET + colored(" OK ", "green", attrs=['bold']) + CL_SQUAR
MSG_SKIPPED = OP_SQUARE_BRACKET + colored(" SKIPPED ", "cyan", attrs=['bold']) + CL_SQUARE_BRACKET MSG_SKIPPED = OP_SQUARE_BRACKET + colored(" SKIPPED ", "cyan", attrs=['bold']) + CL_SQUARE_BRACKET
def remove_control_characters(s):
"""
https://github.com/html5lib/html5lib-python/issues/96#issuecomment-43438438
"""
def str_to_int(s, default, base=10):
if int(s, base) < 0x10000:
return unichr(int(s, base))
return default
s = re.sub(ur"&#(\d+);?", lambda c: str_to_int(c.group(1), c.group(0)), s)
s = re.sub(ur"&#[xX]([0-9a-fA-F]+);?", lambda c: str_to_int(c.group(1), c.group(0), base=16), s)
s = re.sub(ur"[\x00-\x08\x0b\x0e-\x1f\x7f]", "", s)
return s
def main(args): def main(args):
SERVER_DIED = False SERVER_DIED = False
@ -107,6 +120,7 @@ def main(args):
(name, ext) = os.path.splitext(case) (name, ext) = os.path.splitext(case)
report_testcase = et.Element("testcase", attrib = {"name": name}) report_testcase = et.Element("testcase", attrib = {"name": name})
try:
print "{0:70}".format(name + ": "), print "{0:70}".format(name + ": "),
sys.stdout.flush() sys.stdout.flush()
@ -204,9 +218,12 @@ def main(args):
report_testcase.append(failure) report_testcase.append(failure)
stdout_element = et.Element("system-out") stdout_element = et.Element("system-out")
try:
stdout_element.text = et.CDATA(diff) stdout_element.text = et.CDATA(diff)
report_testcase.append(stdout_element) except:
stdout_element.text = et.CDATA(remove_control_characters(diff))
report_testcase.append(stdout_element)
failures = failures + 1 failures = failures + 1
print("{0} - result differs with reference:\n{1}".format(MSG_FAIL, diff.encode('utf-8'))) print("{0} - result differs with reference:\n{1}".format(MSG_FAIL, diff.encode('utf-8')))
else: else:
@ -215,7 +232,14 @@ def main(args):
os.remove(stdout_file) os.remove(stdout_file)
if os.path.exists(stderr_file): if os.path.exists(stderr_file):
os.remove(stderr_file) os.remove(stderr_file)
except:
(exc_type, exc_value) = sys.exc_info()[:2]
error = et.Element("error", attrib = {"type": exc_type.__name__, "message": str(exc_value)})
report_testcase.append(error)
failures = failures + 1
print("{0} - Test internal error: {1}\n{2}".format(MSG_FAIL, exc_type.__name__, exc_value))
finally:
dump_report(args.output, suite, name, report_testcase) dump_report(args.output, suite, name, report_testcase)
failures_total = failures_total + failures failures_total = failures_total + failures
@ -235,13 +259,14 @@ if __name__ == '__main__':
parser.add_argument('-o', '--output', help = 'Output xUnit compliant test report directory') parser.add_argument('-o', '--output', help = 'Output xUnit compliant test report directory')
parser.add_argument('-t', '--timeout', type = int, default = 600, help = 'Timeout for each test case in seconds') parser.add_argument('-t', '--timeout', type = int, default = 600, help = 'Timeout for each test case in seconds')
parser.add_argument('test', nargs = '?', help = 'Optional test case name regex') parser.add_argument('test', nargs = '?', help = 'Optional test case name regex')
parser.add_argument('--stop', action = 'store_true', default = None, dest = 'stop', help = 'Stop on network errors ')
group = parser.add_mutually_exclusive_group(required = False) group = parser.add_mutually_exclusive_group(required = False)
group.add_argument('--zookeeper', action = 'store_true', default = None, dest = 'zookeeper', help = 'Run zookeeper related tests') group.add_argument('--zookeeper', action = 'store_true', default = None, dest = 'zookeeper', help = 'Run zookeeper related tests')
group.add_argument('--no-zookeeper', action = 'store_false', default = None, dest = 'zookeeper', help = 'Do not run zookeeper related tests') group.add_argument('--no-zookeeper', action = 'store_false', default = None, dest = 'zookeeper', help = 'Do not run zookeeper related tests')
group = parser.add_mutually_exclusive_group(required = False)
group.add_argument('--shard', action = 'store_true', default = None, dest = 'shard', help = 'Run sharding related tests (required to clickhouse-server listen 127.0.0.2 127.0.0.3)') group.add_argument('--shard', action = 'store_true', default = None, dest = 'shard', help = 'Run sharding related tests (required to clickhouse-server listen 127.0.0.2 127.0.0.3)')
group.add_argument('--no-shard', action = 'store_false', default = None, dest = 'shard', help = 'Do not run shard related tests') group.add_argument('--no-shard', action = 'store_false', default = None, dest = 'shard', help = 'Do not run shard related tests')
group.add_argument('--stop', action = 'store_true', default = None, dest = 'stop', help = 'Stop on network errors ')
args = parser.parse_args() args = parser.parse_args()

View File

@ -63,6 +63,8 @@ function test {
echo echo
} }
merged_rows_0=`clickhouse-client -q "select value from system.events where event = 'MergedRows'"`
test 8191 8191 test 8191 8191
test 8191 8192 test 8191 8192
test 8192 8191 test 8192 8191
@ -76,4 +78,7 @@ test 8193 8194
test 8194 8193 test 8194 8193
test 8194 8194 test 8194 8194
merged_rows_1=`clickhouse-client -q "select value from system.events where event = 'MergedRows'"`
[[ $merged_rows_1 -le $merged_rows_0 ]]
cleanup cleanup

View File

@ -1,954 +1,45 @@
/* Без дополнительного параметра */ SELECT toUInt8(number) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT toUInt16(number) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(0), ceil(0), floor(0); SELECT toUInt32(number) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT toUInt64(number) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13)), ceil(toUInt8(13)), floor(toUInt8(13)); SELECT toInt8(number - 10) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(toUInt16(13)), ceil(toUInt16(13)), floor(toUInt16(13)); SELECT toInt16(number - 10) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(toUInt32(13)), ceil(toUInt32(13)), floor(toUInt32(13)); SELECT toInt32(number - 10) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(toUInt64(13)), ceil(toUInt64(13)), floor(toUInt64(13)); SELECT toInt64(number - 10) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(toInt8(13)), ceil(toInt8(13)), floor(toInt8(13)); SELECT toFloat32(number - 10) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(toInt16(13)), ceil(toInt16(13)), floor(toInt16(13)); SELECT toFloat64(number - 10) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(toInt32(13)), ceil(toInt32(13)), floor(toInt32(13));
SELECT round(toInt64(13)), ceil(toInt64(13)), floor(toInt64(13)); SELECT toFloat32((number - 10) / 10) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(toFloat32(13)), ceil(toFloat32(13)), floor(toFloat32(13)); SELECT toFloat64((number - 10) / 10) AS x, round(x), floor(x), ceil(x), trunc(x) FROM system.numbers LIMIT 20;
SELECT round(toFloat64(13)), ceil(toFloat64(13)), floor(toFloat64(13));
SELECT toFloat32((number - 10) / 10) AS x, round(x, 1), floor(x, 1), ceil(x, 1), trunc(x, 1) FROM system.numbers LIMIT 20;
SELECT round(toInt8(-13)), ceil(toInt8(-13)), floor(toInt8(-13)); SELECT toFloat64((number - 10) / 10) AS x, round(x, 1), floor(x, 1), ceil(x, 1), trunc(x, 1) FROM system.numbers LIMIT 20;
SELECT round(toInt16(-13)), ceil(toInt16(-13)), floor(toInt16(-13));
SELECT round(toInt32(-13)), ceil(toInt32(-13)), floor(toInt32(-13)); SELECT toUInt8(number) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
SELECT round(toInt64(-13)), ceil(toInt64(-13)), floor(toInt64(-13)); SELECT toUInt16(number) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
SELECT round(toFloat32(-13)), ceil(toFloat32(-13)), floor(toFloat32(-13)); SELECT toUInt32(number) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
SELECT round(toFloat64(-13)), ceil(toFloat64(-13)), floor(toFloat64(-13)); SELECT toUInt64(number) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
SELECT toInt8(number - 10) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
SELECT round(2.7), ceil(2.7), floor(2.7); SELECT toInt16(number - 10) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
SELECT round(2.1), ceil(2,1), floor(2.1); SELECT toInt32(number - 10) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
SELECT toInt64(number - 10) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
SELECT round(-2.7), ceil(-2.7), floor(-2.7); SELECT toFloat32(number - 10) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
SELECT round(-2.1), ceil(-2,1), floor(-2.1); SELECT toFloat64(number - 10) AS x, round(x, -1), floor(x, -1), ceil(x, -1), trunc(x, -1) FROM system.numbers LIMIT 20;
/* UInt8 */ SELECT toUInt8(number) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT toUInt16(number) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13), toUInt8(2)), ceil(toUInt8(13), toUInt8(2)), floor(toUInt8(13), toUInt8(2)); SELECT toUInt32(number) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13), toUInt16(2)), ceil(toUInt8(13), toUInt16(2)), floor(toUInt8(13), toUInt16(2)); SELECT toUInt64(number) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13), toUInt32(2)), ceil(toUInt8(13), toUInt32(2)), floor(toUInt8(13), toUInt32(2)); SELECT toInt8(number - 10) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13), toUInt64(2)), ceil(toUInt8(13), toUInt64(2)), floor(toUInt8(13), toUInt64(2)); SELECT toInt16(number - 10) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13), toInt8(2)), ceil(toUInt8(13), toInt8(2)), floor(toUInt8(13), toInt8(2)); SELECT toInt32(number - 10) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13), toInt16(2)), ceil(toUInt8(13), toInt16(2)), floor(toUInt8(13), toInt16(2)); SELECT toInt64(number - 10) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13), toInt32(2)), ceil(toUInt8(13), toInt32(2)), floor(toUInt8(13), toInt32(2)); SELECT toFloat32(number - 10) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13), toInt64(2)), ceil(toUInt8(13), toInt64(2)), floor(toUInt8(13), toInt64(2)); SELECT toFloat64(number - 10) AS x, round(x, -2), floor(x, -2), ceil(x, -2), trunc(x, -2) FROM system.numbers LIMIT 20;
SELECT round(toUInt8(13), toFloat32(2.1)), ceil(toUInt8(13), toFloat32(2.1)), floor(toUInt8(13), toFloat32(2.1));
SELECT round(toUInt8(13), toFloat64(2.1)), ceil(toUInt8(13), toFloat64(2.1)), floor(toUInt8(13), toFloat64(2.1)); SELECT 123456789 AS x, floor(x, -1), floor(x, -2), floor(x, -3), floor(x, -4), floor(x, -5), floor(x, -6), floor(x, -7), floor(x, -8), floor(x, -9), floor(x, -10);
SELECT 12345.6789 AS x, floor(x, -1), floor(x, -2), floor(x, -3), floor(x, -4), floor(x, -5), floor(x, 1), floor(x, 2), floor(x, 3), floor(x, 4), floor(x, 5);
SELECT round(toUInt8(13), toUInt8(1)), ceil(toUInt8(13), toUInt8(1)), floor(toUInt8(13), toUInt8(1));
SELECT round(toUInt8(13), toUInt16(1)), ceil(toUInt8(13), toUInt16(1)), floor(toUInt8(13), toUInt16(1));
SELECT round(toUInt8(13), toUInt32(1)), ceil(toUInt8(13), toUInt32(1)), floor(toUInt8(13), toUInt32(1)); SELECT roundToExp2(100), roundToExp2(64), roundToExp2(3), roundToExp2(0), roundToExp2(-1);
SELECT round(toUInt8(13), toUInt64(1)), ceil(toUInt8(13), toUInt64(1)), floor(toUInt8(13), toUInt64(1)); SELECT roundToExp2(0.9), roundToExp2(0), roundToExp2(-0.5), roundToExp2(-0.6), roundToExp2(-0.2);
SELECT round(toUInt8(13), toInt8(1)), ceil(toUInt8(13), toInt8(1)), floor(toUInt8(13), toInt8(1));
SELECT round(toUInt8(13), toInt16(1)), ceil(toUInt8(13), toInt16(1)), floor(toUInt8(13), toInt16(1));
SELECT round(toUInt8(13), toInt32(1)), ceil(toUInt8(13), toInt32(1)), floor(toUInt8(13), toInt32(1));
SELECT round(toUInt8(13), toInt64(1)), ceil(toUInt8(13), toInt64(1)), floor(toUInt8(13), toInt64(1));
SELECT round(toUInt8(13), toFloat32(1.1)), ceil(toUInt8(13), toFloat32(1.1)), floor(toUInt8(13), toFloat32(1.1));
SELECT round(toUInt8(13), toFloat64(1.1)), ceil(toUInt8(13), toFloat64(1.1)), floor(toUInt8(13), toFloat64(1.1));
SELECT round(toUInt8(13), toUInt16(0)), ceil(toUInt8(13), toUInt16(0)), floor(toUInt8(13), toUInt16(0));
SELECT round(toUInt8(13), toUInt32(0)), ceil(toUInt8(13), toUInt32(0)), floor(toUInt8(13), toUInt32(0));
SELECT round(toUInt8(13), toUInt64(0)), ceil(toUInt8(13), toUInt64(0)), floor(toUInt8(13), toUInt64(0));
SELECT round(toUInt8(13), toInt8(0)), ceil(toUInt8(13), toInt8(0)), floor(toUInt8(13), toInt8(0));
SELECT round(toUInt8(13), toInt16(0)), ceil(toUInt8(13), toInt16(0)), floor(toUInt8(13), toInt16(0));
SELECT round(toUInt8(13), toInt32(0)), ceil(toUInt8(13), toInt32(0)), floor(toUInt8(13), toInt32(0));
SELECT round(toUInt8(13), toInt64(0)), ceil(toUInt8(13), toInt64(0)), floor(toUInt8(13), toInt64(0));
SELECT round(toUInt8(13), toFloat32(0.1)), ceil(toUInt8(13), toFloat32(0.1)), floor(toUInt8(13), toFloat32(0.1));
SELECT round(toUInt8(13), toFloat64(0.1)), ceil(toUInt8(13), toFloat64(0.1)), floor(toUInt8(13), toFloat64(0.1));
SELECT round(toUInt8(13), toInt8(-1)), ceil(toUInt8(13), toInt8(-1)), floor(toUInt8(13), toInt8(-1));
SELECT round(toUInt8(13), toInt16(-1)), ceil(toUInt8(13), toInt16(-1)), floor(toUInt8(13), toInt16(-1));
SELECT round(toUInt8(13), toInt32(-1)), ceil(toUInt8(13), toInt32(-1)), floor(toUInt8(13), toInt32(-1));
SELECT round(toUInt8(13), toInt64(-1)), ceil(toUInt8(13), toInt64(-1)), floor(toUInt8(13), toInt64(-1));
SELECT round(toUInt8(13), toFloat32(1.1)), ceil(toUInt8(13), toFloat32(-1.1)), floor(toUInt8(13), toFloat32(-1.1));
SELECT round(toUInt8(13), toFloat64(1.1)), ceil(toUInt8(13), toFloat64(-1.1)), floor(toUInt8(13), toFloat64(-1.1));
SELECT round(toUInt8(13), toInt8(-2)), ceil(toUInt8(13), toInt8(-2)), floor(toUInt8(13), toInt8(-2));
SELECT round(toUInt8(13), toInt16(-2)), ceil(toUInt8(13), toInt16(-2)), floor(toUInt8(13), toInt16(-2));
SELECT round(toUInt8(13), toInt32(-2)), ceil(toUInt8(13), toInt32(-2)), floor(toUInt8(13), toInt32(-2));
SELECT round(toUInt8(13), toInt64(-2)), ceil(toUInt8(13), toInt64(-2)), floor(toUInt8(13), toInt64(-2));
SELECT round(toUInt8(13), toFloat32(-2.1)), ceil(toUInt8(13), toFloat32(-2.1)), floor(toUInt8(13), toFloat32(-2.1));
SELECT round(toUInt8(13), toFloat64(-2.1)), ceil(toUInt8(13), toFloat64(-2.1)), floor(toUInt8(13), toFloat64(-2.1));
/* UInt16 */
SELECT round(toUInt16(13), toUInt8(2)), ceil(toUInt16(13), toUInt8(2)), floor(toUInt16(13), toUInt8(2));
SELECT round(toUInt16(13), toUInt16(2)), ceil(toUInt16(13), toUInt16(2)), floor(toUInt16(13), toUInt16(2));
SELECT round(toUInt16(13), toUInt32(2)), ceil(toUInt16(13), toUInt32(2)), floor(toUInt16(13), toUInt32(2));
SELECT round(toUInt16(13), toUInt64(2)), ceil(toUInt16(13), toUInt64(2)), floor(toUInt16(13), toUInt64(2));
SELECT round(toUInt16(13), toInt8(2)), ceil(toUInt16(13), toInt8(2)), floor(toUInt16(13), toInt8(2));
SELECT round(toUInt16(13), toInt16(2)), ceil(toUInt16(13), toInt16(2)), floor(toUInt16(13), toInt16(2));
SELECT round(toUInt16(13), toInt32(2)), ceil(toUInt16(13), toInt32(2)), floor(toUInt16(13), toInt32(2));
SELECT round(toUInt16(13), toInt64(2)), ceil(toUInt16(13), toInt64(2)), floor(toUInt16(13), toInt64(2));
SELECT round(toUInt16(13), toFloat32(2.1)), ceil(toUInt16(13), toFloat32(2.1)), floor(toUInt16(13), toFloat32(2.1));
SELECT round(toUInt16(13), toFloat64(2.1)), ceil(toUInt16(13), toFloat64(2.1)), floor(toUInt16(13), toFloat64(2.1));
SELECT round(toUInt16(13), toUInt8(1)), ceil(toUInt16(13), toUInt8(1)), floor(toUInt16(13), toUInt8(1));
SELECT round(toUInt16(13), toUInt16(1)), ceil(toUInt16(13), toUInt16(1)), floor(toUInt16(13), toUInt16(1));
SELECT round(toUInt16(13), toUInt32(1)), ceil(toUInt16(13), toUInt32(1)), floor(toUInt16(13), toUInt32(1));
SELECT round(toUInt16(13), toUInt64(1)), ceil(toUInt16(13), toUInt64(1)), floor(toUInt16(13), toUInt64(1));
SELECT round(toUInt16(13), toInt8(1)), ceil(toUInt16(13), toInt8(1)), floor(toUInt16(13), toInt8(1));
SELECT round(toUInt16(13), toInt16(1)), ceil(toUInt16(13), toInt16(1)), floor(toUInt16(13), toInt16(1));
SELECT round(toUInt16(13), toInt32(1)), ceil(toUInt16(13), toInt32(1)), floor(toUInt16(13), toInt32(1));
SELECT round(toUInt16(13), toInt64(1)), ceil(toUInt16(13), toInt64(1)), floor(toUInt16(13), toInt64(1));
SELECT round(toUInt16(13), toFloat32(1.1)), ceil(toUInt16(13), toFloat32(1.1)), floor(toUInt16(13), toFloat32(1.1));
SELECT round(toUInt16(13), toFloat64(1.1)), ceil(toUInt16(13), toFloat64(1.1)), floor(toUInt16(13), toFloat64(1.1));
SELECT round(toUInt16(13), toUInt16(0)), ceil(toUInt16(13), toUInt16(0)), floor(toUInt16(13), toUInt16(0));
SELECT round(toUInt16(13), toUInt32(0)), ceil(toUInt16(13), toUInt32(0)), floor(toUInt16(13), toUInt32(0));
SELECT round(toUInt16(13), toUInt64(0)), ceil(toUInt16(13), toUInt64(0)), floor(toUInt16(13), toUInt64(0));
SELECT round(toUInt16(13), toInt8(0)), ceil(toUInt16(13), toInt8(0)), floor(toUInt16(13), toInt8(0));
SELECT round(toUInt16(13), toInt16(0)), ceil(toUInt16(13), toInt16(0)), floor(toUInt16(13), toInt16(0));
SELECT round(toUInt16(13), toInt32(0)), ceil(toUInt16(13), toInt32(0)), floor(toUInt16(13), toInt32(0));
SELECT round(toUInt16(13), toInt64(0)), ceil(toUInt16(13), toInt64(0)), floor(toUInt16(13), toInt64(0));
SELECT round(toUInt16(13), toFloat32(0.1)), ceil(toUInt16(13), toFloat32(0.1)), floor(toUInt16(13), toFloat32(0.1));
SELECT round(toUInt16(13), toFloat64(0.1)), ceil(toUInt16(13), toFloat64(0.1)), floor(toUInt16(13), toFloat64(0.1));
SELECT round(toUInt16(13), toInt8(-1)), ceil(toUInt16(13), toInt8(-1)), floor(toUInt16(13), toInt8(-1));
SELECT round(toUInt16(13), toInt16(-1)), ceil(toUInt16(13), toInt16(-1)), floor(toUInt16(13), toInt16(-1));
SELECT round(toUInt16(13), toInt32(-1)), ceil(toUInt16(13), toInt32(-1)), floor(toUInt16(13), toInt32(-1));
SELECT round(toUInt16(13), toInt64(-1)), ceil(toUInt16(13), toInt64(-1)), floor(toUInt16(13), toInt64(-1));
SELECT round(toUInt16(13), toFloat32(1.1)), ceil(toUInt16(13), toFloat32(-1.1)), floor(toUInt16(13), toFloat32(-1.1));
SELECT round(toUInt16(13), toFloat64(1.1)), ceil(toUInt16(13), toFloat64(-1.1)), floor(toUInt16(13), toFloat64(-1.1));
SELECT round(toUInt16(13), toInt8(-2)), ceil(toUInt16(13), toInt8(-2)), floor(toUInt16(13), toInt8(-2));
SELECT round(toUInt16(13), toInt16(-2)), ceil(toUInt16(13), toInt16(-2)), floor(toUInt16(13), toInt16(-2));
SELECT round(toUInt16(13), toInt32(-2)), ceil(toUInt16(13), toInt32(-2)), floor(toUInt16(13), toInt32(-2));
SELECT round(toUInt16(13), toInt64(-2)), ceil(toUInt16(13), toInt64(-2)), floor(toUInt16(13), toInt64(-2));
SELECT round(toUInt16(13), toFloat32(-2.1)), ceil(toUInt16(13), toFloat32(-2.1)), floor(toUInt16(13), toFloat32(-2.1));
SELECT round(toUInt16(13), toFloat64(-2.1)), ceil(toUInt16(13), toFloat64(-2.1)), floor(toUInt16(13), toFloat64(-2.1));
/* UInt32 */
SELECT round(toUInt32(13), toUInt8(2)), ceil(toUInt32(13), toUInt8(2)), floor(toUInt32(13), toUInt8(2));
SELECT round(toUInt32(13), toUInt16(2)), ceil(toUInt32(13), toUInt16(2)), floor(toUInt32(13), toUInt16(2));
SELECT round(toUInt32(13), toUInt32(2)), ceil(toUInt32(13), toUInt32(2)), floor(toUInt32(13), toUInt32(2));
SELECT round(toUInt32(13), toUInt64(2)), ceil(toUInt32(13), toUInt64(2)), floor(toUInt32(13), toUInt64(2));
SELECT round(toUInt32(13), toInt8(2)), ceil(toUInt32(13), toInt8(2)), floor(toUInt32(13), toInt8(2));
SELECT round(toUInt32(13), toInt16(2)), ceil(toUInt32(13), toInt16(2)), floor(toUInt32(13), toInt16(2));
SELECT round(toUInt32(13), toInt32(2)), ceil(toUInt32(13), toInt32(2)), floor(toUInt32(13), toInt32(2));
SELECT round(toUInt32(13), toInt64(2)), ceil(toUInt32(13), toInt64(2)), floor(toUInt32(13), toInt64(2));
SELECT round(toUInt32(13), toFloat32(2.1)), ceil(toUInt32(13), toFloat32(2.1)), floor(toUInt32(13), toFloat32(2.1));
SELECT round(toUInt32(13), toFloat64(2.1)), ceil(toUInt32(13), toFloat64(2.1)), floor(toUInt32(13), toFloat64(2.1));
SELECT round(toUInt32(13), toUInt8(1)), ceil(toUInt32(13), toUInt8(1)), floor(toUInt32(13), toUInt8(1));
SELECT round(toUInt32(13), toUInt16(1)), ceil(toUInt32(13), toUInt16(1)), floor(toUInt32(13), toUInt16(1));
SELECT round(toUInt32(13), toUInt32(1)), ceil(toUInt32(13), toUInt32(1)), floor(toUInt32(13), toUInt32(1));
SELECT round(toUInt32(13), toUInt64(1)), ceil(toUInt32(13), toUInt64(1)), floor(toUInt32(13), toUInt64(1));
SELECT round(toUInt32(13), toInt8(1)), ceil(toUInt32(13), toInt8(1)), floor(toUInt32(13), toInt8(1));
SELECT round(toUInt32(13), toInt16(1)), ceil(toUInt32(13), toInt16(1)), floor(toUInt32(13), toInt16(1));
SELECT round(toUInt32(13), toInt32(1)), ceil(toUInt32(13), toInt32(1)), floor(toUInt32(13), toInt32(1));
SELECT round(toUInt32(13), toInt64(1)), ceil(toUInt32(13), toInt64(1)), floor(toUInt32(13), toInt64(1));
SELECT round(toUInt32(13), toFloat32(1.1)), ceil(toUInt32(13), toFloat32(1.1)), floor(toUInt32(13), toFloat32(1.1));
SELECT round(toUInt32(13), toFloat64(1.1)), ceil(toUInt32(13), toFloat64(1.1)), floor(toUInt32(13), toFloat64(1.1));
SELECT round(toUInt32(13), toUInt16(0)), ceil(toUInt32(13), toUInt16(0)), floor(toUInt32(13), toUInt16(0));
SELECT round(toUInt32(13), toUInt32(0)), ceil(toUInt32(13), toUInt32(0)), floor(toUInt32(13), toUInt32(0));
SELECT round(toUInt32(13), toUInt64(0)), ceil(toUInt32(13), toUInt64(0)), floor(toUInt32(13), toUInt64(0));
SELECT round(toUInt32(13), toInt8(0)), ceil(toUInt32(13), toInt8(0)), floor(toUInt32(13), toInt8(0));
SELECT round(toUInt32(13), toInt16(0)), ceil(toUInt32(13), toInt16(0)), floor(toUInt32(13), toInt16(0));
SELECT round(toUInt32(13), toInt32(0)), ceil(toUInt32(13), toInt32(0)), floor(toUInt32(13), toInt32(0));
SELECT round(toUInt32(13), toInt64(0)), ceil(toUInt32(13), toInt64(0)), floor(toUInt32(13), toInt64(0));
SELECT round(toUInt32(13), toFloat32(0.1)), ceil(toUInt32(13), toFloat32(0.1)), floor(toUInt32(13), toFloat32(0.1));
SELECT round(toUInt32(13), toFloat64(0.1)), ceil(toUInt32(13), toFloat64(0.1)), floor(toUInt32(13), toFloat64(0.1));
SELECT round(toUInt32(13), toInt8(-1)), ceil(toUInt32(13), toInt8(-1)), floor(toUInt32(13), toInt8(-1));
SELECT round(toUInt32(13), toInt16(-1)), ceil(toUInt32(13), toInt16(-1)), floor(toUInt32(13), toInt16(-1));
SELECT round(toUInt32(13), toInt32(-1)), ceil(toUInt32(13), toInt32(-1)), floor(toUInt32(13), toInt32(-1));
SELECT round(toUInt32(13), toInt64(-1)), ceil(toUInt32(13), toInt64(-1)), floor(toUInt32(13), toInt64(-1));
SELECT round(toUInt32(13), toFloat32(1.1)), ceil(toUInt32(13), toFloat32(-1.1)), floor(toUInt32(13), toFloat32(-1.1));
SELECT round(toUInt32(13), toFloat64(1.1)), ceil(toUInt32(13), toFloat64(-1.1)), floor(toUInt32(13), toFloat64(-1.1));
SELECT round(toUInt32(13), toInt8(-2)), ceil(toUInt32(13), toInt8(-2)), floor(toUInt32(13), toInt8(-2));
SELECT round(toUInt32(13), toInt16(-2)), ceil(toUInt32(13), toInt16(-2)), floor(toUInt32(13), toInt16(-2));
SELECT round(toUInt32(13), toInt32(-2)), ceil(toUInt32(13), toInt32(-2)), floor(toUInt32(13), toInt32(-2));
SELECT round(toUInt32(13), toInt64(-2)), ceil(toUInt32(13), toInt64(-2)), floor(toUInt32(13), toInt64(-2));
SELECT round(toUInt32(13), toFloat32(-2.1)), ceil(toUInt32(13), toFloat32(-2.1)), floor(toUInt32(13), toFloat32(-2.1));
SELECT round(toUInt32(13), toFloat64(-2.1)), ceil(toUInt32(13), toFloat64(-2.1)), floor(toUInt32(13), toFloat64(-2.1));
/* UInt64 */
SELECT round(toUInt64(13), toUInt8(2)), ceil(toUInt64(13), toUInt8(2)), floor(toUInt64(13), toUInt8(2));
SELECT round(toUInt64(13), toUInt16(2)), ceil(toUInt64(13), toUInt16(2)), floor(toUInt64(13), toUInt16(2));
SELECT round(toUInt64(13), toUInt32(2)), ceil(toUInt64(13), toUInt32(2)), floor(toUInt64(13), toUInt32(2));
SELECT round(toUInt64(13), toUInt64(2)), ceil(toUInt64(13), toUInt64(2)), floor(toUInt64(13), toUInt64(2));
SELECT round(toUInt64(13), toInt8(2)), ceil(toUInt64(13), toInt8(2)), floor(toUInt64(13), toInt8(2));
SELECT round(toUInt64(13), toInt16(2)), ceil(toUInt64(13), toInt16(2)), floor(toUInt64(13), toInt16(2));
SELECT round(toUInt64(13), toInt32(2)), ceil(toUInt64(13), toInt32(2)), floor(toUInt64(13), toInt32(2));
SELECT round(toUInt64(13), toInt64(2)), ceil(toUInt64(13), toInt64(2)), floor(toUInt64(13), toInt64(2));
SELECT round(toUInt64(13), toFloat32(2.1)), ceil(toUInt64(13), toFloat32(2.1)), floor(toUInt64(13), toFloat32(2.1));
SELECT round(toUInt64(13), toFloat64(2.1)), ceil(toUInt64(13), toFloat64(2.1)), floor(toUInt64(13), toFloat64(2.1));
SELECT round(toUInt64(13), toUInt8(1)), ceil(toUInt64(13), toUInt8(1)), floor(toUInt64(13), toUInt8(1));
SELECT round(toUInt64(13), toUInt16(1)), ceil(toUInt64(13), toUInt16(1)), floor(toUInt64(13), toUInt16(1));
SELECT round(toUInt64(13), toUInt32(1)), ceil(toUInt64(13), toUInt32(1)), floor(toUInt64(13), toUInt32(1));
SELECT round(toUInt64(13), toUInt64(1)), ceil(toUInt64(13), toUInt64(1)), floor(toUInt64(13), toUInt64(1));
SELECT round(toUInt64(13), toInt8(1)), ceil(toUInt64(13), toInt8(1)), floor(toUInt64(13), toInt8(1));
SELECT round(toUInt64(13), toInt16(1)), ceil(toUInt64(13), toInt16(1)), floor(toUInt64(13), toInt16(1));
SELECT round(toUInt64(13), toInt32(1)), ceil(toUInt64(13), toInt32(1)), floor(toUInt64(13), toInt32(1));
SELECT round(toUInt64(13), toInt64(1)), ceil(toUInt64(13), toInt64(1)), floor(toUInt64(13), toInt64(1));
SELECT round(toUInt64(13), toFloat32(1.1)), ceil(toUInt64(13), toFloat32(1.1)), floor(toUInt64(13), toFloat32(1.1));
SELECT round(toUInt64(13), toFloat64(1.1)), ceil(toUInt64(13), toFloat64(1.1)), floor(toUInt64(13), toFloat64(1.1));
SELECT round(toUInt64(13), toUInt16(0)), ceil(toUInt64(13), toUInt16(0)), floor(toUInt64(13), toUInt16(0));
SELECT round(toUInt64(13), toUInt32(0)), ceil(toUInt64(13), toUInt32(0)), floor(toUInt64(13), toUInt32(0));
SELECT round(toUInt64(13), toUInt64(0)), ceil(toUInt64(13), toUInt64(0)), floor(toUInt64(13), toUInt64(0));
SELECT round(toUInt64(13), toInt8(0)), ceil(toUInt64(13), toInt8(0)), floor(toUInt64(13), toInt8(0));
SELECT round(toUInt64(13), toInt16(0)), ceil(toUInt64(13), toInt16(0)), floor(toUInt64(13), toInt16(0));
SELECT round(toUInt64(13), toInt32(0)), ceil(toUInt64(13), toInt32(0)), floor(toUInt64(13), toInt32(0));
SELECT round(toUInt64(13), toInt64(0)), ceil(toUInt64(13), toInt64(0)), floor(toUInt64(13), toInt64(0));
SELECT round(toUInt64(13), toFloat32(0.1)), ceil(toUInt64(13), toFloat32(0.1)), floor(toUInt64(13), toFloat32(0.1));
SELECT round(toUInt64(13), toFloat64(0.1)), ceil(toUInt64(13), toFloat64(0.1)), floor(toUInt64(13), toFloat64(0.1));
SELECT round(toUInt64(13), toInt8(-1)), ceil(toUInt64(13), toInt8(-1)), floor(toUInt64(13), toInt8(-1));
SELECT round(toUInt64(13), toInt16(-1)), ceil(toUInt64(13), toInt16(-1)), floor(toUInt64(13), toInt16(-1));
SELECT round(toUInt64(13), toInt32(-1)), ceil(toUInt64(13), toInt32(-1)), floor(toUInt64(13), toInt32(-1));
SELECT round(toUInt64(13), toInt64(-1)), ceil(toUInt64(13), toInt64(-1)), floor(toUInt64(13), toInt64(-1));
SELECT round(toUInt64(13), toFloat32(1.1)), ceil(toUInt64(13), toFloat32(-1.1)), floor(toUInt64(13), toFloat32(-1.1));
SELECT round(toUInt64(13), toFloat64(1.1)), ceil(toUInt64(13), toFloat64(-1.1)), floor(toUInt64(13), toFloat64(-1.1));
SELECT round(toUInt64(13), toInt8(-2)), ceil(toUInt64(13), toInt8(-2)), floor(toUInt64(13), toInt8(-2));
SELECT round(toUInt64(13), toInt16(-2)), ceil(toUInt64(13), toInt16(-2)), floor(toUInt64(13), toInt16(-2));
SELECT round(toUInt64(13), toInt32(-2)), ceil(toUInt64(13), toInt32(-2)), floor(toUInt64(13), toInt32(-2));
SELECT round(toUInt64(13), toInt64(-2)), ceil(toUInt64(13), toInt64(-2)), floor(toUInt64(13), toInt64(-2));
SELECT round(toUInt64(13), toFloat32(-2.1)), ceil(toUInt64(13), toFloat32(-2.1)), floor(toUInt64(13), toFloat32(-2.1));
SELECT round(toUInt64(13), toFloat64(-2.1)), ceil(toUInt64(13), toFloat64(-2.1)), floor(toUInt64(13), toFloat64(-2.1));
/* Int8 */
SELECT round(toInt8(13), toUInt8(2)), ceil(toInt8(13), toUInt8(2)), floor(toInt8(13), toUInt8(2));
SELECT round(toInt8(13), toUInt16(2)), ceil(toInt8(13), toUInt16(2)), floor(toInt8(13), toUInt16(2));
SELECT round(toInt8(13), toUInt32(2)), ceil(toInt8(13), toUInt32(2)), floor(toInt8(13), toUInt32(2));
SELECT round(toInt8(13), toUInt64(2)), ceil(toInt8(13), toUInt64(2)), floor(toInt8(13), toUInt64(2));
SELECT round(toInt8(13), toInt8(2)), ceil(toInt8(13), toInt8(2)), floor(toInt8(13), toInt8(2));
SELECT round(toInt8(13), toInt16(2)), ceil(toInt8(13), toInt16(2)), floor(toInt8(13), toInt16(2));
SELECT round(toInt8(13), toInt32(2)), ceil(toInt8(13), toInt32(2)), floor(toInt8(13), toInt32(2));
SELECT round(toInt8(13), toInt64(2)), ceil(toInt8(13), toInt64(2)), floor(toInt8(13), toInt64(2));
SELECT round(toInt8(13), toFloat32(2.1)), ceil(toInt8(13), toFloat32(2.1)), floor(toInt8(13), toFloat32(2.1));
SELECT round(toInt8(13), toFloat64(2.1)), ceil(toInt8(13), toFloat64(2.1)), floor(toInt8(13), toFloat64(2.1));
SELECT round(toInt8(13), toUInt8(1)), ceil(toInt8(13), toUInt8(1)), floor(toInt8(13), toUInt8(1));
SELECT round(toInt8(13), toUInt16(1)), ceil(toInt8(13), toUInt16(1)), floor(toInt8(13), toUInt16(1));
SELECT round(toInt8(13), toUInt32(1)), ceil(toInt8(13), toUInt32(1)), floor(toInt8(13), toUInt32(1));
SELECT round(toInt8(13), toUInt64(1)), ceil(toInt8(13), toUInt64(1)), floor(toInt8(13), toUInt64(1));
SELECT round(toInt8(13), toInt8(1)), ceil(toInt8(13), toInt8(1)), floor(toInt8(13), toInt8(1));
SELECT round(toInt8(13), toInt16(1)), ceil(toInt8(13), toInt16(1)), floor(toInt8(13), toInt16(1));
SELECT round(toInt8(13), toInt32(1)), ceil(toInt8(13), toInt32(1)), floor(toInt8(13), toInt32(1));
SELECT round(toInt8(13), toInt64(1)), ceil(toInt8(13), toInt64(1)), floor(toInt8(13), toInt64(1));
SELECT round(toInt8(13), toFloat32(1.1)), ceil(toInt8(13), toFloat32(1.1)), floor(toInt8(13), toFloat32(1.1));
SELECT round(toInt8(13), toFloat64(1.1)), ceil(toInt8(13), toFloat64(1.1)), floor(toInt8(13), toFloat64(1.1));
SELECT round(toInt8(13), toUInt16(0)), ceil(toInt8(13), toUInt16(0)), floor(toInt8(13), toUInt16(0));
SELECT round(toInt8(13), toUInt32(0)), ceil(toInt8(13), toUInt32(0)), floor(toInt8(13), toUInt32(0));
SELECT round(toInt8(13), toUInt64(0)), ceil(toInt8(13), toUInt64(0)), floor(toInt8(13), toUInt64(0));
SELECT round(toInt8(13), toInt8(0)), ceil(toInt8(13), toInt8(0)), floor(toInt8(13), toInt8(0));
SELECT round(toInt8(13), toInt16(0)), ceil(toInt8(13), toInt16(0)), floor(toInt8(13), toInt16(0));
SELECT round(toInt8(13), toInt32(0)), ceil(toInt8(13), toInt32(0)), floor(toInt8(13), toInt32(0));
SELECT round(toInt8(13), toInt64(0)), ceil(toInt8(13), toInt64(0)), floor(toInt8(13), toInt64(0));
SELECT round(toInt8(13), toFloat32(0.1)), ceil(toInt8(13), toFloat32(0.1)), floor(toInt8(13), toFloat32(0.1));
SELECT round(toInt8(13), toFloat64(0.1)), ceil(toInt8(13), toFloat64(0.1)), floor(toInt8(13), toFloat64(0.1));
SELECT round(toInt8(13), toInt8(-1)), ceil(toInt8(13), toInt8(-1)), floor(toInt8(13), toInt8(-1));
SELECT round(toInt8(13), toInt16(-1)), ceil(toInt8(13), toInt16(-1)), floor(toInt8(13), toInt16(-1));
SELECT round(toInt8(13), toInt32(-1)), ceil(toInt8(13), toInt32(-1)), floor(toInt8(13), toInt32(-1));
SELECT round(toInt8(13), toInt64(-1)), ceil(toInt8(13), toInt64(-1)), floor(toInt8(13), toInt64(-1));
SELECT round(toInt8(13), toFloat32(1.1)), ceil(toInt8(13), toFloat32(-1.1)), floor(toInt8(13), toFloat32(-1.1));
SELECT round(toInt8(13), toFloat64(1.1)), ceil(toInt8(13), toFloat64(-1.1)), floor(toInt8(13), toFloat64(-1.1));
SELECT round(toInt8(13), toInt8(-2)), ceil(toInt8(13), toInt8(-2)), floor(toInt8(13), toInt8(-2));
SELECT round(toInt8(13), toInt16(-2)), ceil(toInt8(13), toInt16(-2)), floor(toInt8(13), toInt16(-2));
SELECT round(toInt8(13), toInt32(-2)), ceil(toInt8(13), toInt32(-2)), floor(toInt8(13), toInt32(-2));
SELECT round(toInt8(13), toInt64(-2)), ceil(toInt8(13), toInt64(-2)), floor(toInt8(13), toInt64(-2));
SELECT round(toInt8(13), toFloat32(-2.1)), ceil(toInt8(13), toFloat32(-2.1)), floor(toInt8(13), toFloat32(-2.1));
SELECT round(toInt8(13), toFloat64(-2.1)), ceil(toInt8(13), toFloat64(-2.1)), floor(toInt8(13), toFloat64(-2.1));
/* Int16 */
SELECT round(toInt16(13), toUInt8(2)), ceil(toInt16(13), toUInt8(2)), floor(toInt16(13), toUInt8(2));
SELECT round(toInt16(13), toUInt16(2)), ceil(toInt16(13), toUInt16(2)), floor(toInt16(13), toUInt16(2));
SELECT round(toInt16(13), toUInt32(2)), ceil(toInt16(13), toUInt32(2)), floor(toInt16(13), toUInt32(2));
SELECT round(toInt16(13), toUInt64(2)), ceil(toInt16(13), toUInt64(2)), floor(toInt16(13), toUInt64(2));
SELECT round(toInt16(13), toInt8(2)), ceil(toInt16(13), toInt8(2)), floor(toInt16(13), toInt8(2));
SELECT round(toInt16(13), toInt16(2)), ceil(toInt16(13), toInt16(2)), floor(toInt16(13), toInt16(2));
SELECT round(toInt16(13), toInt32(2)), ceil(toInt16(13), toInt32(2)), floor(toInt16(13), toInt32(2));
SELECT round(toInt16(13), toInt64(2)), ceil(toInt16(13), toInt64(2)), floor(toInt16(13), toInt64(2));
SELECT round(toInt16(13), toFloat32(2.1)), ceil(toInt16(13), toFloat32(2.1)), floor(toInt16(13), toFloat32(2.1));
SELECT round(toInt16(13), toFloat64(2.1)), ceil(toInt16(13), toFloat64(2.1)), floor(toInt16(13), toFloat64(2.1));
SELECT round(toInt16(13), toUInt8(1)), ceil(toInt16(13), toUInt8(1)), floor(toInt16(13), toUInt8(1));
SELECT round(toInt16(13), toUInt16(1)), ceil(toInt16(13), toUInt16(1)), floor(toInt16(13), toUInt16(1));
SELECT round(toInt16(13), toUInt32(1)), ceil(toInt16(13), toUInt32(1)), floor(toInt16(13), toUInt32(1));
SELECT round(toInt16(13), toUInt64(1)), ceil(toInt16(13), toUInt64(1)), floor(toInt16(13), toUInt64(1));
SELECT round(toInt16(13), toInt8(1)), ceil(toInt16(13), toInt8(1)), floor(toInt16(13), toInt8(1));
SELECT round(toInt16(13), toInt16(1)), ceil(toInt16(13), toInt16(1)), floor(toInt16(13), toInt16(1));
SELECT round(toInt16(13), toInt32(1)), ceil(toInt16(13), toInt32(1)), floor(toInt16(13), toInt32(1));
SELECT round(toInt16(13), toInt64(1)), ceil(toInt16(13), toInt64(1)), floor(toInt16(13), toInt64(1));
SELECT round(toInt16(13), toFloat32(1.1)), ceil(toInt16(13), toFloat32(1.1)), floor(toInt16(13), toFloat32(1.1));
SELECT round(toInt16(13), toFloat64(1.1)), ceil(toInt16(13), toFloat64(1.1)), floor(toInt16(13), toFloat64(1.1));
SELECT round(toInt16(13), toUInt16(0)), ceil(toInt16(13), toUInt16(0)), floor(toInt16(13), toUInt16(0));
SELECT round(toInt16(13), toUInt32(0)), ceil(toInt16(13), toUInt32(0)), floor(toInt16(13), toUInt32(0));
SELECT round(toInt16(13), toUInt64(0)), ceil(toInt16(13), toUInt64(0)), floor(toInt16(13), toUInt64(0));
SELECT round(toInt16(13), toInt8(0)), ceil(toInt16(13), toInt8(0)), floor(toInt16(13), toInt8(0));
SELECT round(toInt16(13), toInt16(0)), ceil(toInt16(13), toInt16(0)), floor(toInt16(13), toInt16(0));
SELECT round(toInt16(13), toInt32(0)), ceil(toInt16(13), toInt32(0)), floor(toInt16(13), toInt32(0));
SELECT round(toInt16(13), toInt64(0)), ceil(toInt16(13), toInt64(0)), floor(toInt16(13), toInt64(0));
SELECT round(toInt16(13), toFloat32(0.1)), ceil(toInt16(13), toFloat32(0.1)), floor(toInt16(13), toFloat32(0.1));
SELECT round(toInt16(13), toFloat64(0.1)), ceil(toInt16(13), toFloat64(0.1)), floor(toInt16(13), toFloat64(0.1));
SELECT round(toInt16(13), toInt8(-1)), ceil(toInt16(13), toInt8(-1)), floor(toInt16(13), toInt8(-1));
SELECT round(toInt16(13), toInt16(-1)), ceil(toInt16(13), toInt16(-1)), floor(toInt16(13), toInt16(-1));
SELECT round(toInt16(13), toInt32(-1)), ceil(toInt16(13), toInt32(-1)), floor(toInt16(13), toInt32(-1));
SELECT round(toInt16(13), toInt64(-1)), ceil(toInt16(13), toInt64(-1)), floor(toInt16(13), toInt64(-1));
SELECT round(toInt16(13), toFloat32(1.1)), ceil(toInt16(13), toFloat32(-1.1)), floor(toInt16(13), toFloat32(-1.1));
SELECT round(toInt16(13), toFloat64(1.1)), ceil(toInt16(13), toFloat64(-1.1)), floor(toInt16(13), toFloat64(-1.1));
SELECT round(toInt16(13), toInt8(-2)), ceil(toInt16(13), toInt8(-2)), floor(toInt16(13), toInt8(-2));
SELECT round(toInt16(13), toInt16(-2)), ceil(toInt16(13), toInt16(-2)), floor(toInt16(13), toInt16(-2));
SELECT round(toInt16(13), toInt32(-2)), ceil(toInt16(13), toInt32(-2)), floor(toInt16(13), toInt32(-2));
SELECT round(toInt16(13), toInt64(-2)), ceil(toInt16(13), toInt64(-2)), floor(toInt16(13), toInt64(-2));
SELECT round(toInt16(13), toFloat32(-2.1)), ceil(toInt16(13), toFloat32(-2.1)), floor(toInt16(13), toFloat32(-2.1));
SELECT round(toInt16(13), toFloat64(-2.1)), ceil(toInt16(13), toFloat64(-2.1)), floor(toInt16(13), toFloat64(-2.1));
/* Int32 */
SELECT round(toInt32(13), toUInt8(2)), ceil(toInt32(13), toUInt8(2)), floor(toInt32(13), toUInt8(2));
SELECT round(toInt32(13), toUInt16(2)), ceil(toInt32(13), toUInt16(2)), floor(toInt32(13), toUInt16(2));
SELECT round(toInt32(13), toUInt32(2)), ceil(toInt32(13), toUInt32(2)), floor(toInt32(13), toUInt32(2));
SELECT round(toInt32(13), toUInt64(2)), ceil(toInt32(13), toUInt64(2)), floor(toInt32(13), toUInt64(2));
SELECT round(toInt32(13), toInt8(2)), ceil(toInt32(13), toInt8(2)), floor(toInt32(13), toInt8(2));
SELECT round(toInt32(13), toInt16(2)), ceil(toInt32(13), toInt16(2)), floor(toInt32(13), toInt16(2));
SELECT round(toInt32(13), toInt32(2)), ceil(toInt32(13), toInt32(2)), floor(toInt32(13), toInt32(2));
SELECT round(toInt32(13), toInt64(2)), ceil(toInt32(13), toInt64(2)), floor(toInt32(13), toInt64(2));
SELECT round(toInt32(13), toFloat32(2.1)), ceil(toInt32(13), toFloat32(2.1)), floor(toInt32(13), toFloat32(2.1));
SELECT round(toInt32(13), toFloat64(2.1)), ceil(toInt32(13), toFloat64(2.1)), floor(toInt32(13), toFloat64(2.1));
SELECT round(toInt32(13), toUInt8(1)), ceil(toInt32(13), toUInt8(1)), floor(toInt32(13), toUInt8(1));
SELECT round(toInt32(13), toUInt16(1)), ceil(toInt32(13), toUInt16(1)), floor(toInt32(13), toUInt16(1));
SELECT round(toInt32(13), toUInt32(1)), ceil(toInt32(13), toUInt32(1)), floor(toInt32(13), toUInt32(1));
SELECT round(toInt32(13), toUInt64(1)), ceil(toInt32(13), toUInt64(1)), floor(toInt32(13), toUInt64(1));
SELECT round(toInt32(13), toInt8(1)), ceil(toInt32(13), toInt8(1)), floor(toInt32(13), toInt8(1));
SELECT round(toInt32(13), toInt16(1)), ceil(toInt32(13), toInt16(1)), floor(toInt32(13), toInt16(1));
SELECT round(toInt32(13), toInt32(1)), ceil(toInt32(13), toInt32(1)), floor(toInt32(13), toInt32(1));
SELECT round(toInt32(13), toInt64(1)), ceil(toInt32(13), toInt64(1)), floor(toInt32(13), toInt64(1));
SELECT round(toInt32(13), toFloat32(1.1)), ceil(toInt32(13), toFloat32(1.1)), floor(toInt32(13), toFloat32(1.1));
SELECT round(toInt32(13), toFloat64(1.1)), ceil(toInt32(13), toFloat64(1.1)), floor(toInt32(13), toFloat64(1.1));
SELECT round(toInt32(13), toUInt16(0)), ceil(toInt32(13), toUInt16(0)), floor(toInt32(13), toUInt16(0));
SELECT round(toInt32(13), toUInt32(0)), ceil(toInt32(13), toUInt32(0)), floor(toInt32(13), toUInt32(0));
SELECT round(toInt32(13), toUInt64(0)), ceil(toInt32(13), toUInt64(0)), floor(toInt32(13), toUInt64(0));
SELECT round(toInt32(13), toInt8(0)), ceil(toInt32(13), toInt8(0)), floor(toInt32(13), toInt8(0));
SELECT round(toInt32(13), toInt16(0)), ceil(toInt32(13), toInt16(0)), floor(toInt32(13), toInt16(0));
SELECT round(toInt32(13), toInt32(0)), ceil(toInt32(13), toInt32(0)), floor(toInt32(13), toInt32(0));
SELECT round(toInt32(13), toInt64(0)), ceil(toInt32(13), toInt64(0)), floor(toInt32(13), toInt64(0));
SELECT round(toInt32(13), toFloat32(0.1)), ceil(toInt32(13), toFloat32(0.1)), floor(toInt32(13), toFloat32(0.1));
SELECT round(toInt32(13), toFloat64(0.1)), ceil(toInt32(13), toFloat64(0.1)), floor(toInt32(13), toFloat64(0.1));
SELECT round(toInt32(13), toInt8(-1)), ceil(toInt32(13), toInt8(-1)), floor(toInt32(13), toInt8(-1));
SELECT round(toInt32(13), toInt16(-1)), ceil(toInt32(13), toInt16(-1)), floor(toInt32(13), toInt16(-1));
SELECT round(toInt32(13), toInt32(-1)), ceil(toInt32(13), toInt32(-1)), floor(toInt32(13), toInt32(-1));
SELECT round(toInt32(13), toInt64(-1)), ceil(toInt32(13), toInt64(-1)), floor(toInt32(13), toInt64(-1));
SELECT round(toInt32(13), toFloat32(1.1)), ceil(toInt32(13), toFloat32(-1.1)), floor(toInt32(13), toFloat32(-1.1));
SELECT round(toInt32(13), toFloat64(1.1)), ceil(toInt32(13), toFloat64(-1.1)), floor(toInt32(13), toFloat64(-1.1));
SELECT round(toInt32(13), toInt8(-2)), ceil(toInt32(13), toInt8(-2)), floor(toInt32(13), toInt8(-2));
SELECT round(toInt32(13), toInt16(-2)), ceil(toInt32(13), toInt16(-2)), floor(toInt32(13), toInt16(-2));
SELECT round(toInt32(13), toInt32(-2)), ceil(toInt32(13), toInt32(-2)), floor(toInt32(13), toInt32(-2));
SELECT round(toInt32(13), toInt64(-2)), ceil(toInt32(13), toInt64(-2)), floor(toInt32(13), toInt64(-2));
SELECT round(toInt32(13), toFloat32(-2.1)), ceil(toInt32(13), toFloat32(-2.1)), floor(toInt32(13), toFloat32(-2.1));
SELECT round(toInt32(13), toFloat64(-2.1)), ceil(toInt32(13), toFloat64(-2.1)), floor(toInt32(13), toFloat64(-2.1));
/* Int64 */
SELECT round(toInt64(13), toUInt8(2)), ceil(toInt64(13), toUInt8(2)), floor(toInt64(13), toUInt8(2));
SELECT round(toInt64(13), toUInt16(2)), ceil(toInt64(13), toUInt16(2)), floor(toInt64(13), toUInt16(2));
SELECT round(toInt64(13), toUInt32(2)), ceil(toInt64(13), toUInt32(2)), floor(toInt64(13), toUInt32(2));
SELECT round(toInt64(13), toUInt64(2)), ceil(toInt64(13), toUInt64(2)), floor(toInt64(13), toUInt64(2));
SELECT round(toInt64(13), toInt8(2)), ceil(toInt64(13), toInt8(2)), floor(toInt64(13), toInt8(2));
SELECT round(toInt64(13), toInt16(2)), ceil(toInt64(13), toInt16(2)), floor(toInt64(13), toInt16(2));
SELECT round(toInt64(13), toInt32(2)), ceil(toInt64(13), toInt32(2)), floor(toInt64(13), toInt32(2));
SELECT round(toInt64(13), toInt64(2)), ceil(toInt64(13), toInt64(2)), floor(toInt64(13), toInt64(2));
SELECT round(toInt64(13), toFloat32(2.1)), ceil(toInt64(13), toFloat32(2.1)), floor(toInt64(13), toFloat32(2.1));
SELECT round(toInt64(13), toFloat64(2.1)), ceil(toInt64(13), toFloat64(2.1)), floor(toInt64(13), toFloat64(2.1));
SELECT round(toInt64(13), toUInt8(1)), ceil(toInt64(13), toUInt8(1)), floor(toInt64(13), toUInt8(1));
SELECT round(toInt64(13), toUInt16(1)), ceil(toInt64(13), toUInt16(1)), floor(toInt64(13), toUInt16(1));
SELECT round(toInt64(13), toUInt32(1)), ceil(toInt64(13), toUInt32(1)), floor(toInt64(13), toUInt32(1));
SELECT round(toInt64(13), toUInt64(1)), ceil(toInt64(13), toUInt64(1)), floor(toInt64(13), toUInt64(1));
SELECT round(toInt64(13), toInt8(1)), ceil(toInt64(13), toInt8(1)), floor(toInt64(13), toInt8(1));
SELECT round(toInt64(13), toInt16(1)), ceil(toInt64(13), toInt16(1)), floor(toInt64(13), toInt16(1));
SELECT round(toInt64(13), toInt32(1)), ceil(toInt64(13), toInt32(1)), floor(toInt64(13), toInt32(1));
SELECT round(toInt64(13), toInt64(1)), ceil(toInt64(13), toInt64(1)), floor(toInt64(13), toInt64(1));
SELECT round(toInt64(13), toFloat32(1.1)), ceil(toInt64(13), toFloat32(1.1)), floor(toInt64(13), toFloat32(1.1));
SELECT round(toInt64(13), toFloat64(1.1)), ceil(toInt64(13), toFloat64(1.1)), floor(toInt64(13), toFloat64(1.1));
SELECT round(toInt64(13), toUInt16(0)), ceil(toInt64(13), toUInt16(0)), floor(toInt64(13), toUInt16(0));
SELECT round(toInt64(13), toUInt32(0)), ceil(toInt64(13), toUInt32(0)), floor(toInt64(13), toUInt32(0));
SELECT round(toInt64(13), toUInt64(0)), ceil(toInt64(13), toUInt64(0)), floor(toInt64(13), toUInt64(0));
SELECT round(toInt64(13), toInt8(0)), ceil(toInt64(13), toInt8(0)), floor(toInt64(13), toInt8(0));
SELECT round(toInt64(13), toInt16(0)), ceil(toInt64(13), toInt16(0)), floor(toInt64(13), toInt16(0));
SELECT round(toInt64(13), toInt32(0)), ceil(toInt64(13), toInt32(0)), floor(toInt64(13), toInt32(0));
SELECT round(toInt64(13), toInt64(0)), ceil(toInt64(13), toInt64(0)), floor(toInt64(13), toInt64(0));
SELECT round(toInt64(13), toFloat32(0.1)), ceil(toInt64(13), toFloat32(0.1)), floor(toInt64(13), toFloat32(0.1));
SELECT round(toInt64(13), toFloat64(0.1)), ceil(toInt64(13), toFloat64(0.1)), floor(toInt64(13), toFloat64(0.1));
SELECT round(toInt64(13), toInt8(-1)), ceil(toInt64(13), toInt8(-1)), floor(toInt64(13), toInt8(-1));
SELECT round(toInt64(13), toInt16(-1)), ceil(toInt64(13), toInt16(-1)), floor(toInt64(13), toInt16(-1));
SELECT round(toInt64(13), toInt32(-1)), ceil(toInt64(13), toInt32(-1)), floor(toInt64(13), toInt32(-1));
SELECT round(toInt64(13), toInt64(-1)), ceil(toInt64(13), toInt64(-1)), floor(toInt64(13), toInt64(-1));
SELECT round(toInt64(13), toFloat32(1.1)), ceil(toInt64(13), toFloat32(-1.1)), floor(toInt64(13), toFloat32(-1.1));
SELECT round(toInt64(13), toFloat64(1.1)), ceil(toInt64(13), toFloat64(-1.1)), floor(toInt64(13), toFloat64(-1.1));
SELECT round(toInt64(13), toInt8(-2)), ceil(toInt64(13), toInt8(-2)), floor(toInt64(13), toInt8(-2));
SELECT round(toInt64(13), toInt16(-2)), ceil(toInt64(13), toInt16(-2)), floor(toInt64(13), toInt16(-2));
SELECT round(toInt64(13), toInt32(-2)), ceil(toInt64(13), toInt32(-2)), floor(toInt64(13), toInt32(-2));
SELECT round(toInt64(13), toInt64(-2)), ceil(toInt64(13), toInt64(-2)), floor(toInt64(13), toInt64(-2));
SELECT round(toInt64(13), toFloat32(-2.1)), ceil(toInt64(13), toFloat32(-2.1)), floor(toInt64(13), toFloat32(-2.1));
SELECT round(toInt64(13), toFloat64(-2.1)), ceil(toInt64(13), toFloat64(-2.1)), floor(toInt64(13), toFloat64(-2.1));
/* Float32 */
SELECT round(toFloat32(13), toUInt8(2)), ceil(toFloat32(13), toUInt8(2)), floor(toFloat32(13), toUInt8(2));
SELECT round(toFloat32(13), toUInt16(2)), ceil(toFloat32(13), toUInt16(2)), floor(toFloat32(13), toUInt16(2));
SELECT round(toFloat32(13), toUInt32(2)), ceil(toFloat32(13), toUInt32(2)), floor(toFloat32(13), toUInt32(2));
SELECT round(toFloat32(13), toUInt64(2)), ceil(toFloat32(13), toUInt64(2)), floor(toFloat32(13), toUInt64(2));
SELECT round(toFloat32(13), toInt8(2)), ceil(toFloat32(13), toInt8(2)), floor(toFloat32(13), toInt8(2));
SELECT round(toFloat32(13), toInt16(2)), ceil(toFloat32(13), toInt16(2)), floor(toFloat32(13), toInt16(2));
SELECT round(toFloat32(13), toInt32(2)), ceil(toFloat32(13), toInt32(2)), floor(toFloat32(13), toInt32(2));
SELECT round(toFloat32(13), toInt64(2)), ceil(toFloat32(13), toInt64(2)), floor(toFloat32(13), toInt64(2));
SELECT round(toFloat32(13), toFloat32(2.1)), ceil(toFloat32(13), toFloat32(2.1)), floor(toFloat32(13), toFloat32(2.1));
SELECT round(toFloat32(13), toFloat64(2.1)), ceil(toFloat32(13), toFloat64(2.1)), floor(toFloat32(13), toFloat64(2.1));
SELECT round(toFloat32(13), toUInt8(1)), ceil(toFloat32(13), toUInt8(1)), floor(toFloat32(13), toUInt8(1));
SELECT round(toFloat32(13), toUInt16(1)), ceil(toFloat32(13), toUInt16(1)), floor(toFloat32(13), toUInt16(1));
SELECT round(toFloat32(13), toUInt32(1)), ceil(toFloat32(13), toUInt32(1)), floor(toFloat32(13), toUInt32(1));
SELECT round(toFloat32(13), toUInt64(1)), ceil(toFloat32(13), toUInt64(1)), floor(toFloat32(13), toUInt64(1));
SELECT round(toFloat32(13), toInt8(1)), ceil(toFloat32(13), toInt8(1)), floor(toFloat32(13), toInt8(1));
SELECT round(toFloat32(13), toInt16(1)), ceil(toFloat32(13), toInt16(1)), floor(toFloat32(13), toInt16(1));
SELECT round(toFloat32(13), toInt32(1)), ceil(toFloat32(13), toInt32(1)), floor(toFloat32(13), toInt32(1));
SELECT round(toFloat32(13), toInt64(1)), ceil(toFloat32(13), toInt64(1)), floor(toFloat32(13), toInt64(1));
SELECT round(toFloat32(13), toFloat32(1.1)), ceil(toFloat32(13), toFloat32(1.1)), floor(toFloat32(13), toFloat32(1.1));
SELECT round(toFloat32(13), toFloat64(1.1)), ceil(toFloat32(13), toFloat64(1.1)), floor(toFloat32(13), toFloat64(1.1));
SELECT round(toFloat32(13), toUInt16(0)), ceil(toFloat32(13), toUInt16(0)), floor(toFloat32(13), toUInt16(0));
SELECT round(toFloat32(13), toUInt32(0)), ceil(toFloat32(13), toUInt32(0)), floor(toFloat32(13), toUInt32(0));
SELECT round(toFloat32(13), toUInt64(0)), ceil(toFloat32(13), toUInt64(0)), floor(toFloat32(13), toUInt64(0));
SELECT round(toFloat32(13), toInt8(0)), ceil(toFloat32(13), toInt8(0)), floor(toFloat32(13), toInt8(0));
SELECT round(toFloat32(13), toInt16(0)), ceil(toFloat32(13), toInt16(0)), floor(toFloat32(13), toInt16(0));
SELECT round(toFloat32(13), toInt32(0)), ceil(toFloat32(13), toInt32(0)), floor(toFloat32(13), toInt32(0));
SELECT round(toFloat32(13), toInt64(0)), ceil(toFloat32(13), toInt64(0)), floor(toFloat32(13), toInt64(0));
SELECT round(toFloat32(13), toFloat32(0.1)), ceil(toFloat32(13), toFloat32(0.1)), floor(toFloat32(13), toFloat32(0.1));
SELECT round(toFloat32(13), toFloat64(0.1)), ceil(toFloat32(13), toFloat64(0.1)), floor(toFloat32(13), toFloat64(0.1));
SELECT round(toFloat32(13), toInt8(-1)), ceil(toFloat32(13), toInt8(-1)), floor(toFloat32(13), toInt8(-1));
SELECT round(toFloat32(13), toInt16(-1)), ceil(toFloat32(13), toInt16(-1)), floor(toFloat32(13), toInt16(-1));
SELECT round(toFloat32(13), toInt32(-1)), ceil(toFloat32(13), toInt32(-1)), floor(toFloat32(13), toInt32(-1));
SELECT round(toFloat32(13), toInt64(-1)), ceil(toFloat32(13), toInt64(-1)), floor(toFloat32(13), toInt64(-1));
SELECT round(toFloat32(13), toFloat32(1.1)), ceil(toFloat32(13), toFloat32(-1.1)), floor(toFloat32(13), toFloat32(-1.1));
SELECT round(toFloat32(13), toFloat64(1.1)), ceil(toFloat32(13), toFloat64(-1.1)), floor(toFloat32(13), toFloat64(-1.1));
SELECT round(toFloat32(13), toInt8(-2)), ceil(toFloat32(13), toInt8(-2)), floor(toFloat32(13), toInt8(-2));
SELECT round(toFloat32(13), toInt16(-2)), ceil(toFloat32(13), toInt16(-2)), floor(toFloat32(13), toInt16(-2));
SELECT round(toFloat32(13), toInt32(-2)), ceil(toFloat32(13), toInt32(-2)), floor(toFloat32(13), toInt32(-2));
SELECT round(toFloat32(13), toInt64(-2)), ceil(toFloat32(13), toInt64(-2)), floor(toFloat32(13), toInt64(-2));
SELECT round(toFloat32(13), toFloat32(-2.1)), ceil(toFloat32(13), toFloat32(-2.1)), floor(toFloat32(13), toFloat32(-2.1));
SELECT round(toFloat32(13), toFloat64(-2.1)), ceil(toFloat32(13), toFloat64(-2.1)), floor(toFloat32(13), toFloat64(-2.1));
/* Float64 */
SELECT round(toFloat64(13), toUInt8(2)), ceil(toFloat64(13), toUInt8(2)), floor(toFloat64(13), toUInt8(2));
SELECT round(toFloat64(13), toUInt16(2)), ceil(toFloat64(13), toUInt16(2)), floor(toFloat64(13), toUInt16(2));
SELECT round(toFloat64(13), toUInt32(2)), ceil(toFloat64(13), toUInt32(2)), floor(toFloat64(13), toUInt32(2));
SELECT round(toFloat64(13), toUInt64(2)), ceil(toFloat64(13), toUInt64(2)), floor(toFloat64(13), toUInt64(2));
SELECT round(toFloat64(13), toInt8(2)), ceil(toFloat64(13), toInt8(2)), floor(toFloat64(13), toInt8(2));
SELECT round(toFloat64(13), toInt16(2)), ceil(toFloat64(13), toInt16(2)), floor(toFloat64(13), toInt16(2));
SELECT round(toFloat64(13), toInt32(2)), ceil(toFloat64(13), toInt32(2)), floor(toFloat64(13), toInt32(2));
SELECT round(toFloat64(13), toInt64(2)), ceil(toFloat64(13), toInt64(2)), floor(toFloat64(13), toInt64(2));
SELECT round(toFloat64(13), toFloat32(2.1)), ceil(toFloat64(13), toFloat32(2.1)), floor(toFloat64(13), toFloat32(2.1));
SELECT round(toFloat64(13), toFloat64(2.1)), ceil(toFloat64(13), toFloat64(2.1)), floor(toFloat64(13), toFloat64(2.1));
SELECT round(toFloat64(13), toUInt8(1)), ceil(toFloat64(13), toUInt8(1)), floor(toFloat64(13), toUInt8(1));
SELECT round(toFloat64(13), toUInt16(1)), ceil(toFloat64(13), toUInt16(1)), floor(toFloat64(13), toUInt16(1));
SELECT round(toFloat64(13), toUInt32(1)), ceil(toFloat64(13), toUInt32(1)), floor(toFloat64(13), toUInt32(1));
SELECT round(toFloat64(13), toUInt64(1)), ceil(toFloat64(13), toUInt64(1)), floor(toFloat64(13), toUInt64(1));
SELECT round(toFloat64(13), toInt8(1)), ceil(toFloat64(13), toInt8(1)), floor(toFloat64(13), toInt8(1));
SELECT round(toFloat64(13), toInt16(1)), ceil(toFloat64(13), toInt16(1)), floor(toFloat64(13), toInt16(1));
SELECT round(toFloat64(13), toInt32(1)), ceil(toFloat64(13), toInt32(1)), floor(toFloat64(13), toInt32(1));
SELECT round(toFloat64(13), toInt64(1)), ceil(toFloat64(13), toInt64(1)), floor(toFloat64(13), toInt64(1));
SELECT round(toFloat64(13), toFloat32(1.1)), ceil(toFloat64(13), toFloat32(1.1)), floor(toFloat64(13), toFloat32(1.1));
SELECT round(toFloat64(13), toFloat64(1.1)), ceil(toFloat64(13), toFloat64(1.1)), floor(toFloat64(13), toFloat64(1.1));
SELECT round(toFloat64(13), toUInt16(0)), ceil(toFloat64(13), toUInt16(0)), floor(toFloat64(13), toUInt16(0));
SELECT round(toFloat64(13), toUInt32(0)), ceil(toFloat64(13), toUInt32(0)), floor(toFloat64(13), toUInt32(0));
SELECT round(toFloat64(13), toUInt64(0)), ceil(toFloat64(13), toUInt64(0)), floor(toFloat64(13), toUInt64(0));
SELECT round(toFloat64(13), toInt8(0)), ceil(toFloat64(13), toInt8(0)), floor(toFloat64(13), toInt8(0));
SELECT round(toFloat64(13), toInt16(0)), ceil(toFloat64(13), toInt16(0)), floor(toFloat64(13), toInt16(0));
SELECT round(toFloat64(13), toInt32(0)), ceil(toFloat64(13), toInt32(0)), floor(toFloat64(13), toInt32(0));
SELECT round(toFloat64(13), toInt64(0)), ceil(toFloat64(13), toInt64(0)), floor(toFloat64(13), toInt64(0));
SELECT round(toFloat64(13), toFloat32(0.1)), ceil(toFloat64(13), toFloat32(0.1)), floor(toFloat64(13), toFloat32(0.1));
SELECT round(toFloat64(13), toFloat64(0.1)), ceil(toFloat64(13), toFloat64(0.1)), floor(toFloat64(13), toFloat64(0.1));
SELECT round(toFloat64(13), toInt8(-1)), ceil(toFloat64(13), toInt8(-1)), floor(toFloat64(13), toInt8(-1));
SELECT round(toFloat64(13), toInt16(-1)), ceil(toFloat64(13), toInt16(-1)), floor(toFloat64(13), toInt16(-1));
SELECT round(toFloat64(13), toInt32(-1)), ceil(toFloat64(13), toInt32(-1)), floor(toFloat64(13), toInt32(-1));
SELECT round(toFloat64(13), toInt64(-1)), ceil(toFloat64(13), toInt64(-1)), floor(toFloat64(13), toInt64(-1));
SELECT round(toFloat64(13), toFloat32(1.1)), ceil(toFloat64(13), toFloat32(-1.1)), floor(toFloat64(13), toFloat32(-1.1));
SELECT round(toFloat64(13), toFloat64(1.1)), ceil(toFloat64(13), toFloat64(-1.1)), floor(toFloat64(13), toFloat64(-1.1));
SELECT round(toFloat64(13), toInt8(-2)), ceil(toFloat64(13), toInt8(-2)), floor(toFloat64(13), toInt8(-2));
SELECT round(toFloat64(13), toInt16(-2)), ceil(toFloat64(13), toInt16(-2)), floor(toFloat64(13), toInt16(-2));
SELECT round(toFloat64(13), toInt32(-2)), ceil(toFloat64(13), toInt32(-2)), floor(toFloat64(13), toInt32(-2));
SELECT round(toFloat64(13), toInt64(-2)), ceil(toFloat64(13), toInt64(-2)), floor(toFloat64(13), toInt64(-2));
SELECT round(toFloat64(13), toFloat32(-2.1)), ceil(toFloat64(13), toFloat32(-2.1)), floor(toFloat64(13), toFloat32(-2.1));
SELECT round(toFloat64(13), toFloat64(-2.1)), ceil(toFloat64(13), toFloat64(-2.1)), floor(toFloat64(13), toFloat64(-2.1));
/* Отрицательное значение */
/* Int8 */
SELECT round(toInt8(-13), toUInt8(2)), ceil(toInt8(-13), toUInt8(2)), floor(toInt8(-13), toUInt8(2));
SELECT round(toInt8(-13), toUInt16(2)), ceil(toInt8(-13), toUInt16(2)), floor(toInt8(-13), toUInt16(2));
SELECT round(toInt8(-13), toUInt32(2)), ceil(toInt8(-13), toUInt32(2)), floor(toInt8(-13), toUInt32(2));
SELECT round(toInt8(-13), toUInt64(2)), ceil(toInt8(-13), toUInt64(2)), floor(toInt8(-13), toUInt64(2));
SELECT round(toInt8(-13), toInt8(2)), ceil(toInt8(-13), toInt8(2)), floor(toInt8(-13), toInt8(2));
SELECT round(toInt8(-13), toInt16(2)), ceil(toInt8(-13), toInt16(2)), floor(toInt8(-13), toInt16(2));
SELECT round(toInt8(-13), toInt32(2)), ceil(toInt8(-13), toInt32(2)), floor(toInt8(-13), toInt32(2));
SELECT round(toInt8(-13), toInt64(2)), ceil(toInt8(-13), toInt64(2)), floor(toInt8(-13), toInt64(2));
SELECT round(toInt8(-13), toFloat32(2.1)), ceil(toInt8(-13), toFloat32(2.1)), floor(toInt8(-13), toFloat32(2.1));
SELECT round(toInt8(-13), toFloat64(2.1)), ceil(toInt8(-13), toFloat64(2.1)), floor(toInt8(-13), toFloat64(2.1));
SELECT round(toInt8(-13), toUInt8(1)), ceil(toInt8(-13), toUInt8(1)), floor(toInt8(-13), toUInt8(1));
SELECT round(toInt8(-13), toUInt16(1)), ceil(toInt8(-13), toUInt16(1)), floor(toInt8(-13), toUInt16(1));
SELECT round(toInt8(-13), toUInt32(1)), ceil(toInt8(-13), toUInt32(1)), floor(toInt8(-13), toUInt32(1));
SELECT round(toInt8(-13), toUInt64(1)), ceil(toInt8(-13), toUInt64(1)), floor(toInt8(-13), toUInt64(1));
SELECT round(toInt8(-13), toInt8(1)), ceil(toInt8(-13), toInt8(1)), floor(toInt8(-13), toInt8(1));
SELECT round(toInt8(-13), toInt16(1)), ceil(toInt8(-13), toInt16(1)), floor(toInt8(-13), toInt16(1));
SELECT round(toInt8(-13), toInt32(1)), ceil(toInt8(-13), toInt32(1)), floor(toInt8(-13), toInt32(1));
SELECT round(toInt8(-13), toInt64(1)), ceil(toInt8(-13), toInt64(1)), floor(toInt8(-13), toInt64(1));
SELECT round(toInt8(-13), toFloat32(1.1)), ceil(toInt8(-13), toFloat32(1.1)), floor(toInt8(-13), toFloat32(1.1));
SELECT round(toInt8(-13), toFloat64(1.1)), ceil(toInt8(-13), toFloat64(1.1)), floor(toInt8(-13), toFloat64(1.1));
SELECT round(toInt8(-13), toUInt16(0)), ceil(toInt8(-13), toUInt16(0)), floor(toInt8(-13), toUInt16(0));
SELECT round(toInt8(-13), toUInt32(0)), ceil(toInt8(-13), toUInt32(0)), floor(toInt8(-13), toUInt32(0));
SELECT round(toInt8(-13), toUInt64(0)), ceil(toInt8(-13), toUInt64(0)), floor(toInt8(-13), toUInt64(0));
SELECT round(toInt8(-13), toInt8(0)), ceil(toInt8(-13), toInt8(0)), floor(toInt8(-13), toInt8(0));
SELECT round(toInt8(-13), toInt16(0)), ceil(toInt8(-13), toInt16(0)), floor(toInt8(-13), toInt16(0));
SELECT round(toInt8(-13), toInt32(0)), ceil(toInt8(-13), toInt32(0)), floor(toInt8(-13), toInt32(0));
SELECT round(toInt8(-13), toInt64(0)), ceil(toInt8(-13), toInt64(0)), floor(toInt8(-13), toInt64(0));
SELECT round(toInt8(-13), toFloat32(0.1)), ceil(toInt8(-13), toFloat32(0.1)), floor(toInt8(-13), toFloat32(0.1));
SELECT round(toInt8(-13), toFloat64(0.1)), ceil(toInt8(-13), toFloat64(0.1)), floor(toInt8(-13), toFloat64(0.1));
SELECT round(toInt8(-13), toInt8(-1)), ceil(toInt8(-13), toInt8(-1)), floor(toInt8(-13), toInt8(-1));
SELECT round(toInt8(-13), toInt16(-1)), ceil(toInt8(-13), toInt16(-1)), floor(toInt8(-13), toInt16(-1));
SELECT round(toInt8(-13), toInt32(-1)), ceil(toInt8(-13), toInt32(-1)), floor(toInt8(-13), toInt32(-1));
SELECT round(toInt8(-13), toInt64(-1)), ceil(toInt8(-13), toInt64(-1)), floor(toInt8(-13), toInt64(-1));
SELECT round(toInt8(-13), toFloat32(1.1)), ceil(toInt8(-13), toFloat32(-1.1)), floor(toInt8(-13), toFloat32(-1.1));
SELECT round(toInt8(-13), toFloat64(1.1)), ceil(toInt8(-13), toFloat64(-1.1)), floor(toInt8(-13), toFloat64(-1.1));
SELECT round(toInt8(-13), toInt8(-2)), ceil(toInt8(-13), toInt8(-2)), floor(toInt8(-13), toInt8(-2));
SELECT round(toInt8(-13), toInt16(-2)), ceil(toInt8(-13), toInt16(-2)), floor(toInt8(-13), toInt16(-2));
SELECT round(toInt8(-13), toInt32(-2)), ceil(toInt8(-13), toInt32(-2)), floor(toInt8(-13), toInt32(-2));
SELECT round(toInt8(-13), toInt64(-2)), ceil(toInt8(-13), toInt64(-2)), floor(toInt8(-13), toInt64(-2));
SELECT round(toInt8(-13), toFloat32(-2.1)), ceil(toInt8(-13), toFloat32(-2.1)), floor(toInt8(-13), toFloat32(-2.1));
SELECT round(toInt8(-13), toFloat64(-2.1)), ceil(toInt8(-13), toFloat64(-2.1)), floor(toInt8(-13), toFloat64(-2.1));
/* Int16 */
SELECT round(toInt16(-13), toUInt8(2)), ceil(toInt16(-13), toUInt8(2)), floor(toInt16(-13), toUInt8(2));
SELECT round(toInt16(-13), toUInt16(2)), ceil(toInt16(-13), toUInt16(2)), floor(toInt16(-13), toUInt16(2));
SELECT round(toInt16(-13), toUInt32(2)), ceil(toInt16(-13), toUInt32(2)), floor(toInt16(-13), toUInt32(2));
SELECT round(toInt16(-13), toUInt64(2)), ceil(toInt16(-13), toUInt64(2)), floor(toInt16(-13), toUInt64(2));
SELECT round(toInt16(-13), toInt8(2)), ceil(toInt16(-13), toInt8(2)), floor(toInt16(-13), toInt8(2));
SELECT round(toInt16(-13), toInt16(2)), ceil(toInt16(-13), toInt16(2)), floor(toInt16(-13), toInt16(2));
SELECT round(toInt16(-13), toInt32(2)), ceil(toInt16(-13), toInt32(2)), floor(toInt16(-13), toInt32(2));
SELECT round(toInt16(-13), toInt64(2)), ceil(toInt16(-13), toInt64(2)), floor(toInt16(-13), toInt64(2));
SELECT round(toInt16(-13), toFloat32(2.1)), ceil(toInt16(-13), toFloat32(2.1)), floor(toInt16(-13), toFloat32(2.1));
SELECT round(toInt16(-13), toFloat64(2.1)), ceil(toInt16(-13), toFloat64(2.1)), floor(toInt16(-13), toFloat64(2.1));
SELECT round(toInt16(-13), toUInt8(1)), ceil(toInt16(-13), toUInt8(1)), floor(toInt16(-13), toUInt8(1));
SELECT round(toInt16(-13), toUInt16(1)), ceil(toInt16(-13), toUInt16(1)), floor(toInt16(-13), toUInt16(1));
SELECT round(toInt16(-13), toUInt32(1)), ceil(toInt16(-13), toUInt32(1)), floor(toInt16(-13), toUInt32(1));
SELECT round(toInt16(-13), toUInt64(1)), ceil(toInt16(-13), toUInt64(1)), floor(toInt16(-13), toUInt64(1));
SELECT round(toInt16(-13), toInt8(1)), ceil(toInt16(-13), toInt8(1)), floor(toInt16(-13), toInt8(1));
SELECT round(toInt16(-13), toInt16(1)), ceil(toInt16(-13), toInt16(1)), floor(toInt16(-13), toInt16(1));
SELECT round(toInt16(-13), toInt32(1)), ceil(toInt16(-13), toInt32(1)), floor(toInt16(-13), toInt32(1));
SELECT round(toInt16(-13), toInt64(1)), ceil(toInt16(-13), toInt64(1)), floor(toInt16(-13), toInt64(1));
SELECT round(toInt16(-13), toFloat32(1.1)), ceil(toInt16(-13), toFloat32(1.1)), floor(toInt16(-13), toFloat32(1.1));
SELECT round(toInt16(-13), toFloat64(1.1)), ceil(toInt16(-13), toFloat64(1.1)), floor(toInt16(-13), toFloat64(1.1));
SELECT round(toInt16(-13), toUInt16(0)), ceil(toInt16(-13), toUInt16(0)), floor(toInt16(-13), toUInt16(0));
SELECT round(toInt16(-13), toUInt32(0)), ceil(toInt16(-13), toUInt32(0)), floor(toInt16(-13), toUInt32(0));
SELECT round(toInt16(-13), toUInt64(0)), ceil(toInt16(-13), toUInt64(0)), floor(toInt16(-13), toUInt64(0));
SELECT round(toInt16(-13), toInt8(0)), ceil(toInt16(-13), toInt8(0)), floor(toInt16(-13), toInt8(0));
SELECT round(toInt16(-13), toInt16(0)), ceil(toInt16(-13), toInt16(0)), floor(toInt16(-13), toInt16(0));
SELECT round(toInt16(-13), toInt32(0)), ceil(toInt16(-13), toInt32(0)), floor(toInt16(-13), toInt32(0));
SELECT round(toInt16(-13), toInt64(0)), ceil(toInt16(-13), toInt64(0)), floor(toInt16(-13), toInt64(0));
SELECT round(toInt16(-13), toFloat32(0.1)), ceil(toInt16(-13), toFloat32(0.1)), floor(toInt16(-13), toFloat32(0.1));
SELECT round(toInt16(-13), toFloat64(0.1)), ceil(toInt16(-13), toFloat64(0.1)), floor(toInt16(-13), toFloat64(0.1));
SELECT round(toInt16(-13), toInt8(-1)), ceil(toInt16(-13), toInt8(-1)), floor(toInt16(-13), toInt8(-1));
SELECT round(toInt16(-13), toInt16(-1)), ceil(toInt16(-13), toInt16(-1)), floor(toInt16(-13), toInt16(-1));
SELECT round(toInt16(-13), toInt32(-1)), ceil(toInt16(-13), toInt32(-1)), floor(toInt16(-13), toInt32(-1));
SELECT round(toInt16(-13), toInt64(-1)), ceil(toInt16(-13), toInt64(-1)), floor(toInt16(-13), toInt64(-1));
SELECT round(toInt16(-13), toFloat32(1.1)), ceil(toInt16(-13), toFloat32(-1.1)), floor(toInt16(-13), toFloat32(-1.1));
SELECT round(toInt16(-13), toFloat64(1.1)), ceil(toInt16(-13), toFloat64(-1.1)), floor(toInt16(-13), toFloat64(-1.1));
SELECT round(toInt16(-13), toInt8(-2)), ceil(toInt16(-13), toInt8(-2)), floor(toInt16(-13), toInt8(-2));
SELECT round(toInt16(-13), toInt16(-2)), ceil(toInt16(-13), toInt16(-2)), floor(toInt16(-13), toInt16(-2));
SELECT round(toInt16(-13), toInt32(-2)), ceil(toInt16(-13), toInt32(-2)), floor(toInt16(-13), toInt32(-2));
SELECT round(toInt16(-13), toInt64(-2)), ceil(toInt16(-13), toInt64(-2)), floor(toInt16(-13), toInt64(-2));
SELECT round(toInt16(-13), toFloat32(-2.1)), ceil(toInt16(-13), toFloat32(-2.1)), floor(toInt16(-13), toFloat32(-2.1));
SELECT round(toInt16(-13), toFloat64(-2.1)), ceil(toInt16(-13), toFloat64(-2.1)), floor(toInt16(-13), toFloat64(-2.1));
/* Int32 */
SELECT round(toInt32(-13), toUInt8(2)), ceil(toInt32(-13), toUInt8(2)), floor(toInt32(-13), toUInt8(2));
SELECT round(toInt32(-13), toUInt16(2)), ceil(toInt32(-13), toUInt16(2)), floor(toInt32(-13), toUInt16(2));
SELECT round(toInt32(-13), toUInt32(2)), ceil(toInt32(-13), toUInt32(2)), floor(toInt32(-13), toUInt32(2));
SELECT round(toInt32(-13), toUInt64(2)), ceil(toInt32(-13), toUInt64(2)), floor(toInt32(-13), toUInt64(2));
SELECT round(toInt32(-13), toInt8(2)), ceil(toInt32(-13), toInt8(2)), floor(toInt32(-13), toInt8(2));
SELECT round(toInt32(-13), toInt16(2)), ceil(toInt32(-13), toInt16(2)), floor(toInt32(-13), toInt16(2));
SELECT round(toInt32(-13), toInt32(2)), ceil(toInt32(-13), toInt32(2)), floor(toInt32(-13), toInt32(2));
SELECT round(toInt32(-13), toInt64(2)), ceil(toInt32(-13), toInt64(2)), floor(toInt32(-13), toInt64(2));
SELECT round(toInt32(-13), toFloat32(2.1)), ceil(toInt32(-13), toFloat32(2.1)), floor(toInt32(-13), toFloat32(2.1));
SELECT round(toInt32(-13), toFloat64(2.1)), ceil(toInt32(-13), toFloat64(2.1)), floor(toInt32(-13), toFloat64(2.1));
SELECT round(toInt32(-13), toUInt8(1)), ceil(toInt32(-13), toUInt8(1)), floor(toInt32(-13), toUInt8(1));
SELECT round(toInt32(-13), toUInt16(1)), ceil(toInt32(-13), toUInt16(1)), floor(toInt32(-13), toUInt16(1));
SELECT round(toInt32(-13), toUInt32(1)), ceil(toInt32(-13), toUInt32(1)), floor(toInt32(-13), toUInt32(1));
SELECT round(toInt32(-13), toUInt64(1)), ceil(toInt32(-13), toUInt64(1)), floor(toInt32(-13), toUInt64(1));
SELECT round(toInt32(-13), toInt8(1)), ceil(toInt32(-13), toInt8(1)), floor(toInt32(-13), toInt8(1));
SELECT round(toInt32(-13), toInt16(1)), ceil(toInt32(-13), toInt16(1)), floor(toInt32(-13), toInt16(1));
SELECT round(toInt32(-13), toInt32(1)), ceil(toInt32(-13), toInt32(1)), floor(toInt32(-13), toInt32(1));
SELECT round(toInt32(-13), toInt64(1)), ceil(toInt32(-13), toInt64(1)), floor(toInt32(-13), toInt64(1));
SELECT round(toInt32(-13), toFloat32(1.1)), ceil(toInt32(-13), toFloat32(1.1)), floor(toInt32(-13), toFloat32(1.1));
SELECT round(toInt32(-13), toFloat64(1.1)), ceil(toInt32(-13), toFloat64(1.1)), floor(toInt32(-13), toFloat64(1.1));
SELECT round(toInt32(-13), toUInt16(0)), ceil(toInt32(-13), toUInt16(0)), floor(toInt32(-13), toUInt16(0));
SELECT round(toInt32(-13), toUInt32(0)), ceil(toInt32(-13), toUInt32(0)), floor(toInt32(-13), toUInt32(0));
SELECT round(toInt32(-13), toUInt64(0)), ceil(toInt32(-13), toUInt64(0)), floor(toInt32(-13), toUInt64(0));
SELECT round(toInt32(-13), toInt8(0)), ceil(toInt32(-13), toInt8(0)), floor(toInt32(-13), toInt8(0));
SELECT round(toInt32(-13), toInt16(0)), ceil(toInt32(-13), toInt16(0)), floor(toInt32(-13), toInt16(0));
SELECT round(toInt32(-13), toInt32(0)), ceil(toInt32(-13), toInt32(0)), floor(toInt32(-13), toInt32(0));
SELECT round(toInt32(-13), toInt64(0)), ceil(toInt32(-13), toInt64(0)), floor(toInt32(-13), toInt64(0));
SELECT round(toInt32(-13), toFloat32(0.1)), ceil(toInt32(-13), toFloat32(0.1)), floor(toInt32(-13), toFloat32(0.1));
SELECT round(toInt32(-13), toFloat64(0.1)), ceil(toInt32(-13), toFloat64(0.1)), floor(toInt32(-13), toFloat64(0.1));
SELECT round(toInt32(-13), toInt8(-1)), ceil(toInt32(-13), toInt8(-1)), floor(toInt32(-13), toInt8(-1));
SELECT round(toInt32(-13), toInt16(-1)), ceil(toInt32(-13), toInt16(-1)), floor(toInt32(-13), toInt16(-1));
SELECT round(toInt32(-13), toInt32(-1)), ceil(toInt32(-13), toInt32(-1)), floor(toInt32(-13), toInt32(-1));
SELECT round(toInt32(-13), toInt64(-1)), ceil(toInt32(-13), toInt64(-1)), floor(toInt32(-13), toInt64(-1));
SELECT round(toInt32(-13), toFloat32(1.1)), ceil(toInt32(-13), toFloat32(-1.1)), floor(toInt32(-13), toFloat32(-1.1));
SELECT round(toInt32(-13), toFloat64(1.1)), ceil(toInt32(-13), toFloat64(-1.1)), floor(toInt32(-13), toFloat64(-1.1));
SELECT round(toInt32(-13), toInt8(-2)), ceil(toInt32(-13), toInt8(-2)), floor(toInt32(-13), toInt8(-2));
SELECT round(toInt32(-13), toInt16(-2)), ceil(toInt32(-13), toInt16(-2)), floor(toInt32(-13), toInt16(-2));
SELECT round(toInt32(-13), toInt32(-2)), ceil(toInt32(-13), toInt32(-2)), floor(toInt32(-13), toInt32(-2));
SELECT round(toInt32(-13), toInt64(-2)), ceil(toInt32(-13), toInt64(-2)), floor(toInt32(-13), toInt64(-2));
SELECT round(toInt32(-13), toFloat32(-2.1)), ceil(toInt32(-13), toFloat32(-2.1)), floor(toInt32(-13), toFloat32(-2.1));
SELECT round(toInt32(-13), toFloat64(-2.1)), ceil(toInt32(-13), toFloat64(-2.1)), floor(toInt32(-13), toFloat64(-2.1));
/* Int64 */
SELECT round(toInt64(-13), toUInt8(2)), ceil(toInt64(-13), toUInt8(2)), floor(toInt64(-13), toUInt8(2));
SELECT round(toInt64(-13), toUInt16(2)), ceil(toInt64(-13), toUInt16(2)), floor(toInt64(-13), toUInt16(2));
SELECT round(toInt64(-13), toUInt32(2)), ceil(toInt64(-13), toUInt32(2)), floor(toInt64(-13), toUInt32(2));
SELECT round(toInt64(-13), toUInt64(2)), ceil(toInt64(-13), toUInt64(2)), floor(toInt64(-13), toUInt64(2));
SELECT round(toInt64(-13), toInt8(2)), ceil(toInt64(-13), toInt8(2)), floor(toInt64(-13), toInt8(2));
SELECT round(toInt64(-13), toInt16(2)), ceil(toInt64(-13), toInt16(2)), floor(toInt64(-13), toInt16(2));
SELECT round(toInt64(-13), toInt32(2)), ceil(toInt64(-13), toInt32(2)), floor(toInt64(-13), toInt32(2));
SELECT round(toInt64(-13), toInt64(2)), ceil(toInt64(-13), toInt64(2)), floor(toInt64(-13), toInt64(2));
SELECT round(toInt64(-13), toFloat32(2.1)), ceil(toInt64(-13), toFloat32(2.1)), floor(toInt64(-13), toFloat32(2.1));
SELECT round(toInt64(-13), toFloat64(2.1)), ceil(toInt64(-13), toFloat64(2.1)), floor(toInt64(-13), toFloat64(2.1));
SELECT round(toInt64(-13), toUInt8(1)), ceil(toInt64(-13), toUInt8(1)), floor(toInt64(-13), toUInt8(1));
SELECT round(toInt64(-13), toUInt16(1)), ceil(toInt64(-13), toUInt16(1)), floor(toInt64(-13), toUInt16(1));
SELECT round(toInt64(-13), toUInt32(1)), ceil(toInt64(-13), toUInt32(1)), floor(toInt64(-13), toUInt32(1));
SELECT round(toInt64(-13), toUInt64(1)), ceil(toInt64(-13), toUInt64(1)), floor(toInt64(-13), toUInt64(1));
SELECT round(toInt64(-13), toInt8(1)), ceil(toInt64(-13), toInt8(1)), floor(toInt64(-13), toInt8(1));
SELECT round(toInt64(-13), toInt16(1)), ceil(toInt64(-13), toInt16(1)), floor(toInt64(-13), toInt16(1));
SELECT round(toInt64(-13), toInt32(1)), ceil(toInt64(-13), toInt32(1)), floor(toInt64(-13), toInt32(1));
SELECT round(toInt64(-13), toInt64(1)), ceil(toInt64(-13), toInt64(1)), floor(toInt64(-13), toInt64(1));
SELECT round(toInt64(-13), toFloat32(1.1)), ceil(toInt64(-13), toFloat32(1.1)), floor(toInt64(-13), toFloat32(1.1));
SELECT round(toInt64(-13), toFloat64(1.1)), ceil(toInt64(-13), toFloat64(1.1)), floor(toInt64(-13), toFloat64(1.1));
SELECT round(toInt64(-13), toUInt16(0)), ceil(toInt64(-13), toUInt16(0)), floor(toInt64(-13), toUInt16(0));
SELECT round(toInt64(-13), toUInt32(0)), ceil(toInt64(-13), toUInt32(0)), floor(toInt64(-13), toUInt32(0));
SELECT round(toInt64(-13), toUInt64(0)), ceil(toInt64(-13), toUInt64(0)), floor(toInt64(-13), toUInt64(0));
SELECT round(toInt64(-13), toInt8(0)), ceil(toInt64(-13), toInt8(0)), floor(toInt64(-13), toInt8(0));
SELECT round(toInt64(-13), toInt16(0)), ceil(toInt64(-13), toInt16(0)), floor(toInt64(-13), toInt16(0));
SELECT round(toInt64(-13), toInt32(0)), ceil(toInt64(-13), toInt32(0)), floor(toInt64(-13), toInt32(0));
SELECT round(toInt64(-13), toInt64(0)), ceil(toInt64(-13), toInt64(0)), floor(toInt64(-13), toInt64(0));
SELECT round(toInt64(-13), toFloat32(0.1)), ceil(toInt64(-13), toFloat32(0.1)), floor(toInt64(-13), toFloat32(0.1));
SELECT round(toInt64(-13), toFloat64(0.1)), ceil(toInt64(-13), toFloat64(0.1)), floor(toInt64(-13), toFloat64(0.1));
SELECT round(toInt64(-13), toInt8(-1)), ceil(toInt64(-13), toInt8(-1)), floor(toInt64(-13), toInt8(-1));
SELECT round(toInt64(-13), toInt16(-1)), ceil(toInt64(-13), toInt16(-1)), floor(toInt64(-13), toInt16(-1));
SELECT round(toInt64(-13), toInt32(-1)), ceil(toInt64(-13), toInt32(-1)), floor(toInt64(-13), toInt32(-1));
SELECT round(toInt64(-13), toInt64(-1)), ceil(toInt64(-13), toInt64(-1)), floor(toInt64(-13), toInt64(-1));
SELECT round(toInt64(-13), toFloat32(1.1)), ceil(toInt64(-13), toFloat32(-1.1)), floor(toInt64(-13), toFloat32(-1.1));
SELECT round(toInt64(-13), toFloat64(1.1)), ceil(toInt64(-13), toFloat64(-1.1)), floor(toInt64(-13), toFloat64(-1.1));
SELECT round(toInt64(-13), toInt8(-2)), ceil(toInt64(-13), toInt8(-2)), floor(toInt64(-13), toInt8(-2));
SELECT round(toInt64(-13), toInt16(-2)), ceil(toInt64(-13), toInt16(-2)), floor(toInt64(-13), toInt16(-2));
SELECT round(toInt64(-13), toInt32(-2)), ceil(toInt64(-13), toInt32(-2)), floor(toInt64(-13), toInt32(-2));
SELECT round(toInt64(-13), toInt64(-2)), ceil(toInt64(-13), toInt64(-2)), floor(toInt64(-13), toInt64(-2));
SELECT round(toInt64(-13), toFloat32(-2.1)), ceil(toInt64(-13), toFloat32(-2.1)), floor(toInt64(-13), toFloat32(-2.1));
SELECT round(toInt64(-13), toFloat64(-2.1)), ceil(toInt64(-13), toFloat64(-2.1)), floor(toInt64(-13), toFloat64(-2.1));
/* Float32 */
SELECT round(toFloat32(-13), toUInt8(2)), ceil(toFloat32(-13), toUInt8(2)), floor(toFloat32(-13), toUInt8(2));
SELECT round(toFloat32(-13), toUInt16(2)), ceil(toFloat32(-13), toUInt16(2)), floor(toFloat32(-13), toUInt16(2));
SELECT round(toFloat32(-13), toUInt32(2)), ceil(toFloat32(-13), toUInt32(2)), floor(toFloat32(-13), toUInt32(2));
SELECT round(toFloat32(-13), toUInt64(2)), ceil(toFloat32(-13), toUInt64(2)), floor(toFloat32(-13), toUInt64(2));
SELECT round(toFloat32(-13), toInt8(2)), ceil(toFloat32(-13), toInt8(2)), floor(toFloat32(-13), toInt8(2));
SELECT round(toFloat32(-13), toInt16(2)), ceil(toFloat32(-13), toInt16(2)), floor(toFloat32(-13), toInt16(2));
SELECT round(toFloat32(-13), toInt32(2)), ceil(toFloat32(-13), toInt32(2)), floor(toFloat32(-13), toInt32(2));
SELECT round(toFloat32(-13), toInt64(2)), ceil(toFloat32(-13), toInt64(2)), floor(toFloat32(-13), toInt64(2));
SELECT round(toFloat32(-13), toFloat32(2.1)), ceil(toFloat32(-13), toFloat32(2.1)), floor(toFloat32(-13), toFloat32(2.1));
SELECT round(toFloat32(-13), toFloat64(2.1)), ceil(toFloat32(-13), toFloat64(2.1)), floor(toFloat32(-13), toFloat64(2.1));
SELECT round(toFloat32(-13), toUInt8(1)), ceil(toFloat32(-13), toUInt8(1)), floor(toFloat32(-13), toUInt8(1));
SELECT round(toFloat32(-13), toUInt16(1)), ceil(toFloat32(-13), toUInt16(1)), floor(toFloat32(-13), toUInt16(1));
SELECT round(toFloat32(-13), toUInt32(1)), ceil(toFloat32(-13), toUInt32(1)), floor(toFloat32(-13), toUInt32(1));
SELECT round(toFloat32(-13), toUInt64(1)), ceil(toFloat32(-13), toUInt64(1)), floor(toFloat32(-13), toUInt64(1));
SELECT round(toFloat32(-13), toInt8(1)), ceil(toFloat32(-13), toInt8(1)), floor(toFloat32(-13), toInt8(1));
SELECT round(toFloat32(-13), toInt16(1)), ceil(toFloat32(-13), toInt16(1)), floor(toFloat32(-13), toInt16(1));
SELECT round(toFloat32(-13), toInt32(1)), ceil(toFloat32(-13), toInt32(1)), floor(toFloat32(-13), toInt32(1));
SELECT round(toFloat32(-13), toInt64(1)), ceil(toFloat32(-13), toInt64(1)), floor(toFloat32(-13), toInt64(1));
SELECT round(toFloat32(-13), toFloat32(1.1)), ceil(toFloat32(-13), toFloat32(1.1)), floor(toFloat32(-13), toFloat32(1.1));
SELECT round(toFloat32(-13), toFloat64(1.1)), ceil(toFloat32(-13), toFloat64(1.1)), floor(toFloat32(-13), toFloat64(1.1));
SELECT round(toFloat32(-13), toUInt16(0)), ceil(toFloat32(-13), toUInt16(0)), floor(toFloat32(-13), toUInt16(0));
SELECT round(toFloat32(-13), toUInt32(0)), ceil(toFloat32(-13), toUInt32(0)), floor(toFloat32(-13), toUInt32(0));
SELECT round(toFloat32(-13), toUInt64(0)), ceil(toFloat32(-13), toUInt64(0)), floor(toFloat32(-13), toUInt64(0));
SELECT round(toFloat32(-13), toInt8(0)), ceil(toFloat32(-13), toInt8(0)), floor(toFloat32(-13), toInt8(0));
SELECT round(toFloat32(-13), toInt16(0)), ceil(toFloat32(-13), toInt16(0)), floor(toFloat32(-13), toInt16(0));
SELECT round(toFloat32(-13), toInt32(0)), ceil(toFloat32(-13), toInt32(0)), floor(toFloat32(-13), toInt32(0));
SELECT round(toFloat32(-13), toInt64(0)), ceil(toFloat32(-13), toInt64(0)), floor(toFloat32(-13), toInt64(0));
SELECT round(toFloat32(-13), toFloat32(0.1)), ceil(toFloat32(-13), toFloat32(0.1)), floor(toFloat32(-13), toFloat32(0.1));
SELECT round(toFloat32(-13), toFloat64(0.1)), ceil(toFloat32(-13), toFloat64(0.1)), floor(toFloat32(-13), toFloat64(0.1));
SELECT round(toFloat32(-13), toInt8(-1)), ceil(toFloat32(-13), toInt8(-1)), floor(toFloat32(-13), toInt8(-1));
SELECT round(toFloat32(-13), toInt16(-1)), ceil(toFloat32(-13), toInt16(-1)), floor(toFloat32(-13), toInt16(-1));
SELECT round(toFloat32(-13), toInt32(-1)), ceil(toFloat32(-13), toInt32(-1)), floor(toFloat32(-13), toInt32(-1));
SELECT round(toFloat32(-13), toInt64(-1)), ceil(toFloat32(-13), toInt64(-1)), floor(toFloat32(-13), toInt64(-1));
SELECT round(toFloat32(-13), toFloat32(1.1)), ceil(toFloat32(-13), toFloat32(-1.1)), floor(toFloat32(-13), toFloat32(-1.1));
SELECT round(toFloat32(-13), toFloat64(1.1)), ceil(toFloat32(-13), toFloat64(-1.1)), floor(toFloat32(-13), toFloat64(-1.1));
SELECT round(toFloat32(-13), toInt8(-2)), ceil(toFloat32(-13), toInt8(-2)), floor(toFloat32(-13), toInt8(-2));
SELECT round(toFloat32(-13), toInt16(-2)), ceil(toFloat32(-13), toInt16(-2)), floor(toFloat32(-13), toInt16(-2));
SELECT round(toFloat32(-13), toInt32(-2)), ceil(toFloat32(-13), toInt32(-2)), floor(toFloat32(-13), toInt32(-2));
SELECT round(toFloat32(-13), toInt64(-2)), ceil(toFloat32(-13), toInt64(-2)), floor(toFloat32(-13), toInt64(-2));
SELECT round(toFloat32(-13), toFloat32(-2.1)), ceil(toFloat32(-13), toFloat32(-2.1)), floor(toFloat32(-13), toFloat32(-2.1));
SELECT round(toFloat32(-13), toFloat64(-2.1)), ceil(toFloat32(-13), toFloat64(-2.1)), floor(toFloat32(-13), toFloat64(-2.1));
/* Float64 */
SELECT round(toFloat64(-13), toUInt8(2)), ceil(toFloat64(-13), toUInt8(2)), floor(toFloat64(-13), toUInt8(2));
SELECT round(toFloat64(-13), toUInt16(2)), ceil(toFloat64(-13), toUInt16(2)), floor(toFloat64(-13), toUInt16(2));
SELECT round(toFloat64(-13), toUInt32(2)), ceil(toFloat64(-13), toUInt32(2)), floor(toFloat64(-13), toUInt32(2));
SELECT round(toFloat64(-13), toUInt64(2)), ceil(toFloat64(-13), toUInt64(2)), floor(toFloat64(-13), toUInt64(2));
SELECT round(toFloat64(-13), toInt8(2)), ceil(toFloat64(-13), toInt8(2)), floor(toFloat64(-13), toInt8(2));
SELECT round(toFloat64(-13), toInt16(2)), ceil(toFloat64(-13), toInt16(2)), floor(toFloat64(-13), toInt16(2));
SELECT round(toFloat64(-13), toInt32(2)), ceil(toFloat64(-13), toInt32(2)), floor(toFloat64(-13), toInt32(2));
SELECT round(toFloat64(-13), toInt64(2)), ceil(toFloat64(-13), toInt64(2)), floor(toFloat64(-13), toInt64(2));
SELECT round(toFloat64(-13), toFloat32(2.1)), ceil(toFloat64(-13), toFloat32(2.1)), floor(toFloat64(-13), toFloat32(2.1));
SELECT round(toFloat64(-13), toFloat64(2.1)), ceil(toFloat64(-13), toFloat64(2.1)), floor(toFloat64(-13), toFloat64(2.1));
SELECT round(toFloat64(-13), toUInt8(1)), ceil(toFloat64(-13), toUInt8(1)), floor(toFloat64(-13), toUInt8(1));
SELECT round(toFloat64(-13), toUInt16(1)), ceil(toFloat64(-13), toUInt16(1)), floor(toFloat64(-13), toUInt16(1));
SELECT round(toFloat64(-13), toUInt32(1)), ceil(toFloat64(-13), toUInt32(1)), floor(toFloat64(-13), toUInt32(1));
SELECT round(toFloat64(-13), toUInt64(1)), ceil(toFloat64(-13), toUInt64(1)), floor(toFloat64(-13), toUInt64(1));
SELECT round(toFloat64(-13), toInt8(1)), ceil(toFloat64(-13), toInt8(1)), floor(toFloat64(-13), toInt8(1));
SELECT round(toFloat64(-13), toInt16(1)), ceil(toFloat64(-13), toInt16(1)), floor(toFloat64(-13), toInt16(1));
SELECT round(toFloat64(-13), toInt32(1)), ceil(toFloat64(-13), toInt32(1)), floor(toFloat64(-13), toInt32(1));
SELECT round(toFloat64(-13), toInt64(1)), ceil(toFloat64(-13), toInt64(1)), floor(toFloat64(-13), toInt64(1));
SELECT round(toFloat64(-13), toFloat32(1.1)), ceil(toFloat64(-13), toFloat32(1.1)), floor(toFloat64(-13), toFloat32(1.1));
SELECT round(toFloat64(-13), toFloat64(1.1)), ceil(toFloat64(-13), toFloat64(1.1)), floor(toFloat64(-13), toFloat64(1.1));
SELECT round(toFloat64(-13), toUInt16(0)), ceil(toFloat64(-13), toUInt16(0)), floor(toFloat64(-13), toUInt16(0));
SELECT round(toFloat64(-13), toUInt32(0)), ceil(toFloat64(-13), toUInt32(0)), floor(toFloat64(-13), toUInt32(0));
SELECT round(toFloat64(-13), toUInt64(0)), ceil(toFloat64(-13), toUInt64(0)), floor(toFloat64(-13), toUInt64(0));
SELECT round(toFloat64(-13), toInt8(0)), ceil(toFloat64(-13), toInt8(0)), floor(toFloat64(-13), toInt8(0));
SELECT round(toFloat64(-13), toInt16(0)), ceil(toFloat64(-13), toInt16(0)), floor(toFloat64(-13), toInt16(0));
SELECT round(toFloat64(-13), toInt32(0)), ceil(toFloat64(-13), toInt32(0)), floor(toFloat64(-13), toInt32(0));
SELECT round(toFloat64(-13), toInt64(0)), ceil(toFloat64(-13), toInt64(0)), floor(toFloat64(-13), toInt64(0));
SELECT round(toFloat64(-13), toFloat32(0.1)), ceil(toFloat64(-13), toFloat32(0.1)), floor(toFloat64(-13), toFloat32(0.1));
SELECT round(toFloat64(-13), toFloat64(0.1)), ceil(toFloat64(-13), toFloat64(0.1)), floor(toFloat64(-13), toFloat64(0.1));
SELECT round(toFloat64(-13), toInt8(-1)), ceil(toFloat64(-13), toInt8(-1)), floor(toFloat64(-13), toInt8(-1));
SELECT round(toFloat64(-13), toInt16(-1)), ceil(toFloat64(-13), toInt16(-1)), floor(toFloat64(-13), toInt16(-1));
SELECT round(toFloat64(-13), toInt32(-1)), ceil(toFloat64(-13), toInt32(-1)), floor(toFloat64(-13), toInt32(-1));
SELECT round(toFloat64(-13), toInt64(-1)), ceil(toFloat64(-13), toInt64(-1)), floor(toFloat64(-13), toInt64(-1));
SELECT round(toFloat64(-13), toFloat32(1.1)), ceil(toFloat64(-13), toFloat32(-1.1)), floor(toFloat64(-13), toFloat32(-1.1));
SELECT round(toFloat64(-13), toFloat64(1.1)), ceil(toFloat64(-13), toFloat64(-1.1)), floor(toFloat64(-13), toFloat64(-1.1));
SELECT round(toFloat64(-13), toInt8(-2)), ceil(toFloat64(-13), toInt8(-2)), floor(toFloat64(-13), toInt8(-2));
SELECT round(toFloat64(-13), toInt16(-2)), ceil(toFloat64(-13), toInt16(-2)), floor(toFloat64(-13), toInt16(-2));
SELECT round(toFloat64(-13), toInt32(-2)), ceil(toFloat64(-13), toInt32(-2)), floor(toFloat64(-13), toInt32(-2));
SELECT round(toFloat64(-13), toInt64(-2)), ceil(toFloat64(-13), toInt64(-2)), floor(toFloat64(-13), toInt64(-2));
SELECT round(toFloat64(-13), toFloat32(-2.1)), ceil(toFloat64(-13), toFloat32(-2.1)), floor(toFloat64(-13), toFloat32(-2.1));
SELECT round(toFloat64(-13), toFloat64(-2.1)), ceil(toFloat64(-13), toFloat64(-2.1)), floor(toFloat64(-13), toFloat64(-2.1));
/* Положительное число с плавающей точкой */
SELECT round(toFloat64(2.718281828459), toUInt8(2)), ceil(toFloat64(2.718281828459), toUInt8(2)), floor(toFloat64(2.718281828459), toUInt8(2));
SELECT round(toFloat64(2.718281828459), toUInt16(2)), ceil(toFloat64(2.718281828459), toUInt16(2)), floor(toFloat64(2.718281828459), toUInt16(2));
SELECT round(toFloat64(2.718281828459), toUInt32(2)), ceil(toFloat64(2.718281828459), toUInt32(2)), floor(toFloat64(2.718281828459), toUInt32(2));
SELECT round(toFloat64(2.718281828459), toUInt64(2)), ceil(toFloat64(2.718281828459), toUInt64(2)), floor(toFloat64(2.718281828459), toUInt64(2));
SELECT round(toFloat64(2.718281828459), toInt8(2)), ceil(toFloat64(2.718281828459), toInt8(2)), floor(toFloat64(2.718281828459), toInt8(2));
SELECT round(toFloat64(2.718281828459), toInt16(2)), ceil(toFloat64(2.718281828459), toInt16(2)), floor(toFloat64(2.718281828459), toInt16(2));
SELECT round(toFloat64(2.718281828459), toInt32(2)), ceil(toFloat64(2.718281828459), toInt32(2)), floor(toFloat64(2.718281828459), toInt32(2));
SELECT round(toFloat64(2.718281828459), toInt64(2)), ceil(toFloat64(2.718281828459), toInt64(2)), floor(toFloat64(2.718281828459), toInt64(2));
SELECT round(toFloat64(2.718281828459), toFloat32(2.1)), ceil(toFloat64(2.718281828459), toFloat32(2.1)), floor(toFloat64(2.718281828459), toFloat32(2.1));
SELECT round(toFloat64(2.718281828459), toFloat64(2.1)), ceil(toFloat64(2.718281828459), toFloat64(2.1)), floor(toFloat64(2.718281828459), toFloat64(2.1));
SELECT round(toFloat64(2.718281828459), toUInt8(1)), ceil(toFloat64(2.718281828459), toUInt8(1)), floor(toFloat64(2.718281828459), toUInt8(1));
SELECT round(toFloat64(2.718281828459), toUInt16(1)), ceil(toFloat64(2.718281828459), toUInt16(1)), floor(toFloat64(2.718281828459), toUInt16(1));
SELECT round(toFloat64(2.718281828459), toUInt32(1)), ceil(toFloat64(2.718281828459), toUInt32(1)), floor(toFloat64(2.718281828459), toUInt32(1));
SELECT round(toFloat64(2.718281828459), toUInt64(1)), ceil(toFloat64(2.718281828459), toUInt64(1)), floor(toFloat64(2.718281828459), toUInt64(1));
SELECT round(toFloat64(2.718281828459), toInt8(1)), ceil(toFloat64(2.718281828459), toInt8(1)), floor(toFloat64(2.718281828459), toInt8(1));
SELECT round(toFloat64(2.718281828459), toInt16(1)), ceil(toFloat64(2.718281828459), toInt16(1)), floor(toFloat64(2.718281828459), toInt16(1));
SELECT round(toFloat64(2.718281828459), toInt32(1)), ceil(toFloat64(2.718281828459), toInt32(1)), floor(toFloat64(2.718281828459), toInt32(1));
SELECT round(toFloat64(2.718281828459), toInt64(1)), ceil(toFloat64(2.718281828459), toInt64(1)), floor(toFloat64(2.718281828459), toInt64(1));
SELECT round(toFloat64(2.718281828459), toFloat32(1.1)), ceil(toFloat64(2.718281828459), toFloat32(1.1)), floor(toFloat64(2.718281828459), toFloat32(1.1));
SELECT round(toFloat64(2.718281828459), toFloat64(1.1)), ceil(toFloat64(2.718281828459), toFloat64(1.1)), floor(toFloat64(2.718281828459), toFloat64(1.1));
SELECT round(toFloat64(2.718281828459), toUInt16(0)), ceil(toFloat64(2.718281828459), toUInt16(0)), floor(toFloat64(2.718281828459), toUInt16(0));
SELECT round(toFloat64(2.718281828459), toUInt32(0)), ceil(toFloat64(2.718281828459), toUInt32(0)), floor(toFloat64(2.718281828459), toUInt32(0));
SELECT round(toFloat64(2.718281828459), toUInt64(0)), ceil(toFloat64(2.718281828459), toUInt64(0)), floor(toFloat64(2.718281828459), toUInt64(0));
SELECT round(toFloat64(2.718281828459), toInt8(0)), ceil(toFloat64(2.718281828459), toInt8(0)), floor(toFloat64(2.718281828459), toInt8(0));
SELECT round(toFloat64(2.718281828459), toInt16(0)), ceil(toFloat64(2.718281828459), toInt16(0)), floor(toFloat64(2.718281828459), toInt16(0));
SELECT round(toFloat64(2.718281828459), toInt32(0)), ceil(toFloat64(2.718281828459), toInt32(0)), floor(toFloat64(2.718281828459), toInt32(0));
SELECT round(toFloat64(2.718281828459), toInt64(0)), ceil(toFloat64(2.718281828459), toInt64(0)), floor(toFloat64(2.718281828459), toInt64(0));
SELECT round(toFloat64(2.718281828459), toFloat32(0.1)), ceil(toFloat64(2.718281828459), toFloat32(0.1)), floor(toFloat64(2.718281828459), toFloat32(0.1));
SELECT round(toFloat64(2.718281828459), toFloat64(0.1)), ceil(toFloat64(2.718281828459), toFloat64(0.1)), floor(toFloat64(2.718281828459), toFloat64(0.1));
SELECT round(toFloat64(2.718281828459), toInt8(-1)), ceil(toFloat64(2.718281828459), toInt8(-1)), floor(toFloat64(2.718281828459), toInt8(-1));
SELECT round(toFloat64(2.718281828459), toInt16(-1)), ceil(toFloat64(2.718281828459), toInt16(-1)), floor(toFloat64(2.718281828459), toInt16(-1));
SELECT round(toFloat64(2.718281828459), toInt32(-1)), ceil(toFloat64(2.718281828459), toInt32(-1)), floor(toFloat64(2.718281828459), toInt32(-1));
SELECT round(toFloat64(2.718281828459), toInt64(-1)), ceil(toFloat64(2.718281828459), toInt64(-1)), floor(toFloat64(2.718281828459), toInt64(-1));
SELECT round(toFloat64(2.718281828459), toFloat32(1.1)), ceil(toFloat64(2.718281828459), toFloat32(-1.1)), floor(toFloat64(2.718281828459), toFloat32(-1.1));
SELECT round(toFloat64(2.718281828459), toFloat64(1.1)), ceil(toFloat64(2.718281828459), toFloat64(-1.1)), floor(toFloat64(2.718281828459), toFloat64(-1.1));
SELECT round(toFloat64(2.718281828459), toInt8(-2)), ceil(toFloat64(2.718281828459), toInt8(-2)), floor(toFloat64(2.718281828459), toInt8(-2));
SELECT round(toFloat64(2.718281828459), toInt16(-2)), ceil(toFloat64(2.718281828459), toInt16(-2)), floor(toFloat64(2.718281828459), toInt16(-2));
SELECT round(toFloat64(2.718281828459), toInt32(-2)), ceil(toFloat64(2.718281828459), toInt32(-2)), floor(toFloat64(2.718281828459), toInt32(-2));
SELECT round(toFloat64(2.718281828459), toInt64(-2)), ceil(toFloat64(2.718281828459), toInt64(-2)), floor(toFloat64(2.718281828459), toInt64(-2));
SELECT round(toFloat64(2.718281828459), toFloat32(-2.1)), ceil(toFloat64(2.718281828459), toFloat32(-2.1)), floor(toFloat64(2.718281828459), toFloat32(-2.1));
SELECT round(toFloat64(2.718281828459), toFloat64(-2.1)), ceil(toFloat64(2.718281828459), toFloat64(-2.1)), floor(toFloat64(2.718281828459), toFloat64(-2.1));
/* Отрицательное число с плавающей точкой */
SELECT round(toFloat64(-2.718281828459), toUInt8(2)), ceil(toFloat64(-2.718281828459), toUInt8(2)), floor(toFloat64(-2.718281828459), toUInt8(2));
SELECT round(toFloat64(-2.718281828459), toUInt16(2)), ceil(toFloat64(-2.718281828459), toUInt16(2)), floor(toFloat64(-2.718281828459), toUInt16(2));
SELECT round(toFloat64(-2.718281828459), toUInt32(2)), ceil(toFloat64(-2.718281828459), toUInt32(2)), floor(toFloat64(-2.718281828459), toUInt32(2));
SELECT round(toFloat64(-2.718281828459), toUInt64(2)), ceil(toFloat64(-2.718281828459), toUInt64(2)), floor(toFloat64(-2.718281828459), toUInt64(2));
SELECT round(toFloat64(-2.718281828459), toInt8(2)), ceil(toFloat64(-2.718281828459), toInt8(2)), floor(toFloat64(-2.718281828459), toInt8(2));
SELECT round(toFloat64(-2.718281828459), toInt16(2)), ceil(toFloat64(-2.718281828459), toInt16(2)), floor(toFloat64(-2.718281828459), toInt16(2));
SELECT round(toFloat64(-2.718281828459), toInt32(2)), ceil(toFloat64(-2.718281828459), toInt32(2)), floor(toFloat64(-2.718281828459), toInt32(2));
SELECT round(toFloat64(-2.718281828459), toInt64(2)), ceil(toFloat64(-2.718281828459), toInt64(2)), floor(toFloat64(-2.718281828459), toInt64(2));
SELECT round(toFloat64(-2.718281828459), toFloat32(2.1)), ceil(toFloat64(-2.718281828459), toFloat32(2.1)), floor(toFloat64(-2.718281828459), toFloat32(2.1));
SELECT round(toFloat64(-2.718281828459), toFloat64(2.1)), ceil(toFloat64(-2.718281828459), toFloat64(2.1)), floor(toFloat64(-2.718281828459), toFloat64(2.1));
SELECT round(toFloat64(-2.718281828459), toUInt8(1)), ceil(toFloat64(-2.718281828459), toUInt8(1)), floor(toFloat64(-2.718281828459), toUInt8(1));
SELECT round(toFloat64(-2.718281828459), toUInt16(1)), ceil(toFloat64(-2.718281828459), toUInt16(1)), floor(toFloat64(-2.718281828459), toUInt16(1));
SELECT round(toFloat64(-2.718281828459), toUInt32(1)), ceil(toFloat64(-2.718281828459), toUInt32(1)), floor(toFloat64(-2.718281828459), toUInt32(1));
SELECT round(toFloat64(-2.718281828459), toUInt64(1)), ceil(toFloat64(-2.718281828459), toUInt64(1)), floor(toFloat64(-2.718281828459), toUInt64(1));
SELECT round(toFloat64(-2.718281828459), toInt8(1)), ceil(toFloat64(-2.718281828459), toInt8(1)), floor(toFloat64(-2.718281828459), toInt8(1));
SELECT round(toFloat64(-2.718281828459), toInt16(1)), ceil(toFloat64(-2.718281828459), toInt16(1)), floor(toFloat64(-2.718281828459), toInt16(1));
SELECT round(toFloat64(-2.718281828459), toInt32(1)), ceil(toFloat64(-2.718281828459), toInt32(1)), floor(toFloat64(-2.718281828459), toInt32(1));
SELECT round(toFloat64(-2.718281828459), toInt64(1)), ceil(toFloat64(-2.718281828459), toInt64(1)), floor(toFloat64(-2.718281828459), toInt64(1));
SELECT round(toFloat64(-2.718281828459), toFloat32(1.1)), ceil(toFloat64(-2.718281828459), toFloat32(1.1)), floor(toFloat64(-2.718281828459), toFloat32(1.1));
SELECT round(toFloat64(-2.718281828459), toFloat64(1.1)), ceil(toFloat64(-2.718281828459), toFloat64(1.1)), floor(toFloat64(-2.718281828459), toFloat64(1.1));
SELECT round(toFloat64(-2.718281828459), toUInt16(0)), ceil(toFloat64(-2.718281828459), toUInt16(0)), floor(toFloat64(-2.718281828459), toUInt16(0));
SELECT round(toFloat64(-2.718281828459), toUInt32(0)), ceil(toFloat64(-2.718281828459), toUInt32(0)), floor(toFloat64(-2.718281828459), toUInt32(0));
SELECT round(toFloat64(-2.718281828459), toUInt64(0)), ceil(toFloat64(-2.718281828459), toUInt64(0)), floor(toFloat64(-2.718281828459), toUInt64(0));
SELECT round(toFloat64(-2.718281828459), toInt8(0)), ceil(toFloat64(-2.718281828459), toInt8(0)), floor(toFloat64(-2.718281828459), toInt8(0));
SELECT round(toFloat64(-2.718281828459), toInt16(0)), ceil(toFloat64(-2.718281828459), toInt16(0)), floor(toFloat64(-2.718281828459), toInt16(0));
SELECT round(toFloat64(-2.718281828459), toInt32(0)), ceil(toFloat64(-2.718281828459), toInt32(0)), floor(toFloat64(-2.718281828459), toInt32(0));
SELECT round(toFloat64(-2.718281828459), toInt64(0)), ceil(toFloat64(-2.718281828459), toInt64(0)), floor(toFloat64(-2.718281828459), toInt64(0));
SELECT round(toFloat64(-2.718281828459), toFloat32(0.1)), ceil(toFloat64(-2.718281828459), toFloat32(0.1)), floor(toFloat64(-2.718281828459), toFloat32(0.1));
SELECT round(toFloat64(-2.718281828459), toFloat64(0.1)), ceil(toFloat64(-2.718281828459), toFloat64(0.1)), floor(toFloat64(-2.718281828459), toFloat64(0.1));
SELECT round(toFloat64(-2.718281828459), toInt8(-1)), ceil(toFloat64(-2.718281828459), toInt8(-1)), floor(toFloat64(-2.718281828459), toInt8(-1));
SELECT round(toFloat64(-2.718281828459), toInt16(-1)), ceil(toFloat64(-2.718281828459), toInt16(-1)), floor(toFloat64(-2.718281828459), toInt16(-1));
SELECT round(toFloat64(-2.718281828459), toInt32(-1)), ceil(toFloat64(-2.718281828459), toInt32(-1)), floor(toFloat64(-2.718281828459), toInt32(-1));
SELECT round(toFloat64(-2.718281828459), toInt64(-1)), ceil(toFloat64(-2.718281828459), toInt64(-1)), floor(toFloat64(-2.718281828459), toInt64(-1));
SELECT round(toFloat64(-2.718281828459), toFloat32(1.1)), ceil(toFloat64(-2.718281828459), toFloat32(-1.1)), floor(toFloat64(-2.718281828459), toFloat32(-1.1));
SELECT round(toFloat64(-2.718281828459), toFloat64(1.1)), ceil(toFloat64(-2.718281828459), toFloat64(-1.1)), floor(toFloat64(-2.718281828459), toFloat64(-1.1));
SELECT round(toFloat64(-2.718281828459), toInt8(-2)), ceil(toFloat64(-2.718281828459), toInt8(-2)), floor(toFloat64(-2.718281828459), toInt8(-2));
SELECT round(toFloat64(-2.718281828459), toInt16(-2)), ceil(toFloat64(-2.718281828459), toInt16(-2)), floor(toFloat64(-2.718281828459), toInt16(-2));
SELECT round(toFloat64(-2.718281828459), toInt32(-2)), ceil(toFloat64(-2.718281828459), toInt32(-2)), floor(toFloat64(-2.718281828459), toInt32(-2));
SELECT round(toFloat64(-2.718281828459), toInt64(-2)), ceil(toFloat64(-2.718281828459), toInt64(-2)), floor(toFloat64(-2.718281828459), toInt64(-2));
SELECT round(toFloat64(-2.718281828459), toFloat32(-2.1)), ceil(toFloat64(-2.718281828459), toFloat32(-2.1)), floor(toFloat64(-2.718281828459), toFloat32(-2.1));
SELECT round(toFloat64(-2.718281828459), toFloat64(-2.1)), ceil(toFloat64(-2.718281828459), toFloat64(-2.1)), floor(toFloat64(-2.718281828459), toFloat64(-2.1));
/* Misc. */
SELECT round(13112221, -1), ceil(13112221, -1), floor(13112221, -1);
SELECT round(13112221, -2), ceil(13112221, -2), floor(13112221, -2);
SELECT round(13112221, -3), ceil(13112221, -3), floor(13112221, -3);
SELECT round(13112221, -4), ceil(13112221, -4), floor(13112221, -4);
SELECT round(13112221, -5), ceil(13112221, -5), floor(13112221, -5);
SELECT round(13112221, -6), ceil(13112221, -6), floor(13112221, -6);
SELECT round(13112221, -7), ceil(13112221, -7), floor(13112221, -7);
SELECT round(13112221, -8), ceil(13112221, -8), floor(13112221, -8);
SELECT round(13112221, -9), ceil(13112221, -9), floor(13112221, -9);
SELECT round(13112221, -10), ceil(13112221, -10), floor(13112221, -10);
SELECT round(13112221, -11), ceil(13112221, -11), floor(13112221, -11);
SELECT round(13112221, -12), ceil(13112221, -12), floor(13112221, -12);
SELECT round(13112221, -13), ceil(13112221, -13), floor(13112221, -13);
SELECT round(13112221, -14), ceil(13112221, -14), floor(13112221, -14);
SELECT round(13112221, -15), ceil(13112221, -15), floor(13112221, -15);
SELECT round(13112221, -16), ceil(13112221, -16), floor(13112221, -16);
SELECT round(13112221, -17), ceil(13112221, -17), floor(13112221, -17);
SELECT round(13112221, -18), ceil(13112221, -18), floor(13112221, -18);
SELECT round(13112221, -19), ceil(13112221, -19), floor(13112221, -19);
SELECT round(13112221, -20), ceil(13112221, -20), floor(13112221, -20);
SELECT round(2.718281828459045, 1), ceil(2.718281828459045, 1), floor(2.718281828459045, 1);
SELECT round(2.718281828459045, 2), ceil(2.718281828459045, 2), floor(2.718281828459045, 2);
SELECT round(2.718281828459045, 3), ceil(2.718281828459045, 3), floor(2.718281828459045, 3);
SELECT round(2.718281828459045, 4), ceil(2.718281828459045, 4), floor(2.718281828459045, 4);
SELECT round(2.718281828459045, 5), ceil(2.718281828459045, 5), floor(2.718281828459045, 5);
SELECT round(2.718281828459045, 6), ceil(2.718281828459045, 6), floor(2.718281828459045, 6);
SELECT round(2.718281828459045, 7), ceil(2.718281828459045, 7), floor(2.718281828459045, 7);
SELECT round(2.718281828459045, 8), ceil(2.718281828459045, 8), floor(2.718281828459045, 8);
SELECT round(2.718281828459045, 9), ceil(2.718281828459045, 9), floor(2.718281828459045, 9);
SELECT round(2.718281828459045, 10), ceil(2.718281828459045, 10), floor(2.718281828459045, 10);
SELECT round(2.718281828459045, 11), ceil(2.718281828459045, 11), floor(2.718281828459045, 11);
SELECT round(2.718281828459045, 12), ceil(2.718281828459045, 12), floor(2.718281828459045, 12);
SELECT round(2.718281828459045, 13), ceil(2.718281828459045, 13), floor(2.718281828459045, 13);
SELECT round(2.718281828459045, 14), ceil(2.718281828459045, 14), floor(2.718281828459045, 14);
SELECT round(2.718281828459045, 15), ceil(2.718281828459045, 15), floor(2.718281828459045, 15);
SELECT round(2.718281828459045, 16), ceil(2.718281828459045, 16), floor(2.718281828459045, 16);
SELECT round(2.718281828459045, 17), ceil(2.718281828459045, 17), floor(2.718281828459045, 17);
SELECT round(2.718281828459045, 18), ceil(2.718281828459045, 18), floor(2.718281828459045, 18);
SELECT round(2.718281828459045, 19), ceil(2.718281828459045, 19), floor(2.718281828459045, 19);
SELECT round(2.718281828459045, 20), ceil(2.718281828459045, 20), floor(2.718281828459045, 20);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(1) AS x);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(2) AS x);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(3) AS x);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(4) AS x);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(5) AS x);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(6) AS x);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(7) AS x);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(8) AS x);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(9) AS x);
SELECT round(y,3) FROM (SELECT 2.718281828459045 + 1/(1+x*x) AS y FROM system.one ARRAY JOIN range(10) AS x);
/* Negative zeroes. */
SELECT round(-0.002);
SELECT round(-0.002, -1);
SELECT round(-0.002, 1);

View File

@ -0,0 +1,2 @@
[0] 00
[1] 11

View File

@ -0,0 +1 @@
select a, b || b from (select [number] as a, toString(number) as b from system.numbers limit 2);

View File

@ -1,2 +1,5 @@
#!/bin/sh
set -e
mkdir -p /etc/clickhouse-client/conf.d mkdir -p /etc/clickhouse-client/conf.d
chown -R clickhouse: /etc/clickhouse-client chown -R clickhouse: /etc/clickhouse-client

5
debian/rules vendored
View File

@ -95,4 +95,7 @@ endif
dh_install --list-missing --sourcedir=$(DESTDIR) dh_install --list-missing --sourcedir=$(DESTDIR)
override_dh_shlibdeps: override_dh_shlibdeps:
dh_shlibdeps -Xdebian/clickhouse-server-base/usr/share/clickhouse/bin/* true # We depend only on libc and dh_shlibdeps gives us wrong (too strict) dependency.
override_dh_builddeb:
dh_builddeb -- -Z gzip # Older systems don't have "xz", so use "gzip" instead.

View File

@ -58,7 +58,7 @@ You can compile packages and install them. You can also use programs without ins
Client: dbms/src/Client/ Client: dbms/src/Client/
Server: dbms/src/Server/ Server: dbms/src/Server/
For the server, create a catalog with data, such as: For the server, create a directory with data, such as:
.. code-block:: text .. code-block:: text
@ -74,6 +74,8 @@ Other methods of installation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Docker image is located here: https://hub.docker.com/r/yandex/clickhouse-server/ The Docker image is located here: https://hub.docker.com/r/yandex/clickhouse-server/
There are RPM packages for CentOS, RHEL: https://github.com/Altinity/clickhouse-rpm-install
There is Gentoo overlay located here: https://github.com/kmeaw/clickhouse-overlay There is Gentoo overlay located here: https://github.com/kmeaw/clickhouse-overlay
@ -86,7 +88,7 @@ To start the server (as a daemon), run:
sudo service clickhouse-server start sudo service clickhouse-server start
View the logs in the catalog `/var/log/clickhouse-server/` View the logs in the directory `/var/log/clickhouse-server/`
If the server doesn't start, check the configurations in the file `/etc/clickhouse-server/config.xml` If the server doesn't start, check the configurations in the file `/etc/clickhouse-server/config.xml`

View File

@ -76,6 +76,8 @@ ClickHouse содержит настройки ограничения досту
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
Docker образ: https://hub.docker.com/r/yandex/clickhouse-server/ Docker образ: https://hub.docker.com/r/yandex/clickhouse-server/
RPM пакеты для CentOS, RHEL: https://github.com/Altinity/clickhouse-rpm-install
Gentoo overlay: https://github.com/kmeaw/clickhouse-overlay Gentoo overlay: https://github.com/kmeaw/clickhouse-overlay

View File

@ -43,6 +43,30 @@ fallback_to_stale_replicas_for_distributed_queries
По умолчанию - 1 (включена). По умолчанию - 1 (включена).
.. _settings-settings-force_index_by_date:
force_index_by_date
-------------------
Запрещает выполнение запросов, если использовать индекс по дате невозможно.
Работает с таблицами семейства MergeTree.
При ``force_index_by_date=1`` ClickHouse проверяет, есть ли в запросе условие на ключ даты, которое может использоваться для отсечения диапазонов данных. Если подходящего условия нет - кидается исключение. При этом не проверяется, действительно ли условие уменьшает объём данных для чтения. Например, условие ``Date != '2000-01-01'`` подходит даже в том случае, когда соответствует всем данным в таблице (т.е. для выполнения запроса требуется full scan). Подробнее про диапазоны данных в таблицах MergeTree читайте в разделе :ref:`table_engines-mergetree`.
.. _settings-settings-force_primary_key:
force_primary_key
-----------------
Запрещает выполнение запросов, если использовать индекс по первичному ключу невозможно.
Работает с таблицами семейства MergeTree.
При ``force_primary_key=1`` ClickHouse проверяет, есть ли в запросе условие на первичный ключ, которое может использоваться для отсечения диапазонов данных. Если подходящего условия нет - кидается исключение. При этом не проверяется, действительно ли условие уменьшает объём данных для чтения. Подробнее про диапазоны данных в таблицах MergeTree читайте в разделе :ref:`table_engines-mergetree`.
input_format_allow_errors_num input_format_allow_errors_num
----------------------------- -----------------------------
Устанавливает максимальное количество допустимых ошибок при чтении из текстовых форматов (CSV, TSV и т.п.). Устанавливает максимальное количество допустимых ошибок при чтении из текстовых форматов (CSV, TSV и т.п.).

View File

@ -627,7 +627,7 @@ ClickHouse отсекает все пробелы и один перенос с
SELECT SELECT
~~~~~~ ~~~~~~
Его величество, запрос SELECT. Выборка данных.
.. code-block:: sql .. code-block:: sql
@ -645,6 +645,7 @@ SELECT
[UNION ALL ...] [UNION ALL ...]
[INTO OUTFILE filename] [INTO OUTFILE filename]
[FORMAT format] [FORMAT format]
[LIMIT n BY columns]
Все секции, кроме списка выражений сразу после SELECT, являются необязательными. Все секции, кроме списка выражений сразу после SELECT, являются необязательными.
Ниже секции будут описаны в порядке, почти соответствующем конвейеру выполнения запроса. Ниже секции будут описаны в порядке, почти соответствующем конвейеру выполнения запроса.
@ -1172,7 +1173,7 @@ GROUP BY во внешней памяти
Модификатор LIMIT N BY Модификатор LIMIT N BY
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
LIMIT N BY COLUMNS позволяет выбрать топ N строк для каждой группы COLUMNS. LIMIT N BY не связан с LIMIT и они могут использоваться в одном запросе. Ключ для LIMIT N BY может содержать произвольное число колонок или выражений. LIMIT N BY COLUMNS выбирает топ N строк для каждой группы COLUMNS. LIMIT N BY не связан с LIMIT и они могут использоваться в одном запросе. Ключ для LIMIT N BY может содержать произвольное число колонок или выражений.
Пример: Пример:
@ -1189,7 +1190,9 @@ LIMIT N BY COLUMNS позволяет выбрать топ N строк для
LIMIT 5 BY domain, device_type LIMIT 5 BY domain, device_type
LIMIT 100 LIMIT 100
выберет топ 5 рефереров для каждой пары domain - device type. Ограничить общее число строк результата 100. Запрос выберет топ 5 рефереров для каждой пары ``domain, device_type``, но не более 100 строк (``LIMIT n BY + LIMIT``).
Секция HAVING Секция HAVING
""""""""""""" """""""""""""

Some files were not shown because too many files have changed in this diff Show More