mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 01:51:59 +00:00
Merge branch 'master' into constant-folding-scalar-subqueries
This commit is contained in:
commit
73cc3e1c92
@ -13,6 +13,7 @@ set (SRCS
|
||||
cgroupsv2.cpp
|
||||
coverage.cpp
|
||||
demangle.cpp
|
||||
Decimal.cpp
|
||||
getAvailableMemoryAmount.cpp
|
||||
getFQDNOrHostName.cpp
|
||||
getMemoryAmount.cpp
|
||||
|
87
base/base/Decimal.cpp
Normal file
87
base/base/Decimal.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include <base/Decimal.h>
|
||||
#include <base/extended_types.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// Explicit template instantiations.
|
||||
|
||||
#define FOR_EACH_UNDERLYING_DECIMAL_TYPE(M) \
|
||||
M(Int32) \
|
||||
M(Int64) \
|
||||
M(Int128) \
|
||||
M(Int256)
|
||||
|
||||
#define FOR_EACH_UNDERLYING_DECIMAL_TYPE_PASS(M, X) \
|
||||
M(Int32, X) \
|
||||
M(Int64, X) \
|
||||
M(Int128, X) \
|
||||
M(Int256, X)
|
||||
|
||||
template <typename T> const Decimal<T> & Decimal<T>::operator += (const T & x) { value += x; return *this; }
|
||||
template <typename T> const Decimal<T> & Decimal<T>::operator -= (const T & x) { value -= x; return *this; }
|
||||
template <typename T> const Decimal<T> & Decimal<T>::operator *= (const T & x) { value *= x; return *this; }
|
||||
template <typename T> const Decimal<T> & Decimal<T>::operator /= (const T & x) { value /= x; return *this; }
|
||||
template <typename T> const Decimal<T> & Decimal<T>::operator %= (const T & x) { value %= x; return *this; }
|
||||
|
||||
template <typename T> void NO_SANITIZE_UNDEFINED Decimal<T>::addOverflow(const T & x) { value += x; }
|
||||
|
||||
/// Maybe this explicit instantiation affects performance since operators cannot be inlined.
|
||||
|
||||
template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator += (const Decimal<U> & x) { value += static_cast<T>(x.value); return *this; }
|
||||
template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator -= (const Decimal<U> & x) { value -= static_cast<T>(x.value); return *this; }
|
||||
template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator *= (const Decimal<U> & x) { value *= static_cast<T>(x.value); return *this; }
|
||||
template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator /= (const Decimal<U> & x) { value /= static_cast<T>(x.value); return *this; }
|
||||
template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator %= (const Decimal<U> & x) { value %= static_cast<T>(x.value); return *this; }
|
||||
|
||||
#define DISPATCH(TYPE_T, TYPE_U) \
|
||||
template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator += (const Decimal<TYPE_U> & x); \
|
||||
template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator -= (const Decimal<TYPE_U> & x); \
|
||||
template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator *= (const Decimal<TYPE_U> & x); \
|
||||
template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator /= (const Decimal<TYPE_U> & x); \
|
||||
template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator %= (const Decimal<TYPE_U> & x);
|
||||
#define INVOKE(X) FOR_EACH_UNDERLYING_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_UNDERLYING_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
#define DISPATCH(TYPE) template struct Decimal<TYPE>;
|
||||
FOR_EACH_UNDERLYING_DECIMAL_TYPE(DISPATCH)
|
||||
#undef DISPATCH
|
||||
|
||||
template <typename T> bool operator< (const Decimal<T> & x, const Decimal<T> & y) { return x.value < y.value; }
|
||||
template <typename T> bool operator> (const Decimal<T> & x, const Decimal<T> & y) { return x.value > y.value; }
|
||||
template <typename T> bool operator<= (const Decimal<T> & x, const Decimal<T> & y) { return x.value <= y.value; }
|
||||
template <typename T> bool operator>= (const Decimal<T> & x, const Decimal<T> & y) { return x.value >= y.value; }
|
||||
template <typename T> bool operator== (const Decimal<T> & x, const Decimal<T> & y) { return x.value == y.value; }
|
||||
template <typename T> bool operator!= (const Decimal<T> & x, const Decimal<T> & y) { return x.value != y.value; }
|
||||
|
||||
#define DISPATCH(TYPE) \
|
||||
template bool operator< (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
template bool operator> (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
template bool operator<= (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
template bool operator>= (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
template bool operator== (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
template bool operator!= (const Decimal<TYPE> & x, const Decimal<TYPE> & y);
|
||||
FOR_EACH_UNDERLYING_DECIMAL_TYPE(DISPATCH)
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename T> Decimal<T> operator+ (const Decimal<T> & x, const Decimal<T> & y) { return x.value + y.value; }
|
||||
template <typename T> Decimal<T> operator- (const Decimal<T> & x, const Decimal<T> & y) { return x.value - y.value; }
|
||||
template <typename T> Decimal<T> operator* (const Decimal<T> & x, const Decimal<T> & y) { return x.value * y.value; }
|
||||
template <typename T> Decimal<T> operator/ (const Decimal<T> & x, const Decimal<T> & y) { return x.value / y.value; }
|
||||
template <typename T> Decimal<T> operator- (const Decimal<T> & x) { return -x.value; }
|
||||
|
||||
#define DISPATCH(TYPE) \
|
||||
template Decimal<TYPE> operator+ (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
template Decimal<TYPE> operator- (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
template Decimal<TYPE> operator* (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
template Decimal<TYPE> operator/ (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
template Decimal<TYPE> operator- (const Decimal<TYPE> & x);
|
||||
FOR_EACH_UNDERLYING_DECIMAL_TYPE(DISPATCH)
|
||||
#undef DISPATCH
|
||||
|
||||
#undef FOR_EACH_UNDERLYING_DECIMAL_TYPE_PASS
|
||||
#undef FOR_EACH_UNDERLYING_DECIMAL_TYPE
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <base/extended_types.h>
|
||||
#include <base/Decimal_fwd.h>
|
||||
#include <base/types.h>
|
||||
#include <base/defines.h>
|
||||
|
||||
|
||||
@ -10,6 +11,18 @@ namespace DB
|
||||
template <class> struct Decimal;
|
||||
class DateTime64;
|
||||
|
||||
#define FOR_EACH_UNDERLYING_DECIMAL_TYPE(M) \
|
||||
M(Int32) \
|
||||
M(Int64) \
|
||||
M(Int128) \
|
||||
M(Int256)
|
||||
|
||||
#define FOR_EACH_UNDERLYING_DECIMAL_TYPE_PASS(M, X) \
|
||||
M(Int32, X) \
|
||||
M(Int64, X) \
|
||||
M(Int128, X) \
|
||||
M(Int256, X)
|
||||
|
||||
using Decimal32 = Decimal<Int32>;
|
||||
using Decimal64 = Decimal<Int64>;
|
||||
using Decimal128 = Decimal<Int128>;
|
||||
@ -50,36 +63,73 @@ struct Decimal
|
||||
return static_cast<U>(value);
|
||||
}
|
||||
|
||||
const Decimal<T> & operator += (const T & x) { value += x; return *this; }
|
||||
const Decimal<T> & operator -= (const T & x) { value -= x; return *this; }
|
||||
const Decimal<T> & operator *= (const T & x) { value *= x; return *this; }
|
||||
const Decimal<T> & operator /= (const T & x) { value /= x; return *this; }
|
||||
const Decimal<T> & operator %= (const T & x) { value %= x; return *this; }
|
||||
const Decimal<T> & operator += (const T & x);
|
||||
const Decimal<T> & operator -= (const T & x);
|
||||
const Decimal<T> & operator *= (const T & x);
|
||||
const Decimal<T> & operator /= (const T & x);
|
||||
const Decimal<T> & operator %= (const T & x);
|
||||
|
||||
template <typename U> const Decimal<T> & operator += (const Decimal<U> & x) { value += x.value; return *this; }
|
||||
template <typename U> const Decimal<T> & operator -= (const Decimal<U> & x) { value -= x.value; return *this; }
|
||||
template <typename U> const Decimal<T> & operator *= (const Decimal<U> & x) { value *= x.value; return *this; }
|
||||
template <typename U> const Decimal<T> & operator /= (const Decimal<U> & x) { value /= x.value; return *this; }
|
||||
template <typename U> const Decimal<T> & operator %= (const Decimal<U> & x) { value %= x.value; return *this; }
|
||||
template <typename U> const Decimal<T> & operator += (const Decimal<U> & x);
|
||||
template <typename U> const Decimal<T> & operator -= (const Decimal<U> & x);
|
||||
template <typename U> const Decimal<T> & operator *= (const Decimal<U> & x);
|
||||
template <typename U> const Decimal<T> & operator /= (const Decimal<U> & x);
|
||||
template <typename U> const Decimal<T> & operator %= (const Decimal<U> & x);
|
||||
|
||||
/// This is to avoid UB for sumWithOverflow()
|
||||
void NO_SANITIZE_UNDEFINED addOverflow(const T & x) { value += x; }
|
||||
void NO_SANITIZE_UNDEFINED addOverflow(const T & x);
|
||||
|
||||
T value;
|
||||
};
|
||||
|
||||
template <typename T> inline bool operator< (const Decimal<T> & x, const Decimal<T> & y) { return x.value < y.value; }
|
||||
template <typename T> inline bool operator> (const Decimal<T> & x, const Decimal<T> & y) { return x.value > y.value; }
|
||||
template <typename T> inline bool operator<= (const Decimal<T> & x, const Decimal<T> & y) { return x.value <= y.value; }
|
||||
template <typename T> inline bool operator>= (const Decimal<T> & x, const Decimal<T> & y) { return x.value >= y.value; }
|
||||
template <typename T> inline bool operator== (const Decimal<T> & x, const Decimal<T> & y) { return x.value == y.value; }
|
||||
template <typename T> inline bool operator!= (const Decimal<T> & x, const Decimal<T> & y) { return x.value != y.value; }
|
||||
#define DISPATCH(TYPE) extern template struct Decimal<TYPE>;
|
||||
FOR_EACH_UNDERLYING_DECIMAL_TYPE(DISPATCH)
|
||||
#undef DISPATCH
|
||||
|
||||
template <typename T> inline Decimal<T> operator+ (const Decimal<T> & x, const Decimal<T> & y) { return x.value + y.value; }
|
||||
template <typename T> inline Decimal<T> operator- (const Decimal<T> & x, const Decimal<T> & y) { return x.value - y.value; }
|
||||
template <typename T> inline Decimal<T> operator* (const Decimal<T> & x, const Decimal<T> & y) { return x.value * y.value; }
|
||||
template <typename T> inline Decimal<T> operator/ (const Decimal<T> & x, const Decimal<T> & y) { return x.value / y.value; }
|
||||
template <typename T> inline Decimal<T> operator- (const Decimal<T> & x) { return -x.value; }
|
||||
#define DISPATCH(TYPE_T, TYPE_U) \
|
||||
extern template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator += (const Decimal<TYPE_U> & x); \
|
||||
extern template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator -= (const Decimal<TYPE_U> & x); \
|
||||
extern template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator *= (const Decimal<TYPE_U> & x); \
|
||||
extern template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator /= (const Decimal<TYPE_U> & x); \
|
||||
extern template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator %= (const Decimal<TYPE_U> & x);
|
||||
#define INVOKE(X) FOR_EACH_UNDERLYING_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_UNDERLYING_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
template <typename T> bool operator< (const Decimal<T> & x, const Decimal<T> & y);
|
||||
template <typename T> bool operator> (const Decimal<T> & x, const Decimal<T> & y);
|
||||
template <typename T> bool operator<= (const Decimal<T> & x, const Decimal<T> & y);
|
||||
template <typename T> bool operator>= (const Decimal<T> & x, const Decimal<T> & y);
|
||||
template <typename T> bool operator== (const Decimal<T> & x, const Decimal<T> & y);
|
||||
template <typename T> bool operator!= (const Decimal<T> & x, const Decimal<T> & y);
|
||||
|
||||
#define DISPATCH(TYPE) \
|
||||
extern template bool operator< (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
extern template bool operator> (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
extern template bool operator<= (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
extern template bool operator>= (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
extern template bool operator== (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
extern template bool operator!= (const Decimal<TYPE> & x, const Decimal<TYPE> & y);
|
||||
FOR_EACH_UNDERLYING_DECIMAL_TYPE(DISPATCH)
|
||||
#undef DISPATCH
|
||||
|
||||
template <typename T> Decimal<T> operator+ (const Decimal<T> & x, const Decimal<T> & y);
|
||||
template <typename T> Decimal<T> operator- (const Decimal<T> & x, const Decimal<T> & y);
|
||||
template <typename T> Decimal<T> operator* (const Decimal<T> & x, const Decimal<T> & y);
|
||||
template <typename T> Decimal<T> operator/ (const Decimal<T> & x, const Decimal<T> & y);
|
||||
template <typename T> Decimal<T> operator- (const Decimal<T> & x);
|
||||
|
||||
#define DISPATCH(TYPE) \
|
||||
extern template Decimal<TYPE> operator+ (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
extern template Decimal<TYPE> operator- (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
extern template Decimal<TYPE> operator* (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
extern template Decimal<TYPE> operator/ (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \
|
||||
extern template Decimal<TYPE> operator- (const Decimal<TYPE> & x);
|
||||
FOR_EACH_UNDERLYING_DECIMAL_TYPE(DISPATCH)
|
||||
#undef DISPATCH
|
||||
|
||||
#undef FOR_EACH_UNDERLYING_DECIMAL_TYPE_PASS
|
||||
#undef FOR_EACH_UNDERLYING_DECIMAL_TYPE
|
||||
|
||||
/// Distinguishable type to allow function resolution/deduction based on value type,
|
||||
/// but also relatively easy to convert to/from Decimal64.
|
||||
|
@ -64,6 +64,44 @@ template <> struct is_arithmetic<UInt256> { static constexpr bool value = true;
|
||||
template <typename T>
|
||||
inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
|
||||
|
||||
#define FOR_EACH_ARITHMETIC_TYPE(M) \
|
||||
M(DataTypeDate) \
|
||||
M(DataTypeDate32) \
|
||||
M(DataTypeDateTime) \
|
||||
M(DataTypeInt8) \
|
||||
M(DataTypeUInt8) \
|
||||
M(DataTypeInt16) \
|
||||
M(DataTypeUInt16) \
|
||||
M(DataTypeInt32) \
|
||||
M(DataTypeUInt32) \
|
||||
M(DataTypeInt64) \
|
||||
M(DataTypeUInt64) \
|
||||
M(DataTypeInt128) \
|
||||
M(DataTypeUInt128) \
|
||||
M(DataTypeInt256) \
|
||||
M(DataTypeUInt256) \
|
||||
M(DataTypeFloat32) \
|
||||
M(DataTypeFloat64)
|
||||
|
||||
#define FOR_EACH_ARITHMETIC_TYPE_PASS(M, X) \
|
||||
M(DataTypeDate, X) \
|
||||
M(DataTypeDate32, X) \
|
||||
M(DataTypeDateTime, X) \
|
||||
M(DataTypeInt8, X) \
|
||||
M(DataTypeUInt8, X) \
|
||||
M(DataTypeInt16, X) \
|
||||
M(DataTypeUInt16, X) \
|
||||
M(DataTypeInt32, X) \
|
||||
M(DataTypeUInt32, X) \
|
||||
M(DataTypeInt64, X) \
|
||||
M(DataTypeUInt64, X) \
|
||||
M(DataTypeInt128, X) \
|
||||
M(DataTypeUInt128, X) \
|
||||
M(DataTypeInt256, X) \
|
||||
M(DataTypeUInt256, X) \
|
||||
M(DataTypeFloat32, X) \
|
||||
M(DataTypeFloat64, X)
|
||||
|
||||
template <typename T>
|
||||
struct make_unsigned // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
|
@ -259,7 +259,7 @@ ShardPriority getReplicasPriority(const Cluster::Addresses & replicas, const std
|
||||
res.is_remote = 1;
|
||||
for (const auto & replica : replicas)
|
||||
{
|
||||
if (isLocalAddress(DNSResolver::instance().resolveHost(replica.host_name)))
|
||||
if (isLocalAddress(DNSResolver::instance().resolveHostAllInOriginOrder(replica.host_name).front()))
|
||||
{
|
||||
res.is_remote = 0;
|
||||
break;
|
||||
|
@ -55,7 +55,7 @@ namespace
|
||||
{
|
||||
IPAddress addr_v6 = toIPv6(address);
|
||||
|
||||
auto host_addresses = DNSResolver::instance().resolveHostAll(host);
|
||||
auto host_addresses = DNSResolver::instance().resolveHostAllInOriginOrder(host);
|
||||
|
||||
for (const auto & addr : host_addresses)
|
||||
{
|
||||
|
@ -115,7 +115,7 @@ ConnectionParameters::ConnectionParameters(const Poco::Util::AbstractConfigurati
|
||||
/// At the same time, I want clickhouse-local to always work, regardless.
|
||||
/// TODO: get rid of glibc, or replace getaddrinfo to c-ares.
|
||||
|
||||
compression = config.getBool("compression", host != "localhost" && !isLocalAddress(DNSResolver::instance().resolveHost(host)))
|
||||
compression = config.getBool("compression", host != "localhost" && !isLocalAddress(DNSResolver::instance().resolveHostAllInOriginOrder(host).front()))
|
||||
? Protocol::Compression::Enable : Protocol::Compression::Disable;
|
||||
|
||||
timeouts = ConnectionTimeouts()
|
||||
|
25
src/Columns/ColumnUnique.cpp
Normal file
25
src/Columns/ColumnUnique.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include <Columns/ColumnUnique.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// Explicit template instantiations.
|
||||
template class ColumnUnique<ColumnInt8>;
|
||||
template class ColumnUnique<ColumnUInt8>;
|
||||
template class ColumnUnique<ColumnInt16>;
|
||||
template class ColumnUnique<ColumnUInt16>;
|
||||
template class ColumnUnique<ColumnInt32>;
|
||||
template class ColumnUnique<ColumnUInt32>;
|
||||
template class ColumnUnique<ColumnInt64>;
|
||||
template class ColumnUnique<ColumnUInt64>;
|
||||
template class ColumnUnique<ColumnInt128>;
|
||||
template class ColumnUnique<ColumnUInt128>;
|
||||
template class ColumnUnique<ColumnInt256>;
|
||||
template class ColumnUnique<ColumnUInt256>;
|
||||
template class ColumnUnique<ColumnFloat32>;
|
||||
template class ColumnUnique<ColumnFloat64>;
|
||||
template class ColumnUnique<ColumnString>;
|
||||
template class ColumnUnique<ColumnFixedString>;
|
||||
template class ColumnUnique<ColumnDateTime64>;
|
||||
|
||||
}
|
@ -15,6 +15,8 @@
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <Common/assert_cast.h>
|
||||
#include <Common/FieldVisitors.h>
|
||||
#include "Columns/ColumnsDateTime.h"
|
||||
#include "Columns/ColumnsNumber.h"
|
||||
|
||||
#include <base/range.h>
|
||||
#include <base/unaligned.h>
|
||||
@ -736,4 +738,23 @@ UInt128 ColumnUnique<ColumnType>::IncrementalHash::getHash(const ColumnType & co
|
||||
return cur_hash;
|
||||
}
|
||||
|
||||
|
||||
extern template class ColumnUnique<ColumnInt8>;
|
||||
extern template class ColumnUnique<ColumnUInt8>;
|
||||
extern template class ColumnUnique<ColumnInt16>;
|
||||
extern template class ColumnUnique<ColumnUInt16>;
|
||||
extern template class ColumnUnique<ColumnInt32>;
|
||||
extern template class ColumnUnique<ColumnUInt32>;
|
||||
extern template class ColumnUnique<ColumnInt64>;
|
||||
extern template class ColumnUnique<ColumnUInt64>;
|
||||
extern template class ColumnUnique<ColumnInt128>;
|
||||
extern template class ColumnUnique<ColumnUInt128>;
|
||||
extern template class ColumnUnique<ColumnInt256>;
|
||||
extern template class ColumnUnique<ColumnUInt256>;
|
||||
extern template class ColumnUnique<ColumnFloat32>;
|
||||
extern template class ColumnUnique<ColumnFloat64>;
|
||||
extern template class ColumnUnique<ColumnString>;
|
||||
extern template class ColumnUnique<ColumnFixedString>;
|
||||
extern template class ColumnUnique<ColumnDateTime64>;
|
||||
|
||||
}
|
||||
|
@ -202,10 +202,10 @@ DNSResolver::DNSResolver() : impl(std::make_unique<DNSResolver::Impl>()), log(ge
|
||||
|
||||
Poco::Net::IPAddress DNSResolver::resolveHost(const std::string & host)
|
||||
{
|
||||
return pickAddress(resolveHostAll(host));
|
||||
return pickAddress(resolveHostAll(host)); // random order -> random pick
|
||||
}
|
||||
|
||||
DNSResolver::IPAddresses DNSResolver::resolveHostAll(const std::string & host)
|
||||
DNSResolver::IPAddresses DNSResolver::resolveHostAllInOriginOrder(const std::string & host)
|
||||
{
|
||||
if (impl->disable_cache)
|
||||
return resolveIPAddressImpl(host);
|
||||
@ -214,6 +214,13 @@ DNSResolver::IPAddresses DNSResolver::resolveHostAll(const std::string & host)
|
||||
return resolveIPAddressWithCache(impl->cache_host, host);
|
||||
}
|
||||
|
||||
DNSResolver::IPAddresses DNSResolver::resolveHostAll(const std::string & host)
|
||||
{
|
||||
auto addresses = resolveHostAllInOriginOrder(host);
|
||||
std::shuffle(addresses.begin(), addresses.end(), thread_local_rng);
|
||||
return addresses;
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress DNSResolver::resolveAddress(const std::string & host_and_port)
|
||||
{
|
||||
if (impl->disable_cache)
|
||||
|
@ -34,6 +34,9 @@ public:
|
||||
Poco::Net::IPAddress resolveHost(const std::string & host);
|
||||
|
||||
/// Accepts host names like 'example.com' or '127.0.0.1' or '::1' and resolves all its IPs
|
||||
/// resolveHostAllInOriginOrder returns addresses with the same order as system call returns it
|
||||
IPAddresses resolveHostAllInOriginOrder(const std::string & host);
|
||||
/// resolveHostAll returns addresses in random order
|
||||
IPAddresses resolveHostAll(const std::string & host);
|
||||
|
||||
/// Accepts host names like 'example.com:port' or '127.0.0.1:port' or '[::1]:port' and resolves its IP and port
|
||||
|
23
src/Common/FieldVisitorConvertToNumber.cpp
Normal file
23
src/Common/FieldVisitorConvertToNumber.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include <Common/FieldVisitorConvertToNumber.h>
|
||||
#include "base/Decimal.h"
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// Explicit template instantiations.
|
||||
template class FieldVisitorConvertToNumber<Int8>;
|
||||
template class FieldVisitorConvertToNumber<UInt8>;
|
||||
template class FieldVisitorConvertToNumber<Int16>;
|
||||
template class FieldVisitorConvertToNumber<UInt16>;
|
||||
template class FieldVisitorConvertToNumber<Int32>;
|
||||
template class FieldVisitorConvertToNumber<UInt32>;
|
||||
template class FieldVisitorConvertToNumber<Int64>;
|
||||
template class FieldVisitorConvertToNumber<UInt64>;
|
||||
template class FieldVisitorConvertToNumber<Int128>;
|
||||
template class FieldVisitorConvertToNumber<UInt128>;
|
||||
template class FieldVisitorConvertToNumber<Int256>;
|
||||
template class FieldVisitorConvertToNumber<UInt256>;
|
||||
template class FieldVisitorConvertToNumber<Float32>;
|
||||
template class FieldVisitorConvertToNumber<Float64>;
|
||||
|
||||
}
|
@ -117,4 +117,19 @@ public:
|
||||
T operator() (const bool & x) const { return T(x); }
|
||||
};
|
||||
|
||||
extern template class FieldVisitorConvertToNumber<Int8>;
|
||||
extern template class FieldVisitorConvertToNumber<UInt8>;
|
||||
extern template class FieldVisitorConvertToNumber<Int16>;
|
||||
extern template class FieldVisitorConvertToNumber<UInt16>;
|
||||
extern template class FieldVisitorConvertToNumber<Int32>;
|
||||
extern template class FieldVisitorConvertToNumber<UInt32>;
|
||||
extern template class FieldVisitorConvertToNumber<Int64>;
|
||||
extern template class FieldVisitorConvertToNumber<UInt64>;
|
||||
extern template class FieldVisitorConvertToNumber<Int128>;
|
||||
extern template class FieldVisitorConvertToNumber<UInt128>;
|
||||
extern template class FieldVisitorConvertToNumber<Int256>;
|
||||
extern template class FieldVisitorConvertToNumber<UInt256>;
|
||||
extern template class FieldVisitorConvertToNumber<Float32>;
|
||||
extern template class FieldVisitorConvertToNumber<Float64>;
|
||||
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ bool isLocalhost(const std::string & hostname)
|
||||
{
|
||||
try
|
||||
{
|
||||
return isLocalAddress(DNSResolver::instance().resolveHost(hostname));
|
||||
return isLocalAddress(DNSResolver::instance().resolveHostAllInOriginOrder(hostname).front());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -207,4 +207,10 @@ inline DataTypePtr createDecimal(UInt64 precision_value, UInt64 scale_value)
|
||||
return std::make_shared<DecimalType<Decimal256>>(precision_value, scale_value);
|
||||
}
|
||||
|
||||
extern template class DataTypeDecimalBase<Decimal32>;
|
||||
extern template class DataTypeDecimalBase<Decimal64>;
|
||||
extern template class DataTypeDecimalBase<Decimal128>;
|
||||
extern template class DataTypeDecimalBase<Decimal256>;
|
||||
extern template class DataTypeDecimalBase<DateTime64>;
|
||||
|
||||
}
|
||||
|
@ -112,6 +112,256 @@ static DataTypePtr createExact(const ASTPtr & arguments)
|
||||
return createDecimal<DataTypeDecimal>(precision, scale);
|
||||
}
|
||||
|
||||
template <typename FromDataType, typename ToDataType, typename ReturnType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>)
|
||||
ReturnType convertDecimalsImpl(const typename FromDataType::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename ToDataType::FieldType & result)
|
||||
{
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
using MaxFieldType = std::conditional_t<(sizeof(FromFieldType) > sizeof(ToFieldType)), FromFieldType, ToFieldType>;
|
||||
using MaxNativeType = typename MaxFieldType::NativeType;
|
||||
|
||||
static constexpr bool throw_exception = std::is_same_v<ReturnType, void>;
|
||||
|
||||
MaxNativeType converted_value;
|
||||
if (scale_to > scale_from)
|
||||
{
|
||||
converted_value = DecimalUtils::scaleMultiplier<MaxNativeType>(scale_to - scale_from);
|
||||
if (common::mulOverflow(static_cast<MaxNativeType>(value.value), converted_value, converted_value))
|
||||
{
|
||||
if constexpr (throw_exception)
|
||||
throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "{} convert overflow while multiplying {} by scale {}",
|
||||
std::string(ToDataType::family_name), toString(value.value), toString(converted_value));
|
||||
else
|
||||
return ReturnType(false);
|
||||
}
|
||||
}
|
||||
else if (scale_to == scale_from)
|
||||
{
|
||||
converted_value = value.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
converted_value = value.value / DecimalUtils::scaleMultiplier<MaxNativeType>(scale_from - scale_to);
|
||||
}
|
||||
|
||||
if constexpr (sizeof(FromFieldType) > sizeof(ToFieldType))
|
||||
{
|
||||
if (converted_value < std::numeric_limits<typename ToFieldType::NativeType>::min() ||
|
||||
converted_value > std::numeric_limits<typename ToFieldType::NativeType>::max())
|
||||
{
|
||||
if constexpr (throw_exception)
|
||||
throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "{} convert overflow: {} is not in range ({}, {})",
|
||||
std::string(ToDataType::family_name), toString(converted_value),
|
||||
toString(std::numeric_limits<typename ToFieldType::NativeType>::min()),
|
||||
toString(std::numeric_limits<typename ToFieldType::NativeType>::max()));
|
||||
else
|
||||
return ReturnType(false);
|
||||
}
|
||||
}
|
||||
|
||||
result = static_cast<typename ToFieldType::NativeType>(converted_value);
|
||||
|
||||
return ReturnType(true);
|
||||
}
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
template void convertDecimalsImpl<FROM_DATA_TYPE, TO_DATA_TYPE, void>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename TO_DATA_TYPE::FieldType & result); \
|
||||
template bool convertDecimalsImpl<FROM_DATA_TYPE, TO_DATA_TYPE, bool>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename TO_DATA_TYPE::FieldType & result);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>)
|
||||
typename ToDataType::FieldType convertDecimals(const typename FromDataType::FieldType & value, UInt32 scale_from, UInt32 scale_to)
|
||||
{
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
ToFieldType result;
|
||||
|
||||
convertDecimalsImpl<FromDataType, ToDataType, void>(value, scale_from, scale_to, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
template typename TO_DATA_TYPE::FieldType convertDecimals<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale_from, UInt32 scale_to);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>)
|
||||
bool tryConvertDecimals(const typename FromDataType::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename ToDataType::FieldType & result)
|
||||
{
|
||||
return convertDecimalsImpl<FromDataType, ToDataType, bool>(value, scale_from, scale_to, result);
|
||||
}
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
template bool tryConvertDecimals<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename TO_DATA_TYPE::FieldType & result);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType, typename ReturnType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && is_arithmetic_v<typename ToDataType::FieldType>)
|
||||
ReturnType convertFromDecimalImpl(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType & result)
|
||||
{
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
|
||||
return DecimalUtils::convertToImpl<ToFieldType, FromFieldType, ReturnType>(value, scale, result);
|
||||
}
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
template void convertFromDecimalImpl<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType & result); \
|
||||
template bool convertFromDecimalImpl<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType & result);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_ARITHMETIC_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && is_arithmetic_v<typename ToDataType::FieldType>)
|
||||
inline typename ToDataType::FieldType convertFromDecimal(const typename FromDataType::FieldType & value, UInt32 scale)
|
||||
{
|
||||
typename ToDataType::FieldType result;
|
||||
|
||||
convertFromDecimalImpl<FromDataType, ToDataType, void>(value, scale, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
template typename TO_DATA_TYPE::FieldType convertFromDecimal<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_ARITHMETIC_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && is_arithmetic_v<typename ToDataType::FieldType>)
|
||||
inline bool tryConvertFromDecimal(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType& result)
|
||||
{
|
||||
return convertFromDecimalImpl<FromDataType, ToDataType, bool>(value, scale, result);
|
||||
}
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
template bool tryConvertFromDecimal<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType& result);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_ARITHMETIC_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType, typename ReturnType>
|
||||
requires (is_arithmetic_v<typename FromDataType::FieldType> && IsDataTypeDecimal<ToDataType>)
|
||||
ReturnType convertToDecimalImpl(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType & result)
|
||||
{
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
using ToNativeType = typename ToFieldType::NativeType;
|
||||
|
||||
static constexpr bool throw_exception = std::is_same_v<ReturnType, void>;
|
||||
|
||||
if constexpr (std::is_floating_point_v<FromFieldType>)
|
||||
{
|
||||
if (!std::isfinite(value))
|
||||
{
|
||||
if constexpr (throw_exception)
|
||||
throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "{} convert overflow. Cannot convert infinity or NaN to decimal", ToDataType::family_name);
|
||||
else
|
||||
return ReturnType(false);
|
||||
}
|
||||
|
||||
auto out = value * static_cast<FromFieldType>(DecimalUtils::scaleMultiplier<ToNativeType>(scale));
|
||||
|
||||
if (out <= static_cast<FromFieldType>(std::numeric_limits<ToNativeType>::min()) ||
|
||||
out >= static_cast<FromFieldType>(std::numeric_limits<ToNativeType>::max()))
|
||||
{
|
||||
if constexpr (throw_exception)
|
||||
throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "{} convert overflow. Float is out of Decimal range", ToDataType::family_name);
|
||||
else
|
||||
return ReturnType(false);
|
||||
}
|
||||
|
||||
result = static_cast<ToNativeType>(out);
|
||||
return ReturnType(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (is_big_int_v<FromFieldType>)
|
||||
return ReturnType(convertDecimalsImpl<DataTypeDecimal<Decimal256>, ToDataType, ReturnType>(static_cast<Int256>(value), 0, scale, result));
|
||||
else if constexpr (std::is_same_v<FromFieldType, UInt64>)
|
||||
return ReturnType(convertDecimalsImpl<DataTypeDecimal<Decimal128>, ToDataType, ReturnType>(static_cast<Int128>(value), 0, scale, result));
|
||||
else
|
||||
return ReturnType(convertDecimalsImpl<DataTypeDecimal<Decimal64>, ToDataType, ReturnType>(static_cast<Int64>(value), 0, scale, result));
|
||||
}
|
||||
}
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
template void convertToDecimalImpl<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType & result); \
|
||||
template bool convertToDecimalImpl<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType & result);
|
||||
#define INVOKE(X) FOR_EACH_ARITHMETIC_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (is_arithmetic_v<typename FromDataType::FieldType> && IsDataTypeDecimal<ToDataType>)
|
||||
inline typename ToDataType::FieldType convertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale)
|
||||
{
|
||||
typename ToDataType::FieldType result;
|
||||
convertToDecimalImpl<FromDataType, ToDataType, void>(value, scale, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
template typename TO_DATA_TYPE::FieldType convertToDecimal<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale);
|
||||
#define INVOKE(X) FOR_EACH_ARITHMETIC_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (is_arithmetic_v<typename FromDataType::FieldType> && IsDataTypeDecimal<ToDataType>)
|
||||
inline bool tryConvertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType& result)
|
||||
{
|
||||
return convertToDecimalImpl<FromDataType, ToDataType, bool>(value, scale, result);
|
||||
}
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
template bool tryConvertToDecimal<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType& result);
|
||||
#define INVOKE(X) FOR_EACH_ARITHMETIC_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename T>
|
||||
DataTypePtr createDecimalMaxPrecision(UInt64 scale)
|
||||
{
|
||||
return std::make_shared<DataTypeDecimal<T>>(DecimalUtils::max_precision<T>, scale);
|
||||
}
|
||||
|
||||
template DataTypePtr createDecimalMaxPrecision<Decimal32>(UInt64 scale);
|
||||
template DataTypePtr createDecimalMaxPrecision<Decimal64>(UInt64 scale);
|
||||
template DataTypePtr createDecimalMaxPrecision<Decimal128>(UInt64 scale);
|
||||
template DataTypePtr createDecimalMaxPrecision<Decimal256>(UInt64 scale);
|
||||
|
||||
/// Explicit template instantiations.
|
||||
template class DataTypeDecimal<Decimal32>;
|
||||
template class DataTypeDecimal<Decimal64>;
|
||||
template class DataTypeDecimal<Decimal128>;
|
||||
template class DataTypeDecimal<Decimal256>;
|
||||
|
||||
void registerDataTypeDecimal(DataTypeFactory & factory)
|
||||
{
|
||||
factory.registerDataType("Decimal32", createExact<Decimal32>, DataTypeFactory::CaseInsensitive);
|
||||
@ -125,10 +375,4 @@ void registerDataTypeDecimal(DataTypeFactory & factory)
|
||||
factory.registerAlias("FIXED", "Decimal", DataTypeFactory::CaseInsensitive);
|
||||
}
|
||||
|
||||
/// Explicit template instantiations.
|
||||
template class DataTypeDecimal<Decimal32>;
|
||||
template class DataTypeDecimal<Decimal64>;
|
||||
template class DataTypeDecimal<Decimal128>;
|
||||
template class DataTypeDecimal<Decimal256>;
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,11 @@
|
||||
#include <base/arithmeticOverflow.h>
|
||||
#include <base/extended_types.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <base/Decimal.h>
|
||||
#include <base/Decimal_fwd.h>
|
||||
#include <DataTypes/IDataType.h>
|
||||
#include <DataTypes/DataTypeDate.h>
|
||||
#include <DataTypes/DataTypeDate32.h>
|
||||
#include <DataTypes/DataTypeDecimalBase.h>
|
||||
#include <DataTypes/DataTypeDateTime64.h>
|
||||
|
||||
@ -13,7 +17,6 @@ namespace DB
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int DECIMAL_OVERFLOW;
|
||||
extern const int LOGICAL_ERROR;
|
||||
}
|
||||
|
||||
@ -99,171 +102,145 @@ inline UInt32 getDecimalScale(const DataTypeDecimal<T> & data_type)
|
||||
return data_type.getScale();
|
||||
}
|
||||
|
||||
#define FOR_EACH_DECIMAL_TYPE(M) \
|
||||
M(DataTypeDecimal<DateTime64>) \
|
||||
M(DataTypeDateTime64) \
|
||||
M(DataTypeDecimal32) \
|
||||
M(DataTypeDecimal64) \
|
||||
M(DataTypeDecimal128) \
|
||||
M(DataTypeDecimal256)
|
||||
|
||||
#define FOR_EACH_DECIMAL_TYPE_PASS(M, X) \
|
||||
M(DataTypeDecimal<DateTime64>, X) \
|
||||
M(DataTypeDateTime64, X) \
|
||||
M(DataTypeDecimal32, X) \
|
||||
M(DataTypeDecimal64, X) \
|
||||
M(DataTypeDecimal128, X) \
|
||||
M(DataTypeDecimal256, X)
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType, typename ReturnType = void>
|
||||
requires (IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>)
|
||||
inline ReturnType convertDecimalsImpl(const typename FromDataType::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename ToDataType::FieldType & result)
|
||||
{
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
using MaxFieldType = std::conditional_t<(sizeof(FromFieldType) > sizeof(ToFieldType)), FromFieldType, ToFieldType>;
|
||||
using MaxNativeType = typename MaxFieldType::NativeType;
|
||||
ReturnType convertDecimalsImpl(const typename FromDataType::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename ToDataType::FieldType & result);
|
||||
|
||||
static constexpr bool throw_exception = std::is_same_v<ReturnType, void>;
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
extern template void convertDecimalsImpl<FROM_DATA_TYPE, TO_DATA_TYPE, void>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename TO_DATA_TYPE::FieldType & result); \
|
||||
extern template bool convertDecimalsImpl<FROM_DATA_TYPE, TO_DATA_TYPE, bool>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename TO_DATA_TYPE::FieldType & result);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
MaxNativeType converted_value;
|
||||
if (scale_to > scale_from)
|
||||
{
|
||||
converted_value = DecimalUtils::scaleMultiplier<MaxNativeType>(scale_to - scale_from);
|
||||
if (common::mulOverflow(static_cast<MaxNativeType>(value.value), converted_value, converted_value))
|
||||
{
|
||||
if constexpr (throw_exception)
|
||||
throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "{} convert overflow while multiplying {} by scale {}",
|
||||
std::string(ToDataType::family_name), toString(value.value), toString(converted_value));
|
||||
else
|
||||
return ReturnType(false);
|
||||
}
|
||||
}
|
||||
else if (scale_to == scale_from)
|
||||
{
|
||||
converted_value = value.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
converted_value = value.value / DecimalUtils::scaleMultiplier<MaxNativeType>(scale_from - scale_to);
|
||||
}
|
||||
|
||||
if constexpr (sizeof(FromFieldType) > sizeof(ToFieldType))
|
||||
{
|
||||
if (converted_value < std::numeric_limits<typename ToFieldType::NativeType>::min() ||
|
||||
converted_value > std::numeric_limits<typename ToFieldType::NativeType>::max())
|
||||
{
|
||||
if constexpr (throw_exception)
|
||||
throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "{} convert overflow: {} is not in range ({}, {})",
|
||||
std::string(ToDataType::family_name), toString(converted_value),
|
||||
toString(std::numeric_limits<typename ToFieldType::NativeType>::min()),
|
||||
toString(std::numeric_limits<typename ToFieldType::NativeType>::max()));
|
||||
else
|
||||
return ReturnType(false);
|
||||
}
|
||||
}
|
||||
|
||||
result = static_cast<typename ToFieldType::NativeType>(converted_value);
|
||||
|
||||
return ReturnType(true);
|
||||
}
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>)
|
||||
inline typename ToDataType::FieldType convertDecimals(const typename FromDataType::FieldType & value, UInt32 scale_from, UInt32 scale_to)
|
||||
{
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
ToFieldType result;
|
||||
typename ToDataType::FieldType convertDecimals(const typename FromDataType::FieldType & value, UInt32 scale_from, UInt32 scale_to);
|
||||
|
||||
convertDecimalsImpl<FromDataType, ToDataType, void>(value, scale_from, scale_to, result);
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
extern template typename TO_DATA_TYPE::FieldType convertDecimals<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale_from, UInt32 scale_to);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>)
|
||||
inline bool tryConvertDecimals(const typename FromDataType::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename ToDataType::FieldType & result)
|
||||
{
|
||||
return convertDecimalsImpl<FromDataType, ToDataType, bool>(value, scale_from, scale_to, result);
|
||||
}
|
||||
bool tryConvertDecimals(const typename FromDataType::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename ToDataType::FieldType & result);
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
extern template bool tryConvertDecimals<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale_from, UInt32 scale_to, typename TO_DATA_TYPE::FieldType & result);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType, typename ReturnType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && is_arithmetic_v<typename ToDataType::FieldType>)
|
||||
inline ReturnType convertFromDecimalImpl(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType& result)
|
||||
{
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
ReturnType convertFromDecimalImpl(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType & result);
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
extern template void convertFromDecimalImpl<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType & result); \
|
||||
extern template bool convertFromDecimalImpl<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType & result);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_ARITHMETIC_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
return DecimalUtils::convertToImpl<ToFieldType, FromFieldType, ReturnType>(value, scale, result);
|
||||
}
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && is_arithmetic_v<typename ToDataType::FieldType>)
|
||||
inline typename ToDataType::FieldType convertFromDecimal(const typename FromDataType::FieldType & value, UInt32 scale)
|
||||
{
|
||||
typename ToDataType::FieldType result;
|
||||
typename ToDataType::FieldType convertFromDecimal(const typename FromDataType::FieldType & value, UInt32 scale);
|
||||
|
||||
convertFromDecimalImpl<FromDataType, ToDataType, void>(value, scale, result);
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
extern template typename TO_DATA_TYPE::FieldType convertFromDecimal<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_ARITHMETIC_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (IsDataTypeDecimal<FromDataType> && is_arithmetic_v<typename ToDataType::FieldType>)
|
||||
inline bool tryConvertFromDecimal(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType& result)
|
||||
{
|
||||
return convertFromDecimalImpl<FromDataType, ToDataType, bool>(value, scale, result);
|
||||
}
|
||||
bool tryConvertFromDecimal(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType& result);
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
extern template bool tryConvertFromDecimal<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType& result);
|
||||
#define INVOKE(X) FOR_EACH_DECIMAL_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_ARITHMETIC_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType, typename ReturnType>
|
||||
requires (is_arithmetic_v<typename FromDataType::FieldType> && IsDataTypeDecimal<ToDataType>)
|
||||
inline ReturnType convertToDecimalImpl(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType& result)
|
||||
{
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
using ToNativeType = typename ToFieldType::NativeType;
|
||||
ReturnType convertToDecimalImpl(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType& result);
|
||||
|
||||
static constexpr bool throw_exception = std::is_same_v<ReturnType, void>;
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
extern template void convertToDecimalImpl<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType & result); \
|
||||
extern template bool convertToDecimalImpl<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType & result);
|
||||
#define INVOKE(X) FOR_EACH_ARITHMETIC_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
if constexpr (std::is_floating_point_v<FromFieldType>)
|
||||
{
|
||||
if (!std::isfinite(value))
|
||||
{
|
||||
if constexpr (throw_exception)
|
||||
throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "{} convert overflow. Cannot convert infinity or NaN to decimal", ToDataType::family_name);
|
||||
else
|
||||
return ReturnType(false);
|
||||
}
|
||||
|
||||
auto out = value * static_cast<FromFieldType>(DecimalUtils::scaleMultiplier<ToNativeType>(scale));
|
||||
|
||||
if (out <= static_cast<FromFieldType>(std::numeric_limits<ToNativeType>::min()) ||
|
||||
out >= static_cast<FromFieldType>(std::numeric_limits<ToNativeType>::max()))
|
||||
{
|
||||
if constexpr (throw_exception)
|
||||
throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "{} convert overflow. Float is out of Decimal range", ToDataType::family_name);
|
||||
else
|
||||
return ReturnType(false);
|
||||
}
|
||||
|
||||
result = static_cast<ToNativeType>(out);
|
||||
return ReturnType(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (is_big_int_v<FromFieldType>)
|
||||
return ReturnType(convertDecimalsImpl<DataTypeDecimal<Decimal256>, ToDataType, ReturnType>(static_cast<Int256>(value), 0, scale, result));
|
||||
else if constexpr (std::is_same_v<FromFieldType, UInt64>)
|
||||
return ReturnType(convertDecimalsImpl<DataTypeDecimal<Decimal128>, ToDataType, ReturnType>(static_cast<Int128>(value), 0, scale, result));
|
||||
else
|
||||
return ReturnType(convertDecimalsImpl<DataTypeDecimal<Decimal64>, ToDataType, ReturnType>(static_cast<Int64>(value), 0, scale, result));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (is_arithmetic_v<typename FromDataType::FieldType> && IsDataTypeDecimal<ToDataType>)
|
||||
inline typename ToDataType::FieldType convertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale)
|
||||
{
|
||||
typename ToDataType::FieldType result;
|
||||
convertToDecimalImpl<FromDataType, ToDataType, void>(value, scale, result);
|
||||
return result;
|
||||
}
|
||||
typename ToDataType::FieldType convertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale);
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
extern template typename TO_DATA_TYPE::FieldType convertToDecimal<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale);
|
||||
#define INVOKE(X) FOR_EACH_ARITHMETIC_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
requires (is_arithmetic_v<typename FromDataType::FieldType> && IsDataTypeDecimal<ToDataType>)
|
||||
inline bool tryConvertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType& result)
|
||||
{
|
||||
return convertToDecimalImpl<FromDataType, ToDataType, bool>(value, scale, result);
|
||||
}
|
||||
bool tryConvertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale, typename ToDataType::FieldType& result);
|
||||
|
||||
#define DISPATCH(FROM_DATA_TYPE, TO_DATA_TYPE) \
|
||||
extern template bool tryConvertToDecimal<FROM_DATA_TYPE, TO_DATA_TYPE>(const typename FROM_DATA_TYPE::FieldType & value, UInt32 scale, typename TO_DATA_TYPE::FieldType& result);
|
||||
#define INVOKE(X) FOR_EACH_ARITHMETIC_TYPE_PASS(DISPATCH, X)
|
||||
FOR_EACH_DECIMAL_TYPE(INVOKE);
|
||||
#undef INVOKE
|
||||
#undef DISPATCH
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline DataTypePtr createDecimalMaxPrecision(UInt64 scale)
|
||||
{
|
||||
return std::make_shared<DataTypeDecimal<T>>(DecimalUtils::max_precision<T>, scale);
|
||||
}
|
||||
DataTypePtr createDecimalMaxPrecision(UInt64 scale);
|
||||
|
||||
extern template DataTypePtr createDecimalMaxPrecision<Decimal32>(UInt64 scale);
|
||||
extern template DataTypePtr createDecimalMaxPrecision<Decimal64>(UInt64 scale);
|
||||
extern template DataTypePtr createDecimalMaxPrecision<Decimal128>(UInt64 scale);
|
||||
extern template DataTypePtr createDecimalMaxPrecision<Decimal256>(UInt64 scale);
|
||||
|
||||
extern template class DataTypeDecimal<Decimal32>;
|
||||
extern template class DataTypeDecimal<Decimal64>;
|
||||
extern template class DataTypeDecimal<Decimal128>;
|
||||
extern template class DataTypeDecimal<Decimal256>;
|
||||
|
||||
}
|
||||
|
@ -102,4 +102,21 @@ void registerDataTypeNumbers(DataTypeFactory & factory)
|
||||
factory.registerAlias("DOUBLE PRECISION", "Float64", DataTypeFactory::CaseInsensitive);
|
||||
}
|
||||
|
||||
/// Explicit template instantiations.
|
||||
template class DataTypeNumber<UInt8>;
|
||||
template class DataTypeNumber<UInt16>;
|
||||
template class DataTypeNumber<UInt32>;
|
||||
template class DataTypeNumber<UInt64>;
|
||||
template class DataTypeNumber<Int8>;
|
||||
template class DataTypeNumber<Int16>;
|
||||
template class DataTypeNumber<Int32>;
|
||||
template class DataTypeNumber<Int64>;
|
||||
template class DataTypeNumber<Float32>;
|
||||
template class DataTypeNumber<Float64>;
|
||||
|
||||
template class DataTypeNumber<UInt128>;
|
||||
template class DataTypeNumber<Int128>;
|
||||
template class DataTypeNumber<UInt256>;
|
||||
template class DataTypeNumber<Int256>;
|
||||
|
||||
}
|
||||
|
@ -55,6 +55,22 @@ private:
|
||||
bool unsigned_can_be_signed = false;
|
||||
};
|
||||
|
||||
extern template class DataTypeNumber<UInt8>;
|
||||
extern template class DataTypeNumber<UInt16>;
|
||||
extern template class DataTypeNumber<UInt32>;
|
||||
extern template class DataTypeNumber<UInt64>;
|
||||
extern template class DataTypeNumber<Int8>;
|
||||
extern template class DataTypeNumber<Int16>;
|
||||
extern template class DataTypeNumber<Int32>;
|
||||
extern template class DataTypeNumber<Int64>;
|
||||
extern template class DataTypeNumber<Float32>;
|
||||
extern template class DataTypeNumber<Float64>;
|
||||
|
||||
extern template class DataTypeNumber<UInt128>;
|
||||
extern template class DataTypeNumber<Int128>;
|
||||
extern template class DataTypeNumber<UInt256>;
|
||||
extern template class DataTypeNumber<Int256>;
|
||||
|
||||
using DataTypeUInt8 = DataTypeNumber<UInt8>;
|
||||
using DataTypeUInt16 = DataTypeNumber<UInt16>;
|
||||
using DataTypeUInt32 = DataTypeNumber<UInt32>;
|
||||
|
@ -267,4 +267,91 @@ SerializationPtr IDataType::getSerialization(const NameAndTypePair & column)
|
||||
return column.type->getDefaultSerialization();
|
||||
}
|
||||
|
||||
#define FOR_TYPES_OF_TYPE(M) \
|
||||
M(TypeIndex) \
|
||||
M(const IDataType &) \
|
||||
M(const DataTypePtr &) \
|
||||
M(WhichDataType)
|
||||
|
||||
#define DISPATCH(TYPE) \
|
||||
bool isUInt8(TYPE data_type) { return WhichDataType(data_type).isUInt8(); } \
|
||||
bool isUInt16(TYPE data_type) { return WhichDataType(data_type).isUInt16(); } \
|
||||
bool isUInt32(TYPE data_type) { return WhichDataType(data_type).isUInt32(); } \
|
||||
bool isUInt64(TYPE data_type) { return WhichDataType(data_type).isUInt64(); } \
|
||||
bool isNativeUInt(TYPE data_type) { return WhichDataType(data_type).isNativeUInt(); } \
|
||||
bool isUInt(TYPE data_type) { return WhichDataType(data_type).isUInt(); } \
|
||||
\
|
||||
bool isInt8(TYPE data_type) { return WhichDataType(data_type).isInt8(); } \
|
||||
bool isInt16(TYPE data_type) { return WhichDataType(data_type).isInt16(); } \
|
||||
bool isInt32(TYPE data_type) { return WhichDataType(data_type).isInt32(); } \
|
||||
bool isInt64(TYPE data_type) { return WhichDataType(data_type).isInt64(); } \
|
||||
bool isNativeInt(TYPE data_type) { return WhichDataType(data_type).isNativeInt(); } \
|
||||
bool isInt(TYPE data_type) { return WhichDataType(data_type).isInt(); } \
|
||||
\
|
||||
bool isInteger(TYPE data_type) { return WhichDataType(data_type).isInteger(); } \
|
||||
bool isNativeInteger(TYPE data_type) { return WhichDataType(data_type).isNativeInteger(); } \
|
||||
\
|
||||
bool isDecimal(TYPE data_type) { return WhichDataType(data_type).isDecimal(); } \
|
||||
\
|
||||
bool isFloat(TYPE data_type) { return WhichDataType(data_type).isFloat(); } \
|
||||
\
|
||||
bool isNativeNumber(TYPE data_type) { return WhichDataType(data_type).isNativeNumber(); } \
|
||||
bool isNumber(TYPE data_type) { return WhichDataType(data_type).isNumber(); } \
|
||||
\
|
||||
bool isEnum8(TYPE data_type) { return WhichDataType(data_type).isEnum8(); } \
|
||||
bool isEnum16(TYPE data_type) { return WhichDataType(data_type).isEnum16(); } \
|
||||
bool isEnum(TYPE data_type) { return WhichDataType(data_type).isEnum(); } \
|
||||
\
|
||||
bool isDate(TYPE data_type) { return WhichDataType(data_type).isDate(); } \
|
||||
bool isDate32(TYPE data_type) { return WhichDataType(data_type).isDate32(); } \
|
||||
bool isDateOrDate32(TYPE data_type) { return WhichDataType(data_type).isDateOrDate32(); } \
|
||||
bool isDateTime(TYPE data_type) { return WhichDataType(data_type).isDateTime(); } \
|
||||
bool isDateTime64(TYPE data_type) { return WhichDataType(data_type).isDateTime64(); } \
|
||||
bool isDateTimeOrDateTime64(TYPE data_type) { return WhichDataType(data_type).isDateTimeOrDateTime64(); } \
|
||||
bool isDateOrDate32OrDateTimeOrDateTime64(TYPE data_type) { return WhichDataType(data_type).isDateOrDate32OrDateTimeOrDateTime64(); } \
|
||||
\
|
||||
bool isString(TYPE data_type) { return WhichDataType(data_type).isString(); } \
|
||||
bool isFixedString(TYPE data_type) { return WhichDataType(data_type).isFixedString(); } \
|
||||
bool isStringOrFixedString(TYPE data_type) { return WhichDataType(data_type).isStringOrFixedString(); } \
|
||||
\
|
||||
bool isUUID(TYPE data_type) { return WhichDataType(data_type).isUUID(); } \
|
||||
bool isIPv4(TYPE data_type) { return WhichDataType(data_type).isIPv4(); } \
|
||||
bool isIPv6(TYPE data_type) { return WhichDataType(data_type).isIPv6(); } \
|
||||
bool isArray(TYPE data_type) { return WhichDataType(data_type).isArray(); } \
|
||||
bool isTuple(TYPE data_type) { return WhichDataType(data_type).isTuple(); } \
|
||||
bool isMap(TYPE data_type) {return WhichDataType(data_type).isMap(); } \
|
||||
bool isInterval(TYPE data_type) {return WhichDataType(data_type).isInterval(); } \
|
||||
bool isObject(TYPE data_type) { return WhichDataType(data_type).isObject(); } \
|
||||
bool isVariant(TYPE data_type) { return WhichDataType(data_type).isVariant(); } \
|
||||
bool isNothing(TYPE data_type) { return WhichDataType(data_type).isNothing(); } \
|
||||
\
|
||||
bool isColumnedAsNumber(TYPE data_type) \
|
||||
{ \
|
||||
WhichDataType which(data_type); \
|
||||
return which.isInteger() || which.isFloat() || which.isDateOrDate32OrDateTimeOrDateTime64() || which.isUUID() || which.isIPv4() || which.isIPv6(); \
|
||||
} \
|
||||
\
|
||||
bool isColumnedAsDecimal(TYPE data_type) \
|
||||
{ \
|
||||
WhichDataType which(data_type); \
|
||||
return which.isDecimal() || which.isDateTime64(); \
|
||||
} \
|
||||
\
|
||||
bool isNotCreatable(TYPE data_type) \
|
||||
{ \
|
||||
WhichDataType which(data_type); \
|
||||
return which.isNothing() || which.isFunction() || which.isSet(); \
|
||||
} \
|
||||
\
|
||||
bool isNotDecimalButComparableToDecimal(TYPE data_type) \
|
||||
{ \
|
||||
WhichDataType which(data_type); \
|
||||
return which.isInt() || which.isUInt() || which.isFloat(); \
|
||||
} \
|
||||
|
||||
FOR_TYPES_OF_TYPE(DISPATCH)
|
||||
|
||||
#undef DISPATCH
|
||||
#undef FOR_TYPES_OF_TYPE
|
||||
|
||||
}
|
||||
|
@ -424,71 +424,76 @@ struct WhichDataType
|
||||
|
||||
/// IDataType helpers (alternative for IDataType virtual methods with single point of truth)
|
||||
|
||||
template <typename T> inline bool isUInt8(const T & data_type) { return WhichDataType(data_type).isUInt8(); }
|
||||
template <typename T> inline bool isUInt16(const T & data_type) { return WhichDataType(data_type).isUInt16(); }
|
||||
template <typename T> inline bool isUInt32(const T & data_type) { return WhichDataType(data_type).isUInt32(); }
|
||||
template <typename T> inline bool isUInt64(const T & data_type) { return WhichDataType(data_type).isUInt64(); }
|
||||
template <typename T> inline bool isNativeUInt(const T & data_type) { return WhichDataType(data_type).isNativeUInt(); }
|
||||
template <typename T> inline bool isUInt(const T & data_type) { return WhichDataType(data_type).isUInt(); }
|
||||
#define FOR_TYPES_OF_TYPE(M) \
|
||||
M(TypeIndex) \
|
||||
M(const IDataType &) \
|
||||
M(const DataTypePtr &) \
|
||||
M(WhichDataType)
|
||||
|
||||
template <typename T> inline bool isInt8(const T & data_type) { return WhichDataType(data_type).isInt8(); }
|
||||
template <typename T> inline bool isInt16(const T & data_type) { return WhichDataType(data_type).isInt16(); }
|
||||
template <typename T> inline bool isInt32(const T & data_type) { return WhichDataType(data_type).isInt32(); }
|
||||
template <typename T> inline bool isInt64(const T & data_type) { return WhichDataType(data_type).isInt64(); }
|
||||
template <typename T> inline bool isNativeInt(const T & data_type) { return WhichDataType(data_type).isNativeInt(); }
|
||||
template <typename T> inline bool isInt(const T & data_type) { return WhichDataType(data_type).isInt(); }
|
||||
#define DISPATCH(TYPE) \
|
||||
bool isUInt8(TYPE data_type); \
|
||||
bool isUInt16(TYPE data_type); \
|
||||
bool isUInt32(TYPE data_type); \
|
||||
bool isUInt64(TYPE data_type); \
|
||||
bool isNativeUInt(TYPE data_type); \
|
||||
bool isUInt(TYPE data_type); \
|
||||
\
|
||||
bool isInt8(TYPE data_type); \
|
||||
bool isInt16(TYPE data_type); \
|
||||
bool isInt32(TYPE data_type); \
|
||||
bool isInt64(TYPE data_type); \
|
||||
bool isNativeInt(TYPE data_type); \
|
||||
bool isInt(TYPE data_type); \
|
||||
\
|
||||
bool isInteger(TYPE data_type); \
|
||||
bool isNativeInteger(TYPE data_type); \
|
||||
\
|
||||
bool isDecimal(TYPE data_type); \
|
||||
\
|
||||
bool isFloat(TYPE data_type); \
|
||||
\
|
||||
bool isNativeNumber(TYPE data_type); \
|
||||
bool isNumber(TYPE data_type); \
|
||||
\
|
||||
bool isEnum8(TYPE data_type); \
|
||||
bool isEnum16(TYPE data_type); \
|
||||
bool isEnum(TYPE data_type); \
|
||||
\
|
||||
bool isDate(TYPE data_type); \
|
||||
bool isDate32(TYPE data_type); \
|
||||
bool isDateOrDate32(TYPE data_type); \
|
||||
bool isDateTime(TYPE data_type); \
|
||||
bool isDateTime64(TYPE data_type); \
|
||||
bool isDateTimeOrDateTime64(TYPE data_type); \
|
||||
bool isDateOrDate32OrDateTimeOrDateTime64(TYPE data_type); \
|
||||
\
|
||||
bool isString(TYPE data_type); \
|
||||
bool isFixedString(TYPE data_type); \
|
||||
bool isStringOrFixedString(TYPE data_type); \
|
||||
\
|
||||
bool isUUID(TYPE data_type); \
|
||||
bool isIPv4(TYPE data_type); \
|
||||
bool isIPv6(TYPE data_type); \
|
||||
bool isArray(TYPE data_type); \
|
||||
bool isTuple(TYPE data_type); \
|
||||
bool isMap(TYPE data_type); \
|
||||
bool isInterval(TYPE data_type); \
|
||||
bool isObject(TYPE data_type); \
|
||||
bool isVariant(TYPE data_type); \
|
||||
bool isNothing(TYPE data_type); \
|
||||
\
|
||||
bool isColumnedAsNumber(TYPE data_type); \
|
||||
\
|
||||
bool isColumnedAsDecimal(TYPE data_type); \
|
||||
\
|
||||
bool isNotCreatable(TYPE data_type); \
|
||||
\
|
||||
bool isNotDecimalButComparableToDecimal(TYPE data_type); \
|
||||
|
||||
template <typename T> inline bool isInteger(const T & data_type) { return WhichDataType(data_type).isInteger(); }
|
||||
template <typename T> inline bool isNativeInteger(const T & data_type) { return WhichDataType(data_type).isNativeInteger(); }
|
||||
FOR_TYPES_OF_TYPE(DISPATCH)
|
||||
|
||||
template <typename T> inline bool isDecimal(const T & data_type) { return WhichDataType(data_type).isDecimal(); }
|
||||
|
||||
template <typename T> inline bool isFloat(const T & data_type) { return WhichDataType(data_type).isFloat(); }
|
||||
|
||||
template <typename T> inline bool isNativeNumber(const T & data_type) { return WhichDataType(data_type).isNativeNumber(); }
|
||||
template <typename T> inline bool isNumber(const T & data_type) { return WhichDataType(data_type).isNumber(); }
|
||||
|
||||
template <typename T> inline bool isEnum8(const T & data_type) { return WhichDataType(data_type).isEnum8(); }
|
||||
template <typename T> inline bool isEnum16(const T & data_type) { return WhichDataType(data_type).isEnum16(); }
|
||||
template <typename T> inline bool isEnum(const T & data_type) { return WhichDataType(data_type).isEnum(); }
|
||||
|
||||
template <typename T> inline bool isDate(const T & data_type) { return WhichDataType(data_type).isDate(); }
|
||||
template <typename T> inline bool isDate32(const T & data_type) { return WhichDataType(data_type).isDate32(); }
|
||||
template <typename T> inline bool isDateOrDate32(const T & data_type) { return WhichDataType(data_type).isDateOrDate32(); }
|
||||
template <typename T> inline bool isDateTime(const T & data_type) { return WhichDataType(data_type).isDateTime(); }
|
||||
template <typename T> inline bool isDateTime64(const T & data_type) { return WhichDataType(data_type).isDateTime64(); }
|
||||
template <typename T> inline bool isDateTimeOrDateTime64(const T & data_type) { return WhichDataType(data_type).isDateTimeOrDateTime64(); }
|
||||
template <typename T> inline bool isDateOrDate32OrDateTimeOrDateTime64(const T & data_type) { return WhichDataType(data_type).isDateOrDate32OrDateTimeOrDateTime64(); }
|
||||
|
||||
template <typename T> inline bool isString(const T & data_type) { return WhichDataType(data_type).isString(); }
|
||||
template <typename T> inline bool isFixedString(const T & data_type) { return WhichDataType(data_type).isFixedString(); }
|
||||
template <typename T> inline bool isStringOrFixedString(const T & data_type) { return WhichDataType(data_type).isStringOrFixedString(); }
|
||||
|
||||
template <typename T> inline bool isUUID(const T & data_type) { return WhichDataType(data_type).isUUID(); }
|
||||
template <typename T> inline bool isIPv4(const T & data_type) { return WhichDataType(data_type).isIPv4(); }
|
||||
template <typename T> inline bool isIPv6(const T & data_type) { return WhichDataType(data_type).isIPv6(); }
|
||||
template <typename T> inline bool isArray(const T & data_type) { return WhichDataType(data_type).isArray(); }
|
||||
template <typename T> inline bool isTuple(const T & data_type) { return WhichDataType(data_type).isTuple(); }
|
||||
template <typename T> inline bool isMap(const T & data_type) {return WhichDataType(data_type).isMap(); }
|
||||
template <typename T> inline bool isInterval(const T & data_type) {return WhichDataType(data_type).isInterval(); }
|
||||
template <typename T> inline bool isObject(const T & data_type) { return WhichDataType(data_type).isObject(); }
|
||||
template <typename T> inline bool isVariant(const T & data_type) { return WhichDataType(data_type).isVariant(); }
|
||||
|
||||
template <typename T> inline bool isNothing(const T & data_type) { return WhichDataType(data_type).isNothing(); }
|
||||
|
||||
template <typename T>
|
||||
inline bool isColumnedAsNumber(const T & data_type)
|
||||
{
|
||||
WhichDataType which(data_type);
|
||||
return which.isInteger() || which.isFloat() || which.isDateOrDate32OrDateTimeOrDateTime64() || which.isUUID() || which.isIPv4() || which.isIPv6();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool isColumnedAsDecimal(const T & data_type)
|
||||
{
|
||||
WhichDataType which(data_type);
|
||||
return which.isDecimal() || which.isDateTime64();
|
||||
}
|
||||
#undef DISPATCH
|
||||
#undef FOR_TYPES_OF_TYPE
|
||||
|
||||
// Same as isColumnedAsDecimal but also checks value type of underlyig column.
|
||||
template <typename T, typename DataType>
|
||||
@ -498,19 +503,6 @@ inline bool isColumnedAsDecimalT(const DataType & data_type)
|
||||
return (which.isDecimal() || which.isDateTime64()) && which.idx == TypeToTypeIndex<T>;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool isNotCreatable(const T & data_type)
|
||||
{
|
||||
WhichDataType which(data_type);
|
||||
return which.isNothing() || which.isFunction() || which.isSet();
|
||||
}
|
||||
|
||||
inline bool isNotDecimalButComparableToDecimal(const DataTypePtr & data_type)
|
||||
{
|
||||
WhichDataType which(data_type);
|
||||
return which.isInt() || which.isUInt() || which.isFloat();
|
||||
}
|
||||
|
||||
inline bool isBool(const DataTypePtr & data_type)
|
||||
{
|
||||
return data_type->getName() == "Bool";
|
||||
|
@ -29,4 +29,10 @@ public:
|
||||
void deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const override;
|
||||
};
|
||||
|
||||
extern template class SerializationDecimalBase<Decimal32>;
|
||||
extern template class SerializationDecimalBase<Decimal64>;
|
||||
extern template class SerializationDecimalBase<Decimal128>;
|
||||
extern template class SerializationDecimalBase<Decimal256>;
|
||||
extern template class SerializationDecimalBase<DateTime64>;
|
||||
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_arguments{
|
||||
{"value", &isStringOrFixedString<IDataType>, nullptr, "String or FixedString"}
|
||||
{"value", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "String or FixedString"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_arguments);
|
||||
|
@ -108,8 +108,10 @@ struct FunctionArgumentDescriptor
|
||||
{
|
||||
const char * argument_name;
|
||||
|
||||
std::function<bool (const IDataType &)> type_validator_func;
|
||||
std::function<bool (const IColumn &)> column_validator_func;
|
||||
using TypeValidator = bool (*)(const IDataType &);
|
||||
TypeValidator type_validator_func;
|
||||
using ColumnValidator = bool (*)(const IColumn &);
|
||||
ColumnValidator column_validator_func;
|
||||
|
||||
const char * expected_type_description;
|
||||
|
||||
|
@ -35,9 +35,9 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"haystack", &isStringOrFixedString<IDataType>, nullptr, "String or FixedString"},
|
||||
{"pattern", &isString<IDataType>, nullptr, "String"},
|
||||
{"replacement", &isString<IDataType>, nullptr, "String"}
|
||||
{"haystack", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "String or FixedString"},
|
||||
{"pattern", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
{"replacement", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
@ -186,12 +186,12 @@ static inline void checkArgumentsWithSeparatorAndOptionalMaxSubstrings(
|
||||
const IFunction & func, const ColumnsWithTypeAndName & arguments)
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"separator", &isString<IDataType>, isColumnConst, "const String"},
|
||||
{"s", &isString<IDataType>, nullptr, "String"}
|
||||
{"separator", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "const String"},
|
||||
{"s", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"}
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{"max_substrings", &isNativeInteger<IDataType>, isColumnConst, "const Number"},
|
||||
{"max_substrings", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNativeInteger), isColumnConst, "const Number"},
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(func, arguments, mandatory_args, optional_args);
|
||||
@ -200,11 +200,11 @@ static inline void checkArgumentsWithSeparatorAndOptionalMaxSubstrings(
|
||||
static inline void checkArgumentsWithOptionalMaxSubstrings(const IFunction & func, const ColumnsWithTypeAndName & arguments)
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"s", &isString<IDataType>, nullptr, "String"},
|
||||
{"s", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{"max_substrings", &isNativeInteger<IDataType>, isColumnConst, "const Number"},
|
||||
{"max_substrings", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNativeInteger), isColumnConst, "const Number"},
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(func, arguments, mandatory_args, optional_args);
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"value", &isDateTime64<IDataType>, nullptr, "DateTime64"}
|
||||
{"value", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isDateTime64), nullptr, "DateTime64"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -154,21 +154,21 @@ private:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
auto optional_args = FunctionArgumentDescriptors{
|
||||
{"IV", &isStringOrFixedString<IDataType>, nullptr, "Initialization vector binary string"},
|
||||
{"IV", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "Initialization vector binary string"},
|
||||
};
|
||||
|
||||
if constexpr (compatibility_mode == OpenSSLDetails::CompatibilityMode::OpenSSL)
|
||||
{
|
||||
optional_args.emplace_back(FunctionArgumentDescriptor{
|
||||
"AAD", &isStringOrFixedString<IDataType>, nullptr, "Additional authenticated data binary string for GCM mode"
|
||||
"AAD", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "Additional authenticated data binary string for GCM mode"
|
||||
});
|
||||
}
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments,
|
||||
FunctionArgumentDescriptors{
|
||||
{"mode", &isStringOrFixedString<IDataType>, isColumnConst, "encryption mode string"},
|
||||
{"input", &isStringOrFixedString<IDataType>, {}, "plaintext"},
|
||||
{"key", &isStringOrFixedString<IDataType>, {}, "encryption key binary string"},
|
||||
{"mode", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), isColumnConst, "encryption mode string"},
|
||||
{"input", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), {}, "plaintext"},
|
||||
{"key", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), {}, "encryption key binary string"},
|
||||
},
|
||||
optional_args
|
||||
);
|
||||
@ -425,21 +425,21 @@ private:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
auto optional_args = FunctionArgumentDescriptors{
|
||||
{"IV", &isStringOrFixedString<IDataType>, nullptr, "Initialization vector binary string"},
|
||||
{"IV", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "Initialization vector binary string"},
|
||||
};
|
||||
|
||||
if constexpr (compatibility_mode == OpenSSLDetails::CompatibilityMode::OpenSSL)
|
||||
{
|
||||
optional_args.emplace_back(FunctionArgumentDescriptor{
|
||||
"AAD", &isStringOrFixedString<IDataType>, nullptr, "Additional authenticated data binary string for GCM mode"
|
||||
"AAD", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "Additional authenticated data binary string for GCM mode"
|
||||
});
|
||||
}
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments,
|
||||
FunctionArgumentDescriptors{
|
||||
{"mode", &isStringOrFixedString<IDataType>, isColumnConst, "decryption mode string"},
|
||||
{"input", &isStringOrFixedString<IDataType>, {}, "ciphertext"},
|
||||
{"key", &isStringOrFixedString<IDataType>, {}, "decryption key binary string"},
|
||||
{"mode", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), isColumnConst, "decryption mode string"},
|
||||
{"input", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), {}, "ciphertext"},
|
||||
{"key", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), {}, "decryption key binary string"},
|
||||
},
|
||||
optional_args
|
||||
);
|
||||
|
@ -2129,12 +2129,12 @@ public:
|
||||
|
||||
if constexpr (to_decimal)
|
||||
{
|
||||
mandatory_args.push_back({"scale", &isNativeInteger<IDataType>, &isColumnConst, "const Integer"});
|
||||
mandatory_args.push_back({"scale", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNativeInteger), &isColumnConst, "const Integer"});
|
||||
}
|
||||
|
||||
if (!to_decimal && isDateTime64<Name, ToDataType>(arguments))
|
||||
{
|
||||
mandatory_args.push_back({"scale", &isNativeInteger<IDataType>, &isColumnConst, "const Integer"});
|
||||
mandatory_args.push_back({"scale", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNativeInteger), &isColumnConst, "const Integer"});
|
||||
}
|
||||
|
||||
// toString(DateTime or DateTime64, [timezone: String])
|
||||
@ -2150,7 +2150,7 @@ public:
|
||||
// toDateTime64(value, scale : Integer[, timezone: String])
|
||||
|| std::is_same_v<ToDataType, DataTypeDateTime64>)
|
||||
{
|
||||
optional_args.push_back({"timezone", &isString<IDataType>, nullptr, "String"});
|
||||
optional_args.push_back({"timezone", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"});
|
||||
}
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
@ -2498,11 +2498,11 @@ public:
|
||||
if (isDateTime64<Name, ToDataType>(arguments))
|
||||
{
|
||||
validateFunctionArgumentTypes(*this, arguments,
|
||||
FunctionArgumentDescriptors{{"string", &isStringOrFixedString<IDataType>, nullptr, "String or FixedString"}},
|
||||
FunctionArgumentDescriptors{{"string", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "String or FixedString"}},
|
||||
// optional
|
||||
FunctionArgumentDescriptors{
|
||||
{"precision", &isUInt8<IDataType>, isColumnConst, "const UInt8"},
|
||||
{"timezone", &isStringOrFixedString<IDataType>, isColumnConst, "const String or FixedString"},
|
||||
{"precision", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isUInt8), isColumnConst, "const UInt8"},
|
||||
{"timezone", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), isColumnConst, "const String or FixedString"},
|
||||
});
|
||||
|
||||
UInt64 scale = to_datetime64 ? DataTypeDateTime64::default_scale : 0;
|
||||
|
@ -45,7 +45,7 @@ namespace
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
auto args = FunctionArgumentDescriptors{
|
||||
{"json", &isString<IDataType>, nullptr, "String"},
|
||||
{"json", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
static void checkArguments(const IFunction & func, const ColumnsWithTypeAndName & arguments)
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"URL", &isString<IDataType>, nullptr, "String"},
|
||||
{"URL", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(func, arguments, mandatory_args);
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
static void checkArguments(const IFunction & func, const ColumnsWithTypeAndName & arguments)
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"URL", &isString<IDataType>, nullptr, "String"},
|
||||
{"URL", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(func, arguments, mandatory_args);
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
static void checkArguments(const IFunction & func, const ColumnsWithTypeAndName & arguments)
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"URL", &isString<IDataType>, nullptr, "String"},
|
||||
{"URL", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(func, arguments, mandatory_args);
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
static void checkArguments(const IFunction & func, const ColumnsWithTypeAndName & arguments)
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"URL", &isString<IDataType>, nullptr, "String"},
|
||||
{"URL", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(func, arguments, mandatory_args);
|
||||
|
@ -84,8 +84,8 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"array_1", &isArray<IDataType>, nullptr, "Array"},
|
||||
{"array_2", &isArray<IDataType>, nullptr, "Array"},
|
||||
{"array_1", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isArray), nullptr, "Array"},
|
||||
{"array_2", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isArray), nullptr, "Array"},
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
return std::make_shared<DataTypeNumber<ResultType>>();
|
||||
|
@ -36,8 +36,8 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"array", &isArray<IDataType>, nullptr, "Array"},
|
||||
{"samples", &isUInt<IDataType>, isColumnConst, "const UInt*"},
|
||||
{"array", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isArray), nullptr, "Array"},
|
||||
{"samples", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isUInt), isColumnConst, "const UInt*"},
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -28,8 +28,8 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"array", &isArray<IDataType>, nullptr, "Array"},
|
||||
{"length", &isInteger<IDataType>, nullptr, "Integer"}
|
||||
{"array", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isArray), nullptr, "Array"},
|
||||
{"length", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isInteger), nullptr, "Integer"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -151,12 +151,12 @@ public:
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args
|
||||
{
|
||||
{"arr", &isArray<IDataType>, nullptr, "Array"},
|
||||
{"arr", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isArray), nullptr, "Array"},
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args
|
||||
{
|
||||
{"separator", &isString<IDataType>, isColumnConst, "const String"},
|
||||
{"separator", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "const String"},
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
|
@ -210,10 +210,10 @@ private:
|
||||
FunctionArgumentDescriptors optional_args;
|
||||
|
||||
if constexpr (IsDataTypeDecimal<Type>)
|
||||
mandatory_args.push_back({"scale", &isNativeInteger<IDataType>, &isColumnConst, "const Integer"});
|
||||
mandatory_args.push_back({"scale", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNativeInteger), &isColumnConst, "const Integer"});
|
||||
|
||||
if (std::is_same_v<Type, DataTypeDateTime> || std::is_same_v<Type, DataTypeDateTime64>)
|
||||
optional_args.push_back({"timezone", &isString<IDataType>, isColumnConst, "const String"});
|
||||
optional_args.push_back({"timezone", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "const String"});
|
||||
|
||||
optional_args.push_back({"default_value", nullptr, nullptr, nullptr});
|
||||
|
||||
|
@ -35,8 +35,8 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"haystack", &isStringOrFixedString<IDataType>, nullptr, "String or FixedString"},
|
||||
{"pattern", &isString<IDataType>, isColumnConst, "constant String"}
|
||||
{"haystack", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "String or FixedString"},
|
||||
{"pattern", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "constant String"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -55,8 +55,8 @@ public:
|
||||
static void checkArguments(const IFunction & func, const ColumnsWithTypeAndName & arguments)
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"haystack", &isString<IDataType>, nullptr, "String"},
|
||||
{"pattern", &isString<IDataType>, isColumnConst, "const String"}
|
||||
{"haystack", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
{"pattern", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(func, arguments, mandatory_args);
|
||||
|
@ -71,8 +71,8 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"haystack", &isStringOrFixedString<IDataType>, nullptr, "const String or const FixedString"},
|
||||
{"needle", &isStringOrFixedString<IDataType>, isColumnConst, "const String or const FixedString"},
|
||||
{"haystack", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "const String or const FixedString"},
|
||||
{"needle", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), isColumnConst, "const String or const FixedString"},
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -45,8 +45,8 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"haystack", &isStringOrFixedString<IDataType>, nullptr, "const String or const FixedString"},
|
||||
{"needle", &isStringOrFixedString<IDataType>, isColumnConst, "const String or const FixedString"},
|
||||
{"haystack", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "const String or const FixedString"},
|
||||
{"needle", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), isColumnConst, "const String or const FixedString"},
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"query", &isString<IDataType>, nullptr, "String"}
|
||||
{"query", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{{"days", &isNativeInteger<IDataType>, nullptr, "Integer"}};
|
||||
FunctionArgumentDescriptors args{{"days", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNativeInteger), nullptr, "Integer"}};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -82,17 +82,17 @@ public:
|
||||
if (is_year_month_variant)
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{mandatory_argument_names_year_month_day[0], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names_year_month_day[1], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names_year_month_day[2], &isNumber<IDataType>, nullptr, "Number"}
|
||||
{mandatory_argument_names_year_month_day[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names_year_month_day[1], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names_year_month_day[2], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{mandatory_argument_names_year_dayofyear[0], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names_year_dayofyear[1], &isNumber<IDataType>, nullptr, "Number"}
|
||||
{mandatory_argument_names_year_dayofyear[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names_year_dayofyear[1], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
}
|
||||
@ -189,7 +189,7 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{mandatory_argument_names[0], &isNumber<IDataType>, nullptr, "Number"}
|
||||
{mandatory_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
@ -344,16 +344,16 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{mandatory_argument_names[0], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[1], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[2], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[3], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[4], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[5], &isNumber<IDataType>, nullptr, "Number"}
|
||||
{mandatory_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[1], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[2], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[3], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[4], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[5], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"}
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{optional_argument_names[0], &isString<IDataType>, isColumnConst, "const String"}
|
||||
{optional_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
@ -425,18 +425,18 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{mandatory_argument_names[0], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[1], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[2], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[3], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[4], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{mandatory_argument_names[5], &isNumber<IDataType>, nullptr, "Number"}
|
||||
{mandatory_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[1], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[2], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[3], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[4], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{mandatory_argument_names[5], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"}
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{optional_argument_names[0], &isNumber<IDataType>, nullptr, "const Number"},
|
||||
{optional_argument_names[1], &isNumber<IDataType>, isColumnConst, "const Number"},
|
||||
{optional_argument_names[2], &isString<IDataType>, isColumnConst, "const String"}
|
||||
{optional_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "const Number"},
|
||||
{optional_argument_names[1], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), isColumnConst, "const Number"},
|
||||
{optional_argument_names[2], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
@ -564,11 +564,11 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{mandatory_argument_names[0], &isNumber<IDataType>, nullptr, "Number"}
|
||||
{mandatory_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"}
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{optional_argument_names[0], &isString<IDataType>, isColumnConst, "const String"}
|
||||
{optional_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
@ -643,12 +643,12 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{mandatory_argument_names[0], &isNumber<IDataType>, nullptr, "Number"}
|
||||
{mandatory_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"}
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{optional_argument_names[0], &isNumber<IDataType>, isColumnConst, "const Number"},
|
||||
{optional_argument_names[0], &isString<IDataType>, isColumnConst, "const String"}
|
||||
{optional_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), isColumnConst, "const Number"},
|
||||
{optional_argument_names[0], static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
|
@ -489,12 +489,12 @@ namespace
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"time", &isString<IDataType>, nullptr, "String"},
|
||||
{"format", &isString<IDataType>, nullptr, "String"}
|
||||
{"time", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
{"format", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"}
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{"timezone", &isString<IDataType>, &isColumnConst, "const String"}
|
||||
{"timezone", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), &isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
|
@ -47,12 +47,12 @@ public:
|
||||
arguments.size());
|
||||
|
||||
FunctionArgumentDescriptors args{
|
||||
{"haystack", &isString<IDataType>, nullptr, "String"},
|
||||
{"pattern", &isString<IDataType>, isColumnConst, "const String"},
|
||||
{"haystack", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
{"pattern", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), isColumnConst, "const String"},
|
||||
};
|
||||
|
||||
if (arguments.size() == 3)
|
||||
args.emplace_back(FunctionArgumentDescriptor{"index", &isInteger<IDataType>, nullptr, "Integer"});
|
||||
args.emplace_back(FunctionArgumentDescriptor{"index", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isInteger), nullptr, "Integer"});
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -186,8 +186,8 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"s", &isString<IDataType>, nullptr, "String"},
|
||||
{"n", &isInteger<IDataType>, nullptr, "Integer"},
|
||||
{"s", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
|
||||
{"n", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isInteger), nullptr, "Integer"},
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
@ -42,8 +42,8 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"time_series", &isArray<IDataType>, nullptr, "Array"},
|
||||
{"period", &isNativeUInt<IDataType>, nullptr, "Unsigned Integer"},
|
||||
{"time_series", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isArray), nullptr, "Array"},
|
||||
{"period", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNativeUInt), nullptr, "Unsigned Integer"},
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -45,11 +45,11 @@ public:
|
||||
getName(),
|
||||
arguments.size());
|
||||
|
||||
FunctionArgumentDescriptors mandatory_args{{"time_series", &isArray<IDataType>, nullptr, "Array"}};
|
||||
FunctionArgumentDescriptors mandatory_args{{"time_series", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isArray), nullptr, "Array"}};
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{"min_percentile", &isFloat<IDataType>, isColumnConst, "Number"},
|
||||
{"max_percentile", &isFloat<IDataType>, isColumnConst, "Number"},
|
||||
{"k", &isNativeNumber<IDataType>, isColumnConst, "Number"}};
|
||||
{"min_percentile", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isFloat), isColumnConst, "Number"},
|
||||
{"max_percentile", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isFloat), isColumnConst, "Number"},
|
||||
{"k", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNativeNumber), isColumnConst, "Number"}};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{{"time_series", &isArray<IDataType>, nullptr, "Array"}};
|
||||
FunctionArgumentDescriptors args{{"time_series", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isArray), nullptr, "Array"}};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
return std::make_shared<DataTypeFloat64>();
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"value", &isDateTime<IDataType>, nullptr, "DateTime"}
|
||||
{"value", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isDateTime), nullptr, "DateTime"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
@ -91,10 +91,10 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"value", &isInt64<IDataType>, nullptr, "Int64"}
|
||||
{"value", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isInt64), nullptr, "Int64"}
|
||||
};
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{"time_zone", &isString<IDataType>, nullptr, "String"}
|
||||
{"time_zone", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
|
||||
@ -151,7 +151,7 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"value", &isDateTime64<IDataType>, nullptr, "DateTime64"}
|
||||
{"value", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isDateTime64), nullptr, "DateTime64"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
@ -203,10 +203,10 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"value", &isInt64<IDataType>, nullptr, "Int64"}
|
||||
{"value", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isInt64), nullptr, "Int64"}
|
||||
};
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{"time_zone", &isString<IDataType>, nullptr, "String"}
|
||||
{"time_zone", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"n", &isInteger<IDataType>, nullptr, "Integer"}
|
||||
{"n", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isInteger), nullptr, "Integer"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{"sqid", &isString<IDataType>, nullptr, "String"}
|
||||
{"sqid", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
|
@ -41,10 +41,10 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{"timestamp", &isStringOrFixedString<IDataType>, nullptr, "String or FixedString"}
|
||||
{"timestamp", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isStringOrFixedString), nullptr, "String or FixedString"}
|
||||
};
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{"time", &isString<IDataType>, nullptr, "String"}
|
||||
{"time", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"}
|
||||
};
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
|
||||
|
@ -39,8 +39,8 @@ public:
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args = {
|
||||
{"Value", &isNumber<IDataType>, nullptr, "Number"},
|
||||
{"precision", &isNativeInteger<IDataType>, &isColumnConst, "const Integer"}
|
||||
{"Value", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNumber), nullptr, "Number"},
|
||||
{"precision", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isNativeInteger), &isColumnConst, "const Integer"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, {});
|
||||
|
@ -3270,7 +3270,7 @@ bool checkZooKeeperConfigIsLocal(const Poco::Util::AbstractConfiguration & confi
|
||||
if (startsWith(key, "node"))
|
||||
{
|
||||
String host = config.getString(config_name + "." + key + ".host");
|
||||
if (isLocalAddress(DNSResolver::instance().resolveHost(host)))
|
||||
if (isLocalAddress(DNSResolver::instance().resolveHostAllInOriginOrder(host).front()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <Columns/IColumn.h>
|
||||
|
||||
#include <Common/assert_cast.h>
|
||||
#include "DataTypes/IDataType.h"
|
||||
|
||||
#include <DataTypes/DataTypeMap.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
@ -35,9 +36,12 @@ namespace ErrorCodes
|
||||
extern const int BAD_ARGUMENTS;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr auto FORMAT_NAME = "Prometheus";
|
||||
|
||||
static bool isDataTypeMapString(const DataTypePtr & type)
|
||||
bool isDataTypeMapString(const DataTypePtr & type)
|
||||
{
|
||||
if (!isMap(type))
|
||||
return false;
|
||||
@ -45,8 +49,8 @@ static bool isDataTypeMapString(const DataTypePtr & type)
|
||||
return isStringOrFixedString(type_map->getKeyType()) && isStringOrFixedString(type_map->getValueType());
|
||||
}
|
||||
|
||||
template <typename ResType, typename Pred>
|
||||
static void getColumnPos(const Block & header, const String & col_name, Pred pred, ResType & res)
|
||||
template <typename ResType>
|
||||
void getColumnPos(const Block & header, const String & col_name, bool (*pred)(const DataTypePtr &), ResType & res)
|
||||
{
|
||||
static_assert(std::is_same_v<ResType, size_t> || std::is_same_v<ResType, std::optional<size_t>>, "Illegal ResType");
|
||||
|
||||
@ -71,7 +75,7 @@ static void getColumnPos(const Block & header, const String & col_name, Pred pre
|
||||
}
|
||||
}
|
||||
|
||||
static Float64 tryParseFloat(const String & s)
|
||||
Float64 tryParseFloat(const String & s)
|
||||
{
|
||||
Float64 t = 0;
|
||||
ReadBufferFromString buf(s);
|
||||
@ -79,6 +83,8 @@ static Float64 tryParseFloat(const String & s)
|
||||
return t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PrometheusTextOutputFormat::PrometheusTextOutputFormat(
|
||||
WriteBuffer & out_,
|
||||
const Block & header_,
|
||||
@ -89,12 +95,12 @@ PrometheusTextOutputFormat::PrometheusTextOutputFormat(
|
||||
{
|
||||
const Block & header = getPort(PortKind::Main).getHeader();
|
||||
|
||||
getColumnPos(header, "name", isStringOrFixedString<DataTypePtr>, pos.name);
|
||||
getColumnPos(header, "value", isNumber<DataTypePtr>, pos.value);
|
||||
getColumnPos(header, "name", isStringOrFixedString, pos.name);
|
||||
getColumnPos(header, "value", isNumber, pos.value);
|
||||
|
||||
getColumnPos(header, "help", isStringOrFixedString<DataTypePtr>, pos.help);
|
||||
getColumnPos(header, "type", isStringOrFixedString<DataTypePtr>, pos.type);
|
||||
getColumnPos(header, "timestamp", isNumber<DataTypePtr>, pos.timestamp);
|
||||
getColumnPos(header, "help", isStringOrFixedString, pos.help);
|
||||
getColumnPos(header, "type", isStringOrFixedString, pos.type);
|
||||
getColumnPos(header, "timestamp", isNumber, pos.timestamp);
|
||||
getColumnPos(header, "labels", isDataTypeMapString, pos.labels);
|
||||
}
|
||||
|
||||
|
@ -8,23 +8,23 @@ INSERT INTO merge_tree_in_subqueries VALUES(5, 'test5', 0);
|
||||
|
||||
SET max_parallel_replicas=3, cluster_for_parallel_replicas='test_cluster_one_shard_three_replicas_localhost', parallel_replicas_for_non_replicated_merge_tree=1;
|
||||
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 0) SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_subqueries_for_in=0; -- { serverError SUPPORT_IS_DISABLED }
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 0) SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_subqueries_for_in=1;
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 0) SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_in_with_subquery=0; -- { serverError SUPPORT_IS_DISABLED }
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 0) SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_in_with_subquery=1;
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 0) SETTINGS allow_experimental_parallel_reading_from_replicas=1;
|
||||
|
||||
SELECT '---';
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 2, 3) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_subqueries_for_in=0; -- { serverError SUPPORT_IS_DISABLED };
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 2, 3) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_subqueries_for_in=1;
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 2, 3) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_in_with_subquery=0; -- { serverError SUPPORT_IS_DISABLED };
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 2, 3) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_in_with_subquery=1;
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT * FROM system.numbers LIMIT 2, 3) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=1;
|
||||
|
||||
SELECT '---';
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT 1) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_subqueries_for_in=0; -- { serverError SUPPORT_IS_DISABLED };
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT 1) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_subqueries_for_in=1;
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT 1) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_in_with_subquery=0; -- { serverError SUPPORT_IS_DISABLED };
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT 1) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_in_with_subquery=1;
|
||||
SELECT * FROM merge_tree_in_subqueries WHERE id IN (SELECT 1) ORDER BY id SETTINGS allow_experimental_parallel_reading_from_replicas=1;
|
||||
|
||||
-- IN with tuples is allowed
|
||||
SELECT '---';
|
||||
SELECT id, name FROM merge_tree_in_subqueries WHERE (id, name) IN (3, 'test3') SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_subqueries_for_in=0;
|
||||
SELECT id, name FROM merge_tree_in_subqueries WHERE (id, name) IN (3, 'test3') SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_subqueries_for_in=1;
|
||||
SELECT id, name FROM merge_tree_in_subqueries WHERE (id, name) IN (3, 'test3') SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_in_with_subquery=0;
|
||||
SELECT id, name FROM merge_tree_in_subqueries WHERE (id, name) IN (3, 'test3') SETTINGS allow_experimental_parallel_reading_from_replicas=2, parallel_replicas_allow_in_with_subquery=1;
|
||||
|
||||
DROP TABLE IF EXISTS merge_tree_in_subqueries;
|
||||
|
@ -294,7 +294,7 @@ sub3 as (select l.x, l.y, r.y, r.z as z from sub1 l any left join sub2 r on l.y
|
||||
sub4 as (select z, a from tab3 where z != 8),
|
||||
sub5 as (select x, y, r.y, z, rr.z, a from sub3 ll any left join sub4 rr on ll.z = rr.z)
|
||||
select * from sub5 order by x
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_subqueries_for_in=0;
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_in_with_subquery=0;
|
||||
0 0 0 0 0 0
|
||||
1 1 0 0 0 0
|
||||
3 3 0 0 0 0
|
||||
@ -317,7 +317,7 @@ sub3 as (select l.x, l.y, r.y, r.z as z from sub1 l any left join sub2 r on l.y
|
||||
sub4 as (select z, a from tab3 where z != 8),
|
||||
sub5 as (select x, y, r.y, z, rr.z, a from sub3 ll any left join sub4 rr on ll.z = rr.z)
|
||||
select * from sub5 order by x
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_subqueries_for_in=0;-- { echoOn }
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_in_with_subquery=0;-- { echoOn }
|
||||
Expression
|
||||
Sorting
|
||||
Expression
|
||||
@ -631,7 +631,7 @@ sub3 as (select l.x, l.y, r.y, r.z as z from sub1 l any left join sub2 r on l.y
|
||||
sub4 as (select z, a from tab3 where z != 8),
|
||||
sub5 as (select x, y, r.y, z, rr.z, a from sub3 ll any left join sub4 rr on ll.z = rr.z)
|
||||
select * from sub5 order by x
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_subqueries_for_in=0;
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_in_with_subquery=0;
|
||||
0 0 0 0 0 0
|
||||
1 1 0 0 0 0
|
||||
3 3 0 0 0 0
|
||||
@ -654,7 +654,7 @@ sub3 as (select l.x, l.y, r.y, r.z as z from sub1 l any left join sub2 r on l.y
|
||||
sub4 as (select z, a from tab3 where z != 8),
|
||||
sub5 as (select x, y, r.y, z, rr.z, a from sub3 ll any left join sub4 rr on ll.z = rr.z)
|
||||
select * from sub5 order by x
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_subqueries_for_in=0;
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_in_with_subquery=0;
|
||||
Expression
|
||||
Sorting
|
||||
Expression
|
||||
|
@ -153,7 +153,7 @@ sub3 as (select l.x, l.y, r.y, r.z as z from sub1 l any left join sub2 r on l.y
|
||||
sub4 as (select z, a from tab3 where z != 8),
|
||||
sub5 as (select x, y, r.y, z, rr.z, a from sub3 ll any left join sub4 rr on ll.z = rr.z)
|
||||
select * from sub5 order by x
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_subqueries_for_in=0;
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_in_with_subquery=0;
|
||||
|
||||
explain description=0
|
||||
with sub1 as (select x, y from tab1 where x in (select number from numbers(16) where number != 2)),
|
||||
@ -162,6 +162,6 @@ sub3 as (select l.x, l.y, r.y, r.z as z from sub1 l any left join sub2 r on l.y
|
||||
sub4 as (select z, a from tab3 where z != 8),
|
||||
sub5 as (select x, y, r.y, z, rr.z, a from sub3 ll any left join sub4 rr on ll.z = rr.z)
|
||||
select * from sub5 order by x
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_subqueries_for_in=0;
|
||||
SETTINGS allow_experimental_parallel_reading_from_replicas = 1, max_parallel_replicas = 2, parallel_replicas_for_non_replicated_merge_tree = 1, prefer_localhost_replica = 1, cluster_for_parallel_replicas = 'test_cluster_one_shard_three_replicas_localhost', allow_experimental_analyzer=1, parallel_replicas_allow_in_with_subquery=0;
|
||||
|
||||
{%- endfor %}
|
||||
|
Loading…
Reference in New Issue
Block a user