mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-10-10 10:30:51 +00:00
Merge branch 'master' of github.com:yandex/ClickHouse
This commit is contained in:
commit
ea236912e1
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -64,3 +64,6 @@
|
|||||||
[submodule "contrib/cppkafka"]
|
[submodule "contrib/cppkafka"]
|
||||||
path = contrib/cppkafka
|
path = contrib/cppkafka
|
||||||
url = https://github.com/ClickHouse-Extras/cppkafka.git
|
url = https://github.com/ClickHouse-Extras/cppkafka.git
|
||||||
|
[submodule "contrib/brotli"]
|
||||||
|
path = contrib/brotli
|
||||||
|
url = https://github.com/google/brotli.git
|
||||||
|
@ -252,6 +252,7 @@ if (NOT USE_CPUID)
|
|||||||
endif()
|
endif()
|
||||||
include (cmake/find_libgsasl.cmake)
|
include (cmake/find_libgsasl.cmake)
|
||||||
include (cmake/find_libxml2.cmake)
|
include (cmake/find_libxml2.cmake)
|
||||||
|
include (cmake/find_brotli.cmake)
|
||||||
include (cmake/find_protobuf.cmake)
|
include (cmake/find_protobuf.cmake)
|
||||||
include (cmake/find_pdqsort.cmake)
|
include (cmake/find_pdqsort.cmake)
|
||||||
include (cmake/find_hdfs3.cmake)
|
include (cmake/find_hdfs3.cmake)
|
||||||
|
30
cmake/find_brotli.cmake
Normal file
30
cmake/find_brotli.cmake
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
option (USE_INTERNAL_BROTLI_LIBRARY "Set to FALSE to use system libbrotli library instead of bundled" ${NOT_UNBUNDLED})
|
||||||
|
|
||||||
|
if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/brotli/c/include/brotli/decode.h")
|
||||||
|
if (USE_INTERNAL_BROTLI_LIBRARY)
|
||||||
|
message (WARNING "submodule contrib/brotli is missing. to fix try run: \n git submodule update --init --recursive")
|
||||||
|
set (USE_INTERNAL_BROTLI_LIBRARY 0)
|
||||||
|
endif ()
|
||||||
|
set (MISSING_INTERNAL_BROTLI_LIBRARY 1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if(NOT USE_INTERNAL_BROTLI_LIBRARY)
|
||||||
|
find_library(BROTLI_LIBRARY_COMMON brotlicommon)
|
||||||
|
find_library(BROTLI_LIBRARY_DEC brotlidec)
|
||||||
|
find_library(BROTLI_LIBRARY_ENC brotlienc)
|
||||||
|
find_path(BROTLI_INCLUDE_DIR NAMES brotli/decode.h brotli/encode.h brotli/port.h brotli/types.h PATHS ${BROTLI_INCLUDE_PATHS})
|
||||||
|
if(BROTLI_LIBRARY_DEC AND BROTLI_LIBRARY_ENC AND BROTLI_LIBRARY_COMMON)
|
||||||
|
set(BROTLI_LIBRARY ${BROTLI_LIBRARY_DEC} ${BROTLI_LIBRARY_ENC} ${BROTLI_LIBRARY_COMMON})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (BROTLI_LIBRARY AND BROTLI_INCLUDE_DIR)
|
||||||
|
set (USE_BROTLI 1)
|
||||||
|
elseif (NOT MISSING_INTERNAL_BROTLI_LIBRARY)
|
||||||
|
set (BROTLI_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/brotli/c/include)
|
||||||
|
set (USE_INTERNAL_BROTLI_LIBRARY 1)
|
||||||
|
set (BROTLI_LIBRARY brotli)
|
||||||
|
set (USE_BROTLI 1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
message (STATUS "Using brotli=${USE_BROTLI}: ${BROTLI_INCLUDE_DIR} : ${BROTLI_LIBRARY}")
|
4
contrib/CMakeLists.txt
vendored
4
contrib/CMakeLists.txt
vendored
@ -217,6 +217,10 @@ if (USE_INTERNAL_LIBXML2_LIBRARY)
|
|||||||
add_subdirectory(libxml2-cmake)
|
add_subdirectory(libxml2-cmake)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (USE_INTERNAL_BROTLI_LIBRARY)
|
||||||
|
add_subdirectory(brotli-cmake)
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (USE_INTERNAL_PROTOBUF_LIBRARY)
|
if (USE_INTERNAL_PROTOBUF_LIBRARY)
|
||||||
set(protobuf_BUILD_TESTS OFF CACHE INTERNAL "" FORCE)
|
set(protobuf_BUILD_TESTS OFF CACHE INTERNAL "" FORCE)
|
||||||
set(protobuf_BUILD_SHARED_LIBS OFF CACHE INTERNAL "" FORCE)
|
set(protobuf_BUILD_SHARED_LIBS OFF CACHE INTERNAL "" FORCE)
|
||||||
|
1
contrib/brotli
vendored
Submodule
1
contrib/brotli
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 5805f99a533a8f8118699c0100d8c102f3605f65
|
33
contrib/brotli-cmake/CMakeLists.txt
Normal file
33
contrib/brotli-cmake/CMakeLists.txt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
set(BROTLI_SOURCE_DIR ${CMAKE_SOURCE_DIR}/contrib/brotli/c)
|
||||||
|
set(BROTLI_BINARY_DIR ${CMAKE_BINARY_DIR}/contrib/brotli/c)
|
||||||
|
|
||||||
|
set(SRCS
|
||||||
|
${BROTLI_SOURCE_DIR}/dec/bit_reader.c
|
||||||
|
${BROTLI_SOURCE_DIR}/dec/state.c
|
||||||
|
${BROTLI_SOURCE_DIR}/dec/huffman.c
|
||||||
|
${BROTLI_SOURCE_DIR}/dec/decode.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/encode.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/dictionary_hash.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/cluster.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/entropy_encode.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/literal_cost.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/compress_fragment_two_pass.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/static_dict.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/compress_fragment.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/block_splitter.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/backward_references_hq.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/histogram.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/brotli_bit_stream.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/utf8_util.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/encoder_dict.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/backward_references.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/bit_cost.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/metablock.c
|
||||||
|
${BROTLI_SOURCE_DIR}/enc/memory.c
|
||||||
|
${BROTLI_SOURCE_DIR}/common/dictionary.c
|
||||||
|
${BROTLI_SOURCE_DIR}/common/transform.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(brotli ${LINK_MODE} ${SRCS})
|
||||||
|
|
||||||
|
target_include_directories(brotli PUBLIC ${BROTLI_SOURCE_DIR}/include)
|
@ -102,9 +102,6 @@ add_headers_and_sources(dbms src/Interpreters/ClusterProxy)
|
|||||||
add_headers_and_sources(dbms src/Columns)
|
add_headers_and_sources(dbms src/Columns)
|
||||||
add_headers_and_sources(dbms src/Storages)
|
add_headers_and_sources(dbms src/Storages)
|
||||||
add_headers_and_sources(dbms src/Storages/Distributed)
|
add_headers_and_sources(dbms src/Storages/Distributed)
|
||||||
if(USE_RDKAFKA)
|
|
||||||
add_headers_and_sources(dbms src/Storages/Kafka)
|
|
||||||
endif()
|
|
||||||
add_headers_and_sources(dbms src/Storages/MergeTree)
|
add_headers_and_sources(dbms src/Storages/MergeTree)
|
||||||
add_headers_and_sources(dbms src/Client)
|
add_headers_and_sources(dbms src/Client)
|
||||||
add_headers_and_sources(dbms src/Formats)
|
add_headers_and_sources(dbms src/Formats)
|
||||||
@ -297,11 +294,7 @@ if (USE_CAPNP)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (USE_RDKAFKA)
|
if (USE_RDKAFKA)
|
||||||
target_link_libraries (dbms PRIVATE ${RDKAFKA_LIBRARY})
|
target_link_libraries (dbms PRIVATE clickhouse_storage_kafka)
|
||||||
target_link_libraries (dbms PRIVATE ${CPPKAFKA_LIBRARY})
|
|
||||||
if (NOT USE_INTERNAL_RDKAFKA_LIBRARY)
|
|
||||||
target_include_directories (dbms SYSTEM BEFORE PRIVATE ${RDKAFKA_INCLUDE_DIR})
|
|
||||||
endif ()
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
target_link_libraries(dbms PRIVATE ${OPENSSL_CRYPTO_LIBRARY} Threads::Threads)
|
target_link_libraries(dbms PRIVATE ${OPENSSL_CRYPTO_LIBRARY} Threads::Threads)
|
||||||
@ -319,6 +312,11 @@ if (USE_HDFS)
|
|||||||
target_include_directories (clickhouse_common_io SYSTEM BEFORE PRIVATE ${HDFS3_INCLUDE_DIR})
|
target_include_directories (clickhouse_common_io SYSTEM BEFORE PRIVATE ${HDFS3_INCLUDE_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (USE_BROTLI)
|
||||||
|
target_link_libraries (clickhouse_common_io PRIVATE ${BROTLI_LIBRARY})
|
||||||
|
target_include_directories (clickhouse_common_io SYSTEM BEFORE PRIVATE ${BROTLI_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
if (USE_JEMALLOC)
|
if (USE_JEMALLOC)
|
||||||
target_include_directories (dbms SYSTEM BEFORE PRIVATE ${JEMALLOC_INCLUDE_DIR}) # used in Interpreters/AsynchronousMetrics.cpp
|
target_include_directories (dbms SYSTEM BEFORE PRIVATE ${JEMALLOC_INCLUDE_DIR}) # used in Interpreters/AsynchronousMetrics.cpp
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
set(VERSION_REVISION 54415)
|
set(VERSION_REVISION 54415)
|
||||||
set(VERSION_MAJOR 19)
|
set(VERSION_MAJOR 19)
|
||||||
set(VERSION_MINOR 3)
|
set(VERSION_MINOR 3)
|
||||||
set(VERSION_PATCH 0)
|
set(VERSION_PATCH 3)
|
||||||
set(VERSION_GITHASH 1db4bd8c2a1a0cd610c8a6564e8194dca5265562)
|
set(VERSION_GITHASH f5560660beff430896d7a23d70a7ea8a06416ea9)
|
||||||
set(VERSION_DESCRIBE v19.3.0-testing)
|
set(VERSION_DESCRIBE v19.3.3-testing)
|
||||||
set(VERSION_STRING 19.3.0)
|
set(VERSION_STRING 19.3.3)
|
||||||
# end of autochange
|
# end of autochange
|
||||||
|
|
||||||
set(VERSION_EXTRA "" CACHE STRING "")
|
set(VERSION_EXTRA "" CACHE STRING "")
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
add_library (clickhouse-odbc-bridge-lib ${LINK_MODE}
|
add_headers_and_sources(clickhouse_odbc_bridge .)
|
||||||
PingHandler.cpp
|
|
||||||
MainHandler.cpp
|
add_library (clickhouse-odbc-bridge-lib ${LINK_MODE} ${clickhouse_odbc_bridge_sources})
|
||||||
ColumnInfoHandler.cpp
|
|
||||||
IdentifierQuoteHandler.cpp
|
|
||||||
HandlerFactory.cpp
|
|
||||||
ODBCBridge.cpp
|
|
||||||
getIdentifierQuote.cpp
|
|
||||||
validateODBCConnectionString.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries (clickhouse-odbc-bridge-lib PRIVATE daemon dbms clickhouse_common_io)
|
target_link_libraries (clickhouse-odbc-bridge-lib PRIVATE daemon dbms clickhouse_common_io)
|
||||||
target_include_directories (clickhouse-odbc-bridge-lib PUBLIC ${ClickHouse_SOURCE_DIR}/libs/libdaemon/include)
|
target_include_directories (clickhouse-odbc-bridge-lib PUBLIC ${ClickHouse_SOURCE_DIR}/libs/libdaemon/include)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <DataStreams/copyData.h>
|
#include <DataStreams/copyData.h>
|
||||||
#include <DataTypes/DataTypeFactory.h>
|
#include <DataTypes/DataTypeFactory.h>
|
||||||
#include <Dictionaries/ODBCBlockInputStream.h>
|
#include "ODBCBlockInputStream.h"
|
||||||
#include <Formats/BinaryRowInputStream.h>
|
#include <Formats/BinaryRowInputStream.h>
|
||||||
#include <Formats/FormatFactory.h>
|
#include <Formats/FormatFactory.h>
|
||||||
#include <IO/WriteBufferFromHTTPServerResponse.h>
|
#include <IO/WriteBufferFromHTTPServerResponse.h>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <Poco/Data/RecordSet.h>
|
#include <Poco/Data/RecordSet.h>
|
||||||
#include <Poco/Data/Session.h>
|
#include <Poco/Data/Session.h>
|
||||||
#include <Poco/Data/Statement.h>
|
#include <Poco/Data/Statement.h>
|
||||||
#include "ExternalResultDescription.h"
|
#include <Dictionaries/ExternalResultDescription.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
@ -20,6 +20,7 @@
|
|||||||
#include <Compression/CompressedWriteBuffer.h>
|
#include <Compression/CompressedWriteBuffer.h>
|
||||||
#include <IO/ReadBufferFromIStream.h>
|
#include <IO/ReadBufferFromIStream.h>
|
||||||
#include <IO/ZlibInflatingReadBuffer.h>
|
#include <IO/ZlibInflatingReadBuffer.h>
|
||||||
|
#include <IO/BrotliReadBuffer.h>
|
||||||
#include <IO/ReadBufferFromString.h>
|
#include <IO/ReadBufferFromString.h>
|
||||||
#include <IO/WriteBufferFromString.h>
|
#include <IO/WriteBufferFromString.h>
|
||||||
#include <IO/WriteBufferFromHTTPServerResponse.h>
|
#include <IO/WriteBufferFromHTTPServerResponse.h>
|
||||||
@ -396,19 +397,23 @@ void HTTPHandler::processQuery(
|
|||||||
String http_request_compression_method_str = request.get("Content-Encoding", "");
|
String http_request_compression_method_str = request.get("Content-Encoding", "");
|
||||||
if (!http_request_compression_method_str.empty())
|
if (!http_request_compression_method_str.empty())
|
||||||
{
|
{
|
||||||
ZlibCompressionMethod method;
|
|
||||||
if (http_request_compression_method_str == "gzip")
|
if (http_request_compression_method_str == "gzip")
|
||||||
{
|
{
|
||||||
method = ZlibCompressionMethod::Gzip;
|
in_post = std::make_unique<ZlibInflatingReadBuffer>(*in_post_raw, ZlibCompressionMethod::Gzip);
|
||||||
}
|
}
|
||||||
else if (http_request_compression_method_str == "deflate")
|
else if (http_request_compression_method_str == "deflate")
|
||||||
{
|
{
|
||||||
method = ZlibCompressionMethod::Zlib;
|
in_post = std::make_unique<ZlibInflatingReadBuffer>(*in_post_raw, ZlibCompressionMethod::Zlib);
|
||||||
|
}
|
||||||
|
else if (http_request_compression_method_str == "br")
|
||||||
|
{
|
||||||
|
in_post = std::make_unique<BrotliReadBuffer>(*in_post_raw);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
throw Exception("Unknown Content-Encoding of HTTP request: " + http_request_compression_method_str,
|
throw Exception("Unknown Content-Encoding of HTTP request: " + http_request_compression_method_str,
|
||||||
ErrorCodes::UNKNOWN_COMPRESSION_METHOD);
|
ErrorCodes::UNKNOWN_COMPRESSION_METHOD);
|
||||||
in_post = std::make_unique<ZlibInflatingReadBuffer>(*in_post_raw, method);
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
in_post = std::move(in_post_raw);
|
in_post = std::move(in_post_raw);
|
||||||
|
@ -185,8 +185,9 @@ void TCPHandler::runImpl()
|
|||||||
state.maybe_compressed_in.reset(); /// For more accurate accounting by MemoryTracker.
|
state.maybe_compressed_in.reset(); /// For more accurate accounting by MemoryTracker.
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bool may_have_embedded_data = client_revision >= DBMS_MIN_REVISION_WITH_CLIENT_SUPPORT_EMBEDDED_DATA;
|
||||||
/// Processing Query
|
/// Processing Query
|
||||||
state.io = executeQuery(state.query, query_context, false, state.stage);
|
state.io = executeQuery(state.query, query_context, false, state.stage, may_have_embedded_data);
|
||||||
|
|
||||||
if (state.io.out)
|
if (state.io.out)
|
||||||
state.need_receive_data_for_insert = true;
|
state.need_receive_data_for_insert = true;
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
NOTE: User and query level settings are set up in "users.xml" file.
|
||||||
|
-->
|
||||||
<yandex>
|
<yandex>
|
||||||
<logger>
|
<logger>
|
||||||
<!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger.h#L105 -->
|
<!-- Possible levels: https://github.com/pocoproject/poco/blob/develop/Foundation/include/Poco/Logger.h#L105 -->
|
||||||
|
@ -31,12 +31,13 @@ template <typename Data>
|
|||||||
class AggregateFunctionArgMinMax final : public IAggregateFunctionDataHelper<Data, AggregateFunctionArgMinMax<Data>>
|
class AggregateFunctionArgMinMax final : public IAggregateFunctionDataHelper<Data, AggregateFunctionArgMinMax<Data>>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
DataTypePtr type_res;
|
const DataTypePtr & type_res;
|
||||||
DataTypePtr type_val;
|
const DataTypePtr & type_val;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionArgMinMax(const DataTypePtr & type_res, const DataTypePtr & type_val)
|
AggregateFunctionArgMinMax(const DataTypePtr & type_res, const DataTypePtr & type_val)
|
||||||
: type_res(type_res), type_val(type_val)
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionArgMinMax<Data>>({type_res, type_val}, {}),
|
||||||
|
type_res(this->argument_types[0]), type_val(this->argument_types[1])
|
||||||
{
|
{
|
||||||
if (!type_val->isComparable())
|
if (!type_val->isComparable())
|
||||||
throw Exception("Illegal type " + type_val->getName() + " of second argument of aggregate function " + getName()
|
throw Exception("Illegal type " + type_val->getName() + " of second argument of aggregate function " + getName()
|
||||||
|
@ -28,7 +28,8 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionArray(AggregateFunctionPtr nested_, const DataTypes & arguments)
|
AggregateFunctionArray(AggregateFunctionPtr nested_, const DataTypes & arguments)
|
||||||
: nested_func(nested_), num_arguments(arguments.size())
|
: IAggregateFunctionHelper<AggregateFunctionArray>(arguments, {})
|
||||||
|
, nested_func(nested_), num_arguments(arguments.size())
|
||||||
{
|
{
|
||||||
for (const auto & type : arguments)
|
for (const auto & type : arguments)
|
||||||
if (!isArray(type))
|
if (!isArray(type))
|
||||||
|
@ -27,9 +27,9 @@ AggregateFunctionPtr createAggregateFunctionAvg(const std::string & name, const
|
|||||||
AggregateFunctionPtr res;
|
AggregateFunctionPtr res;
|
||||||
DataTypePtr data_type = argument_types[0];
|
DataTypePtr data_type = argument_types[0];
|
||||||
if (isDecimal(data_type))
|
if (isDecimal(data_type))
|
||||||
res.reset(createWithDecimalType<AggregateFuncAvg>(*data_type, *data_type));
|
res.reset(createWithDecimalType<AggregateFuncAvg>(*data_type, *data_type, argument_types));
|
||||||
else
|
else
|
||||||
res.reset(createWithNumericType<AggregateFuncAvg>(*data_type));
|
res.reset(createWithNumericType<AggregateFuncAvg>(*data_type, argument_types));
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name,
|
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name,
|
||||||
|
@ -49,13 +49,15 @@ public:
|
|||||||
using ColVecResult = std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<Decimal128>, ColumnVector<Float64>>;
|
using ColVecResult = std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<Decimal128>, ColumnVector<Float64>>;
|
||||||
|
|
||||||
/// ctor for native types
|
/// ctor for native types
|
||||||
AggregateFunctionAvg()
|
AggregateFunctionAvg(const DataTypes & argument_types_)
|
||||||
: scale(0)
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionAvg<T, Data>>(argument_types_, {})
|
||||||
|
, scale(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// ctor for Decimals
|
/// ctor for Decimals
|
||||||
AggregateFunctionAvg(const IDataType & data_type)
|
AggregateFunctionAvg(const IDataType & data_type, const DataTypes & argument_types_)
|
||||||
: scale(getDecimalScale(data_type))
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionAvg<T, Data>>(argument_types_, {})
|
||||||
|
, scale(getDecimalScale(data_type))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String getName() const override { return "avg"; }
|
String getName() const override { return "avg"; }
|
||||||
|
@ -21,7 +21,7 @@ AggregateFunctionPtr createAggregateFunctionBitwise(const std::string & name, co
|
|||||||
+ " is illegal, because it cannot be used in bitwise operations",
|
+ " is illegal, because it cannot be used in bitwise operations",
|
||||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithUnsignedIntegerType<AggregateFunctionBitwise, Data>(*argument_types[0]));
|
AggregateFunctionPtr res(createWithUnsignedIntegerType<AggregateFunctionBitwise, Data>(*argument_types[0], argument_types[0]));
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
@ -43,6 +43,9 @@ template <typename T, typename Data>
|
|||||||
class AggregateFunctionBitwise final : public IAggregateFunctionDataHelper<Data, AggregateFunctionBitwise<T, Data>>
|
class AggregateFunctionBitwise final : public IAggregateFunctionDataHelper<Data, AggregateFunctionBitwise<T, Data>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionBitwise(const DataTypePtr & type)
|
||||||
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionBitwise<T, Data>>({type}, {}) {}
|
||||||
|
|
||||||
String getName() const override { return Data::name(); }
|
String getName() const override { return Data::name(); }
|
||||||
|
|
||||||
DataTypePtr getReturnType() const override
|
DataTypePtr getReturnType() const override
|
||||||
|
@ -111,6 +111,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
AggregateFunctionBoundingRatio(const DataTypes & arguments)
|
AggregateFunctionBoundingRatio(const DataTypes & arguments)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionBoundingRatioData, AggregateFunctionBoundingRatio>(arguments, {})
|
||||||
{
|
{
|
||||||
const auto x_arg = arguments.at(0).get();
|
const auto x_arg = arguments.at(0).get();
|
||||||
const auto y_arg = arguments.at(0).get();
|
const auto y_arg = arguments.at(0).get();
|
||||||
|
@ -9,12 +9,12 @@ namespace DB
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
AggregateFunctionPtr createAggregateFunctionCount(const std::string & name, const DataTypes & /*argument_types*/, const Array & parameters)
|
AggregateFunctionPtr createAggregateFunctionCount(const std::string & name, const DataTypes & argument_types, const Array & parameters)
|
||||||
{
|
{
|
||||||
assertNoParameters(name, parameters);
|
assertNoParameters(name, parameters);
|
||||||
|
|
||||||
/// 'count' accept any number of arguments and (in this case of non-Nullable types) simply ignore them.
|
/// 'count' accept any number of arguments and (in this case of non-Nullable types) simply ignore them.
|
||||||
return std::make_shared<AggregateFunctionCount>();
|
return std::make_shared<AggregateFunctionCount>(argument_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ namespace ErrorCodes
|
|||||||
class AggregateFunctionCount final : public IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCount>
|
class AggregateFunctionCount final : public IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCount>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionCount(const DataTypes & argument_types_) : IAggregateFunctionDataHelper(argument_types_, {}) {}
|
||||||
|
|
||||||
String getName() const override { return "count"; }
|
String getName() const override { return "count"; }
|
||||||
|
|
||||||
DataTypePtr getReturnType() const override
|
DataTypePtr getReturnType() const override
|
||||||
@ -74,7 +76,8 @@ public:
|
|||||||
class AggregateFunctionCountNotNullUnary final : public IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCountNotNullUnary>
|
class AggregateFunctionCountNotNullUnary final : public IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCountNotNullUnary>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AggregateFunctionCountNotNullUnary(const DataTypePtr & argument)
|
AggregateFunctionCountNotNullUnary(const DataTypePtr & argument, const Array & params)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCountNotNullUnary>({argument}, params)
|
||||||
{
|
{
|
||||||
if (!argument->isNullable())
|
if (!argument->isNullable())
|
||||||
throw Exception("Logical error: not Nullable data type passed to AggregateFunctionCountNotNullUnary", ErrorCodes::LOGICAL_ERROR);
|
throw Exception("Logical error: not Nullable data type passed to AggregateFunctionCountNotNullUnary", ErrorCodes::LOGICAL_ERROR);
|
||||||
@ -120,7 +123,8 @@ public:
|
|||||||
class AggregateFunctionCountNotNullVariadic final : public IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCountNotNullVariadic>
|
class AggregateFunctionCountNotNullVariadic final : public IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCountNotNullVariadic>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AggregateFunctionCountNotNullVariadic(const DataTypes & arguments)
|
AggregateFunctionCountNotNullVariadic(const DataTypes & arguments, const Array & params)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCountNotNullVariadic>(arguments, params)
|
||||||
{
|
{
|
||||||
number_of_arguments = arguments.size();
|
number_of_arguments = arguments.size();
|
||||||
|
|
||||||
|
@ -26,12 +26,12 @@ AggregateFunctionPtr createAggregateFunctionEntropy(const std::string & name, co
|
|||||||
if (num_args == 1)
|
if (num_args == 1)
|
||||||
{
|
{
|
||||||
/// Specialized implementation for single argument of numeric type.
|
/// Specialized implementation for single argument of numeric type.
|
||||||
if (auto res = createWithNumericBasedType<AggregateFunctionEntropy>(*argument_types[0], num_args))
|
if (auto res = createWithNumericBasedType<AggregateFunctionEntropy>(*argument_types[0], argument_types))
|
||||||
return AggregateFunctionPtr(res);
|
return AggregateFunctionPtr(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic implementation for other types or for multiple arguments.
|
/// Generic implementation for other types or for multiple arguments.
|
||||||
return std::make_shared<AggregateFunctionEntropy<UInt128>>(num_args);
|
return std::make_shared<AggregateFunctionEntropy<UInt128>>(argument_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,9 @@ private:
|
|||||||
size_t num_args;
|
size_t num_args;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionEntropy(size_t num_args) : num_args(num_args)
|
AggregateFunctionEntropy(const DataTypes & argument_types_)
|
||||||
|
: IAggregateFunctionDataHelper<EntropyData<Value>, AggregateFunctionEntropy<Value>>(argument_types_, {})
|
||||||
|
, num_args(argument_types_.size())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,8 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionForEach(AggregateFunctionPtr nested_, const DataTypes & arguments)
|
AggregateFunctionForEach(AggregateFunctionPtr nested_, const DataTypes & arguments)
|
||||||
: nested_func(nested_), num_arguments(arguments.size())
|
: IAggregateFunctionDataHelper<AggregateFunctionForEachData, AggregateFunctionForEach>(arguments, {})
|
||||||
|
, nested_func(nested_), num_arguments(arguments.size())
|
||||||
{
|
{
|
||||||
nested_size_of_data = nested_func->sizeOfData();
|
nested_size_of_data = nested_func->sizeOfData();
|
||||||
|
|
||||||
|
@ -48,12 +48,13 @@ class GroupArrayNumericImpl final
|
|||||||
: public IAggregateFunctionDataHelper<GroupArrayNumericData<T>, GroupArrayNumericImpl<T, Tlimit_num_elems>>
|
: public IAggregateFunctionDataHelper<GroupArrayNumericData<T>, GroupArrayNumericImpl<T, Tlimit_num_elems>>
|
||||||
{
|
{
|
||||||
static constexpr bool limit_num_elems = Tlimit_num_elems::value;
|
static constexpr bool limit_num_elems = Tlimit_num_elems::value;
|
||||||
DataTypePtr data_type;
|
DataTypePtr & data_type;
|
||||||
UInt64 max_elems;
|
UInt64 max_elems;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GroupArrayNumericImpl(const DataTypePtr & data_type_, UInt64 max_elems_ = std::numeric_limits<UInt64>::max())
|
explicit GroupArrayNumericImpl(const DataTypePtr & data_type_, UInt64 max_elems_ = std::numeric_limits<UInt64>::max())
|
||||||
: data_type(data_type_), max_elems(max_elems_) {}
|
: IAggregateFunctionDataHelper<GroupArrayNumericData<T>, GroupArrayNumericImpl<T, Tlimit_num_elems>>({data_type_}, {})
|
||||||
|
, data_type(this->argument_types[0]), max_elems(max_elems_) {}
|
||||||
|
|
||||||
String getName() const override { return "groupArray"; }
|
String getName() const override { return "groupArray"; }
|
||||||
|
|
||||||
@ -248,12 +249,13 @@ class GroupArrayGeneralListImpl final
|
|||||||
static Data & data(AggregateDataPtr place) { return *reinterpret_cast<Data*>(place); }
|
static Data & data(AggregateDataPtr place) { return *reinterpret_cast<Data*>(place); }
|
||||||
static const Data & data(ConstAggregateDataPtr place) { return *reinterpret_cast<const Data*>(place); }
|
static const Data & data(ConstAggregateDataPtr place) { return *reinterpret_cast<const Data*>(place); }
|
||||||
|
|
||||||
DataTypePtr data_type;
|
DataTypePtr & data_type;
|
||||||
UInt64 max_elems;
|
UInt64 max_elems;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GroupArrayGeneralListImpl(const DataTypePtr & data_type, UInt64 max_elems_ = std::numeric_limits<UInt64>::max())
|
GroupArrayGeneralListImpl(const DataTypePtr & data_type, UInt64 max_elems_ = std::numeric_limits<UInt64>::max())
|
||||||
: data_type(data_type), max_elems(max_elems_) {}
|
: IAggregateFunctionDataHelper<GroupArrayGeneralListData<Node>, GroupArrayGeneralListImpl<Node, limit_num_elems>>({data_type}, {})
|
||||||
|
, data_type(this->argument_types[0]), max_elems(max_elems_) {}
|
||||||
|
|
||||||
String getName() const override { return "groupArray"; }
|
String getName() const override { return "groupArray"; }
|
||||||
|
|
||||||
|
@ -13,6 +13,10 @@ namespace
|
|||||||
AggregateFunctionPtr createAggregateFunctionGroupArrayInsertAt(const std::string & name, const DataTypes & argument_types, const Array & parameters)
|
AggregateFunctionPtr createAggregateFunctionGroupArrayInsertAt(const std::string & name, const DataTypes & argument_types, const Array & parameters)
|
||||||
{
|
{
|
||||||
assertBinary(name, argument_types);
|
assertBinary(name, argument_types);
|
||||||
|
|
||||||
|
if (argument_types.size() != 2)
|
||||||
|
throw Exception("Aggregate function groupArrayInsertAt requires two arguments.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
|
|
||||||
return std::make_shared<AggregateFunctionGroupArrayInsertAtGeneric>(argument_types, parameters);
|
return std::make_shared<AggregateFunctionGroupArrayInsertAtGeneric>(argument_types, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,14 @@ class AggregateFunctionGroupArrayInsertAtGeneric final
|
|||||||
: public IAggregateFunctionDataHelper<AggregateFunctionGroupArrayInsertAtDataGeneric, AggregateFunctionGroupArrayInsertAtGeneric>
|
: public IAggregateFunctionDataHelper<AggregateFunctionGroupArrayInsertAtDataGeneric, AggregateFunctionGroupArrayInsertAtGeneric>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
DataTypePtr type;
|
DataTypePtr & type;
|
||||||
Field default_value;
|
Field default_value;
|
||||||
UInt64 length_to_resize = 0; /// zero means - do not do resizing.
|
UInt64 length_to_resize = 0; /// zero means - do not do resizing.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionGroupArrayInsertAtGeneric(const DataTypes & arguments, const Array & params)
|
AggregateFunctionGroupArrayInsertAtGeneric(const DataTypes & arguments, const Array & params)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionGroupArrayInsertAtDataGeneric, AggregateFunctionGroupArrayInsertAtGeneric>(arguments, params)
|
||||||
|
, type(argument_types[0])
|
||||||
{
|
{
|
||||||
if (!params.empty())
|
if (!params.empty())
|
||||||
{
|
{
|
||||||
@ -76,14 +78,9 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments.size() != 2)
|
|
||||||
throw Exception("Aggregate function " + getName() + " requires two arguments.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
||||||
|
|
||||||
if (!isUnsignedInteger(arguments[1]))
|
if (!isUnsignedInteger(arguments[1]))
|
||||||
throw Exception("Second argument of aggregate function " + getName() + " must be integer.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
throw Exception("Second argument of aggregate function " + getName() + " must be integer.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
type = arguments.front();
|
|
||||||
|
|
||||||
if (default_value.isNull())
|
if (default_value.isNull())
|
||||||
default_value = type->getDefault();
|
default_value = type->getDefault();
|
||||||
else
|
else
|
||||||
|
@ -15,11 +15,15 @@ namespace
|
|||||||
/// Substitute return type for Date and DateTime
|
/// Substitute return type for Date and DateTime
|
||||||
class AggregateFunctionGroupUniqArrayDate : public AggregateFunctionGroupUniqArray<DataTypeDate::FieldType>
|
class AggregateFunctionGroupUniqArrayDate : public AggregateFunctionGroupUniqArray<DataTypeDate::FieldType>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
AggregateFunctionGroupUniqArrayDate(const DataTypePtr & argument_type) : AggregateFunctionGroupUniqArray<DataTypeDate::FieldType>(argument_type) {}
|
||||||
DataTypePtr getReturnType() const override { return std::make_shared<DataTypeArray>(std::make_shared<DataTypeDate>()); }
|
DataTypePtr getReturnType() const override { return std::make_shared<DataTypeArray>(std::make_shared<DataTypeDate>()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AggregateFunctionGroupUniqArrayDateTime : public AggregateFunctionGroupUniqArray<DataTypeDateTime::FieldType>
|
class AggregateFunctionGroupUniqArrayDateTime : public AggregateFunctionGroupUniqArray<DataTypeDateTime::FieldType>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
AggregateFunctionGroupUniqArrayDateTime(const DataTypePtr & argument_type) : AggregateFunctionGroupUniqArray<DataTypeDateTime::FieldType>(argument_type) {}
|
||||||
DataTypePtr getReturnType() const override { return std::make_shared<DataTypeArray>(std::make_shared<DataTypeDateTime>()); }
|
DataTypePtr getReturnType() const override { return std::make_shared<DataTypeArray>(std::make_shared<DataTypeDateTime>()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,8 +31,8 @@ class AggregateFunctionGroupUniqArrayDateTime : public AggregateFunctionGroupUni
|
|||||||
static IAggregateFunction * createWithExtraTypes(const DataTypePtr & argument_type)
|
static IAggregateFunction * createWithExtraTypes(const DataTypePtr & argument_type)
|
||||||
{
|
{
|
||||||
WhichDataType which(argument_type);
|
WhichDataType which(argument_type);
|
||||||
if (which.idx == TypeIndex::Date) return new AggregateFunctionGroupUniqArrayDate;
|
if (which.idx == TypeIndex::Date) return new AggregateFunctionGroupUniqArrayDate(argument_type);
|
||||||
else if (which.idx == TypeIndex::DateTime) return new AggregateFunctionGroupUniqArrayDateTime;
|
else if (which.idx == TypeIndex::DateTime) return new AggregateFunctionGroupUniqArrayDateTime(argument_type);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/// Check that we can use plain version of AggreagteFunctionGroupUniqArrayGeneric
|
/// Check that we can use plain version of AggreagteFunctionGroupUniqArrayGeneric
|
||||||
@ -44,7 +48,7 @@ AggregateFunctionPtr createAggregateFunctionGroupUniqArray(const std::string & n
|
|||||||
assertNoParameters(name, parameters);
|
assertNoParameters(name, parameters);
|
||||||
assertUnary(name, argument_types);
|
assertUnary(name, argument_types);
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionGroupUniqArray>(*argument_types[0]));
|
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionGroupUniqArray>(*argument_types[0], argument_types[0]));
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
res = AggregateFunctionPtr(createWithExtraTypes(argument_types[0]));
|
res = AggregateFunctionPtr(createWithExtraTypes(argument_types[0]));
|
||||||
|
@ -44,6 +44,9 @@ private:
|
|||||||
using State = AggregateFunctionGroupUniqArrayData<T>;
|
using State = AggregateFunctionGroupUniqArrayData<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionGroupUniqArray(const DataTypePtr & argument_type)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionGroupUniqArrayData<T>, AggregateFunctionGroupUniqArray<T>>({argument_type}, {}) {}
|
||||||
|
|
||||||
String getName() const override { return "groupUniqArray"; }
|
String getName() const override { return "groupUniqArray"; }
|
||||||
|
|
||||||
DataTypePtr getReturnType() const override
|
DataTypePtr getReturnType() const override
|
||||||
@ -115,7 +118,7 @@ template <bool is_plain_column = false>
|
|||||||
class AggreagteFunctionGroupUniqArrayGeneric
|
class AggreagteFunctionGroupUniqArrayGeneric
|
||||||
: public IAggregateFunctionDataHelper<AggreagteFunctionGroupUniqArrayGenericData, AggreagteFunctionGroupUniqArrayGeneric<is_plain_column>>
|
: public IAggregateFunctionDataHelper<AggreagteFunctionGroupUniqArrayGenericData, AggreagteFunctionGroupUniqArrayGeneric<is_plain_column>>
|
||||||
{
|
{
|
||||||
DataTypePtr input_data_type;
|
DataTypePtr & input_data_type;
|
||||||
|
|
||||||
using State = AggreagteFunctionGroupUniqArrayGenericData;
|
using State = AggreagteFunctionGroupUniqArrayGenericData;
|
||||||
|
|
||||||
@ -125,7 +128,8 @@ class AggreagteFunctionGroupUniqArrayGeneric
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AggreagteFunctionGroupUniqArrayGeneric(const DataTypePtr & input_data_type)
|
AggreagteFunctionGroupUniqArrayGeneric(const DataTypePtr & input_data_type)
|
||||||
: input_data_type(input_data_type) {}
|
: IAggregateFunctionDataHelper<AggreagteFunctionGroupUniqArrayGenericData, AggreagteFunctionGroupUniqArrayGeneric<is_plain_column>>({input_data_type}, {})
|
||||||
|
, input_data_type(this->argument_types[0]) {}
|
||||||
|
|
||||||
String getName() const override { return "groupUniqArray"; }
|
String getName() const override { return "groupUniqArray"; }
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ AggregateFunctionPtr createAggregateFunctionHistogram(const std::string & name,
|
|||||||
throw Exception("Bin count should be positive", ErrorCodes::BAD_ARGUMENTS);
|
throw Exception("Bin count should be positive", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
assertUnary(name, arguments);
|
assertUnary(name, arguments);
|
||||||
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionHistogram>(*arguments[0], bins_count));
|
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionHistogram>(*arguments[0], bins_count, arguments, params));
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal type " + arguments[0]->getName() + " of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
throw Exception("Illegal type " + arguments[0]->getName() + " of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
@ -304,8 +304,9 @@ private:
|
|||||||
const UInt32 max_bins;
|
const UInt32 max_bins;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionHistogram(UInt32 max_bins)
|
AggregateFunctionHistogram(UInt32 max_bins, const DataTypes & arguments, const Array & params)
|
||||||
: max_bins(max_bins)
|
: IAggregateFunctionDataHelper<AggregateFunctionHistogramData, AggregateFunctionHistogram<T>>(arguments, params)
|
||||||
|
, max_bins(max_bins)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,8 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionIf(AggregateFunctionPtr nested, const DataTypes & types)
|
AggregateFunctionIf(AggregateFunctionPtr nested, const DataTypes & types)
|
||||||
: nested_func(nested), num_arguments(types.size())
|
: IAggregateFunctionHelper<AggregateFunctionIf>(types, nested->getParameters())
|
||||||
|
, nested_func(nested), num_arguments(types.size())
|
||||||
{
|
{
|
||||||
if (num_arguments == 0)
|
if (num_arguments == 0)
|
||||||
throw Exception("Aggregate function " + getName() + " require at least one argument", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
throw Exception("Aggregate function " + getName() + " require at least one argument", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
|
@ -59,7 +59,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionIntersectionsMax(AggregateFunctionIntersectionsKind kind_, const DataTypes & arguments)
|
AggregateFunctionIntersectionsMax(AggregateFunctionIntersectionsKind kind_, const DataTypes & arguments)
|
||||||
: kind(kind_)
|
: IAggregateFunctionDataHelper<MaxIntersectionsData<PointType>, AggregateFunctionIntersectionsMax<PointType>>(arguments, {}), kind(kind_)
|
||||||
{
|
{
|
||||||
if (!isNumber(arguments[0]))
|
if (!isNumber(arguments[0]))
|
||||||
throw Exception{getName() + ": first argument must be represented by integer", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
|
throw Exception{getName() + ": first argument must be represented by integer", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
+ ", because it corresponds to different aggregate function: " + function->getFunctionName() + " instead of " + nested_function->getName(),
|
+ ", because it corresponds to different aggregate function: " + function->getFunctionName() + " instead of " + nested_function->getName(),
|
||||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
return std::make_shared<AggregateFunctionMerge>(nested_function, *argument);
|
return std::make_shared<AggregateFunctionMerge>(nested_function, argument);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,13 +22,14 @@ private:
|
|||||||
AggregateFunctionPtr nested_func;
|
AggregateFunctionPtr nested_func;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionMerge(const AggregateFunctionPtr & nested_, const IDataType & argument)
|
AggregateFunctionMerge(const AggregateFunctionPtr & nested_, const DataTypePtr & argument)
|
||||||
: nested_func(nested_)
|
: IAggregateFunctionHelper<AggregateFunctionMerge>({argument}, nested_->getParameters())
|
||||||
|
, nested_func(nested_)
|
||||||
{
|
{
|
||||||
const DataTypeAggregateFunction * data_type = typeid_cast<const DataTypeAggregateFunction *>(&argument);
|
const DataTypeAggregateFunction * data_type = typeid_cast<const DataTypeAggregateFunction *>(argument.get());
|
||||||
|
|
||||||
if (!data_type || data_type->getFunctionName() != nested_func->getName())
|
if (!data_type || data_type->getFunctionName() != nested_func->getName())
|
||||||
throw Exception("Illegal type " + argument.getName() + " of argument for aggregate function " + getName(),
|
throw Exception("Illegal type " + argument->getName() + " of argument for aggregate function " + getName(),
|
||||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,10 +676,12 @@ template <typename Data>
|
|||||||
class AggregateFunctionsSingleValue final : public IAggregateFunctionDataHelper<Data, AggregateFunctionsSingleValue<Data>>
|
class AggregateFunctionsSingleValue final : public IAggregateFunctionDataHelper<Data, AggregateFunctionsSingleValue<Data>>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
DataTypePtr type;
|
DataTypePtr & type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionsSingleValue(const DataTypePtr & type) : type(type)
|
AggregateFunctionsSingleValue(const DataTypePtr & type)
|
||||||
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionsSingleValue<Data>>({type}, {})
|
||||||
|
, type(this->argument_types[0])
|
||||||
{
|
{
|
||||||
if (StringRef(Data::name()) == StringRef("min")
|
if (StringRef(Data::name()) == StringRef("min")
|
||||||
|| StringRef(Data::name()) == StringRef("max"))
|
|| StringRef(Data::name()) == StringRef("max"))
|
||||||
|
@ -15,6 +15,9 @@ namespace DB
|
|||||||
class AggregateFunctionNothing final : public IAggregateFunctionHelper<AggregateFunctionNothing>
|
class AggregateFunctionNothing final : public IAggregateFunctionHelper<AggregateFunctionNothing>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionNothing(const DataTypes & arguments, const Array & params)
|
||||||
|
: IAggregateFunctionHelper<AggregateFunctionNothing>(arguments, params) {}
|
||||||
|
|
||||||
String getName() const override
|
String getName() const override
|
||||||
{
|
{
|
||||||
return "nothing";
|
return "nothing";
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
AggregateFunctionPtr transformAggregateFunction(
|
AggregateFunctionPtr transformAggregateFunction(
|
||||||
const AggregateFunctionPtr & nested_function, const DataTypes & arguments, const Array &) const override
|
const AggregateFunctionPtr & nested_function, const DataTypes & arguments, const Array & params) const override
|
||||||
{
|
{
|
||||||
bool has_nullable_types = false;
|
bool has_nullable_types = false;
|
||||||
bool has_null_types = false;
|
bool has_null_types = false;
|
||||||
@ -55,29 +55,29 @@ public:
|
|||||||
if (nested_function && nested_function->getName() == "count")
|
if (nested_function && nested_function->getName() == "count")
|
||||||
{
|
{
|
||||||
if (arguments.size() == 1)
|
if (arguments.size() == 1)
|
||||||
return std::make_shared<AggregateFunctionCountNotNullUnary>(arguments[0]);
|
return std::make_shared<AggregateFunctionCountNotNullUnary>(arguments[0], params);
|
||||||
else
|
else
|
||||||
return std::make_shared<AggregateFunctionCountNotNullVariadic>(arguments);
|
return std::make_shared<AggregateFunctionCountNotNullVariadic>(arguments, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_null_types)
|
if (has_null_types)
|
||||||
return std::make_shared<AggregateFunctionNothing>();
|
return std::make_shared<AggregateFunctionNothing>(arguments, params);
|
||||||
|
|
||||||
bool return_type_is_nullable = nested_function->getReturnType()->canBeInsideNullable();
|
bool return_type_is_nullable = nested_function->getReturnType()->canBeInsideNullable();
|
||||||
|
|
||||||
if (arguments.size() == 1)
|
if (arguments.size() == 1)
|
||||||
{
|
{
|
||||||
if (return_type_is_nullable)
|
if (return_type_is_nullable)
|
||||||
return std::make_shared<AggregateFunctionNullUnary<true>>(nested_function);
|
return std::make_shared<AggregateFunctionNullUnary<true>>(nested_function, arguments, params);
|
||||||
else
|
else
|
||||||
return std::make_shared<AggregateFunctionNullUnary<false>>(nested_function);
|
return std::make_shared<AggregateFunctionNullUnary<false>>(nested_function, arguments, params);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (return_type_is_nullable)
|
if (return_type_is_nullable)
|
||||||
return std::make_shared<AggregateFunctionNullVariadic<true>>(nested_function, arguments);
|
return std::make_shared<AggregateFunctionNullVariadic<true>>(nested_function, arguments, params);
|
||||||
else
|
else
|
||||||
return std::make_shared<AggregateFunctionNullVariadic<false>>(nested_function, arguments);
|
return std::make_shared<AggregateFunctionNullVariadic<false>>(nested_function, arguments, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -68,8 +68,8 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionNullBase(AggregateFunctionPtr nested_function_)
|
AggregateFunctionNullBase(AggregateFunctionPtr nested_function_, const DataTypes & arguments, const Array & params)
|
||||||
: nested_function{nested_function_}
|
: IAggregateFunctionHelper<Derived>(arguments, params), nested_function{nested_function_}
|
||||||
{
|
{
|
||||||
if (result_is_nullable)
|
if (result_is_nullable)
|
||||||
prefix_size = nested_function->alignOfData();
|
prefix_size = nested_function->alignOfData();
|
||||||
@ -187,8 +187,8 @@ template <bool result_is_nullable>
|
|||||||
class AggregateFunctionNullUnary final : public AggregateFunctionNullBase<result_is_nullable, AggregateFunctionNullUnary<result_is_nullable>>
|
class AggregateFunctionNullUnary final : public AggregateFunctionNullBase<result_is_nullable, AggregateFunctionNullUnary<result_is_nullable>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AggregateFunctionNullUnary(AggregateFunctionPtr nested_function_)
|
AggregateFunctionNullUnary(AggregateFunctionPtr nested_function_, const DataTypes & arguments, const Array & params)
|
||||||
: AggregateFunctionNullBase<result_is_nullable, AggregateFunctionNullUnary<result_is_nullable>>(std::move(nested_function_))
|
: AggregateFunctionNullBase<result_is_nullable, AggregateFunctionNullUnary<result_is_nullable>>(std::move(nested_function_), arguments, params)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,8 +209,8 @@ template <bool result_is_nullable>
|
|||||||
class AggregateFunctionNullVariadic final : public AggregateFunctionNullBase<result_is_nullable, AggregateFunctionNullVariadic<result_is_nullable>>
|
class AggregateFunctionNullVariadic final : public AggregateFunctionNullBase<result_is_nullable, AggregateFunctionNullVariadic<result_is_nullable>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AggregateFunctionNullVariadic(AggregateFunctionPtr nested_function_, const DataTypes & arguments)
|
AggregateFunctionNullVariadic(AggregateFunctionPtr nested_function_, const DataTypes & arguments, const Array & params)
|
||||||
: AggregateFunctionNullBase<result_is_nullable, AggregateFunctionNullVariadic<result_is_nullable>>(std::move(nested_function_)),
|
: AggregateFunctionNullBase<result_is_nullable, AggregateFunctionNullVariadic<result_is_nullable>>(std::move(nested_function_), arguments, params),
|
||||||
number_of_arguments(arguments.size())
|
number_of_arguments(arguments.size())
|
||||||
{
|
{
|
||||||
if (number_of_arguments == 1)
|
if (number_of_arguments == 1)
|
||||||
|
@ -73,11 +73,12 @@ private:
|
|||||||
/// Used when there are single level to get.
|
/// Used when there are single level to get.
|
||||||
Float64 level = 0.5;
|
Float64 level = 0.5;
|
||||||
|
|
||||||
DataTypePtr argument_type;
|
DataTypePtr & argument_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionQuantile(const DataTypePtr & argument_type, const Array & params)
|
AggregateFunctionQuantile(const DataTypePtr & argument_type, const Array & params)
|
||||||
: levels(params, returns_many), level(levels.levels[0]), argument_type(argument_type)
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionQuantile<Value, Data, Name, has_second_arg, FloatReturnType, returns_many>>({argument_type}, params)
|
||||||
|
, levels(params, returns_many), level(levels.levels[0]), argument_type(this->argument_types[0])
|
||||||
{
|
{
|
||||||
if (!returns_many && levels.size() > 1)
|
if (!returns_many && levels.size() > 1)
|
||||||
throw Exception("Aggregate function " + getName() + " require one parameter or less", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
throw Exception("Aggregate function " + getName() + " require one parameter or less", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
@ -174,16 +175,16 @@ public:
|
|||||||
|
|
||||||
const char * getHeaderFilePath() const override { return __FILE__; }
|
const char * getHeaderFilePath() const override { return __FILE__; }
|
||||||
|
|
||||||
static void assertSecondArg(const DataTypes & argument_types)
|
static void assertSecondArg(const DataTypes & types)
|
||||||
{
|
{
|
||||||
if constexpr (has_second_arg)
|
if constexpr (has_second_arg)
|
||||||
{
|
{
|
||||||
assertBinary(Name::name, argument_types);
|
assertBinary(Name::name, types);
|
||||||
if (!isUnsignedInteger(argument_types[1]))
|
if (!isUnsignedInteger(types[1]))
|
||||||
throw Exception("Second argument (weight) for function " + std::string(Name::name) + " must be unsigned integer, but it has type " + argument_types[1]->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
throw Exception("Second argument (weight) for function " + std::string(Name::name) + " must be unsigned integer, but it has type " + types[1]->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assertUnary(Name::name, argument_types);
|
assertUnary(Name::name, types);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
AggregateFunctionRetention(const DataTypes & arguments)
|
AggregateFunctionRetention(const DataTypes & arguments)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionRetentionData, AggregateFunctionRetention>(arguments, {})
|
||||||
{
|
{
|
||||||
for (const auto i : ext::range(0, arguments.size()))
|
for (const auto i : ext::range(0, arguments.size()))
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ AggregateFunctionPtr createAggregateFunctionSequenceCount(const std::string & na
|
|||||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
|
||||||
|
|
||||||
String pattern = params.front().safeGet<std::string>();
|
String pattern = params.front().safeGet<std::string>();
|
||||||
return std::make_shared<AggregateFunctionSequenceCount>(argument_types, pattern);
|
return std::make_shared<AggregateFunctionSequenceCount>(argument_types, params, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
AggregateFunctionPtr createAggregateFunctionSequenceMatch(const std::string & name, const DataTypes & argument_types, const Array & params)
|
AggregateFunctionPtr createAggregateFunctionSequenceMatch(const std::string & name, const DataTypes & argument_types, const Array & params)
|
||||||
@ -29,7 +29,7 @@ AggregateFunctionPtr createAggregateFunctionSequenceMatch(const std::string & na
|
|||||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH};
|
||||||
|
|
||||||
String pattern = params.front().safeGet<std::string>();
|
String pattern = params.front().safeGet<std::string>();
|
||||||
return std::make_shared<AggregateFunctionSequenceMatch>(argument_types, pattern);
|
return std::make_shared<AggregateFunctionSequenceMatch>(argument_types, params, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -139,8 +139,9 @@ template <typename Derived>
|
|||||||
class AggregateFunctionSequenceBase : public IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData, Derived>
|
class AggregateFunctionSequenceBase : public IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData, Derived>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AggregateFunctionSequenceBase(const DataTypes & arguments, const String & pattern)
|
AggregateFunctionSequenceBase(const DataTypes & arguments, const Array & params, const String & pattern)
|
||||||
: pattern(pattern)
|
: IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData, Derived>(arguments, params)
|
||||||
|
, pattern(pattern)
|
||||||
{
|
{
|
||||||
arg_count = arguments.size();
|
arg_count = arguments.size();
|
||||||
|
|
||||||
@ -578,6 +579,9 @@ private:
|
|||||||
class AggregateFunctionSequenceMatch final : public AggregateFunctionSequenceBase<AggregateFunctionSequenceMatch>
|
class AggregateFunctionSequenceMatch final : public AggregateFunctionSequenceBase<AggregateFunctionSequenceMatch>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionSequenceMatch(const DataTypes & arguments, const Array & params, const String & pattern)
|
||||||
|
: AggregateFunctionSequenceBase<AggregateFunctionSequenceMatch>(arguments, params, pattern) {}
|
||||||
|
|
||||||
using AggregateFunctionSequenceBase<AggregateFunctionSequenceMatch>::AggregateFunctionSequenceBase;
|
using AggregateFunctionSequenceBase<AggregateFunctionSequenceMatch>::AggregateFunctionSequenceBase;
|
||||||
|
|
||||||
String getName() const override { return "sequenceMatch"; }
|
String getName() const override { return "sequenceMatch"; }
|
||||||
@ -603,6 +607,9 @@ public:
|
|||||||
class AggregateFunctionSequenceCount final : public AggregateFunctionSequenceBase<AggregateFunctionSequenceCount>
|
class AggregateFunctionSequenceCount final : public AggregateFunctionSequenceBase<AggregateFunctionSequenceCount>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionSequenceCount(const DataTypes & arguments, const Array & params, const String & pattern)
|
||||||
|
: AggregateFunctionSequenceBase<AggregateFunctionSequenceCount>(arguments, params, pattern) {}
|
||||||
|
|
||||||
using AggregateFunctionSequenceBase<AggregateFunctionSequenceCount>::AggregateFunctionSequenceBase;
|
using AggregateFunctionSequenceBase<AggregateFunctionSequenceCount>::AggregateFunctionSequenceBase;
|
||||||
|
|
||||||
String getName() const override { return "sequenceCount"; }
|
String getName() const override { return "sequenceCount"; }
|
||||||
|
@ -24,7 +24,8 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionState(AggregateFunctionPtr nested, const DataTypes & arguments, const Array & params)
|
AggregateFunctionState(AggregateFunctionPtr nested, const DataTypes & arguments, const Array & params)
|
||||||
: nested_func(nested), arguments(arguments), params(params) {}
|
: IAggregateFunctionHelper<AggregateFunctionState>(arguments, params)
|
||||||
|
, nested_func(nested), arguments(arguments), params(params) {}
|
||||||
|
|
||||||
String getName() const override
|
String getName() const override
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,7 @@ AggregateFunctionPtr createAggregateFunctionStatisticsUnary(const std::string &
|
|||||||
assertNoParameters(name, parameters);
|
assertNoParameters(name, parameters);
|
||||||
assertUnary(name, argument_types);
|
assertUnary(name, argument_types);
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithNumericType<FunctionTemplate>(*argument_types[0]));
|
AggregateFunctionPtr res(createWithNumericType<FunctionTemplate>(*argument_types[0], argument_types[0]));
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
@ -35,7 +35,7 @@ AggregateFunctionPtr createAggregateFunctionStatisticsBinary(const std::string &
|
|||||||
assertNoParameters(name, parameters);
|
assertNoParameters(name, parameters);
|
||||||
assertBinary(name, argument_types);
|
assertBinary(name, argument_types);
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithTwoNumericTypes<FunctionTemplate>(*argument_types[0], *argument_types[1]));
|
AggregateFunctionPtr res(createWithTwoNumericTypes<FunctionTemplate>(*argument_types[0], *argument_types[1], argument_types));
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal types " + argument_types[0]->getName() + " and " + argument_types[1]->getName()
|
throw Exception("Illegal types " + argument_types[0]->getName() + " and " + argument_types[1]->getName()
|
||||||
+ " of arguments for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
+ " of arguments for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
@ -111,6 +111,9 @@ class AggregateFunctionVariance final
|
|||||||
: public IAggregateFunctionDataHelper<AggregateFunctionVarianceData<T, Op>, AggregateFunctionVariance<T, Op>>
|
: public IAggregateFunctionDataHelper<AggregateFunctionVarianceData<T, Op>, AggregateFunctionVariance<T, Op>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionVariance(const DataTypePtr & arg)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionVarianceData<T, Op>, AggregateFunctionVariance<T, Op>>({arg}, {}) {}
|
||||||
|
|
||||||
String getName() const override { return Op::name; }
|
String getName() const override { return Op::name; }
|
||||||
|
|
||||||
DataTypePtr getReturnType() const override
|
DataTypePtr getReturnType() const override
|
||||||
@ -361,6 +364,10 @@ class AggregateFunctionCovariance final
|
|||||||
AggregateFunctionCovariance<T, U, Op, compute_marginal_moments>>
|
AggregateFunctionCovariance<T, U, Op, compute_marginal_moments>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionCovariance(const DataTypes & args) : IAggregateFunctionDataHelper<
|
||||||
|
CovarianceData<T, U, Op, compute_marginal_moments>,
|
||||||
|
AggregateFunctionCovariance<T, U, Op, compute_marginal_moments>>(args, {}) {}
|
||||||
|
|
||||||
String getName() const override { return Op::name; }
|
String getName() const override { return Op::name; }
|
||||||
|
|
||||||
DataTypePtr getReturnType() const override
|
DataTypePtr getReturnType() const override
|
||||||
|
@ -288,12 +288,14 @@ public:
|
|||||||
using ResultType = typename StatFunc::ResultType;
|
using ResultType = typename StatFunc::ResultType;
|
||||||
using ColVecResult = ColumnVector<ResultType>;
|
using ColVecResult = ColumnVector<ResultType>;
|
||||||
|
|
||||||
AggregateFunctionVarianceSimple()
|
AggregateFunctionVarianceSimple(const DataTypes & argument_types_)
|
||||||
: src_scale(0)
|
: IAggregateFunctionDataHelper<typename StatFunc::Data, AggregateFunctionVarianceSimple<StatFunc>>(argument_types_, {})
|
||||||
|
, src_scale(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
AggregateFunctionVarianceSimple(const IDataType & data_type)
|
AggregateFunctionVarianceSimple(const IDataType & data_type, const DataTypes & argument_types_)
|
||||||
: src_scale(getDecimalScale(data_type))
|
: IAggregateFunctionDataHelper<typename StatFunc::Data, AggregateFunctionVarianceSimple<StatFunc>>(argument_types_, {})
|
||||||
|
, src_scale(getDecimalScale(data_type))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String getName() const override
|
String getName() const override
|
||||||
|
@ -50,9 +50,9 @@ AggregateFunctionPtr createAggregateFunctionSum(const std::string & name, const
|
|||||||
AggregateFunctionPtr res;
|
AggregateFunctionPtr res;
|
||||||
DataTypePtr data_type = argument_types[0];
|
DataTypePtr data_type = argument_types[0];
|
||||||
if (isDecimal(data_type))
|
if (isDecimal(data_type))
|
||||||
res.reset(createWithDecimalType<Function>(*data_type, *data_type));
|
res.reset(createWithDecimalType<Function>(*data_type, *data_type, argument_types));
|
||||||
else
|
else
|
||||||
res.reset(createWithNumericType<Function>(*data_type));
|
res.reset(createWithNumericType<Function>(*data_type, argument_types));
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name,
|
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name,
|
||||||
|
@ -102,12 +102,14 @@ public:
|
|||||||
|
|
||||||
String getName() const override { return "sum"; }
|
String getName() const override { return "sum"; }
|
||||||
|
|
||||||
AggregateFunctionSum()
|
AggregateFunctionSum(const DataTypes & argument_types_)
|
||||||
: scale(0)
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionSum<T, TResult, Data>>(argument_types_, {})
|
||||||
|
, scale(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
AggregateFunctionSum(const IDataType & data_type)
|
AggregateFunctionSum(const IDataType & data_type, const DataTypes & argument_types_)
|
||||||
: scale(getDecimalScale(data_type))
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionSum<T, TResult, Data>>(argument_types_, {})
|
||||||
|
, scale(getDecimalScale(data_type))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
DataTypePtr getReturnType() const override
|
DataTypePtr getReturnType() const override
|
||||||
|
@ -80,9 +80,9 @@ AggregateFunctionPtr createAggregateFunctionSumMap(const std::string & name, con
|
|||||||
|
|
||||||
auto [keys_type, values_types] = parseArguments(name, arguments);
|
auto [keys_type, values_types] = parseArguments(name, arguments);
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithNumericBasedType<Function>(*keys_type, keys_type, values_types));
|
AggregateFunctionPtr res(createWithNumericBasedType<Function>(*keys_type, keys_type, values_types, arguments));
|
||||||
if (!res)
|
if (!res)
|
||||||
res.reset(createWithDecimalType<Function>(*keys_type, keys_type, values_types));
|
res.reset(createWithDecimalType<Function>(*keys_type, keys_type, values_types, arguments));
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal type of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
throw Exception("Illegal type of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
@ -103,9 +103,9 @@ AggregateFunctionPtr createAggregateFunctionSumMapFiltered(const std::string & n
|
|||||||
|
|
||||||
auto [keys_type, values_types] = parseArguments(name, arguments);
|
auto [keys_type, values_types] = parseArguments(name, arguments);
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithNumericBasedType<Function>(*keys_type, keys_type, values_types, keys_to_keep));
|
AggregateFunctionPtr res(createWithNumericBasedType<Function>(*keys_type, keys_type, values_types, keys_to_keep, arguments, params));
|
||||||
if (!res)
|
if (!res)
|
||||||
res.reset(createWithDecimalType<Function>(*keys_type, keys_type, values_types, keys_to_keep));
|
res.reset(createWithDecimalType<Function>(*keys_type, keys_type, values_types, keys_to_keep, arguments, params));
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal type of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
throw Exception("Illegal type of argument for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
|
@ -61,8 +61,11 @@ private:
|
|||||||
DataTypes values_types;
|
DataTypes values_types;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionSumMapBase(const DataTypePtr & keys_type, const DataTypes & values_types)
|
AggregateFunctionSumMapBase(
|
||||||
: keys_type(keys_type), values_types(values_types) {}
|
const DataTypePtr & keys_type, const DataTypes & values_types,
|
||||||
|
const DataTypes & argument_types_, const Array & params_)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionSumMapData<NearestFieldType<T>>, Derived>(argument_types_, params_)
|
||||||
|
, keys_type(keys_type), values_types(values_types) {}
|
||||||
|
|
||||||
String getName() const override { return "sumMap"; }
|
String getName() const override { return "sumMap"; }
|
||||||
|
|
||||||
@ -271,8 +274,8 @@ private:
|
|||||||
using Base = AggregateFunctionSumMapBase<T, Self, OverflowPolicy>;
|
using Base = AggregateFunctionSumMapBase<T, Self, OverflowPolicy>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionSumMap(const DataTypePtr & keys_type, DataTypes & values_types)
|
AggregateFunctionSumMap(const DataTypePtr & keys_type_, DataTypes & values_types_, const DataTypes & argument_types_)
|
||||||
: Base{keys_type, values_types}
|
: Base{keys_type_, values_types_, argument_types_, {}}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String getName() const override { return "sumMap"; }
|
String getName() const override { return "sumMap"; }
|
||||||
@ -291,8 +294,10 @@ private:
|
|||||||
std::unordered_set<T> keys_to_keep;
|
std::unordered_set<T> keys_to_keep;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionSumMapFiltered(const DataTypePtr & keys_type, const DataTypes & values_types, const Array & keys_to_keep_)
|
AggregateFunctionSumMapFiltered(
|
||||||
: Base{keys_type, values_types}
|
const DataTypePtr & keys_type, const DataTypes & values_types, const Array & keys_to_keep_,
|
||||||
|
const DataTypes & argument_types_, const Array & params_)
|
||||||
|
: Base{keys_type, values_types, argument_types_, params_}
|
||||||
{
|
{
|
||||||
keys_to_keep.reserve(keys_to_keep_.size());
|
keys_to_keep.reserve(keys_to_keep_.size());
|
||||||
for (const Field & f : keys_to_keep_)
|
for (const Field & f : keys_to_keep_)
|
||||||
|
@ -39,19 +39,19 @@ class AggregateFunctionTopKDateTime : public AggregateFunctionTopK<DataTypeDateT
|
|||||||
|
|
||||||
|
|
||||||
template <bool is_weighted>
|
template <bool is_weighted>
|
||||||
static IAggregateFunction * createWithExtraTypes(const DataTypePtr & argument_type, UInt64 threshold)
|
static IAggregateFunction * createWithExtraTypes(const DataTypePtr & argument_type, UInt64 threshold, const Array & params)
|
||||||
{
|
{
|
||||||
WhichDataType which(argument_type);
|
WhichDataType which(argument_type);
|
||||||
if (which.idx == TypeIndex::Date)
|
if (which.idx == TypeIndex::Date)
|
||||||
return new AggregateFunctionTopKDate<is_weighted>(threshold);
|
return new AggregateFunctionTopKDate<is_weighted>(threshold, {argument_type}, params);
|
||||||
if (which.idx == TypeIndex::DateTime)
|
if (which.idx == TypeIndex::DateTime)
|
||||||
return new AggregateFunctionTopKDateTime<is_weighted>(threshold);
|
return new AggregateFunctionTopKDateTime<is_weighted>(threshold, {argument_type}, params);
|
||||||
|
|
||||||
/// Check that we can use plain version of AggregateFunctionTopKGeneric
|
/// Check that we can use plain version of AggregateFunctionTopKGeneric
|
||||||
if (argument_type->isValueUnambiguouslyRepresentedInContiguousMemoryRegion())
|
if (argument_type->isValueUnambiguouslyRepresentedInContiguousMemoryRegion())
|
||||||
return new AggregateFunctionTopKGeneric<true, is_weighted>(threshold, argument_type);
|
return new AggregateFunctionTopKGeneric<true, is_weighted>(threshold, argument_type, params);
|
||||||
else
|
else
|
||||||
return new AggregateFunctionTopKGeneric<false, is_weighted>(threshold, argument_type);
|
return new AggregateFunctionTopKGeneric<false, is_weighted>(threshold, argument_type, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -90,10 +90,10 @@ AggregateFunctionPtr createAggregateFunctionTopK(const std::string & name, const
|
|||||||
threshold = k;
|
threshold = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionTopK, is_weighted>(*argument_types[0], threshold));
|
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionTopK, is_weighted>(*argument_types[0], threshold, argument_types, params));
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
res = AggregateFunctionPtr(createWithExtraTypes<is_weighted>(argument_types[0], threshold));
|
res = AggregateFunctionPtr(createWithExtraTypes<is_weighted>(argument_types[0], threshold, params));
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal type " + argument_types[0]->getName() +
|
throw Exception("Illegal type " + argument_types[0]->getName() +
|
||||||
|
@ -48,8 +48,9 @@ protected:
|
|||||||
UInt64 reserved;
|
UInt64 reserved;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionTopK(UInt64 threshold)
|
AggregateFunctionTopK(UInt64 threshold, const DataTypes & argument_types_, const Array & params)
|
||||||
: threshold(threshold), reserved(TOP_K_LOAD_FACTOR * threshold) {}
|
: IAggregateFunctionDataHelper<AggregateFunctionTopKData<T>, AggregateFunctionTopK<T, is_weighted>>(argument_types_, params)
|
||||||
|
, threshold(threshold), reserved(TOP_K_LOAD_FACTOR * threshold) {}
|
||||||
|
|
||||||
String getName() const override { return is_weighted ? "topKWeighted" : "topK"; }
|
String getName() const override { return is_weighted ? "topKWeighted" : "topK"; }
|
||||||
|
|
||||||
@ -136,13 +137,15 @@ private:
|
|||||||
|
|
||||||
UInt64 threshold;
|
UInt64 threshold;
|
||||||
UInt64 reserved;
|
UInt64 reserved;
|
||||||
DataTypePtr input_data_type;
|
DataTypePtr & input_data_type;
|
||||||
|
|
||||||
static void deserializeAndInsert(StringRef str, IColumn & data_to);
|
static void deserializeAndInsert(StringRef str, IColumn & data_to);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionTopKGeneric(UInt64 threshold, const DataTypePtr & input_data_type)
|
AggregateFunctionTopKGeneric(
|
||||||
: threshold(threshold), reserved(TOP_K_LOAD_FACTOR * threshold), input_data_type(input_data_type) {}
|
UInt64 threshold, const DataTypePtr & input_data_type, const Array & params)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionTopKGenericData, AggregateFunctionTopKGeneric<is_plain_column, is_weighted>>({input_data_type}, params)
|
||||||
|
, threshold(threshold), reserved(TOP_K_LOAD_FACTOR * threshold), input_data_type(this->argument_types[0]) {}
|
||||||
|
|
||||||
String getName() const override { return is_weighted ? "topKWeighted" : "topK"; }
|
String getName() const override { return is_weighted ? "topKWeighted" : "topK"; }
|
||||||
|
|
||||||
|
@ -43,19 +43,19 @@ AggregateFunctionPtr createAggregateFunctionUniq(const std::string & name, const
|
|||||||
{
|
{
|
||||||
const IDataType & argument_type = *argument_types[0];
|
const IDataType & argument_type = *argument_types[0];
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionUniq, Data>(*argument_types[0]));
|
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionUniq, Data>(*argument_types[0], argument_types));
|
||||||
|
|
||||||
WhichDataType which(argument_type);
|
WhichDataType which(argument_type);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
else if (which.isDate())
|
else if (which.isDate())
|
||||||
return std::make_shared<AggregateFunctionUniq<DataTypeDate::FieldType, Data>>();
|
return std::make_shared<AggregateFunctionUniq<DataTypeDate::FieldType, Data>>(argument_types);
|
||||||
else if (which.isDateTime())
|
else if (which.isDateTime())
|
||||||
return std::make_shared<AggregateFunctionUniq<DataTypeDateTime::FieldType, Data>>();
|
return std::make_shared<AggregateFunctionUniq<DataTypeDateTime::FieldType, Data>>(argument_types);
|
||||||
else if (which.isStringOrFixedString())
|
else if (which.isStringOrFixedString())
|
||||||
return std::make_shared<AggregateFunctionUniq<String, Data>>();
|
return std::make_shared<AggregateFunctionUniq<String, Data>>(argument_types);
|
||||||
else if (which.isUUID())
|
else if (which.isUUID())
|
||||||
return std::make_shared<AggregateFunctionUniq<DataTypeUUID::FieldType, Data>>();
|
return std::make_shared<AggregateFunctionUniq<DataTypeUUID::FieldType, Data>>(argument_types);
|
||||||
else if (which.isTuple())
|
else if (which.isTuple())
|
||||||
{
|
{
|
||||||
if (use_exact_hash_function)
|
if (use_exact_hash_function)
|
||||||
@ -89,19 +89,19 @@ AggregateFunctionPtr createAggregateFunctionUniq(const std::string & name, const
|
|||||||
{
|
{
|
||||||
const IDataType & argument_type = *argument_types[0];
|
const IDataType & argument_type = *argument_types[0];
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionUniq, Data>(*argument_types[0]));
|
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionUniq, Data>(*argument_types[0], argument_types));
|
||||||
|
|
||||||
WhichDataType which(argument_type);
|
WhichDataType which(argument_type);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
else if (which.isDate())
|
else if (which.isDate())
|
||||||
return std::make_shared<AggregateFunctionUniq<DataTypeDate::FieldType, Data<DataTypeDate::FieldType>>>();
|
return std::make_shared<AggregateFunctionUniq<DataTypeDate::FieldType, Data<DataTypeDate::FieldType>>>(argument_types);
|
||||||
else if (which.isDateTime())
|
else if (which.isDateTime())
|
||||||
return std::make_shared<AggregateFunctionUniq<DataTypeDateTime::FieldType, Data<DataTypeDateTime::FieldType>>>();
|
return std::make_shared<AggregateFunctionUniq<DataTypeDateTime::FieldType, Data<DataTypeDateTime::FieldType>>>(argument_types);
|
||||||
else if (which.isStringOrFixedString())
|
else if (which.isStringOrFixedString())
|
||||||
return std::make_shared<AggregateFunctionUniq<String, Data<String>>>();
|
return std::make_shared<AggregateFunctionUniq<String, Data<String>>>(argument_types);
|
||||||
else if (which.isUUID())
|
else if (which.isUUID())
|
||||||
return std::make_shared<AggregateFunctionUniq<DataTypeUUID::FieldType, Data<DataTypeUUID::FieldType>>>();
|
return std::make_shared<AggregateFunctionUniq<DataTypeUUID::FieldType, Data<DataTypeUUID::FieldType>>>(argument_types);
|
||||||
else if (which.isTuple())
|
else if (which.isTuple())
|
||||||
{
|
{
|
||||||
if (use_exact_hash_function)
|
if (use_exact_hash_function)
|
||||||
|
@ -209,6 +209,9 @@ template <typename T, typename Data>
|
|||||||
class AggregateFunctionUniq final : public IAggregateFunctionDataHelper<Data, AggregateFunctionUniq<T, Data>>
|
class AggregateFunctionUniq final : public IAggregateFunctionDataHelper<Data, AggregateFunctionUniq<T, Data>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionUniq(const DataTypes & argument_types_)
|
||||||
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionUniq<T, Data>>(argument_types_, {}) {}
|
||||||
|
|
||||||
String getName() const override { return Data::getName(); }
|
String getName() const override { return Data::getName(); }
|
||||||
|
|
||||||
DataTypePtr getReturnType() const override
|
DataTypePtr getReturnType() const override
|
||||||
@ -257,6 +260,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionUniqVariadic(const DataTypes & arguments)
|
AggregateFunctionUniqVariadic(const DataTypes & arguments)
|
||||||
|
: IAggregateFunctionDataHelper<Data, AggregateFunctionUniqVariadic<Data, is_exact, argument_is_tuple>>(arguments, {})
|
||||||
{
|
{
|
||||||
if (argument_is_tuple)
|
if (argument_is_tuple)
|
||||||
num_args = typeid_cast<const DataTypeTuple &>(*arguments[0]).getElements().size();
|
num_args = typeid_cast<const DataTypeTuple &>(*arguments[0]).getElements().size();
|
||||||
|
@ -28,7 +28,7 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <UInt8 K>
|
template <UInt8 K>
|
||||||
AggregateFunctionPtr createAggregateFunctionWithK(const DataTypes & argument_types)
|
AggregateFunctionPtr createAggregateFunctionWithK(const DataTypes & argument_types, const Array & params)
|
||||||
{
|
{
|
||||||
/// We use exact hash function if the arguments are not contiguous in memory, because only exact hash function has support for this case.
|
/// We use exact hash function if the arguments are not contiguous in memory, because only exact hash function has support for this case.
|
||||||
bool use_exact_hash_function = !isAllArgumentsContiguousInMemory(argument_types);
|
bool use_exact_hash_function = !isAllArgumentsContiguousInMemory(argument_types);
|
||||||
@ -37,33 +37,33 @@ namespace
|
|||||||
{
|
{
|
||||||
const IDataType & argument_type = *argument_types[0];
|
const IDataType & argument_type = *argument_types[0];
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithNumericType<WithK<K>::template AggregateFunction>(*argument_types[0]));
|
AggregateFunctionPtr res(createWithNumericType<WithK<K>::template AggregateFunction>(*argument_types[0], argument_types, params));
|
||||||
|
|
||||||
WhichDataType which(argument_type);
|
WhichDataType which(argument_type);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
else if (which.isDate())
|
else if (which.isDate())
|
||||||
return std::make_shared<typename WithK<K>::template AggregateFunction<DataTypeDate::FieldType>>();
|
return std::make_shared<typename WithK<K>::template AggregateFunction<DataTypeDate::FieldType>>(argument_types, params);
|
||||||
else if (which.isDateTime())
|
else if (which.isDateTime())
|
||||||
return std::make_shared<typename WithK<K>::template AggregateFunction<DataTypeDateTime::FieldType>>();
|
return std::make_shared<typename WithK<K>::template AggregateFunction<DataTypeDateTime::FieldType>>(argument_types, params);
|
||||||
else if (which.isStringOrFixedString())
|
else if (which.isStringOrFixedString())
|
||||||
return std::make_shared<typename WithK<K>::template AggregateFunction<String>>();
|
return std::make_shared<typename WithK<K>::template AggregateFunction<String>>(argument_types, params);
|
||||||
else if (which.isUUID())
|
else if (which.isUUID())
|
||||||
return std::make_shared<typename WithK<K>::template AggregateFunction<DataTypeUUID::FieldType>>();
|
return std::make_shared<typename WithK<K>::template AggregateFunction<DataTypeUUID::FieldType>>(argument_types, params);
|
||||||
else if (which.isTuple())
|
else if (which.isTuple())
|
||||||
{
|
{
|
||||||
if (use_exact_hash_function)
|
if (use_exact_hash_function)
|
||||||
return std::make_shared<typename WithK<K>::template AggregateFunctionVariadic<true, true>>(argument_types);
|
return std::make_shared<typename WithK<K>::template AggregateFunctionVariadic<true, true>>(argument_types, params);
|
||||||
else
|
else
|
||||||
return std::make_shared<typename WithK<K>::template AggregateFunctionVariadic<false, true>>(argument_types);
|
return std::make_shared<typename WithK<K>::template AggregateFunctionVariadic<false, true>>(argument_types, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "Variadic" method also works as a fallback generic case for a single argument.
|
/// "Variadic" method also works as a fallback generic case for a single argument.
|
||||||
if (use_exact_hash_function)
|
if (use_exact_hash_function)
|
||||||
return std::make_shared<typename WithK<K>::template AggregateFunctionVariadic<true, false>>(argument_types);
|
return std::make_shared<typename WithK<K>::template AggregateFunctionVariadic<true, false>>(argument_types, params);
|
||||||
else
|
else
|
||||||
return std::make_shared<typename WithK<K>::template AggregateFunctionVariadic<false, false>>(argument_types);
|
return std::make_shared<typename WithK<K>::template AggregateFunctionVariadic<false, false>>(argument_types, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
AggregateFunctionPtr createAggregateFunctionUniqCombined(
|
AggregateFunctionPtr createAggregateFunctionUniqCombined(
|
||||||
@ -95,23 +95,23 @@ namespace
|
|||||||
switch (precision)
|
switch (precision)
|
||||||
{
|
{
|
||||||
case 12:
|
case 12:
|
||||||
return createAggregateFunctionWithK<12>(argument_types);
|
return createAggregateFunctionWithK<12>(argument_types, params);
|
||||||
case 13:
|
case 13:
|
||||||
return createAggregateFunctionWithK<13>(argument_types);
|
return createAggregateFunctionWithK<13>(argument_types, params);
|
||||||
case 14:
|
case 14:
|
||||||
return createAggregateFunctionWithK<14>(argument_types);
|
return createAggregateFunctionWithK<14>(argument_types, params);
|
||||||
case 15:
|
case 15:
|
||||||
return createAggregateFunctionWithK<15>(argument_types);
|
return createAggregateFunctionWithK<15>(argument_types, params);
|
||||||
case 16:
|
case 16:
|
||||||
return createAggregateFunctionWithK<16>(argument_types);
|
return createAggregateFunctionWithK<16>(argument_types, params);
|
||||||
case 17:
|
case 17:
|
||||||
return createAggregateFunctionWithK<17>(argument_types);
|
return createAggregateFunctionWithK<17>(argument_types, params);
|
||||||
case 18:
|
case 18:
|
||||||
return createAggregateFunctionWithK<18>(argument_types);
|
return createAggregateFunctionWithK<18>(argument_types, params);
|
||||||
case 19:
|
case 19:
|
||||||
return createAggregateFunctionWithK<19>(argument_types);
|
return createAggregateFunctionWithK<19>(argument_types, params);
|
||||||
case 20:
|
case 20:
|
||||||
return createAggregateFunctionWithK<20>(argument_types);
|
return createAggregateFunctionWithK<20>(argument_types, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
|
@ -114,6 +114,9 @@ class AggregateFunctionUniqCombined final
|
|||||||
: public IAggregateFunctionDataHelper<AggregateFunctionUniqCombinedData<T, K>, AggregateFunctionUniqCombined<T, K>>
|
: public IAggregateFunctionDataHelper<AggregateFunctionUniqCombinedData<T, K>, AggregateFunctionUniqCombined<T, K>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
AggregateFunctionUniqCombined(const DataTypes & argument_types_, const Array & params_)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionUniqCombinedData<T, K>, AggregateFunctionUniqCombined<T, K>>(argument_types_, params_) {}
|
||||||
|
|
||||||
String getName() const override
|
String getName() const override
|
||||||
{
|
{
|
||||||
return "uniqCombined";
|
return "uniqCombined";
|
||||||
@ -176,7 +179,9 @@ private:
|
|||||||
size_t num_args = 0;
|
size_t num_args = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AggregateFunctionUniqCombinedVariadic(const DataTypes & arguments)
|
explicit AggregateFunctionUniqCombinedVariadic(const DataTypes & arguments, const Array & params)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionUniqCombinedData<UInt64, K>,
|
||||||
|
AggregateFunctionUniqCombinedVariadic<is_exact, argument_is_tuple, K>>(arguments, params)
|
||||||
{
|
{
|
||||||
if (argument_is_tuple)
|
if (argument_is_tuple)
|
||||||
num_args = typeid_cast<const DataTypeTuple &>(*arguments[0]).getElements().size();
|
num_args = typeid_cast<const DataTypeTuple &>(*arguments[0]).getElements().size();
|
||||||
|
@ -52,33 +52,33 @@ AggregateFunctionPtr createAggregateFunctionUniqUpTo(const std::string & name, c
|
|||||||
{
|
{
|
||||||
const IDataType & argument_type = *argument_types[0];
|
const IDataType & argument_type = *argument_types[0];
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionUniqUpTo>(*argument_types[0], threshold));
|
AggregateFunctionPtr res(createWithNumericType<AggregateFunctionUniqUpTo>(*argument_types[0], threshold, argument_types, params));
|
||||||
|
|
||||||
WhichDataType which(argument_type);
|
WhichDataType which(argument_type);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
else if (which.isDate())
|
else if (which.isDate())
|
||||||
return std::make_shared<AggregateFunctionUniqUpTo<DataTypeDate::FieldType>>(threshold);
|
return std::make_shared<AggregateFunctionUniqUpTo<DataTypeDate::FieldType>>(threshold, argument_types, params);
|
||||||
else if (which.isDateTime())
|
else if (which.isDateTime())
|
||||||
return std::make_shared<AggregateFunctionUniqUpTo<DataTypeDateTime::FieldType>>(threshold);
|
return std::make_shared<AggregateFunctionUniqUpTo<DataTypeDateTime::FieldType>>(threshold, argument_types, params);
|
||||||
else if (which.isStringOrFixedString())
|
else if (which.isStringOrFixedString())
|
||||||
return std::make_shared<AggregateFunctionUniqUpTo<String>>(threshold);
|
return std::make_shared<AggregateFunctionUniqUpTo<String>>(threshold, argument_types, params);
|
||||||
else if (which.isUUID())
|
else if (which.isUUID())
|
||||||
return std::make_shared<AggregateFunctionUniqUpTo<DataTypeUUID::FieldType>>(threshold);
|
return std::make_shared<AggregateFunctionUniqUpTo<DataTypeUUID::FieldType>>(threshold, argument_types, params);
|
||||||
else if (which.isTuple())
|
else if (which.isTuple())
|
||||||
{
|
{
|
||||||
if (use_exact_hash_function)
|
if (use_exact_hash_function)
|
||||||
return std::make_shared<AggregateFunctionUniqUpToVariadic<true, true>>(argument_types, threshold);
|
return std::make_shared<AggregateFunctionUniqUpToVariadic<true, true>>(argument_types, params, threshold);
|
||||||
else
|
else
|
||||||
return std::make_shared<AggregateFunctionUniqUpToVariadic<false, true>>(argument_types, threshold);
|
return std::make_shared<AggregateFunctionUniqUpToVariadic<false, true>>(argument_types, params, threshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "Variadic" method also works as a fallback generic case for single argument.
|
/// "Variadic" method also works as a fallback generic case for single argument.
|
||||||
if (use_exact_hash_function)
|
if (use_exact_hash_function)
|
||||||
return std::make_shared<AggregateFunctionUniqUpToVariadic<true, false>>(argument_types, threshold);
|
return std::make_shared<AggregateFunctionUniqUpToVariadic<true, false>>(argument_types, params, threshold);
|
||||||
else
|
else
|
||||||
return std::make_shared<AggregateFunctionUniqUpToVariadic<false, false>>(argument_types, threshold);
|
return std::make_shared<AggregateFunctionUniqUpToVariadic<false, false>>(argument_types, params, threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -136,8 +136,9 @@ private:
|
|||||||
UInt8 threshold;
|
UInt8 threshold;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionUniqUpTo(UInt8 threshold)
|
AggregateFunctionUniqUpTo(UInt8 threshold, const DataTypes & argument_types_, const Array & params_)
|
||||||
: threshold(threshold)
|
: IAggregateFunctionDataHelper<AggregateFunctionUniqUpToData<T>, AggregateFunctionUniqUpTo<T>>(argument_types_, params_)
|
||||||
|
, threshold(threshold)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,8 +196,9 @@ private:
|
|||||||
UInt8 threshold;
|
UInt8 threshold;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggregateFunctionUniqUpToVariadic(const DataTypes & arguments, UInt8 threshold)
|
AggregateFunctionUniqUpToVariadic(const DataTypes & arguments, const Array & params, UInt8 threshold)
|
||||||
: threshold(threshold)
|
: IAggregateFunctionDataHelper<AggregateFunctionUniqUpToData<UInt64>, AggregateFunctionUniqUpToVariadic<is_exact, argument_is_tuple>>(arguments, params)
|
||||||
|
, threshold(threshold)
|
||||||
{
|
{
|
||||||
if (argument_is_tuple)
|
if (argument_is_tuple)
|
||||||
num_args = typeid_cast<const DataTypeTuple &>(*arguments[0]).getElements().size();
|
num_args = typeid_cast<const DataTypeTuple &>(*arguments[0]).getElements().size();
|
||||||
|
@ -189,6 +189,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
AggregateFunctionWindowFunnel(const DataTypes & arguments, const Array & params)
|
AggregateFunctionWindowFunnel(const DataTypes & arguments, const Array & params)
|
||||||
|
: IAggregateFunctionDataHelper<AggregateFunctionWindowFunnelData, AggregateFunctionWindowFunnel>(arguments, params)
|
||||||
{
|
{
|
||||||
const auto time_arg = arguments.front().get();
|
const auto time_arg = arguments.front().get();
|
||||||
if (!WhichDataType(time_arg).isDateTime() && !WhichDataType(time_arg).isUInt32())
|
if (!WhichDataType(time_arg).isDateTime() && !WhichDataType(time_arg).isUInt32())
|
||||||
|
@ -24,9 +24,9 @@ AggregateFunctionPtr createAggregateFunctionStatisticsUnary(const std::string &
|
|||||||
AggregateFunctionPtr res;
|
AggregateFunctionPtr res;
|
||||||
DataTypePtr data_type = argument_types[0];
|
DataTypePtr data_type = argument_types[0];
|
||||||
if (isDecimal(data_type))
|
if (isDecimal(data_type))
|
||||||
res.reset(createWithDecimalType<FunctionTemplate>(*data_type, *data_type));
|
res.reset(createWithDecimalType<FunctionTemplate>(*data_type, *data_type, argument_types));
|
||||||
else
|
else
|
||||||
res.reset(createWithNumericType<FunctionTemplate>(*data_type));
|
res.reset(createWithNumericType<FunctionTemplate>(*data_type, argument_types));
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name,
|
throw Exception("Illegal type " + argument_types[0]->getName() + " of argument for aggregate function " + name,
|
||||||
@ -40,7 +40,7 @@ AggregateFunctionPtr createAggregateFunctionStatisticsBinary(const std::string &
|
|||||||
assertNoParameters(name, parameters);
|
assertNoParameters(name, parameters);
|
||||||
assertBinary(name, argument_types);
|
assertBinary(name, argument_types);
|
||||||
|
|
||||||
AggregateFunctionPtr res(createWithTwoNumericTypes<FunctionTemplate>(*argument_types[0], *argument_types[1]));
|
AggregateFunctionPtr res(createWithTwoNumericTypes<FunctionTemplate>(*argument_types[0], *argument_types[1], argument_types));
|
||||||
if (!res)
|
if (!res)
|
||||||
throw Exception("Illegal types " + argument_types[0]->getName() + " and " + argument_types[1]->getName()
|
throw Exception("Illegal types " + argument_types[0]->getName() + " and " + argument_types[1]->getName()
|
||||||
+ " of arguments for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
+ " of arguments for aggregate function " + name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
@ -37,6 +37,9 @@ using ConstAggregateDataPtr = const char *;
|
|||||||
class IAggregateFunction
|
class IAggregateFunction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
IAggregateFunction(const DataTypes & argument_types_, const Array & parameters_)
|
||||||
|
: argument_types(argument_types_), parameters(parameters_) {}
|
||||||
|
|
||||||
/// Get main function name.
|
/// Get main function name.
|
||||||
virtual String getName() const = 0;
|
virtual String getName() const = 0;
|
||||||
|
|
||||||
@ -108,6 +111,13 @@ public:
|
|||||||
* const char * getHeaderFilePath() const override { return __FILE__; }
|
* const char * getHeaderFilePath() const override { return __FILE__; }
|
||||||
*/
|
*/
|
||||||
virtual const char * getHeaderFilePath() const = 0;
|
virtual const char * getHeaderFilePath() const = 0;
|
||||||
|
|
||||||
|
const DataTypes & getArgumentTypes() const { return argument_types; }
|
||||||
|
const Array & getParameters() const { return parameters; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DataTypes argument_types;
|
||||||
|
Array parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -122,6 +132,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
IAggregateFunctionHelper(const DataTypes & argument_types_, const Array & parameters_)
|
||||||
|
: IAggregateFunction(argument_types_, parameters_) {}
|
||||||
AddFunc getAddressOfAddFunction() const override { return &addFree; }
|
AddFunc getAddressOfAddFunction() const override { return &addFree; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,6 +149,10 @@ protected:
|
|||||||
static const Data & data(ConstAggregateDataPtr place) { return *reinterpret_cast<const Data*>(place); }
|
static const Data & data(ConstAggregateDataPtr place) { return *reinterpret_cast<const Data*>(place); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
IAggregateFunctionDataHelper(const DataTypes & argument_types_, const Array & parameters_)
|
||||||
|
: IAggregateFunctionHelper<Derived>(argument_types_, parameters_) {}
|
||||||
|
|
||||||
void create(AggregateDataPtr place) const override
|
void create(AggregateDataPtr place) const override
|
||||||
{
|
{
|
||||||
new (place) Data;
|
new (place) Data;
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <AggregateFunctions/AggregateFunctionState.h>
|
#include <AggregateFunctions/AggregateFunctionState.h>
|
||||||
#include <DataStreams/ColumnGathererStream.h>
|
#include <DataStreams/ColumnGathererStream.h>
|
||||||
#include <IO/WriteBufferFromArena.h>
|
#include <IO/WriteBufferFromArena.h>
|
||||||
|
#include <IO/WriteBufferFromString.h>
|
||||||
|
#include <IO/Operators.h>
|
||||||
#include <Common/SipHash.h>
|
#include <Common/SipHash.h>
|
||||||
#include <Common/AlignedBuffer.h>
|
#include <Common/AlignedBuffer.h>
|
||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
@ -258,11 +260,17 @@ MutableColumnPtr ColumnAggregateFunction::cloneEmpty() const
|
|||||||
return create(func, Arenas(1, std::make_shared<Arena>()));
|
return create(func, Arenas(1, std::make_shared<Arena>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String ColumnAggregateFunction::getTypeString() const
|
||||||
|
{
|
||||||
|
return DataTypeAggregateFunction(func, func->getArgumentTypes(), func->getParameters()).getName();
|
||||||
|
}
|
||||||
|
|
||||||
Field ColumnAggregateFunction::operator[](size_t n) const
|
Field ColumnAggregateFunction::operator[](size_t n) const
|
||||||
{
|
{
|
||||||
Field field = String();
|
Field field = AggregateFunctionStateData();
|
||||||
|
field.get<AggregateFunctionStateData &>().name = getTypeString();
|
||||||
{
|
{
|
||||||
WriteBufferFromString buffer(field.get<String &>());
|
WriteBufferFromString buffer(field.get<AggregateFunctionStateData &>().data);
|
||||||
func->serialize(data[n], buffer);
|
func->serialize(data[n], buffer);
|
||||||
}
|
}
|
||||||
return field;
|
return field;
|
||||||
@ -270,9 +278,10 @@ Field ColumnAggregateFunction::operator[](size_t n) const
|
|||||||
|
|
||||||
void ColumnAggregateFunction::get(size_t n, Field & res) const
|
void ColumnAggregateFunction::get(size_t n, Field & res) const
|
||||||
{
|
{
|
||||||
res = String();
|
res = AggregateFunctionStateData();
|
||||||
|
res.get<AggregateFunctionStateData &>().name = getTypeString();
|
||||||
{
|
{
|
||||||
WriteBufferFromString buffer(res.get<String &>());
|
WriteBufferFromString buffer(res.get<AggregateFunctionStateData &>().data);
|
||||||
func->serialize(data[n], buffer);
|
func->serialize(data[n], buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -337,13 +346,23 @@ static void pushBackAndCreateState(ColumnAggregateFunction::Container & data, Ar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ColumnAggregateFunction::insert(const Field & x)
|
void ColumnAggregateFunction::insert(const Field & x)
|
||||||
{
|
{
|
||||||
|
String type_string = getTypeString();
|
||||||
|
|
||||||
|
if (x.getType() != Field::Types::AggregateFunctionState)
|
||||||
|
throw Exception(String("Inserting field of type ") + x.getTypeName() + " into ColumnAggregateFunction. "
|
||||||
|
"Expected " + Field::Types::toString(Field::Types::AggregateFunctionState), ErrorCodes::LOGICAL_ERROR);
|
||||||
|
|
||||||
|
auto & field_name = x.get<const AggregateFunctionStateData &>().name;
|
||||||
|
if (type_string != field_name)
|
||||||
|
throw Exception("Cannot insert filed with type " + field_name + " into column with type " + type_string,
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
ensureOwnership();
|
ensureOwnership();
|
||||||
Arena & arena = createOrGetArena();
|
Arena & arena = createOrGetArena();
|
||||||
pushBackAndCreateState(data, arena, func.get());
|
pushBackAndCreateState(data, arena, func.get());
|
||||||
ReadBufferFromString read_buffer(x.get<const String &>());
|
ReadBufferFromString read_buffer(x.get<const AggregateFunctionStateData &>().data);
|
||||||
func->deserialize(data.back(), read_buffer, &arena);
|
func->deserialize(data.back(), read_buffer, &arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,12 +484,13 @@ void ColumnAggregateFunction::getExtremes(Field & min, Field & max) const
|
|||||||
AlignedBuffer place_buffer(func->sizeOfData(), func->alignOfData());
|
AlignedBuffer place_buffer(func->sizeOfData(), func->alignOfData());
|
||||||
AggregateDataPtr place = place_buffer.data();
|
AggregateDataPtr place = place_buffer.data();
|
||||||
|
|
||||||
String serialized;
|
AggregateFunctionStateData serialized;
|
||||||
|
serialized.name = getTypeString();
|
||||||
|
|
||||||
func->create(place);
|
func->create(place);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteBufferFromString buffer(serialized);
|
WriteBufferFromString buffer(serialized.data);
|
||||||
func->serialize(place, buffer);
|
func->serialize(place, buffer);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
@ -94,6 +94,8 @@ private:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getTypeString() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~ColumnAggregateFunction() override;
|
~ColumnAggregateFunction() override;
|
||||||
|
|
||||||
|
@ -364,7 +364,10 @@ struct HashMethodSingleLowCardinalityColumn : public SingleColumnMethod
|
|||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (has_mapped)
|
if constexpr (has_mapped)
|
||||||
|
{
|
||||||
|
mapped_cache[row] = it->second;
|
||||||
return EmplaceResult(it->second, mapped_cache[row], inserted);
|
return EmplaceResult(it->second, mapped_cache[row], inserted);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return EmplaceResult(inserted);
|
return EmplaceResult(inserted);
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,13 @@ String FieldVisitorDump::operator() (const Tuple & x_def) const
|
|||||||
return wb.str();
|
return wb.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String FieldVisitorDump::operator() (const AggregateFunctionStateData & x) const
|
||||||
|
{
|
||||||
|
WriteBufferFromOwnString wb;
|
||||||
|
writeQuoted(x.name, wb);
|
||||||
|
writeQuoted(x.data, wb);
|
||||||
|
return wb.str();
|
||||||
|
}
|
||||||
|
|
||||||
/** In contrast to writeFloatText (and writeQuoted),
|
/** In contrast to writeFloatText (and writeQuoted),
|
||||||
* even if number looks like integer after formatting, prints decimal point nevertheless (for example, Float64(1) is printed as 1.).
|
* even if number looks like integer after formatting, prints decimal point nevertheless (for example, Float64(1) is printed as 1.).
|
||||||
@ -121,6 +128,10 @@ String FieldVisitorToString::operator() (const DecimalField<Decimal32> & x) cons
|
|||||||
String FieldVisitorToString::operator() (const DecimalField<Decimal64> & x) const { return formatQuoted(x); }
|
String FieldVisitorToString::operator() (const DecimalField<Decimal64> & x) const { return formatQuoted(x); }
|
||||||
String FieldVisitorToString::operator() (const DecimalField<Decimal128> & x) const { return formatQuoted(x); }
|
String FieldVisitorToString::operator() (const DecimalField<Decimal128> & x) const { return formatQuoted(x); }
|
||||||
String FieldVisitorToString::operator() (const UInt128 & x) const { return formatQuoted(UUID(x)); }
|
String FieldVisitorToString::operator() (const UInt128 & x) const { return formatQuoted(UUID(x)); }
|
||||||
|
String FieldVisitorToString::operator() (const AggregateFunctionStateData & x) const
|
||||||
|
{
|
||||||
|
return "(" + formatQuoted(x.name) + ")" + formatQuoted(x.data);
|
||||||
|
}
|
||||||
|
|
||||||
String FieldVisitorToString::operator() (const Array & x) const
|
String FieldVisitorToString::operator() (const Array & x) const
|
||||||
{
|
{
|
||||||
@ -231,5 +242,15 @@ void FieldVisitorHash::operator() (const DecimalField<Decimal128> & x) const
|
|||||||
hash.update(x);
|
hash.update(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FieldVisitorHash::operator() (const AggregateFunctionStateData & x) const
|
||||||
|
{
|
||||||
|
UInt8 type = Field::Types::AggregateFunctionState;
|
||||||
|
hash.update(type);
|
||||||
|
hash.update(x.name.size());
|
||||||
|
hash.update(x.name.data(), x.name.size());
|
||||||
|
hash.update(x.data.size());
|
||||||
|
hash.update(x.data.data(), x.data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ typename std::decay_t<Visitor>::ResultType applyVisitor(Visitor && visitor, F &&
|
|||||||
case Field::Types::Decimal32: return visitor(field.template get<DecimalField<Decimal32>>());
|
case Field::Types::Decimal32: return visitor(field.template get<DecimalField<Decimal32>>());
|
||||||
case Field::Types::Decimal64: return visitor(field.template get<DecimalField<Decimal64>>());
|
case Field::Types::Decimal64: return visitor(field.template get<DecimalField<Decimal64>>());
|
||||||
case Field::Types::Decimal128: return visitor(field.template get<DecimalField<Decimal128>>());
|
case Field::Types::Decimal128: return visitor(field.template get<DecimalField<Decimal128>>());
|
||||||
|
case Field::Types::AggregateFunctionState: return visitor(field.template get<AggregateFunctionStateData>());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
@ -72,6 +73,7 @@ static typename std::decay_t<Visitor>::ResultType applyBinaryVisitorImpl(Visitor
|
|||||||
case Field::Types::Decimal32: return visitor(field1, field2.template get<DecimalField<Decimal32>>());
|
case Field::Types::Decimal32: return visitor(field1, field2.template get<DecimalField<Decimal32>>());
|
||||||
case Field::Types::Decimal64: return visitor(field1, field2.template get<DecimalField<Decimal64>>());
|
case Field::Types::Decimal64: return visitor(field1, field2.template get<DecimalField<Decimal64>>());
|
||||||
case Field::Types::Decimal128: return visitor(field1, field2.template get<DecimalField<Decimal128>>());
|
case Field::Types::Decimal128: return visitor(field1, field2.template get<DecimalField<Decimal128>>());
|
||||||
|
case Field::Types::AggregateFunctionState: return visitor(field1, field2.template get<AggregateFunctionStateData>());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
@ -116,6 +118,9 @@ typename std::decay_t<Visitor>::ResultType applyVisitor(Visitor && visitor, F1 &
|
|||||||
case Field::Types::Decimal128:
|
case Field::Types::Decimal128:
|
||||||
return applyBinaryVisitorImpl(
|
return applyBinaryVisitorImpl(
|
||||||
std::forward<Visitor>(visitor), field1.template get<DecimalField<Decimal128>>(), std::forward<F2>(field2));
|
std::forward<Visitor>(visitor), field1.template get<DecimalField<Decimal128>>(), std::forward<F2>(field2));
|
||||||
|
case Field::Types::AggregateFunctionState:
|
||||||
|
return applyBinaryVisitorImpl(
|
||||||
|
std::forward<Visitor>(visitor), field1.template get<AggregateFunctionStateData>(), std::forward<F2>(field2));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
@ -138,6 +143,7 @@ public:
|
|||||||
String operator() (const DecimalField<Decimal32> & x) const;
|
String operator() (const DecimalField<Decimal32> & x) const;
|
||||||
String operator() (const DecimalField<Decimal64> & x) const;
|
String operator() (const DecimalField<Decimal64> & x) const;
|
||||||
String operator() (const DecimalField<Decimal128> & x) const;
|
String operator() (const DecimalField<Decimal128> & x) const;
|
||||||
|
String operator() (const AggregateFunctionStateData & x) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -156,6 +162,7 @@ public:
|
|||||||
String operator() (const DecimalField<Decimal32> & x) const;
|
String operator() (const DecimalField<Decimal32> & x) const;
|
||||||
String operator() (const DecimalField<Decimal64> & x) const;
|
String operator() (const DecimalField<Decimal64> & x) const;
|
||||||
String operator() (const DecimalField<Decimal128> & x) const;
|
String operator() (const DecimalField<Decimal128> & x) const;
|
||||||
|
String operator() (const AggregateFunctionStateData & x) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -201,6 +208,11 @@ public:
|
|||||||
else
|
else
|
||||||
return x.getValue() / x.getScaleMultiplier();
|
return x.getValue() / x.getScaleMultiplier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T operator() (const AggregateFunctionStateData &) const
|
||||||
|
{
|
||||||
|
throw Exception("Cannot convert AggregateFunctionStateData to " + demangle(typeid(T).name()), ErrorCodes::CANNOT_CONVERT_TYPE);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -222,6 +234,7 @@ public:
|
|||||||
void operator() (const DecimalField<Decimal32> & x) const;
|
void operator() (const DecimalField<Decimal32> & x) const;
|
||||||
void operator() (const DecimalField<Decimal64> & x) const;
|
void operator() (const DecimalField<Decimal64> & x) const;
|
||||||
void operator() (const DecimalField<Decimal128> & x) const;
|
void operator() (const DecimalField<Decimal128> & x) const;
|
||||||
|
void operator() (const AggregateFunctionStateData & x) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -246,6 +259,7 @@ public:
|
|||||||
bool operator() (const UInt64 & l, const String & r) const { return cantCompare(l, r); }
|
bool operator() (const UInt64 & l, const String & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const UInt64 & l, const Array & r) const { return cantCompare(l, r); }
|
bool operator() (const UInt64 & l, const Array & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const UInt64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
bool operator() (const UInt64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
||||||
|
bool operator() (const UInt64 & l, const AggregateFunctionStateData & r) const { return cantCompare(l, r); }
|
||||||
|
|
||||||
bool operator() (const Int64 & l, const Null & r) const { return cantCompare(l, r); }
|
bool operator() (const Int64 & l, const Null & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Int64 & l, const UInt64 & r) const { return accurate::equalsOp(l, r); }
|
bool operator() (const Int64 & l, const UInt64 & r) const { return accurate::equalsOp(l, r); }
|
||||||
@ -255,6 +269,7 @@ public:
|
|||||||
bool operator() (const Int64 & l, const String & r) const { return cantCompare(l, r); }
|
bool operator() (const Int64 & l, const String & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Int64 & l, const Array & r) const { return cantCompare(l, r); }
|
bool operator() (const Int64 & l, const Array & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Int64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
bool operator() (const Int64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
||||||
|
bool operator() (const Int64 & l, const AggregateFunctionStateData & r) const { return cantCompare(l, r); }
|
||||||
|
|
||||||
bool operator() (const Float64 & l, const Null & r) const { return cantCompare(l, r); }
|
bool operator() (const Float64 & l, const Null & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Float64 & l, const UInt64 & r) const { return accurate::equalsOp(l, r); }
|
bool operator() (const Float64 & l, const UInt64 & r) const { return accurate::equalsOp(l, r); }
|
||||||
@ -264,6 +279,7 @@ public:
|
|||||||
bool operator() (const Float64 & l, const String & r) const { return cantCompare(l, r); }
|
bool operator() (const Float64 & l, const String & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Float64 & l, const Array & r) const { return cantCompare(l, r); }
|
bool operator() (const Float64 & l, const Array & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Float64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
bool operator() (const Float64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
||||||
|
bool operator() (const Float64 & l, const AggregateFunctionStateData & r) const { return cantCompare(l, r); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool operator() (const Null &, const T &) const
|
bool operator() (const Null &, const T &) const
|
||||||
@ -321,6 +337,14 @@ public:
|
|||||||
template <typename T> bool operator() (const Int64 & l, const DecimalField<T> & r) const { return DecimalField<Decimal128>(l, 0) == r; }
|
template <typename T> bool operator() (const Int64 & l, const DecimalField<T> & r) const { return DecimalField<Decimal128>(l, 0) == r; }
|
||||||
template <typename T> bool operator() (const Float64 & l, const DecimalField<T> & r) const { return cantCompare(l, r); }
|
template <typename T> bool operator() (const Float64 & l, const DecimalField<T> & r) const { return cantCompare(l, r); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool operator() (const AggregateFunctionStateData & l, const T & r) const
|
||||||
|
{
|
||||||
|
if constexpr (std::is_same_v<T, AggregateFunctionStateData>)
|
||||||
|
return l == r;
|
||||||
|
return cantCompare(l, r);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
bool cantCompare(const T &, const U &) const
|
bool cantCompare(const T &, const U &) const
|
||||||
@ -344,6 +368,7 @@ public:
|
|||||||
bool operator() (const UInt64 & l, const String & r) const { return cantCompare(l, r); }
|
bool operator() (const UInt64 & l, const String & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const UInt64 & l, const Array & r) const { return cantCompare(l, r); }
|
bool operator() (const UInt64 & l, const Array & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const UInt64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
bool operator() (const UInt64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
||||||
|
bool operator() (const UInt64 & l, const AggregateFunctionStateData & r) const { return cantCompare(l, r); }
|
||||||
|
|
||||||
bool operator() (const Int64 & l, const Null & r) const { return cantCompare(l, r); }
|
bool operator() (const Int64 & l, const Null & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Int64 & l, const UInt64 & r) const { return accurate::lessOp(l, r); }
|
bool operator() (const Int64 & l, const UInt64 & r) const { return accurate::lessOp(l, r); }
|
||||||
@ -353,6 +378,7 @@ public:
|
|||||||
bool operator() (const Int64 & l, const String & r) const { return cantCompare(l, r); }
|
bool operator() (const Int64 & l, const String & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Int64 & l, const Array & r) const { return cantCompare(l, r); }
|
bool operator() (const Int64 & l, const Array & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Int64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
bool operator() (const Int64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
||||||
|
bool operator() (const Int64 & l, const AggregateFunctionStateData & r) const { return cantCompare(l, r); }
|
||||||
|
|
||||||
bool operator() (const Float64 & l, const Null & r) const { return cantCompare(l, r); }
|
bool operator() (const Float64 & l, const Null & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Float64 & l, const UInt64 & r) const { return accurate::lessOp(l, r); }
|
bool operator() (const Float64 & l, const UInt64 & r) const { return accurate::lessOp(l, r); }
|
||||||
@ -362,6 +388,7 @@ public:
|
|||||||
bool operator() (const Float64 & l, const String & r) const { return cantCompare(l, r); }
|
bool operator() (const Float64 & l, const String & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Float64 & l, const Array & r) const { return cantCompare(l, r); }
|
bool operator() (const Float64 & l, const Array & r) const { return cantCompare(l, r); }
|
||||||
bool operator() (const Float64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
bool operator() (const Float64 & l, const Tuple & r) const { return cantCompare(l, r); }
|
||||||
|
bool operator() (const Float64 & l, const AggregateFunctionStateData & r) const { return cantCompare(l, r); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool operator() (const Null &, const T &) const
|
bool operator() (const Null &, const T &) const
|
||||||
@ -419,6 +446,12 @@ public:
|
|||||||
template <typename T> bool operator() (const Int64 & l, const DecimalField<T> & r) const { return DecimalField<Decimal128>(l, 0) < r; }
|
template <typename T> bool operator() (const Int64 & l, const DecimalField<T> & r) const { return DecimalField<Decimal128>(l, 0) < r; }
|
||||||
template <typename T> bool operator() (const Float64 &, const DecimalField<T> &) const { return false; }
|
template <typename T> bool operator() (const Float64 &, const DecimalField<T> &) const { return false; }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool operator() (const AggregateFunctionStateData & l, const T & r) const
|
||||||
|
{
|
||||||
|
return cantCompare(l, r);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
bool cantCompare(const T &, const U &) const
|
bool cantCompare(const T &, const U &) const
|
||||||
@ -447,6 +480,7 @@ public:
|
|||||||
bool operator() (String &) const { throw Exception("Cannot sum Strings", ErrorCodes::LOGICAL_ERROR); }
|
bool operator() (String &) const { throw Exception("Cannot sum Strings", ErrorCodes::LOGICAL_ERROR); }
|
||||||
bool operator() (Array &) const { throw Exception("Cannot sum Arrays", ErrorCodes::LOGICAL_ERROR); }
|
bool operator() (Array &) const { throw Exception("Cannot sum Arrays", ErrorCodes::LOGICAL_ERROR); }
|
||||||
bool operator() (UInt128 &) const { throw Exception("Cannot sum UUIDs", ErrorCodes::LOGICAL_ERROR); }
|
bool operator() (UInt128 &) const { throw Exception("Cannot sum UUIDs", ErrorCodes::LOGICAL_ERROR); }
|
||||||
|
bool operator() (AggregateFunctionStateData &) const { throw Exception("Cannot sum AggregateFunctionStates", ErrorCodes::LOGICAL_ERROR); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool operator() (DecimalField<T> & x) const
|
bool operator() (DecimalField<T> & x) const
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#cmakedefine01 USE_PROTOBUF
|
#cmakedefine01 USE_PROTOBUF
|
||||||
#cmakedefine01 USE_CPUID
|
#cmakedefine01 USE_CPUID
|
||||||
#cmakedefine01 USE_CPUINFO
|
#cmakedefine01 USE_CPUINFO
|
||||||
|
#cmakedefine01 USE_BROTLI
|
||||||
|
|
||||||
#cmakedefine01 CLICKHOUSE_SPLIT_BINARY
|
#cmakedefine01 CLICKHOUSE_SPLIT_BINARY
|
||||||
#cmakedefine01 LLVM_HAS_RTTI
|
#cmakedefine01 LLVM_HAS_RTTI
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#define DBMS_MIN_REVISION_WITH_SERVER_DISPLAY_NAME 54372
|
#define DBMS_MIN_REVISION_WITH_SERVER_DISPLAY_NAME 54372
|
||||||
#define DBMS_MIN_REVISION_WITH_VERSION_PATCH 54401
|
#define DBMS_MIN_REVISION_WITH_VERSION_PATCH 54401
|
||||||
#define DBMS_MIN_REVISION_WITH_SERVER_LOGS 54406
|
#define DBMS_MIN_REVISION_WITH_SERVER_LOGS 54406
|
||||||
|
#define DBMS_MIN_REVISION_WITH_CLIENT_SUPPORT_EMBEDDED_DATA 54415
|
||||||
/// Minimum revision with exactly the same set of aggregation methods and rules to select them.
|
/// Minimum revision with exactly the same set of aggregation methods and rules to select them.
|
||||||
/// Two-level (bucketed) aggregation is incompatible if servers are inconsistent in these rules
|
/// Two-level (bucketed) aggregation is incompatible if servers are inconsistent in these rules
|
||||||
/// (keys will be placed in different buckets and result will not be fully aggregated).
|
/// (keys will be placed in different buckets and result will not be fully aggregated).
|
||||||
@ -110,7 +111,9 @@
|
|||||||
/// Example: multiplication of signed integers with possibility of overflow when both sides are from user input.
|
/// Example: multiplication of signed integers with possibility of overflow when both sides are from user input.
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#define NO_SANITIZE_UNDEFINED __attribute__((__no_sanitize__("undefined")))
|
#define NO_SANITIZE_UNDEFINED __attribute__((__no_sanitize__("undefined")))
|
||||||
|
#define NO_SANITIZE_ADDRESS __attribute__((__no_sanitize__("address")))
|
||||||
#else
|
#else
|
||||||
/// It does not work in GCC. GCC 7 cannot recognize this attribute and GCC 8 simply ignores it.
|
/// It does not work in GCC. GCC 7 cannot recognize this attribute and GCC 8 simply ignores it.
|
||||||
#define NO_SANITIZE_UNDEFINED
|
#define NO_SANITIZE_UNDEFINED
|
||||||
|
#define NO_SANITIZE_ADDRESS
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,6 +75,14 @@ namespace DB
|
|||||||
x.push_back(value);
|
x.push_back(value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Field::Types::AggregateFunctionState:
|
||||||
|
{
|
||||||
|
AggregateFunctionStateData value;
|
||||||
|
DB::readStringBinary(value.name, buf);
|
||||||
|
DB::readStringBinary(value.data, buf);
|
||||||
|
x.push_back(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,6 +136,12 @@ namespace DB
|
|||||||
DB::writeBinary(get<Tuple>(*it), buf);
|
DB::writeBinary(get<Tuple>(*it), buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Field::Types::AggregateFunctionState:
|
||||||
|
{
|
||||||
|
DB::writeStringBinary(it->get<AggregateFunctionStateData>().name, buf);
|
||||||
|
DB::writeStringBinary(it->get<AggregateFunctionStateData>().data, buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,6 +223,14 @@ namespace DB
|
|||||||
x.push_back(value);
|
x.push_back(value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Field::Types::AggregateFunctionState:
|
||||||
|
{
|
||||||
|
AggregateFunctionStateData value;
|
||||||
|
DB::readStringBinary(value.name, buf);
|
||||||
|
DB::readStringBinary(value.data, buf);
|
||||||
|
x.push_back(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,6 +284,12 @@ namespace DB
|
|||||||
DB::writeBinary(get<Tuple>(*it), buf);
|
DB::writeBinary(get<Tuple>(*it), buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Field::Types::AggregateFunctionState:
|
||||||
|
{
|
||||||
|
DB::writeStringBinary(it->get<AggregateFunctionStateData>().name, buf);
|
||||||
|
DB::writeStringBinary(it->get<AggregateFunctionStateData>().data, buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ namespace ErrorCodes
|
|||||||
extern const int BAD_GET;
|
extern const int BAD_GET;
|
||||||
extern const int NOT_IMPLEMENTED;
|
extern const int NOT_IMPLEMENTED;
|
||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Field;
|
class Field;
|
||||||
@ -30,6 +31,41 @@ using Array = std::vector<Field>;
|
|||||||
using TupleBackend = std::vector<Field>;
|
using TupleBackend = std::vector<Field>;
|
||||||
STRONG_TYPEDEF(TupleBackend, Tuple) /// Array and Tuple are different types with equal representation inside Field.
|
STRONG_TYPEDEF(TupleBackend, Tuple) /// Array and Tuple are different types with equal representation inside Field.
|
||||||
|
|
||||||
|
struct AggregateFunctionStateData
|
||||||
|
{
|
||||||
|
String name; /// Name with arguments.
|
||||||
|
String data;
|
||||||
|
|
||||||
|
bool operator < (const AggregateFunctionStateData &) const
|
||||||
|
{
|
||||||
|
throw Exception("Operator < is not implemented for AggregateFunctionStateData.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator <= (const AggregateFunctionStateData &) const
|
||||||
|
{
|
||||||
|
throw Exception("Operator <= is not implemented for AggregateFunctionStateData.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator > (const AggregateFunctionStateData &) const
|
||||||
|
{
|
||||||
|
throw Exception("Operator > is not implemented for AggregateFunctionStateData.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator >= (const AggregateFunctionStateData &) const
|
||||||
|
{
|
||||||
|
throw Exception("Operator >= is not implemented for AggregateFunctionStateData.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator == (const AggregateFunctionStateData & rhs) const
|
||||||
|
{
|
||||||
|
if (name != rhs.name)
|
||||||
|
throw Exception("Comparing aggregate functions with different types: " + name + " and " + rhs.name,
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
|
return data == rhs.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T> bool decimalEqual(T x, T y, UInt32 x_scale, UInt32 y_scale);
|
template <typename T> bool decimalEqual(T x, T y, UInt32 x_scale, UInt32 y_scale);
|
||||||
template <typename T> bool decimalLess(T x, T y, UInt32 x_scale, UInt32 y_scale);
|
template <typename T> bool decimalLess(T x, T y, UInt32 x_scale, UInt32 y_scale);
|
||||||
template <typename T> bool decimalLessOrEqual(T x, T y, UInt32 x_scale, UInt32 y_scale);
|
template <typename T> bool decimalLessOrEqual(T x, T y, UInt32 x_scale, UInt32 y_scale);
|
||||||
@ -131,6 +167,7 @@ public:
|
|||||||
Decimal32 = 19,
|
Decimal32 = 19,
|
||||||
Decimal64 = 20,
|
Decimal64 = 20,
|
||||||
Decimal128 = 21,
|
Decimal128 = 21,
|
||||||
|
AggregateFunctionState = 22,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int MIN_NON_POD = 16;
|
static const int MIN_NON_POD = 16;
|
||||||
@ -151,6 +188,7 @@ public:
|
|||||||
case Decimal32: return "Decimal32";
|
case Decimal32: return "Decimal32";
|
||||||
case Decimal64: return "Decimal64";
|
case Decimal64: return "Decimal64";
|
||||||
case Decimal128: return "Decimal128";
|
case Decimal128: return "Decimal128";
|
||||||
|
case AggregateFunctionState: return "AggregateFunctionState";
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
@ -325,6 +363,7 @@ public:
|
|||||||
case Types::Decimal32: return get<DecimalField<Decimal32>>() < rhs.get<DecimalField<Decimal32>>();
|
case Types::Decimal32: return get<DecimalField<Decimal32>>() < rhs.get<DecimalField<Decimal32>>();
|
||||||
case Types::Decimal64: return get<DecimalField<Decimal64>>() < rhs.get<DecimalField<Decimal64>>();
|
case Types::Decimal64: return get<DecimalField<Decimal64>>() < rhs.get<DecimalField<Decimal64>>();
|
||||||
case Types::Decimal128: return get<DecimalField<Decimal128>>() < rhs.get<DecimalField<Decimal128>>();
|
case Types::Decimal128: return get<DecimalField<Decimal128>>() < rhs.get<DecimalField<Decimal128>>();
|
||||||
|
case Types::AggregateFunctionState: return get<AggregateFunctionStateData>() < rhs.get<AggregateFunctionStateData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
@ -356,6 +395,7 @@ public:
|
|||||||
case Types::Decimal32: return get<DecimalField<Decimal32>>() <= rhs.get<DecimalField<Decimal32>>();
|
case Types::Decimal32: return get<DecimalField<Decimal32>>() <= rhs.get<DecimalField<Decimal32>>();
|
||||||
case Types::Decimal64: return get<DecimalField<Decimal64>>() <= rhs.get<DecimalField<Decimal64>>();
|
case Types::Decimal64: return get<DecimalField<Decimal64>>() <= rhs.get<DecimalField<Decimal64>>();
|
||||||
case Types::Decimal128: return get<DecimalField<Decimal128>>() <= rhs.get<DecimalField<Decimal128>>();
|
case Types::Decimal128: return get<DecimalField<Decimal128>>() <= rhs.get<DecimalField<Decimal128>>();
|
||||||
|
case Types::AggregateFunctionState: return get<AggregateFunctionStateData>() <= rhs.get<AggregateFunctionStateData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
@ -385,6 +425,7 @@ public:
|
|||||||
case Types::Decimal32: return get<DecimalField<Decimal32>>() == rhs.get<DecimalField<Decimal32>>();
|
case Types::Decimal32: return get<DecimalField<Decimal32>>() == rhs.get<DecimalField<Decimal32>>();
|
||||||
case Types::Decimal64: return get<DecimalField<Decimal64>>() == rhs.get<DecimalField<Decimal64>>();
|
case Types::Decimal64: return get<DecimalField<Decimal64>>() == rhs.get<DecimalField<Decimal64>>();
|
||||||
case Types::Decimal128: return get<DecimalField<Decimal128>>() == rhs.get<DecimalField<Decimal128>>();
|
case Types::Decimal128: return get<DecimalField<Decimal128>>() == rhs.get<DecimalField<Decimal128>>();
|
||||||
|
case Types::AggregateFunctionState: return get<AggregateFunctionStateData>() == rhs.get<AggregateFunctionStateData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
@ -398,7 +439,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
std::aligned_union_t<DBMS_MIN_FIELD_SIZE - sizeof(Types::Which),
|
std::aligned_union_t<DBMS_MIN_FIELD_SIZE - sizeof(Types::Which),
|
||||||
Null, UInt64, UInt128, Int64, Int128, Float64, String, Array, Tuple,
|
Null, UInt64, UInt128, Int64, Int128, Float64, String, Array, Tuple,
|
||||||
DecimalField<Decimal32>, DecimalField<Decimal64>, DecimalField<Decimal128>
|
DecimalField<Decimal32>, DecimalField<Decimal64>, DecimalField<Decimal128>, AggregateFunctionStateData
|
||||||
> storage;
|
> storage;
|
||||||
|
|
||||||
Types::Which which;
|
Types::Which which;
|
||||||
@ -449,6 +490,7 @@ private:
|
|||||||
case Types::Decimal32: f(field.template get<DecimalField<Decimal32>>()); return;
|
case Types::Decimal32: f(field.template get<DecimalField<Decimal32>>()); return;
|
||||||
case Types::Decimal64: f(field.template get<DecimalField<Decimal64>>()); return;
|
case Types::Decimal64: f(field.template get<DecimalField<Decimal64>>()); return;
|
||||||
case Types::Decimal128: f(field.template get<DecimalField<Decimal128>>()); return;
|
case Types::Decimal128: f(field.template get<DecimalField<Decimal128>>()); return;
|
||||||
|
case Types::AggregateFunctionState: f(field.template get<AggregateFunctionStateData>()); return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,6 +543,9 @@ private:
|
|||||||
case Types::Tuple:
|
case Types::Tuple:
|
||||||
destroy<Tuple>();
|
destroy<Tuple>();
|
||||||
break;
|
break;
|
||||||
|
case Types::AggregateFunctionState:
|
||||||
|
destroy<AggregateFunctionStateData>();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -531,6 +576,7 @@ template <> struct Field::TypeToEnum<Tuple> { static const Types::Which value
|
|||||||
template <> struct Field::TypeToEnum<DecimalField<Decimal32>>{ static const Types::Which value = Types::Decimal32; };
|
template <> struct Field::TypeToEnum<DecimalField<Decimal32>>{ static const Types::Which value = Types::Decimal32; };
|
||||||
template <> struct Field::TypeToEnum<DecimalField<Decimal64>>{ static const Types::Which value = Types::Decimal64; };
|
template <> struct Field::TypeToEnum<DecimalField<Decimal64>>{ static const Types::Which value = Types::Decimal64; };
|
||||||
template <> struct Field::TypeToEnum<DecimalField<Decimal128>>{ static const Types::Which value = Types::Decimal128; };
|
template <> struct Field::TypeToEnum<DecimalField<Decimal128>>{ static const Types::Which value = Types::Decimal128; };
|
||||||
|
template <> struct Field::TypeToEnum<AggregateFunctionStateData>{ static const Types::Which value = Types::AggregateFunctionState; };
|
||||||
|
|
||||||
template <> struct Field::EnumToType<Field::Types::Null> { using Type = Null; };
|
template <> struct Field::EnumToType<Field::Types::Null> { using Type = Null; };
|
||||||
template <> struct Field::EnumToType<Field::Types::UInt64> { using Type = UInt64; };
|
template <> struct Field::EnumToType<Field::Types::UInt64> { using Type = UInt64; };
|
||||||
@ -544,6 +590,7 @@ template <> struct Field::EnumToType<Field::Types::Tuple> { using Type = Tuple
|
|||||||
template <> struct Field::EnumToType<Field::Types::Decimal32> { using Type = DecimalField<Decimal32>; };
|
template <> struct Field::EnumToType<Field::Types::Decimal32> { using Type = DecimalField<Decimal32>; };
|
||||||
template <> struct Field::EnumToType<Field::Types::Decimal64> { using Type = DecimalField<Decimal64>; };
|
template <> struct Field::EnumToType<Field::Types::Decimal64> { using Type = DecimalField<Decimal64>; };
|
||||||
template <> struct Field::EnumToType<Field::Types::Decimal128> { using Type = DecimalField<Decimal128>; };
|
template <> struct Field::EnumToType<Field::Types::Decimal128> { using Type = DecimalField<Decimal128>; };
|
||||||
|
template <> struct Field::EnumToType<Field::Types::AggregateFunctionState> { using Type = DecimalField<AggregateFunctionStateData>; };
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -573,6 +620,7 @@ T safeGet(Field & field)
|
|||||||
|
|
||||||
template <> struct TypeName<Array> { static std::string get() { return "Array"; } };
|
template <> struct TypeName<Array> { static std::string get() { return "Array"; } };
|
||||||
template <> struct TypeName<Tuple> { static std::string get() { return "Tuple"; } };
|
template <> struct TypeName<Tuple> { static std::string get() { return "Tuple"; } };
|
||||||
|
template <> struct TypeName<AggregateFunctionStateData> { static std::string get() { return "AggregateFunctionState"; } };
|
||||||
|
|
||||||
|
|
||||||
template <typename T> struct NearestFieldTypeImpl;
|
template <typename T> struct NearestFieldTypeImpl;
|
||||||
@ -616,6 +664,8 @@ template <> struct NearestFieldTypeImpl<Tuple> { using Type = Tuple; };
|
|||||||
template <> struct NearestFieldTypeImpl<bool> { using Type = UInt64; };
|
template <> struct NearestFieldTypeImpl<bool> { using Type = UInt64; };
|
||||||
template <> struct NearestFieldTypeImpl<Null> { using Type = Null; };
|
template <> struct NearestFieldTypeImpl<Null> { using Type = Null; };
|
||||||
|
|
||||||
|
template <> struct NearestFieldTypeImpl<AggregateFunctionStateData> { using Type = AggregateFunctionStateData; };
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using NearestFieldType = typename NearestFieldTypeImpl<T>::Type;
|
using NearestFieldType = typename NearestFieldTypeImpl<T>::Type;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <common/logger_useful.h>
|
#include <common/logger_useful.h>
|
||||||
|
|
||||||
#include <DataStreams/MergingSortedBlockInputStream.h>
|
#include <DataStreams/MergingSortedBlockInputStream.h>
|
||||||
|
#include <DataStreams/ColumnGathererStream.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <DataStreams/MergingSortedBlockInputStream.h>
|
#include <DataStreams/MergingSortedBlockInputStream.h>
|
||||||
|
#include <DataStreams/ColumnGathererStream.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
|
|
||||||
#include <DataStreams/IBlockInputStream.h>
|
#include <DataStreams/IBlockInputStream.h>
|
||||||
#include <DataStreams/ColumnGathererStream.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <common/logger_useful.h>
|
#include <common/logger_useful.h>
|
||||||
|
|
||||||
#include <DataStreams/MergingSortedBlockInputStream.h>
|
#include <DataStreams/MergingSortedBlockInputStream.h>
|
||||||
|
#include <DataStreams/ColumnGathererStream.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <common/logger_useful.h>
|
#include <common/logger_useful.h>
|
||||||
|
|
||||||
#include <DataStreams/MergingSortedBlockInputStream.h>
|
#include <DataStreams/MergingSortedBlockInputStream.h>
|
||||||
|
#include <DataStreams/ColumnGathererStream.h>
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
@ -264,7 +264,8 @@ MutableColumnPtr DataTypeAggregateFunction::createColumn() const
|
|||||||
/// Create empty state
|
/// Create empty state
|
||||||
Field DataTypeAggregateFunction::getDefault() const
|
Field DataTypeAggregateFunction::getDefault() const
|
||||||
{
|
{
|
||||||
Field field = String();
|
Field field = AggregateFunctionStateData();
|
||||||
|
field.get<AggregateFunctionStateData &>().name = getName();
|
||||||
|
|
||||||
AlignedBuffer place_buffer(function->sizeOfData(), function->alignOfData());
|
AlignedBuffer place_buffer(function->sizeOfData(), function->alignOfData());
|
||||||
AggregateDataPtr place = place_buffer.data();
|
AggregateDataPtr place = place_buffer.data();
|
||||||
@ -273,7 +274,7 @@ Field DataTypeAggregateFunction::getDefault() const
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteBufferFromString buffer_from_field(field.get<String &>());
|
WriteBufferFromString buffer_from_field(field.get<AggregateFunctionStateData &>().data);
|
||||||
function->serialize(place, buffer_from_field);
|
function->serialize(place, buffer_from_field);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <DataTypes/DataTypeNullable.h>
|
#include <DataTypes/DataTypeNullable.h>
|
||||||
#include <DataTypes/DataTypeNothing.h>
|
#include <DataTypes/DataTypeNothing.h>
|
||||||
#include <DataTypes/getLeastSupertype.h>
|
#include <DataTypes/getLeastSupertype.h>
|
||||||
|
#include <DataTypes/DataTypeFactory.h>
|
||||||
#include <Common/Exception.h>
|
#include <Common/Exception.h>
|
||||||
#include <ext/size.h>
|
#include <ext/size.h>
|
||||||
|
|
||||||
@ -104,5 +105,10 @@ DataTypePtr FieldToDataType::operator() (const Tuple & x) const
|
|||||||
return std::make_shared<DataTypeTuple>(element_types);
|
return std::make_shared<DataTypeTuple>(element_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataTypePtr FieldToDataType::operator() (const AggregateFunctionStateData & x) const
|
||||||
|
{
|
||||||
|
auto & name = static_cast<const AggregateFunctionStateData &>(x).name;
|
||||||
|
return DataTypeFactory::instance().get(name);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ public:
|
|||||||
DataTypePtr operator() (const DecimalField<Decimal32> & x) const;
|
DataTypePtr operator() (const DecimalField<Decimal32> & x) const;
|
||||||
DataTypePtr operator() (const DecimalField<Decimal64> & x) const;
|
DataTypePtr operator() (const DecimalField<Decimal64> & x) const;
|
||||||
DataTypePtr operator() (const DecimalField<Decimal128> & x) const;
|
DataTypePtr operator() (const DecimalField<Decimal128> & x) const;
|
||||||
|
DataTypePtr operator() (const AggregateFunctionStateData & x) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -65,9 +65,9 @@ struct ToStartOfDayImpl
|
|||||||
{
|
{
|
||||||
return time_zone.toDate(t);
|
return time_zone.toDate(t);
|
||||||
}
|
}
|
||||||
static inline UInt32 execute(UInt16, const DateLUTImpl &)
|
static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone)
|
||||||
{
|
{
|
||||||
return dateIsNotSupported(name);
|
return time_zone.toDate(DayNum(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
using FactorTransform = ZeroTransform;
|
using FactorTransform = ZeroTransform;
|
||||||
|
@ -37,23 +37,33 @@ public:
|
|||||||
if (arguments.size() == 1)
|
if (arguments.size() == 1)
|
||||||
{
|
{
|
||||||
if (!isDateOrDateTime(arguments[0].type))
|
if (!isDateOrDateTime(arguments[0].type))
|
||||||
throw Exception("Illegal type " + arguments[0].type->getName() + " of argument of function " + getName() +
|
throw Exception(
|
||||||
". Should be a date or a date with time", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
"Illegal type " + arguments[0].type->getName() + " of argument of function " + getName()
|
||||||
|
+ ". Should be a date or a date with time",
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
}
|
}
|
||||||
else if (arguments.size() == 2)
|
else if (arguments.size() == 2)
|
||||||
{
|
{
|
||||||
if (!WhichDataType(arguments[0].type).isDateTime()
|
if (!isDateOrDateTime(arguments[0].type))
|
||||||
|| !WhichDataType(arguments[1].type).isString())
|
throw Exception(
|
||||||
|
"Illegal type " + arguments[0].type->getName() + " of argument of function " + getName()
|
||||||
|
+ ". Should be a date or a date with time",
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
if (!isString(arguments[1].type))
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"Function " + getName() + " supports 1 or 2 arguments. The 1st argument "
|
"Function " + getName() + " supports 1 or 2 arguments. The 1st argument "
|
||||||
"must be of type Date or DateTime. The 2nd argument (optional) must be "
|
"must be of type Date or DateTime. The 2nd argument (optional) must be "
|
||||||
"a constant string with timezone name. The timezone argument is allowed "
|
"a constant string with timezone name",
|
||||||
"only when the 1st argument has the type DateTime",
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
if (isDate(arguments[0].type) && std::is_same_v<ToDataType, DataTypeDate>)
|
||||||
|
throw Exception(
|
||||||
|
"The timezone argument of function " + getName() + " is allowed only when the 1st argument has the type DateTime",
|
||||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception(
|
||||||
+ toString(arguments.size()) + ", should be 1 or 2",
|
"Number of arguments for function " + getName() + " doesn't match: passed " + toString(arguments.size())
|
||||||
|
+ ", should be 1 or 2",
|
||||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
|
|
||||||
/// For DateTime, if time zone is specified, attach it to type.
|
/// For DateTime, if time zone is specified, attach it to type.
|
||||||
|
@ -332,9 +332,9 @@ static const ColumnLowCardinality * findLowCardinalityArgument(const Block & blo
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
|
static ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
|
||||||
Block & block, const ColumnNumbers & args, bool can_be_executed_on_default_arguments)
|
Block & block, const ColumnNumbers & args, bool can_be_executed_on_default_arguments, size_t input_rows_count)
|
||||||
{
|
{
|
||||||
size_t num_rows = 0;
|
size_t num_rows = input_rows_count;
|
||||||
ColumnPtr indexes;
|
ColumnPtr indexes;
|
||||||
|
|
||||||
for (auto arg : args)
|
for (auto arg : args)
|
||||||
@ -354,7 +354,10 @@ static ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
|
|||||||
{
|
{
|
||||||
ColumnWithTypeAndName & column = block.getByPosition(arg);
|
ColumnWithTypeAndName & column = block.getByPosition(arg);
|
||||||
if (auto * column_const = checkAndGetColumn<ColumnConst>(column.column.get()))
|
if (auto * column_const = checkAndGetColumn<ColumnConst>(column.column.get()))
|
||||||
|
{
|
||||||
column.column = column_const->removeLowCardinality()->cloneResized(num_rows);
|
column.column = column_const->removeLowCardinality()->cloneResized(num_rows);
|
||||||
|
column.type = removeLowCardinality(column.type);
|
||||||
|
}
|
||||||
else if (auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(column.column.get()))
|
else if (auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(column.column.get()))
|
||||||
{
|
{
|
||||||
auto * low_cardinality_type = checkAndGetDataType<DataTypeLowCardinality>(column.type.get());
|
auto * low_cardinality_type = checkAndGetDataType<DataTypeLowCardinality>(column.type.get());
|
||||||
@ -423,7 +426,7 @@ void PreparedFunctionImpl::execute(Block & block, const ColumnNumbers & args, si
|
|||||||
|
|
||||||
block_without_low_cardinality.safeGetByPosition(result).type = res_low_cardinality_type->getDictionaryType();
|
block_without_low_cardinality.safeGetByPosition(result).type = res_low_cardinality_type->getDictionaryType();
|
||||||
ColumnPtr indexes = replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
|
ColumnPtr indexes = replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
|
||||||
block_without_low_cardinality, args, can_be_executed_on_default_arguments);
|
block_without_low_cardinality, args, can_be_executed_on_default_arguments, input_rows_count);
|
||||||
|
|
||||||
executeWithoutLowCardinalityColumns(block_without_low_cardinality, args, result, block_without_low_cardinality.rows(), dry_run);
|
executeWithoutLowCardinalityColumns(block_without_low_cardinality, args, result, block_without_low_cardinality.rows(), dry_run);
|
||||||
|
|
||||||
|
@ -142,41 +142,54 @@ public:
|
|||||||
|
|
||||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||||
{
|
{
|
||||||
auto check_date_time_argument = [&] {
|
bool first_argument_is_date = false;
|
||||||
|
auto check_first_argument = [&]
|
||||||
|
{
|
||||||
if (!isDateOrDateTime(arguments[0].type))
|
if (!isDateOrDateTime(arguments[0].type))
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"Illegal type " + arguments[0].type->getName() + " of argument of function " + getName()
|
"Illegal type " + arguments[0].type->getName() + " of argument of function " + getName()
|
||||||
+ ". Should be a date or a date with time",
|
+ ". Should be a date or a date with time",
|
||||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
first_argument_is_date = isDate(arguments[0].type);
|
||||||
};
|
};
|
||||||
|
|
||||||
const DataTypeInterval * interval_type = nullptr;
|
const DataTypeInterval * interval_type = nullptr;
|
||||||
auto check_interval_argument = [&] {
|
bool result_type_is_date = false;
|
||||||
|
auto check_interval_argument = [&]
|
||||||
|
{
|
||||||
interval_type = checkAndGetDataType<DataTypeInterval>(arguments[1].type.get());
|
interval_type = checkAndGetDataType<DataTypeInterval>(arguments[1].type.get());
|
||||||
if (!interval_type)
|
if (!interval_type)
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"Illegal type " + arguments[1].type->getName() + " of argument of function " + getName()
|
"Illegal type " + arguments[1].type->getName() + " of argument of function " + getName()
|
||||||
+ ". Should be an interval of time",
|
+ ". Should be an interval of time",
|
||||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
result_type_is_date = (interval_type->getKind() == DataTypeInterval::Year)
|
||||||
|
|| (interval_type->getKind() == DataTypeInterval::Quarter) || (interval_type->getKind() == DataTypeInterval::Month)
|
||||||
|
|| (interval_type->getKind() == DataTypeInterval::Week);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto check_timezone_argument = [&] {
|
auto check_timezone_argument = [&]
|
||||||
|
{
|
||||||
if (!WhichDataType(arguments[2].type).isString())
|
if (!WhichDataType(arguments[2].type).isString())
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"Illegal type " + arguments[2].type->getName() + " of argument of function " + getName()
|
"Illegal type " + arguments[2].type->getName() + " of argument of function " + getName()
|
||||||
+ ". This argument is optional and must be a constant string with timezone name"
|
+ ". This argument is optional and must be a constant string with timezone name",
|
||||||
". This argument is allowed only when the 1st argument has the type DateTime",
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
if (first_argument_is_date && result_type_is_date)
|
||||||
|
throw Exception(
|
||||||
|
"The timezone argument of function " + getName() + " with interval type " + interval_type->kindToString()
|
||||||
|
+ " is allowed only when the 1st argument has the type DateTime",
|
||||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (arguments.size() == 2)
|
if (arguments.size() == 2)
|
||||||
{
|
{
|
||||||
check_date_time_argument();
|
check_first_argument();
|
||||||
check_interval_argument();
|
check_interval_argument();
|
||||||
}
|
}
|
||||||
else if (arguments.size() == 3)
|
else if (arguments.size() == 3)
|
||||||
{
|
{
|
||||||
check_date_time_argument();
|
check_first_argument();
|
||||||
check_interval_argument();
|
check_interval_argument();
|
||||||
check_timezone_argument();
|
check_timezone_argument();
|
||||||
}
|
}
|
||||||
@ -188,11 +201,10 @@ public:
|
|||||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((interval_type->getKind() == DataTypeInterval::Second) || (interval_type->getKind() == DataTypeInterval::Minute)
|
if (result_type_is_date)
|
||||||
|| (interval_type->getKind() == DataTypeInterval::Hour) || (interval_type->getKind() == DataTypeInterval::Day))
|
|
||||||
return std::make_shared<DataTypeDateTime>(extractTimeZoneNameFromFunctionArguments(arguments, 2, 0));
|
|
||||||
else
|
|
||||||
return std::make_shared<DataTypeDate>();
|
return std::make_shared<DataTypeDate>();
|
||||||
|
else
|
||||||
|
return std::make_shared<DataTypeDateTime>(extractTimeZoneNameFromFunctionArguments(arguments, 2, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useDefaultImplementationForConstants() const override { return true; }
|
bool useDefaultImplementationForConstants() const override { return true; }
|
||||||
|
92
dbms/src/IO/BrotliReadBuffer.cpp
Normal file
92
dbms/src/IO/BrotliReadBuffer.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include <Common/config.h>
|
||||||
|
#if USE_BROTLI
|
||||||
|
|
||||||
|
#include "BrotliReadBuffer.h"
|
||||||
|
#include <brotli/decode.h>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
class BrotliReadBuffer::BrotliStateWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BrotliStateWrapper()
|
||||||
|
: state(BrotliDecoderCreateInstance(nullptr, nullptr, nullptr))
|
||||||
|
, result(BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~BrotliStateWrapper()
|
||||||
|
{
|
||||||
|
BrotliDecoderDestroyInstance(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
BrotliDecoderState * state;
|
||||||
|
BrotliDecoderResult result;
|
||||||
|
};
|
||||||
|
|
||||||
|
BrotliReadBuffer::BrotliReadBuffer(ReadBuffer &in_, size_t buf_size, char *existing_memory, size_t alignment)
|
||||||
|
: BufferWithOwnMemory<ReadBuffer>(buf_size, existing_memory, alignment)
|
||||||
|
, in(in_)
|
||||||
|
, brotli(new BrotliStateWrapper())
|
||||||
|
, in_available(0)
|
||||||
|
, in_data(nullptr)
|
||||||
|
, out_capacity(0)
|
||||||
|
, out_data(nullptr)
|
||||||
|
, eof(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BrotliReadBuffer::~BrotliReadBuffer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BrotliReadBuffer::nextImpl()
|
||||||
|
{
|
||||||
|
if (eof)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!in_available)
|
||||||
|
{
|
||||||
|
in.nextIfAtEnd();
|
||||||
|
in_available = in.buffer().end() - in.position();
|
||||||
|
in_data = reinterpret_cast<uint8_t *>(in.position());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (brotli->result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT && (!in_available || in.eof()))
|
||||||
|
{
|
||||||
|
throw Exception(std::string("brotli decode error"), ErrorCodes::CANNOT_READ_ALL_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
out_capacity = internal_buffer.size();
|
||||||
|
out_data = reinterpret_cast<uint8_t *>(internal_buffer.begin());
|
||||||
|
|
||||||
|
brotli->result = BrotliDecoderDecompressStream(brotli->state, &in_available, &in_data, &out_capacity, &out_data, nullptr);
|
||||||
|
|
||||||
|
in.position() = in.buffer().end() - in_available;
|
||||||
|
working_buffer.resize(internal_buffer.size() - out_capacity);
|
||||||
|
|
||||||
|
if (brotli->result == BROTLI_DECODER_RESULT_SUCCESS)
|
||||||
|
{
|
||||||
|
if (in.eof())
|
||||||
|
{
|
||||||
|
eof = true;
|
||||||
|
return working_buffer.size() != 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw Exception(std::string("brotli decode error"), ErrorCodes::CANNOT_READ_ALL_DATA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (brotli->result == BROTLI_DECODER_RESULT_ERROR)
|
||||||
|
{
|
||||||
|
throw Exception(std::string("brotli decode error"), ErrorCodes::CANNOT_READ_ALL_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
38
dbms/src/IO/BrotliReadBuffer.h
Normal file
38
dbms/src/IO/BrotliReadBuffer.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <IO/ReadBuffer.h>
|
||||||
|
#include <IO/BufferWithOwnMemory.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
class BrotliReadBuffer : public BufferWithOwnMemory<ReadBuffer>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BrotliReadBuffer(
|
||||||
|
ReadBuffer & in_,
|
||||||
|
size_t buf_size = DBMS_DEFAULT_BUFFER_SIZE,
|
||||||
|
char * existing_memory = nullptr,
|
||||||
|
size_t alignment = 0);
|
||||||
|
|
||||||
|
~BrotliReadBuffer() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool nextImpl() override;
|
||||||
|
|
||||||
|
ReadBuffer & in;
|
||||||
|
|
||||||
|
class BrotliStateWrapper;
|
||||||
|
std::unique_ptr<BrotliStateWrapper> brotli;
|
||||||
|
|
||||||
|
size_t in_available;
|
||||||
|
const uint8_t * in_data;
|
||||||
|
|
||||||
|
size_t out_capacity;
|
||||||
|
uint8_t * out_data;
|
||||||
|
|
||||||
|
bool eof;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -35,6 +35,7 @@
|
|||||||
#include <Interpreters/evaluateConstantExpression.h>
|
#include <Interpreters/evaluateConstantExpression.h>
|
||||||
#include <Interpreters/convertFieldToType.h>
|
#include <Interpreters/convertFieldToType.h>
|
||||||
#include <Interpreters/interpretSubquery.h>
|
#include <Interpreters/interpretSubquery.h>
|
||||||
|
#include <Interpreters/DatabaseAndTableWithAlias.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -98,6 +98,18 @@ struct AggregationDataWithNullKey : public Base
|
|||||||
AggregateDataPtr & getNullKeyData() { return null_key_data; }
|
AggregateDataPtr & getNullKeyData() { return null_key_data; }
|
||||||
bool hasNullKeyData() const { return has_null_key_data; }
|
bool hasNullKeyData() const { return has_null_key_data; }
|
||||||
const AggregateDataPtr & getNullKeyData() const { return null_key_data; }
|
const AggregateDataPtr & getNullKeyData() const { return null_key_data; }
|
||||||
|
size_t size() const { return Base::size() + (has_null_key_data ? 1 : 0); }
|
||||||
|
bool empty() const { return Base::empty() && !has_null_key_data; }
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
Base::clear();
|
||||||
|
has_null_key_data = false;
|
||||||
|
}
|
||||||
|
void clearAndShrink()
|
||||||
|
{
|
||||||
|
Base::clearAndShrink();
|
||||||
|
has_null_key_data = false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool has_null_key_data = false;
|
bool has_null_key_data = false;
|
||||||
|
@ -132,7 +132,7 @@ public:
|
|||||||
std::string msg;
|
std::string msg;
|
||||||
{
|
{
|
||||||
WriteBufferFromString buffer(msg);
|
WriteBufferFromString buffer(msg);
|
||||||
buffer << "Column " << i << "should be numeric to make float feature.";
|
buffer << "Column " << i << " should be numeric to make float feature.";
|
||||||
}
|
}
|
||||||
throw Exception(msg, ErrorCodes::BAD_ARGUMENTS);
|
throw Exception(msg, ErrorCodes::BAD_ARGUMENTS);
|
||||||
}
|
}
|
||||||
@ -150,7 +150,7 @@ public:
|
|||||||
std::string msg;
|
std::string msg;
|
||||||
{
|
{
|
||||||
WriteBufferFromString buffer(msg);
|
WriteBufferFromString buffer(msg);
|
||||||
buffer << "Column " << i << "should be numeric or string.";
|
buffer << "Column " << i << " should be numeric or string.";
|
||||||
}
|
}
|
||||||
throw Exception(msg, ErrorCodes::BAD_ARGUMENTS);
|
throw Exception(msg, ErrorCodes::BAD_ARGUMENTS);
|
||||||
}
|
}
|
||||||
|
@ -109,11 +109,6 @@ void ExecuteScalarSubqueriesMatcher::visit(const ASTSubquery & subquery, ASTPtr
|
|||||||
size_t columns = block.columns();
|
size_t columns = block.columns();
|
||||||
if (columns == 1)
|
if (columns == 1)
|
||||||
{
|
{
|
||||||
if (typeid_cast<const DataTypeAggregateFunction*>(block.safeGetByPosition(0).type.get()))
|
|
||||||
{
|
|
||||||
throw Exception("Scalar subquery can't return an aggregate function state", ErrorCodes::INCORRECT_RESULT_OF_SCALAR_SUBQUERY);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lit = std::make_unique<ASTLiteral>((*block.safeGetByPosition(0).column)[0]);
|
auto lit = std::make_unique<ASTLiteral>((*block.safeGetByPosition(0).column)[0]);
|
||||||
lit->alias = subquery.alias;
|
lit->alias = subquery.alias;
|
||||||
lit->prefer_alias_to_column_name = subquery.prefer_alias_to_column_name;
|
lit->prefer_alias_to_column_name = subquery.prefer_alias_to_column_name;
|
||||||
@ -132,11 +127,6 @@ void ExecuteScalarSubqueriesMatcher::visit(const ASTSubquery & subquery, ASTPtr
|
|||||||
exp_list->children.resize(columns);
|
exp_list->children.resize(columns);
|
||||||
for (size_t i = 0; i < columns; ++i)
|
for (size_t i = 0; i < columns; ++i)
|
||||||
{
|
{
|
||||||
if (typeid_cast<const DataTypeAggregateFunction*>(block.safeGetByPosition(i).type.get()))
|
|
||||||
{
|
|
||||||
throw Exception("Scalar subquery can't return an aggregate function state", ErrorCodes::INCORRECT_RESULT_OF_SCALAR_SUBQUERY);
|
|
||||||
}
|
|
||||||
|
|
||||||
exp_list->children[i] = addTypeConversion(
|
exp_list->children[i] = addTypeConversion(
|
||||||
std::make_unique<ASTLiteral>((*block.safeGetByPosition(i).column)[0]),
|
std::make_unique<ASTLiteral>((*block.safeGetByPosition(i).column)[0]),
|
||||||
block.safeGetByPosition(i).type->getName());
|
block.safeGetByPosition(i).type->getName());
|
||||||
|
@ -1019,9 +1019,10 @@ void ExpressionAnalyzer::collectUsedColumns()
|
|||||||
|
|
||||||
for (NamesAndTypesList::iterator it = source_columns.begin(); it != source_columns.end();)
|
for (NamesAndTypesList::iterator it = source_columns.begin(); it != source_columns.end();)
|
||||||
{
|
{
|
||||||
unknown_required_source_columns.erase(it->name);
|
const String & column_name = it->name;
|
||||||
|
unknown_required_source_columns.erase(column_name);
|
||||||
|
|
||||||
if (!required.count(it->name))
|
if (!required.count(column_name))
|
||||||
source_columns.erase(it++);
|
source_columns.erase(it++);
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
|
@ -37,12 +37,17 @@ std::optional<String> IdentifierSemantic::getTableName(const ASTPtr & ast)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IdentifierSemantic::setNeedLongName(ASTIdentifier & identifier, bool value)
|
void IdentifierSemantic::setNeedLongName(ASTIdentifier & identifier, bool value)
|
||||||
{
|
{
|
||||||
identifier.semantic->need_long_name = value;
|
identifier.semantic->need_long_name = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IdentifierSemantic::canBeAlias(const ASTIdentifier & identifier)
|
||||||
|
{
|
||||||
|
return identifier.semantic->can_be_alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<String, String> IdentifierSemantic::extractDatabaseAndTable(const ASTIdentifier & identifier)
|
std::pair<String, String> IdentifierSemantic::extractDatabaseAndTable(const ASTIdentifier & identifier)
|
||||||
{
|
{
|
||||||
if (identifier.name_parts.size() > 2)
|
if (identifier.name_parts.size() > 2)
|
||||||
@ -108,6 +113,8 @@ void IdentifierSemantic::setColumnNormalName(ASTIdentifier & identifier, const D
|
|||||||
size_t match = IdentifierSemantic::canReferColumnToTable(identifier, db_and_table);
|
size_t match = IdentifierSemantic::canReferColumnToTable(identifier, db_and_table);
|
||||||
|
|
||||||
setColumnShortName(identifier, match);
|
setColumnShortName(identifier, match);
|
||||||
|
if (match)
|
||||||
|
identifier.semantic->can_be_alias = false;
|
||||||
|
|
||||||
if (identifier.semantic->need_long_name)
|
if (identifier.semantic->need_long_name)
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ struct IdentifierSemanticImpl
|
|||||||
{
|
{
|
||||||
bool special = false;
|
bool special = false;
|
||||||
bool need_long_name = false;
|
bool need_long_name = false;
|
||||||
|
bool can_be_alias = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Static calss to manipulate IdentifierSemanticImpl via ASTIdentifier
|
/// Static calss to manipulate IdentifierSemanticImpl via ASTIdentifier
|
||||||
@ -28,6 +29,7 @@ struct IdentifierSemantic
|
|||||||
static String columnNormalName(const ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
|
static String columnNormalName(const ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
|
||||||
static void setColumnNormalName(ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
|
static void setColumnNormalName(ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
|
||||||
static void setNeedLongName(ASTIdentifier & identifier, bool); /// if set setColumnNormalName makes qualified name
|
static void setNeedLongName(ASTIdentifier & identifier, bool); /// if set setColumnNormalName makes qualified name
|
||||||
|
static bool canBeAlias(const ASTIdentifier & identifier);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool doesIdentifierBelongTo(const ASTIdentifier & identifier, const String & database, const String & table);
|
static bool doesIdentifierBelongTo(const ASTIdentifier & identifier, const String & database, const String & table);
|
||||||
|
@ -1207,7 +1207,8 @@ private:
|
|||||||
for (size_t i = 0; i < right_sample_block.columns(); ++i)
|
for (size_t i = 0; i < right_sample_block.columns(); ++i)
|
||||||
{
|
{
|
||||||
const ColumnWithTypeAndName & src_column = right_sample_block.getByPosition(i);
|
const ColumnWithTypeAndName & src_column = right_sample_block.getByPosition(i);
|
||||||
result_sample_block.insert(src_column.cloneEmpty());
|
if (!result_sample_block.has(src_column.name))
|
||||||
|
result_sample_block.insert(src_column.cloneEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto & key_names_right = parent.key_names_right;
|
const auto & key_names_right = parent.key_names_right;
|
||||||
|
@ -250,7 +250,6 @@ void PredicateExpressionsOptimizer::setNewAliasesForInnerPredicate(
|
|||||||
name = ast->getAliasOrColumnName();
|
name = ast->getAliasOrColumnName();
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentifierSemantic::setNeedLongName(*identifier, false);
|
|
||||||
identifier->setShortName(name);
|
identifier->setShortName(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -338,9 +337,9 @@ ASTs PredicateExpressionsOptimizer::getSelectQueryProjectionColumns(ASTPtr & ast
|
|||||||
std::unordered_map<String, ASTPtr> aliases;
|
std::unordered_map<String, ASTPtr> aliases;
|
||||||
std::vector<DatabaseAndTableWithAlias> tables = getDatabaseAndTables(*select_query, context.getCurrentDatabase());
|
std::vector<DatabaseAndTableWithAlias> tables = getDatabaseAndTables(*select_query, context.getCurrentDatabase());
|
||||||
|
|
||||||
std::vector<TableWithColumnNames> tables_with_columns;
|
/// TODO: get tables from evaluateAsterisk instead of tablesOnly() to extract asterisks in general way
|
||||||
TranslateQualifiedNamesVisitor::Data::setTablesOnly(tables, tables_with_columns);
|
std::vector<TableWithColumnNames> tables_with_columns = TranslateQualifiedNamesVisitor::Data::tablesOnly(tables);
|
||||||
TranslateQualifiedNamesVisitor::Data qn_visitor_data{{}, tables_with_columns};
|
TranslateQualifiedNamesVisitor::Data qn_visitor_data({}, tables_with_columns, false);
|
||||||
TranslateQualifiedNamesVisitor(qn_visitor_data).visit(ast);
|
TranslateQualifiedNamesVisitor(qn_visitor_data).visit(ast);
|
||||||
|
|
||||||
QueryAliasesVisitor::Data query_aliases_data{aliases};
|
QueryAliasesVisitor::Data query_aliases_data{aliases};
|
||||||
|
@ -56,14 +56,16 @@ std::vector<ASTPtr *> QueryAliasesMatcher::visit(const ASTArrayJoin &, const AST
|
|||||||
{
|
{
|
||||||
visitOther(ast, data);
|
visitOther(ast, data);
|
||||||
|
|
||||||
/// @warning It breaks botom-to-top order (childs processed after node here), could lead to some effects.
|
std::vector<ASTPtr> grand_children;
|
||||||
/// It's possible to add ast back to result vec to save order. It will need two phase ASTArrayJoin visit (setting phase in data).
|
|
||||||
std::vector<ASTPtr *> out;
|
|
||||||
for (auto & child1 : ast->children)
|
for (auto & child1 : ast->children)
|
||||||
for (auto & child2 : child1->children)
|
for (auto & child2 : child1->children)
|
||||||
for (auto & child3 : child2->children)
|
for (auto & child3 : child2->children)
|
||||||
out.push_back(&child3);
|
grand_children.push_back(child3);
|
||||||
return out;
|
|
||||||
|
/// create own visitor to run bottom to top
|
||||||
|
for (auto & child : grand_children)
|
||||||
|
QueryAliasesVisitor(data).visit(child);
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set unique aliases for all subqueries. this is needed, because:
|
/// set unique aliases for all subqueries. this is needed, because:
|
||||||
|
@ -7,12 +7,10 @@
|
|||||||
#include <Parsers/ASTAsterisk.h>
|
#include <Parsers/ASTAsterisk.h>
|
||||||
#include <Parsers/ASTFunction.h>
|
#include <Parsers/ASTFunction.h>
|
||||||
#include <Parsers/ASTIdentifier.h>
|
#include <Parsers/ASTIdentifier.h>
|
||||||
#include <Parsers/ASTLiteral.h>
|
|
||||||
#include <Parsers/ASTSelectQuery.h>
|
#include <Parsers/ASTSelectQuery.h>
|
||||||
#include <Parsers/ASTTablesInSelectQuery.h>
|
#include <Parsers/ASTTablesInSelectQuery.h>
|
||||||
#include <Common/StringUtils/StringUtils.h>
|
#include <Common/StringUtils/StringUtils.h>
|
||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
#include <Parsers/ASTQualifiedAsterisk.h>
|
|
||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -91,13 +89,6 @@ void QueryNormalizer::visit(ASTFunction & node, const ASTPtr &, Data & data)
|
|||||||
/// and on all remote servers, function implementation will be same.
|
/// and on all remote servers, function implementation will be same.
|
||||||
if (endsWith(func_name, "Distinct") && func_name_lowercase == "countdistinct")
|
if (endsWith(func_name, "Distinct") && func_name_lowercase == "countdistinct")
|
||||||
func_name = data.settings.count_distinct_implementation;
|
func_name = data.settings.count_distinct_implementation;
|
||||||
|
|
||||||
/// As special case, treat count(*) as count(), not as count(list of all columns).
|
|
||||||
if (func_name_lowercase == "count" && func_arguments->children.size() == 1
|
|
||||||
&& typeid_cast<const ASTAsterisk *>(func_arguments->children[0].get()))
|
|
||||||
{
|
|
||||||
func_arguments->children.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +102,7 @@ void QueryNormalizer::visit(ASTIdentifier & node, ASTPtr & ast, Data & data)
|
|||||||
|
|
||||||
/// If it is an alias, but not a parent alias (for constructs like "SELECT column + 1 AS column").
|
/// If it is an alias, but not a parent alias (for constructs like "SELECT column + 1 AS column").
|
||||||
auto it_alias = data.aliases.find(node.name);
|
auto it_alias = data.aliases.find(node.name);
|
||||||
if (it_alias != data.aliases.end() && current_alias != node.name)
|
if (IdentifierSemantic::canBeAlias(node) && it_alias != data.aliases.end() && current_alias != node.name)
|
||||||
{
|
{
|
||||||
auto & alias_node = it_alias->second;
|
auto & alias_node = it_alias->second;
|
||||||
|
|
||||||
@ -138,84 +129,6 @@ void QueryNormalizer::visit(ASTIdentifier & node, ASTPtr & ast, Data & data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace *, alias.*, database.table.* with a list of columns.
|
|
||||||
void QueryNormalizer::visit(ASTExpressionList & node, const ASTPtr &, Data & data)
|
|
||||||
{
|
|
||||||
if (!data.tables_with_columns)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto & tables_with_columns = *data.tables_with_columns;
|
|
||||||
const auto & source_columns_set = data.source_columns_set;
|
|
||||||
|
|
||||||
ASTs old_children;
|
|
||||||
if (data.processAsterisks())
|
|
||||||
{
|
|
||||||
bool has_asterisk = false;
|
|
||||||
for (const auto & child : node.children)
|
|
||||||
{
|
|
||||||
if (typeid_cast<const ASTAsterisk *>(child.get()) ||
|
|
||||||
typeid_cast<const ASTQualifiedAsterisk *>(child.get()))
|
|
||||||
{
|
|
||||||
has_asterisk = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_asterisk)
|
|
||||||
{
|
|
||||||
old_children.swap(node.children);
|
|
||||||
node.children.reserve(old_children.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto & child : old_children)
|
|
||||||
{
|
|
||||||
if (typeid_cast<const ASTAsterisk *>(child.get()))
|
|
||||||
{
|
|
||||||
bool first_table = true;
|
|
||||||
for (const auto & [table_name, table_columns] : tables_with_columns)
|
|
||||||
{
|
|
||||||
for (const auto & column_name : table_columns)
|
|
||||||
if (first_table || !data.join_using_columns.count(column_name))
|
|
||||||
{
|
|
||||||
/// qualifed names for duplicates
|
|
||||||
if (!first_table && source_columns_set && source_columns_set->count(column_name))
|
|
||||||
node.children.emplace_back(std::make_shared<ASTIdentifier>(table_name.getQualifiedNamePrefix() + column_name));
|
|
||||||
else
|
|
||||||
node.children.emplace_back(std::make_shared<ASTIdentifier>(column_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
first_table = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (const auto * qualified_asterisk = typeid_cast<const ASTQualifiedAsterisk *>(child.get()))
|
|
||||||
{
|
|
||||||
DatabaseAndTableWithAlias ident_db_and_name(qualified_asterisk->children[0]);
|
|
||||||
|
|
||||||
bool first_table = true;
|
|
||||||
for (const auto & [table_name, table_columns] : tables_with_columns)
|
|
||||||
{
|
|
||||||
if (ident_db_and_name.satisfies(table_name, true))
|
|
||||||
{
|
|
||||||
for (const auto & column_name : table_columns)
|
|
||||||
{
|
|
||||||
/// qualifed names for duplicates
|
|
||||||
if (!first_table && source_columns_set && source_columns_set->count(column_name))
|
|
||||||
node.children.emplace_back(std::make_shared<ASTIdentifier>(table_name.getQualifiedNamePrefix() + column_name));
|
|
||||||
else
|
|
||||||
node.children.emplace_back(std::make_shared<ASTIdentifier>(column_name));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
first_table = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
node.children.emplace_back(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// mark table identifiers as 'not columns'
|
/// mark table identifiers as 'not columns'
|
||||||
void QueryNormalizer::visit(ASTTablesInSelectQueryElement & node, const ASTPtr &, Data &)
|
void QueryNormalizer::visit(ASTTablesInSelectQueryElement & node, const ASTPtr &, Data &)
|
||||||
{
|
{
|
||||||
@ -229,9 +142,6 @@ void QueryNormalizer::visit(ASTTablesInSelectQueryElement & node, const ASTPtr &
|
|||||||
/// special visitChildren() for ASTSelectQuery
|
/// special visitChildren() for ASTSelectQuery
|
||||||
void QueryNormalizer::visit(ASTSelectQuery & select, const ASTPtr & ast, Data & data)
|
void QueryNormalizer::visit(ASTSelectQuery & select, const ASTPtr & ast, Data & data)
|
||||||
{
|
{
|
||||||
if (auto join = select.join())
|
|
||||||
extractJoinUsingColumns(join->table_join, data);
|
|
||||||
|
|
||||||
for (auto & child : ast->children)
|
for (auto & child : ast->children)
|
||||||
{
|
{
|
||||||
if (typeid_cast<const ASTSelectQuery *>(child.get()) ||
|
if (typeid_cast<const ASTSelectQuery *>(child.get()) ||
|
||||||
@ -312,8 +222,6 @@ void QueryNormalizer::visit(ASTPtr & ast, Data & data)
|
|||||||
visit(*node, ast, data);
|
visit(*node, ast, data);
|
||||||
if (auto * node = typeid_cast<ASTIdentifier *>(ast.get()))
|
if (auto * node = typeid_cast<ASTIdentifier *>(ast.get()))
|
||||||
visit(*node, ast, data);
|
visit(*node, ast, data);
|
||||||
if (auto * node = typeid_cast<ASTExpressionList *>(ast.get()))
|
|
||||||
visit(*node, ast, data);
|
|
||||||
if (auto * node = typeid_cast<ASTTablesInSelectQueryElement *>(ast.get()))
|
if (auto * node = typeid_cast<ASTTablesInSelectQueryElement *>(ast.get()))
|
||||||
visit(*node, ast, data);
|
visit(*node, ast, data);
|
||||||
if (auto * node = typeid_cast<ASTSelectQuery *>(ast.get()))
|
if (auto * node = typeid_cast<ASTSelectQuery *>(ast.get()))
|
||||||
@ -344,27 +252,4 @@ void QueryNormalizer::visit(ASTPtr & ast, Data & data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 'select * from a join b using id' should result one 'id' column
|
|
||||||
void QueryNormalizer::extractJoinUsingColumns(const ASTPtr ast, Data & data)
|
|
||||||
{
|
|
||||||
const auto & table_join = typeid_cast<const ASTTableJoin &>(*ast);
|
|
||||||
|
|
||||||
if (table_join.using_expression_list)
|
|
||||||
{
|
|
||||||
auto & keys = typeid_cast<ASTExpressionList &>(*table_join.using_expression_list);
|
|
||||||
for (const auto & key : keys.children)
|
|
||||||
if (auto opt_column = getIdentifierName(key))
|
|
||||||
data.join_using_columns.insert(*opt_column);
|
|
||||||
else if (typeid_cast<const ASTLiteral *>(key.get()))
|
|
||||||
data.join_using_columns.insert(key->getColumnName());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String alias = key->tryGetAlias();
|
|
||||||
if (alias.empty())
|
|
||||||
throw Exception("Logical error: expected identifier or alias, got: " + key->getID(), ErrorCodes::LOGICAL_ERROR);
|
|
||||||
data.join_using_columns.insert(alias);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <Core/Names.h>
|
#include <Core/Names.h>
|
||||||
#include <Parsers/IAST.h>
|
#include <Parsers/IAST.h>
|
||||||
#include <Interpreters/DatabaseAndTableWithAlias.h>
|
|
||||||
#include <Interpreters/Aliases.h>
|
#include <Interpreters/Aliases.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -21,9 +19,9 @@ inline bool functionIsInOrGlobalInOperator(const String & name)
|
|||||||
return functionIsInOperator(name) || name == "globalIn" || name == "globalNotIn";
|
return functionIsInOperator(name) || name == "globalIn" || name == "globalNotIn";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ASTSelectQuery;
|
||||||
class ASTFunction;
|
class ASTFunction;
|
||||||
class ASTIdentifier;
|
class ASTIdentifier;
|
||||||
class ASTExpressionList;
|
|
||||||
struct ASTTablesInSelectQueryElement;
|
struct ASTTablesInSelectQueryElement;
|
||||||
class Context;
|
class Context;
|
||||||
|
|
||||||
@ -53,10 +51,6 @@ public:
|
|||||||
|
|
||||||
const Aliases & aliases;
|
const Aliases & aliases;
|
||||||
const ExtractedSettings settings;
|
const ExtractedSettings settings;
|
||||||
const Context * context;
|
|
||||||
const NameSet * source_columns_set;
|
|
||||||
const std::vector<TableWithColumnNames> * tables_with_columns;
|
|
||||||
std::unordered_set<String> join_using_columns;
|
|
||||||
|
|
||||||
/// tmp data
|
/// tmp data
|
||||||
size_t level;
|
size_t level;
|
||||||
@ -64,26 +58,11 @@ public:
|
|||||||
SetOfASTs current_asts; /// vertices in the current call stack of this method
|
SetOfASTs current_asts; /// vertices in the current call stack of this method
|
||||||
std::string current_alias; /// the alias referencing to the ancestor of ast (the deepest ancestor with aliases)
|
std::string current_alias; /// the alias referencing to the ancestor of ast (the deepest ancestor with aliases)
|
||||||
|
|
||||||
Data(const Aliases & aliases_, ExtractedSettings && settings_, const Context & context_,
|
|
||||||
const NameSet & source_columns_set, const std::vector<TableWithColumnNames> & tables_with_columns_)
|
|
||||||
: aliases(aliases_)
|
|
||||||
, settings(settings_)
|
|
||||||
, context(&context_)
|
|
||||||
, source_columns_set(&source_columns_set)
|
|
||||||
, tables_with_columns(&tables_with_columns_)
|
|
||||||
, level(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Data(const Aliases & aliases_, ExtractedSettings && settings_)
|
Data(const Aliases & aliases_, ExtractedSettings && settings_)
|
||||||
: aliases(aliases_)
|
: aliases(aliases_)
|
||||||
, settings(settings_)
|
, settings(settings_)
|
||||||
, context(nullptr)
|
|
||||||
, source_columns_set(nullptr)
|
|
||||||
, tables_with_columns(nullptr)
|
|
||||||
, level(0)
|
, level(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool processAsterisks() const { return tables_with_columns && !tables_with_columns->empty(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QueryNormalizer(Data & data)
|
QueryNormalizer(Data & data)
|
||||||
@ -102,13 +81,10 @@ private:
|
|||||||
|
|
||||||
static void visit(ASTIdentifier &, ASTPtr &, Data &);
|
static void visit(ASTIdentifier &, ASTPtr &, Data &);
|
||||||
static void visit(ASTFunction &, const ASTPtr &, Data &);
|
static void visit(ASTFunction &, const ASTPtr &, Data &);
|
||||||
static void visit(ASTExpressionList &, const ASTPtr &, Data &);
|
|
||||||
static void visit(ASTTablesInSelectQueryElement &, const ASTPtr &, Data &);
|
static void visit(ASTTablesInSelectQueryElement &, const ASTPtr &, Data &);
|
||||||
static void visit(ASTSelectQuery &, const ASTPtr &, Data &);
|
static void visit(ASTSelectQuery &, const ASTPtr &, Data &);
|
||||||
|
|
||||||
static void visitChildren(const ASTPtr &, Data & data);
|
static void visitChildren(const ASTPtr &, Data & data);
|
||||||
|
|
||||||
static void extractJoinUsingColumns(const ASTPtr ast, Data & data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user