[refactor]use clear concept to replace std::enable_if_t (#22801)
--------- Signed-off-by: flynn <fenglv15@mails.ucas.ac.cn>
This commit is contained in:
@ -24,6 +24,7 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
@ -279,7 +280,8 @@ std::pair<ColumnPtr, size_t> check_column_const_set_readability(const IColumn& c
|
||||
/*
|
||||
* @warning use this function sometimes cause performance problem in GCC.
|
||||
*/
|
||||
template <typename T, std::enable_if_t<std::is_integral_v<T>, T> = 0>
|
||||
template <typename T>
|
||||
requires std::is_integral_v<T>
|
||||
T index_check_const(T arg, bool constancy) noexcept {
|
||||
return constancy ? 0 : arg;
|
||||
}
|
||||
|
||||
@ -315,8 +315,9 @@ struct HashMethodSingleLowNullableColumn : public SingleColumnMethod {
|
||||
}
|
||||
|
||||
template <typename Data, typename Func, typename CreatorForNull>
|
||||
ALWAYS_INLINE typename std::enable_if_t<has_mapped, Mapped>& lazy_emplace_key(
|
||||
Data& data, size_t row, Arena& pool, Func&& f, CreatorForNull&& null_creator) {
|
||||
requires has_mapped
|
||||
ALWAYS_INLINE Mapped& lazy_emplace_key(Data& data, size_t row, Arena& pool, Func&& f,
|
||||
CreatorForNull&& null_creator) {
|
||||
if (key_column->is_null_at(row)) {
|
||||
bool has_null_key = data.has_null_key_data();
|
||||
data.has_null_key_data() = true;
|
||||
@ -330,9 +331,9 @@ struct HashMethodSingleLowNullableColumn : public SingleColumnMethod {
|
||||
}
|
||||
|
||||
template <typename Data, typename Func, typename CreatorForNull>
|
||||
ALWAYS_INLINE typename std::enable_if_t<has_mapped, Mapped>& lazy_emplace_key(
|
||||
Data& data, size_t row, Arena& pool, size_t hash_value, Func&& f,
|
||||
CreatorForNull&& null_creator) {
|
||||
requires has_mapped
|
||||
ALWAYS_INLINE Mapped& lazy_emplace_key(Data& data, size_t row, Arena& pool, size_t hash_value,
|
||||
Func&& f, CreatorForNull&& null_creator) {
|
||||
if (key_column->is_null_at(row)) {
|
||||
bool has_null_key = data.has_null_key_data();
|
||||
data.has_null_key_data() = true;
|
||||
|
||||
@ -121,7 +121,7 @@ class HashMethodBase {
|
||||
public:
|
||||
using EmplaceResult = EmplaceResultImpl<Mapped>;
|
||||
using FindResult = FindResultImpl<Mapped>;
|
||||
static constexpr bool has_mapped = !std::is_same<Mapped, void>::value;
|
||||
static constexpr bool has_mapped = !std::is_same_v<Mapped, void>;
|
||||
using Cache = LastElementCache<Value, consecutive_keys_optimization>;
|
||||
|
||||
static HashMethodContextPtr createContext(const HashMethodContext::Settings&) {
|
||||
@ -147,17 +147,16 @@ public:
|
||||
}
|
||||
|
||||
template <typename Data, typename Func>
|
||||
ALWAYS_INLINE typename std::enable_if_t<has_mapped, Mapped>& lazy_emplace_key(Data& data,
|
||||
size_t row,
|
||||
Arena& pool,
|
||||
Func&& f) {
|
||||
requires has_mapped
|
||||
ALWAYS_INLINE Mapped& lazy_emplace_key(Data& data, size_t row, Arena& pool, Func&& f) {
|
||||
auto key_holder = static_cast<Derived&>(*this).get_key_holder(row, pool);
|
||||
return lazy_emplace_impl(key_holder, data, std::forward<Func>(f));
|
||||
}
|
||||
|
||||
template <typename Data, typename Func>
|
||||
ALWAYS_INLINE typename std::enable_if_t<has_mapped, Mapped>& lazy_emplace_key(
|
||||
Data& data, size_t hash_value, size_t row, Arena& pool, Func&& f) {
|
||||
requires has_mapped
|
||||
ALWAYS_INLINE Mapped& lazy_emplace_key(Data& data, size_t hash_value, size_t row, Arena& pool,
|
||||
Func&& f) {
|
||||
auto key_holder = static_cast<Derived&>(*this).get_key_holder(row, pool);
|
||||
return lazy_emplace_impl(key_holder, hash_value, data, std::forward<Func>(f));
|
||||
}
|
||||
@ -314,16 +313,17 @@ protected:
|
||||
}
|
||||
|
||||
template <typename Data, typename KeyHolder, typename Func>
|
||||
ALWAYS_INLINE typename std::enable_if_t<has_mapped, Mapped>& lazy_emplace_impl(
|
||||
KeyHolder& key_holder, Data& data, Func&& f) {
|
||||
requires has_mapped
|
||||
ALWAYS_INLINE Mapped& lazy_emplace_impl(KeyHolder& key_holder, Data& data, Func&& f) {
|
||||
typename Data::LookupResult it;
|
||||
data.lazy_emplace(key_holder, it, std::forward<Func>(f));
|
||||
return *lookup_result_get_mapped(it);
|
||||
}
|
||||
|
||||
template <typename Data, typename KeyHolder, typename Func>
|
||||
ALWAYS_INLINE typename std::enable_if_t<has_mapped, Mapped>& lazy_emplace_impl(
|
||||
KeyHolder& key_holder, size_t hash_value, Data& data, Func&& f) {
|
||||
requires has_mapped
|
||||
ALWAYS_INLINE Mapped& lazy_emplace_impl(KeyHolder& key_holder, size_t hash_value, Data& data,
|
||||
Func&& f) {
|
||||
typename Data::LookupResult it;
|
||||
data.lazy_emplace(key_holder, it, hash_value, std::forward<Func>(f));
|
||||
|
||||
|
||||
@ -86,7 +86,8 @@ template <typename T, typename Enable = void>
|
||||
struct DefaultHash;
|
||||
|
||||
template <typename T>
|
||||
struct DefaultHash<T, std::enable_if_t<std::is_arithmetic_v<T>>> {
|
||||
requires std::is_arithmetic_v<T>
|
||||
struct DefaultHash<T> {
|
||||
size_t operator()(T key) const { return default_hash64<T>(key); }
|
||||
};
|
||||
|
||||
|
||||
@ -26,44 +26,51 @@
|
||||
|
||||
/// To be sure, that this function is zero-cost for non-floating point types.
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_floating_point_v<T>, bool> is_nan(T x) {
|
||||
requires std::is_floating_point_v<T>
|
||||
bool is_nan(T x) {
|
||||
return std::isnan(x);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<!std::is_floating_point_v<T>, bool> is_nan(T) {
|
||||
requires(!std::is_floating_point_v<T>)
|
||||
bool is_nan(T) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_floating_point_v<T>, bool> is_finite(T x) {
|
||||
requires std::is_floating_point_v<T>
|
||||
bool is_finite(T x) {
|
||||
return std::isfinite(x);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<!std::is_floating_point_v<T>, bool> is_finite(T) {
|
||||
requires(!std::is_floating_point_v<T>)
|
||||
bool is_finite(T) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_floating_point_v<T>, T> nan_or_zero() {
|
||||
requires std::is_floating_point_v<T>
|
||||
T nan_or_zero() {
|
||||
return std::numeric_limits<T>::quiet_NaN();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::numeric_limits<T>::is_integer, T> nan_or_zero() {
|
||||
requires std::numeric_limits<T>::is_integer
|
||||
T nan_or_zero() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_class_v<T>, T> nan_or_zero() {
|
||||
requires std::is_class_v<T>
|
||||
T nan_or_zero() {
|
||||
return T {};
|
||||
}
|
||||
|
||||
#if 1 /// __int128
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_same_v<T, __int128> && !std::numeric_limits<T>::is_integer, __int128>
|
||||
nan_or_zero() {
|
||||
requires(std::is_same_v<T, __int128> && !std::numeric_limits<T>::is_integer)
|
||||
__int128 nan_or_zero() {
|
||||
return __int128(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -171,8 +171,8 @@ public:
|
||||
|
||||
/// NOTE: std::has_unique_object_representations is only available since clang 6. As of Mar 2017 we still use clang 5 sometimes.
|
||||
template <typename T>
|
||||
std::enable_if_t<std::/*has_unique_object_representations_v*/ is_standard_layout_v<T>, void>
|
||||
update(const T& x) {
|
||||
requires std::is_standard_layout_v<T>
|
||||
void update(const T& x) {
|
||||
update(reinterpret_cast<const char*>(&x), sizeof(x));
|
||||
}
|
||||
|
||||
@ -225,9 +225,8 @@ inline doris::vectorized::UInt64 sip_hash64(const char* data, const size_t size)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::/*has_unique_object_representations_v*/ is_standard_layout_v<T>,
|
||||
doris::vectorized::UInt64>
|
||||
sip_hash64(const T& x) {
|
||||
requires std::is_standard_layout_v<T>
|
||||
doris::vectorized::UInt64 sip_hash64(const T& x) {
|
||||
SipHash hash;
|
||||
hash.update(x);
|
||||
return hash.get64();
|
||||
|
||||
@ -42,7 +42,8 @@
|
||||
* In the rest, behaves like a dynamic_cast.
|
||||
*/
|
||||
template <typename To, typename From>
|
||||
std::enable_if_t<std::is_reference_v<To>, To> typeid_cast(From& from) {
|
||||
requires std::is_reference_v<To>
|
||||
To typeid_cast(From& from) {
|
||||
try {
|
||||
if (typeid(from) == typeid(To)) {
|
||||
return static_cast<To>(from);
|
||||
|
||||
@ -135,8 +135,8 @@ private:
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
static std::enable_if_t<IsDecimalNumber<T> && IsDecimalNumber<U>, Shift> getScales(
|
||||
const DataTypePtr& left_type, const DataTypePtr& right_type) {
|
||||
requires IsDecimalNumber<T> && IsDecimalNumber<U>
|
||||
static Shift getScales(const DataTypePtr& left_type, const DataTypePtr& right_type) {
|
||||
const DataTypeDecimal<T>* decimal0 = check_decimal<T>(*left_type);
|
||||
const DataTypeDecimal<U>* decimal1 = check_decimal<U>(*right_type);
|
||||
|
||||
@ -157,8 +157,8 @@ private:
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
static std::enable_if_t<IsDecimalNumber<T> && !IsDecimalNumber<U>, Shift> getScales(
|
||||
const DataTypePtr& left_type, const DataTypePtr&) {
|
||||
requires(IsDecimalNumber<T> && !IsDecimalNumber<U>)
|
||||
static Shift getScales(const DataTypePtr& left_type, const DataTypePtr&) {
|
||||
Shift shift;
|
||||
const DataTypeDecimal<T>* decimal0 = check_decimal<T>(*left_type);
|
||||
if (decimal0) shift.b = decimal0->get_scale_multiplier();
|
||||
@ -166,8 +166,8 @@ private:
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
static std::enable_if_t<!IsDecimalNumber<T> && IsDecimalNumber<U>, Shift> getScales(
|
||||
const DataTypePtr&, const DataTypePtr& right_type) {
|
||||
requires(!IsDecimalNumber<T> && IsDecimalNumber<U>)
|
||||
static Shift getScales(const DataTypePtr&, const DataTypePtr& right_type) {
|
||||
Shift shift;
|
||||
const DataTypeDecimal<U>* decimal1 = check_decimal<U>(*right_type);
|
||||
if (decimal1) shift.a = decimal1->get_scale_multiplier();
|
||||
|
||||
@ -415,7 +415,8 @@ public:
|
||||
Field(Field&& rhs) { create(std::move(rhs)); }
|
||||
|
||||
template <typename T>
|
||||
Field(T&& rhs, std::enable_if_t<!std::is_same_v<std::decay_t<T>, Field>, void*> = nullptr);
|
||||
requires(!std::is_same_v<std::decay_t<T>, Field>)
|
||||
Field(T&& rhs);
|
||||
|
||||
/// Create a string inplace.
|
||||
Field(const char* data, size_t size) { create(data, size); }
|
||||
@ -466,7 +467,8 @@ public:
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<!std::is_same_v<std::decay_t<T>, Field>, Field&> operator=(T&& rhs);
|
||||
requires(!std::is_same_v<std::decay_t<T>, Field>)
|
||||
Field& operator=(T&& rhs);
|
||||
|
||||
~Field() { destroy(); }
|
||||
|
||||
@ -1218,13 +1220,15 @@ decltype(auto) cast_to_nearest_field_type(T&& x) {
|
||||
/// 1. float <--> int needs explicit cast
|
||||
/// 2. customized types needs explicit cast
|
||||
template <typename T>
|
||||
Field::Field(T&& rhs, std::enable_if_t<!std::is_same_v<std::decay_t<T>, Field>, void*>) {
|
||||
requires(!std::is_same_v<std::decay_t<T>, Field>)
|
||||
Field::Field(T&& rhs) {
|
||||
auto&& val = cast_to_nearest_field_type(std::forward<T>(rhs));
|
||||
create_concrete(std::forward<decltype(val)>(val));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<!std::is_same_v<std::decay_t<T>, Field>, Field&> Field::operator=(T&& rhs) {
|
||||
requires(!std::is_same_v<std::decay_t<T>, Field>)
|
||||
Field& Field::operator=(T&& rhs) {
|
||||
auto&& val = cast_to_nearest_field_type(std::forward<T>(rhs));
|
||||
using U = decltype(val);
|
||||
if (which != TypeToEnum<std::decay_t<U>>::value) {
|
||||
|
||||
@ -407,10 +407,10 @@ constexpr bool IsDataTypeDecimalOrNumber =
|
||||
IsDataTypeDecimal<DataType> || IsDataTypeNumber<DataType>;
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
std::enable_if_t<IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>,
|
||||
typename ToDataType::FieldType>
|
||||
convert_decimals(const typename FromDataType::FieldType& value, UInt32 scale_from, UInt32 scale_to,
|
||||
UInt8* overflow_flag = nullptr) {
|
||||
requires IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>
|
||||
ToDataType::FieldType convert_decimals(const typename FromDataType::FieldType& value,
|
||||
UInt32 scale_from, UInt32 scale_to,
|
||||
UInt8* overflow_flag = nullptr) {
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
using MaxFieldType =
|
||||
@ -534,9 +534,9 @@ void convert_decimal_cols(
|
||||
}
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
std::enable_if_t<IsDataTypeDecimal<FromDataType> && IsDataTypeNumber<ToDataType>,
|
||||
typename ToDataType::FieldType>
|
||||
convert_from_decimal(const typename FromDataType::FieldType& value, UInt32 scale) {
|
||||
requires IsDataTypeDecimal<FromDataType> && IsDataTypeNumber<ToDataType>
|
||||
ToDataType::FieldType convert_from_decimal(const typename FromDataType::FieldType& value,
|
||||
UInt32 scale) {
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToFieldType = typename ToDataType::FieldType;
|
||||
|
||||
@ -578,10 +578,9 @@ convert_from_decimal(const typename FromDataType::FieldType& value, UInt32 scale
|
||||
}
|
||||
|
||||
template <typename FromDataType, typename ToDataType>
|
||||
std::enable_if_t<IsDataTypeNumber<FromDataType> && IsDataTypeDecimal<ToDataType>,
|
||||
typename ToDataType::FieldType>
|
||||
convert_to_decimal(const typename FromDataType::FieldType& value, UInt32 scale,
|
||||
UInt8* overflow_flag) {
|
||||
requires IsDataTypeNumber<FromDataType> && IsDataTypeDecimal<ToDataType>
|
||||
ToDataType::FieldType convert_to_decimal(const typename FromDataType::FieldType& value,
|
||||
UInt32 scale, UInt8* overflow_flag) {
|
||||
using FromFieldType = typename FromDataType::FieldType;
|
||||
using ToNativeType = typename ToDataType::FieldType::NativeType;
|
||||
|
||||
|
||||
@ -182,7 +182,8 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename... Ts, std::enable_if_t<(sizeof...(Ts) > 0), int> = 0>
|
||||
template <typename T, typename... Ts>
|
||||
requires(sizeof...(Ts) > 0)
|
||||
static bool _execute_internal(ColumnArrayMutableData& dst, ColumnArrayExecutionDatas datas,
|
||||
std::vector<bool>& col_const, int start_row, int end_row) {
|
||||
return _execute_internal<T>(dst, datas, col_const, start_row, end_row) ||
|
||||
@ -190,4 +191,4 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace doris::vectorized
|
||||
} // namespace doris::vectorized
|
||||
|
||||
@ -206,8 +206,8 @@ private:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <bool LCONST, bool RCONST, typename T, typename... Ts,
|
||||
std::enable_if_t<(sizeof...(Ts) > 0), int> = 0>
|
||||
template <bool LCONST, bool RCONST, typename T, typename... Ts>
|
||||
requires(sizeof...(Ts) > 0)
|
||||
static bool _execute_internal(ColumnArrayMutableData& dst,
|
||||
const ColumnArrayExecutionData& left_data,
|
||||
const ColumnArrayExecutionData& right_data) {
|
||||
@ -216,4 +216,4 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace doris::vectorized
|
||||
} // namespace doris::vectorized
|
||||
|
||||
@ -442,7 +442,8 @@ struct ConvertImpl {
|
||||
/** If types are identical, just take reference to column.
|
||||
*/
|
||||
template <typename T, typename Name>
|
||||
struct ConvertImpl<std::enable_if_t<!T::is_parametric, T>, T, Name> {
|
||||
requires(!T::is_parametric)
|
||||
struct ConvertImpl<T, T, Name> {
|
||||
static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
|
||||
size_t result, size_t /*input_rows_count*/) {
|
||||
block.get_by_position(result).column = block.get_by_position(arguments[0]).column;
|
||||
|
||||
@ -81,12 +81,14 @@ const ColumnConst* check_and_get_column_const_string_or_fixedstring(const IColum
|
||||
|
||||
/// Transform anything to Field.
|
||||
template <typename T>
|
||||
std::enable_if_t<!IsDecimalNumber<T>, Field> to_field(const T& x) {
|
||||
requires(!IsDecimalNumber<T>)
|
||||
Field to_field(const T& x) {
|
||||
return Field(NearestFieldType<T>(x));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<IsDecimalNumber<T>, Field> to_field(const T& x, UInt32 scale) {
|
||||
requires IsDecimalNumber<T>
|
||||
Field to_field(const T& x, UInt32 scale) {
|
||||
return Field(NearestFieldType<T>(x, scale));
|
||||
}
|
||||
|
||||
|
||||
@ -355,7 +355,8 @@ struct GetJsonNumberType {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_same_v<double, T>, T>* = nullptr>
|
||||
template <typename T>
|
||||
requires std::is_same_v<double, T>
|
||||
static void handle_result(rapidjson::Value* root, T& res, uint8_t& res_null) {
|
||||
if (root == nullptr || root->IsNull()) {
|
||||
res = 0;
|
||||
@ -371,7 +372,8 @@ struct GetJsonNumberType {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_same_v<int32_t, T>, T>* = nullptr>
|
||||
template <typename T>
|
||||
requires std::is_same_v<T, int32_t>
|
||||
static void handle_result(rapidjson::Value* root, int32_t& res, uint8_t& res_null) {
|
||||
if (root != nullptr && root->IsInt()) {
|
||||
res = root->GetInt();
|
||||
@ -380,7 +382,8 @@ struct GetJsonNumberType {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_same_v<int64_t, T>, T>* = nullptr>
|
||||
template <typename T>
|
||||
requires std::is_same_v<T, int64_t>
|
||||
static void handle_result(rapidjson::Value* root, int64_t& res, uint8_t& res_null) {
|
||||
if (root != nullptr && root->IsInt64()) {
|
||||
res = root->GetInt64();
|
||||
|
||||
@ -65,7 +65,8 @@ public:
|
||||
|
||||
private:
|
||||
// handle result == DataTypeString
|
||||
template <typename T, std::enable_if_t<std::is_same_v<T, DataTypeString>, T>* = nullptr>
|
||||
template <typename T>
|
||||
requires std::is_same_v<T, DataTypeString>
|
||||
Status execute_impl(Block& block, const ColumnNumbers& arguments, size_t result,
|
||||
size_t input_rows_count) {
|
||||
const ColumnPtr column = block.get_by_position(arguments[0]).column;
|
||||
@ -92,7 +93,8 @@ private:
|
||||
block.get_by_position(arguments[0]).column->get_name(),
|
||||
get_name());
|
||||
}
|
||||
template <typename T, std::enable_if_t<!std::is_same_v<T, DataTypeString>, T>* = nullptr>
|
||||
template <typename T>
|
||||
requires(!std::is_same_v<T, DataTypeString>)
|
||||
Status execute_impl(Block& block, const ColumnNumbers& arguments, size_t result,
|
||||
size_t input_rows_count) {
|
||||
const ColumnPtr column = block.get_by_position(arguments[0]).column;
|
||||
@ -223,9 +225,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename ReturnDataType,
|
||||
std::enable_if_t<!std::is_same_v<ResultDataType, DataTypeString>, ReturnDataType>* =
|
||||
nullptr>
|
||||
template <typename ReturnDataType>
|
||||
requires(!std::is_same_v<ResultDataType, DataTypeString>)
|
||||
Status execute_inner_impl(const ColumnWithTypeAndName& left, const ColumnWithTypeAndName& right,
|
||||
Block& block, const ColumnNumbers& arguments, size_t result) {
|
||||
const auto& [lcol, left_const] = unpack_if_const(left.column);
|
||||
@ -261,9 +262,8 @@ private:
|
||||
return Status::RuntimeError("unimplements function {}", get_name());
|
||||
}
|
||||
|
||||
template <typename ReturnDataType,
|
||||
std::enable_if_t<std::is_same_v<ResultDataType, DataTypeString>, ReturnDataType>* =
|
||||
nullptr>
|
||||
template <typename ReturnDataType>
|
||||
requires std::is_same_v<ResultDataType, DataTypeString>
|
||||
Status execute_inner_impl(const ColumnWithTypeAndName& left, const ColumnWithTypeAndName& right,
|
||||
Block& block, const ColumnNumbers& arguments, size_t result) {
|
||||
const auto& [lcol, left_const] = unpack_if_const(left.column);
|
||||
|
||||
@ -267,8 +267,8 @@ struct literal_traits<TYPE_DECIMALV2> {
|
||||
};
|
||||
|
||||
//======================== set literal ===================================
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType,
|
||||
std::enable_if_t<std::is_integral<U>::value, bool> = true>
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType>
|
||||
requires std::is_integral_v<U>
|
||||
void set_literal(TExprNode& node, const U& value) {
|
||||
TIntLiteral int_literal;
|
||||
int_literal.__set_value(value);
|
||||
@ -289,64 +289,64 @@ void set_literal<TYPE_LARGEINT, __int128_t>(TExprNode& node, const __int128_t& v
|
||||
node.__set_large_int_literal(largeIntLiteral);
|
||||
}
|
||||
// std::is_same<U, std::string>::value
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType,
|
||||
std::enable_if_t<T == TYPE_DATETIME, bool> = true>
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType>
|
||||
requires(T == TYPE_DATETIME)
|
||||
void set_literal(TExprNode& node, const U& value) {
|
||||
TDateLiteral date_literal;
|
||||
date_literal.__set_value(value);
|
||||
node.__set_date_literal(date_literal);
|
||||
}
|
||||
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType,
|
||||
std::enable_if_t<T == TYPE_DATETIMEV2, bool> = true>
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType>
|
||||
requires(T == TYPE_DATETIMEV2)
|
||||
void set_literal(TExprNode& node, const U& value) {
|
||||
TDateLiteral date_literal;
|
||||
date_literal.__set_value(value);
|
||||
node.__set_date_literal(date_literal);
|
||||
}
|
||||
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType,
|
||||
std::enable_if_t<T == TYPE_DATE, bool> = true>
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType>
|
||||
requires(T == TYPE_DATE)
|
||||
void set_literal(TExprNode& node, const U& value) {
|
||||
TDateLiteral date_literal;
|
||||
date_literal.__set_value(value);
|
||||
node.__set_date_literal(date_literal);
|
||||
}
|
||||
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType,
|
||||
std::enable_if_t<T == TYPE_DATEV2, bool> = true>
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType>
|
||||
requires(T == TYPE_DATEV2)
|
||||
void set_literal(TExprNode& node, const U& value) {
|
||||
TDateLiteral date_literal;
|
||||
date_literal.__set_value(value);
|
||||
node.__set_date_literal(date_literal);
|
||||
}
|
||||
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType,
|
||||
std::enable_if_t<T == TYPE_JSONB, bool> = true>
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType>
|
||||
requires(T == TYPE_JSONB)
|
||||
void set_literal(TExprNode& node, const U& value) {
|
||||
TJsonLiteral jsonb_literal;
|
||||
jsonb_literal.__set_value(value);
|
||||
node.__set_json_literal(jsonb_literal);
|
||||
}
|
||||
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType,
|
||||
std::enable_if_t<T == TYPE_STRING, bool> = true>
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType>
|
||||
requires(T == TYPE_STRING)
|
||||
void set_literal(TExprNode& node, const U& value) {
|
||||
TStringLiteral string_literal;
|
||||
string_literal.__set_value(value);
|
||||
node.__set_string_literal(string_literal);
|
||||
}
|
||||
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType,
|
||||
std::enable_if_t<std::numeric_limits<U>::is_iec559, bool> = true>
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType>
|
||||
requires std::numeric_limits<U>::is_iec559
|
||||
void set_literal(TExprNode& node, const U& value) {
|
||||
TFloatLiteral floatLiteral;
|
||||
floatLiteral.__set_value(value);
|
||||
node.__set_float_literal(floatLiteral);
|
||||
}
|
||||
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType,
|
||||
std::enable_if_t<T == TYPE_DECIMALV2, bool> = true>
|
||||
template <PrimitiveType T, class U = typename literal_traits<T>::CXXType>
|
||||
requires(T == TYPE_DECIMALV2)
|
||||
void set_literal(TExprNode& node, const U& value) {
|
||||
TDecimalLiteral decimal_literal;
|
||||
decimal_literal.__set_value(value);
|
||||
|
||||
Reference in New Issue
Block a user