Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize overflow check when cast to decimal #3912

Merged
merged 62 commits into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
7e73663
optimize int cast to decimal to skip check overflow
guo-shaoge Jan 19, 2022
bcd8dc2
more impl and unittest
guo-shaoge Jan 20, 2022
5f5b04c
fix wrong if branch
guo-shaoge Jan 20, 2022
3d182cd
fix fmt
guo-shaoge Jan 20, 2022
57fca6c
Merge branch 'master' of github.com:pingcap/tics into optimize_cast_o…
guo-shaoge Jan 27, 2022
07e18bb
fix comment(more concise way to impl createWrapperForDecimal)
guo-shaoge Jan 27, 2022
0483fb7
Merge branch 'optimize_cast_overflow' of github.com:guo-shaoge/tics i…
guo-shaoge Jan 27, 2022
f37618d
fix comment(use is_integral_v instead of is_same_v)
guo-shaoge Feb 8, 2022
0dd4619
fix clang-format(canSkip -> can_skip)
guo-shaoge Feb 8, 2022
fec28c5
fix comment(update CMakeLists.txt)
guo-shaoge Feb 8, 2022
91a574b
Merge branch 'master' into optimize_cast_overflow
guo-shaoge Feb 8, 2022
9956f0b
fix IntPrec
guo-shaoge Feb 8, 2022
ee531ba
Merge branch 'optimize_cast_overflow' of github.com:guo-shaoge/tics i…
guo-shaoge Feb 8, 2022
a809678
Merge branch 'master' into optimize_cast_overflow
guo-shaoge Feb 8, 2022
b9470c0
make cast decimal to decimal correct
guo-shaoge Feb 9, 2022
6e46838
Merge branch 'optimize_cast_overflow' of github.com:guo-shaoge/tics i…
guo-shaoge Feb 9, 2022
d9b1cf2
add date/datetime to dec check
guo-shaoge Feb 9, 2022
aeb3302
fix fmt
guo-shaoge Feb 10, 2022
1f9d5ef
remove duplicated code in bench_function_cast.cpp
guo-shaoge Feb 11, 2022
7ee8afd
predicate ScaleMulType instead of using Int256 directly
guo-shaoge Feb 13, 2022
4942c99
compute scale_mul per block
guo-shaoge Feb 13, 2022
418ac1c
Merge branch 'master' into optimize_cast_overflow
guo-shaoge Feb 13, 2022
2301e9e
Merge branch 'master' of github.com:pingcap/tics into optimize_cast_o…
guo-shaoge Feb 14, 2022
6aac099
use Int512 for cast(decimal as decimal) if necessary.
guo-shaoge Feb 14, 2022
ac24ca3
use ScaleMulType instead of ScaleMulNativeType
guo-shaoge Feb 15, 2022
0e8bab9
add comments for some code
guo-shaoge Feb 16, 2022
235cef1
delete IntPrec::real_prec
guo-shaoge Feb 16, 2022
6808d65
fix unit test case
guo-shaoge Feb 16, 2022
88427a7
add benchmark which expose the huge cost of computation of Int256
guo-shaoge Feb 16, 2022
bca800b
Merge branch 'master' into optimize_cast_overflow
guo-shaoge Feb 16, 2022
f505339
remove file
guo-shaoge Feb 17, 2022
ca933de
Merge branch 'optimize_cast_overflow' of github.com:guo-shaoge/tics i…
guo-shaoge Feb 17, 2022
84de905
optimize decimal to decimal, use scale_mul instead of for loop
guo-shaoge Feb 17, 2022
a02254b
compute max_value for each block instead of for each row
guo-shaoge Feb 17, 2022
5b8d74b
fix datetime to decimal error(fsp)
guo-shaoge Feb 17, 2022
45e0660
fix
guo-shaoge Feb 17, 2022
fe17f40
Merge branch 'master' of github.com:pingcap/tics into optimize_cast_o…
guo-shaoge Feb 18, 2022
2485329
remove benchmark_case, update gtest
guo-shaoge Feb 21, 2022
037158c
fix
guo-shaoge Feb 21, 2022
d9f2589
avoid performance regression
guo-shaoge Feb 24, 2022
61bd210
fix comment, make code cleaner
guo-shaoge Feb 25, 2022
976e397
fix fmt
guo-shaoge Feb 25, 2022
0b5eafe
use original impl for cast datetime to decimal
guo-shaoge Feb 28, 2022
d227e5d
Merge branch 'master' of github.com:pingcap/tics into optimize_cast_o…
guo-shaoge Feb 28, 2022
e2165da
Merge branch 'optimize_cast_overflow' of github.com:guo-shaoge/tics i…
guo-shaoge Feb 28, 2022
d036bc8
Merge branch 'master' of github.com:pingcap/tics into optimize_cast_o…
guo-shaoge Mar 3, 2022
1f62770
address part of comments
guo-shaoge Mar 4, 2022
7a13eee
address some comments
guo-shaoge Mar 7, 2022
2366721
fix
guo-shaoge Mar 7, 2022
e385e22
address last(maybe) comments
guo-shaoge Mar 7, 2022
0c6d27a
fix
guo-shaoge Mar 7, 2022
37d219b
Merge branch 'master' into optimize_cast_overflow
guo-shaoge Mar 8, 2022
aecbc55
add more comments
guo-shaoge Mar 8, 2022
e96d4f6
Merge branch 'optimize_cast_overflow' of github.com:guo-shaoge/tics i…
guo-shaoge Mar 8, 2022
be4cd1a
clean comment
guo-shaoge Mar 8, 2022
9149ec8
fix comments
guo-shaoge Mar 9, 2022
751660e
Merge branch 'master' into optimize_cast_overflow
guo-shaoge Mar 9, 2022
a95945e
Merge branch 'master' into optimize_cast_overflow
ti-chi-bot Mar 11, 2022
af1a9be
Merge branch 'master' into optimize_cast_overflow
ti-chi-bot Mar 11, 2022
e518833
Merge branch 'master' into optimize_cast_overflow
ti-chi-bot Mar 11, 2022
3decfb4
Merge branch 'master' into optimize_cast_overflow
ti-chi-bot Mar 11, 2022
0fd8651
Merge branch 'master' into optimize_cast_overflow
ti-chi-bot Mar 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions dbms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,11 @@ if (ENABLE_TESTS)
file(GLOB_RECURSE "${DST_VAR}" RELATIVE "${BASE_DIR}" "gtest*.cpp")
endmacro()

macro(grep_bench_sources BASE_DIR DST_VAR)
# Cold match files that are not in tests/ directories
file(GLOB_RECURSE "${DST_VAR}" RELATIVE "${BASE_DIR}" "bench*.cpp")
endmacro()

# attach all dbms gtest sources
grep_gtest_sources(${ClickHouse_SOURCE_DIR}/dbms dbms_gtest_sources)
add_executable(gtests_dbms EXCLUDE_FROM_ALL
Expand All @@ -280,6 +285,23 @@ if (ENABLE_TESTS)

target_compile_options(gtests_dbms PRIVATE -Wno-unknown-pragmas -Wno-deprecated-copy)
add_check(gtests_dbms)

grep_bench_sources(${ClickHouse_SOURCE_DIR}/dbms dbms_bench_sources)
add_executable(bench_dbms EXCLUDE_FROM_ALL
${ClickHouse_SOURCE_DIR}/dbms/src/Functions/tests/bench_function_cast.cpp
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
${ClickHouse_SOURCE_DIR}/dbms/src/Server/StorageConfigParser.cpp
${ClickHouse_SOURCE_DIR}/dbms/src/Server/UserConfigParser.cpp
${ClickHouse_SOURCE_DIR}/dbms/src/Server/RaftConfigParser.cpp
${ClickHouse_SOURCE_DIR}/dbms/src/AggregateFunctions/AggregateFunctionSum.cpp
)
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
target_include_directories(bench_dbms BEFORE PRIVATE ${SPARCEHASH_INCLUDE_DIR})

target_link_libraries(bench_dbms gtest dbms test_utils benchmark clickhouse_functions)
if (ENABLE_TIFLASH_DTWORKLOAD)
target_link_libraries(bench_dbms dt-workload-lib)
endif ()

add_check(bench_dbms)
endif ()

if (TEST_COVERAGE AND CMAKE_BUILD_TYPE STREQUAL "Debug")
Expand Down
6 changes: 3 additions & 3 deletions dbms/src/Common/Decimal.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct IntPrec
template <>
struct IntPrec<int8_t>
{
static constexpr PrecType prec = 4;
static constexpr PrecType prec = 3;
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
};
template <>
struct IntPrec<uint8_t>
Expand All @@ -37,7 +37,7 @@ struct IntPrec<uint8_t>
template <>
struct IntPrec<int16_t>
{
static constexpr PrecType prec = 6;
static constexpr PrecType prec = 5;
};
template <>
struct IntPrec<uint16_t>
Expand All @@ -47,7 +47,7 @@ struct IntPrec<uint16_t>
template <>
struct IntPrec<int32_t>
{
static constexpr PrecType prec = 11;
static constexpr PrecType prec = 10;
};
template <>
struct IntPrec<uint32_t>
Expand Down
263 changes: 189 additions & 74 deletions dbms/src/Functions/FunctionsTiDBConversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <Functions/FunctionsDateTime.h>
#include <Functions/FunctionsMiscellaneous.h>
#include <Functions/IFunction.h>
#include <Functions/castTypeToEither.h>
#include <IO/Operators.h>
#include <IO/ReadBufferFromMemory.h>
#include <IO/WriteBufferFromVector.h>
Expand Down Expand Up @@ -810,23 +811,26 @@ struct TiDBConvertToFloat

/// cast int/real/decimal/enum/string/time/string as decimal
// todo TiKV does not check unsigned flag but TiDB checks, currently follow TiKV's code, maybe changed latter
template <typename FromDataType, typename ToFieldType, bool return_nullable>
template <typename FromDataType, typename ToFieldType, bool return_nullable, bool canSkipCheckOverflow>
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
struct TiDBConvertToDecimal
{
using FromFieldType = typename FromDataType::FieldType;

template <typename T, typename U>
static U toTiDBDecimalInternal(T value, PrecType prec, ScaleType scale, const Context & context)
static U toTiDBDecimalInternal(T value, PrecType prec [[maybe_unused]], ScaleType scale, const Context & context)
{
using UType = typename U::NativeType;
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
auto max_value = DecimalMaxValue::get(prec);
if (value > max_value || value < -max_value)
if constexpr (!canSkipCheckOverflow)
{
context.getDAGContext()->handleOverflowError("cast to decimal", Errors::Types::Truncated);
if (value > 0)
return static_cast<UType>(max_value);
else
return static_cast<UType>(-max_value);
auto max_value = DecimalMaxValue::get(prec);
if (value > max_value || value < -max_value)
{
context.getDAGContext()->handleOverflowError("cast to decimal", Errors::Types::Truncated);
if (value > 0)
return static_cast<UType>(max_value);
else
return static_cast<UType>(-max_value);
}
}
UType scale_mul = getScaleMultiplier<U>(scale);
U result = static_cast<UType>(value) * scale_mul;
Expand Down Expand Up @@ -1727,6 +1731,29 @@ class FunctionTiDBCast final : public IFunctionBase
return monotonicity_for_range(type, left, right);
}

template <typename FromDataType>
static bool canSkipCheckOverflowForDecimal(DataTypePtr from_type, PrecType to_decimal_prec, ScaleType to_decimal_scale)
{
using FromFieldType = typename FromDataType::FieldType;

// cast(int as decimal)
constexpr int isUnsignedInt = (std::is_same_v<FromFieldType, UInt8> || std::is_same_v<FromFieldType, UInt16> || std::is_same_v<FromFieldType, UInt32> || std::is_same_v<FromFieldType, UInt64>);
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
constexpr int isSignedInt = (std::is_same_v<FromFieldType, Int8> || std::is_same_v<FromFieldType, Int16> || std::is_same_v<FromFieldType, Int32> || std::is_same_v<FromFieldType, Int64>);
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
if constexpr (isUnsignedInt || isSignedInt)
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
{
PrecType from_prec = IntPrec<FromFieldType>::prec;
if (from_prec <= (to_decimal_prec - to_decimal_scale))
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
{
return true;
}
}

// cast(decimal as decimal)
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
return castTypeToEither<DataTypeDecimal32, DataTypeDecimal64, DataTypeDecimal128, DataTypeDecimal256>(from_type.get(), [to_decimal_prec, to_decimal_scale](const auto & from_type_ptr, bool) -> bool {
return (from_type_ptr.getPrec() <= to_decimal_prec) && (from_type_ptr.getScale() <= to_decimal_scale);
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
});
}
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved

private:
const Context & context;
const char * name;
Expand All @@ -1740,7 +1767,7 @@ class FunctionTiDBCast final : public IFunctionBase

/// createWrapper creates lambda functions that do the real type conversion job
template <typename FromDataType, bool return_nullable>
WrapperType createWrapper(const DataTypePtr & to_type) const
WrapperType createWrapper(const DataTypePtr & from_type, const DataTypePtr & to_type) const
{
/// cast as int
if (checkDataType<DataTypeUInt64>(to_type.get()))
Expand All @@ -1765,53 +1792,141 @@ class FunctionTiDBCast final : public IFunctionBase
};
/// cast as decimal
if (const auto * decimal_type = checkAndGetDataType<DataTypeDecimal32>(to_type.get()))
return [decimal_type](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal32::FieldType, return_nullable>::execute(
block,
arguments,
result,
decimal_type->getPrec(),
decimal_type->getScale(),
in_union_,
tidb_tp_,
context_);
};
{
PrecType prec = decimal_type->getPrec();
ScaleType scale = decimal_type->getScale();
bool canSkip = canSkipCheckOverflowForDecimal<FromDataType>(from_type, prec, scale);
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
if (canSkip)
{
return [prec, scale](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal32::FieldType, return_nullable, true>::execute(
block,
arguments,
result,
prec,
scale,
in_union_,
tidb_tp_,
context_);
};
}
else
{
return [prec, scale](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal32::FieldType, return_nullable, false>::execute(
block,
arguments,
result,
prec,
scale,
in_union_,
tidb_tp_,
context_);
};
}
}
if (const auto * decimal_type = checkAndGetDataType<DataTypeDecimal64>(to_type.get()))
return [decimal_type](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal64::FieldType, return_nullable>::execute(
block,
arguments,
result,
decimal_type->getPrec(),
decimal_type->getScale(),
in_union_,
tidb_tp_,
context_);
};
{
PrecType prec = decimal_type->getPrec();
ScaleType scale = decimal_type->getScale();
bool canSkip = canSkipCheckOverflowForDecimal<FromDataType>(from_type, prec, scale);
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
if (canSkip)
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
{
return [prec, scale](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal64::FieldType, return_nullable, true>::execute(
block,
arguments,
result,
prec,
scale,
in_union_,
tidb_tp_,
context_);
};
}
else
{
return [prec, scale](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal64::FieldType, return_nullable, false>::execute(
block,
arguments,
result,
prec,
scale,
in_union_,
tidb_tp_,
context_);
};
}
}
if (const auto * decimal_type = checkAndGetDataType<DataTypeDecimal128>(to_type.get()))
return [decimal_type](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal128::FieldType, return_nullable>::execute(
block,
arguments,
result,
decimal_type->getPrec(),
decimal_type->getScale(),
in_union_,
tidb_tp_,
context_);
};
{
PrecType prec = decimal_type->getPrec();
ScaleType scale = decimal_type->getScale();
bool canSkip = canSkipCheckOverflowForDecimal<FromDataType>(from_type, prec, scale);
if (canSkip)
{
return [prec, scale](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal128::FieldType, return_nullable, true>::execute(
block,
arguments,
result,
prec,
scale,
in_union_,
tidb_tp_,
context_);
};
}
else
{
return [prec, scale](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal128::FieldType, return_nullable, false>::execute(
block,
arguments,
result,
prec,
scale,
in_union_,
tidb_tp_,
context_);
};
}
}
if (const auto * decimal_type = checkAndGetDataType<DataTypeDecimal256>(to_type.get()))
return [decimal_type](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal256::FieldType, return_nullable>::execute(
block,
arguments,
result,
decimal_type->getPrec(),
decimal_type->getScale(),
in_union_,
tidb_tp_,
context_);
};
{
PrecType prec = decimal_type->getPrec();
ScaleType scale = decimal_type->getScale();
bool canSkip = canSkipCheckOverflowForDecimal<FromDataType>(from_type, prec, scale);
if (canSkip)
{
return [prec, scale](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal256::FieldType, return_nullable, true>::execute(
block,
arguments,
result,
prec,
scale,
in_union_,
tidb_tp_,
context_);
};
}
else
{
return [prec, scale](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
TiDBConvertToDecimal<FromDataType, DataTypeDecimal256::FieldType, return_nullable, false>::execute(
block,
arguments,
result,
prec,
scale,
in_union_,
tidb_tp_,
context_);
};
}
}
/// cast as real
if (checkDataType<DataTypeFloat64>(to_type.get()))
return [](Block & block, const ColumnNumbers & arguments, const size_t result, bool in_union_, const tipb::FieldType & tidb_tp_, const Context & context_) {
Expand Down Expand Up @@ -1892,45 +2007,45 @@ class FunctionTiDBCast final : public IFunctionBase
if (isIdentityCast(from_type, to_type))
return createIdentityWrapper(from_type);
if (checkAndGetDataType<DataTypeUInt8>(from_type.get()))
return createWrapper<DataTypeUInt8, return_nullable>(to_type);
return createWrapper<DataTypeUInt8, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeUInt16>(from_type.get()))
return createWrapper<DataTypeUInt16, return_nullable>(to_type);
return createWrapper<DataTypeUInt16, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeUInt32>(from_type.get()))
return createWrapper<DataTypeUInt32, return_nullable>(to_type);
return createWrapper<DataTypeUInt32, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeUInt64>(from_type.get()))
return createWrapper<DataTypeUInt64, return_nullable>(to_type);
return createWrapper<DataTypeUInt64, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeInt8>(from_type.get()))
return createWrapper<DataTypeInt8, return_nullable>(to_type);
return createWrapper<DataTypeInt8, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeInt16>(from_type.get()))
return createWrapper<DataTypeInt16, return_nullable>(to_type);
return createWrapper<DataTypeInt16, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeInt32>(from_type.get()))
return createWrapper<DataTypeInt32, return_nullable>(to_type);
return createWrapper<DataTypeInt32, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeInt64>(from_type.get()))
return createWrapper<DataTypeInt64, return_nullable>(to_type);
return createWrapper<DataTypeInt64, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeFloat32>(from_type.get()))
return createWrapper<DataTypeFloat32, return_nullable>(to_type);
return createWrapper<DataTypeFloat32, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeFloat64>(from_type.get()))
return createWrapper<DataTypeFloat64, return_nullable>(to_type);
return createWrapper<DataTypeFloat64, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeDecimal32>(from_type.get()))
return createWrapper<DataTypeDecimal32, return_nullable>(to_type);
return createWrapper<DataTypeDecimal32, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeDecimal64>(from_type.get()))
return createWrapper<DataTypeDecimal64, return_nullable>(to_type);
return createWrapper<DataTypeDecimal64, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeDecimal128>(from_type.get()))
return createWrapper<DataTypeDecimal128, return_nullable>(to_type);
return createWrapper<DataTypeDecimal128, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeDecimal256>(from_type.get()))
return createWrapper<DataTypeDecimal256, return_nullable>(to_type);
return createWrapper<DataTypeDecimal256, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeMyDate>(from_type.get()))
return createWrapper<DataTypeMyDate, return_nullable>(to_type);
return createWrapper<DataTypeMyDate, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeMyDateTime>(from_type.get()))
return createWrapper<DataTypeMyDateTime, return_nullable>(to_type);
return createWrapper<DataTypeMyDateTime, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeString>(from_type.get()))
return createWrapper<DataTypeString, return_nullable>(to_type);
return createWrapper<DataTypeString, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeEnum8>(from_type.get()))
return createWrapper<DataTypeEnum8, return_nullable>(to_type);
return createWrapper<DataTypeEnum8, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeEnum16>(from_type.get()))
return createWrapper<DataTypeEnum16, return_nullable>(to_type);
return createWrapper<DataTypeEnum16, return_nullable>(from_type, to_type);
if (checkAndGetDataType<DataTypeMyDuration>(from_type.get()))
return createWrapper<DataTypeMyDuration, return_nullable>(to_type);
return createWrapper<DataTypeMyDuration, return_nullable>(from_type, to_type);

// todo support convert to duration/json type
throw Exception{
Expand Down
Loading