mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
fix decimal vs int arithm, add some tests
This commit is contained in:
parent
267f28f98d
commit
e1881d4cfb
@ -189,7 +189,7 @@ public:
|
||||
|
||||
/// @returns multiplier for U to become T with correct scale
|
||||
template <typename U>
|
||||
T scaleFactorFor(const DataTypeDecimal<U> & x) const
|
||||
T scaleFactorFor(const DataTypeDecimal<U> & x, bool ) const
|
||||
{
|
||||
if (getScale() < x.getScale())
|
||||
throw Exception("Decimal result's scale is less then argiment's one", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
|
||||
@ -198,7 +198,12 @@ public:
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
T scaleFactorFor(const DataTypeNumber<U> & ) const { return 1; }
|
||||
T scaleFactorFor(const DataTypeNumber<U> & , bool is_multiply_or_divisor) const
|
||||
{
|
||||
if (is_multiply_or_divisor)
|
||||
return 1;
|
||||
return getScaleMultiplier();
|
||||
}
|
||||
|
||||
T parseFromString(const String & str) const;
|
||||
|
||||
@ -214,7 +219,7 @@ template <typename T, typename U>
|
||||
typename std::enable_if_t<(sizeof(T) >= sizeof(U)), const DataTypeDecimal<T>>
|
||||
decimalResultType(const DataTypeDecimal<T> & tx, const DataTypeDecimal<U> & ty, bool is_multiply, bool is_divide)
|
||||
{
|
||||
T scale = (tx.getScale() > ty.getScale() ? tx.getScale() : ty.getScale());
|
||||
UInt32 scale = (tx.getScale() > ty.getScale() ? tx.getScale() : ty.getScale());
|
||||
if (is_multiply)
|
||||
scale = tx.getScale() + ty.getScale();
|
||||
else if (is_divide)
|
||||
@ -226,7 +231,7 @@ template <typename T, typename U>
|
||||
typename std::enable_if_t<(sizeof(T) < sizeof(U)), const DataTypeDecimal<U>>
|
||||
decimalResultType(const DataTypeDecimal<T> & tx, const DataTypeDecimal<U> & ty, bool is_multiply, bool is_divide)
|
||||
{
|
||||
U scale = (tx.getScale() > ty.getScale() ? tx.getScale() : ty.getScale());
|
||||
UInt32 scale = (tx.getScale() > ty.getScale() ? tx.getScale() : ty.getScale());
|
||||
if (is_multiply)
|
||||
scale = tx.getScale() * ty.getScale();
|
||||
else if (is_divide)
|
||||
|
@ -233,7 +233,6 @@ template <typename A, typename B>
|
||||
struct DivideIntegralImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfIntegerDivision<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -251,7 +250,6 @@ template <typename A, typename B>
|
||||
struct DivideIntegralOrZeroImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfIntegerDivision<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -268,7 +266,6 @@ template <typename A, typename B>
|
||||
struct ModuloImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfModulo<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -286,7 +283,6 @@ template <typename A, typename B>
|
||||
struct BitAndImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfBit<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -310,7 +306,6 @@ template <typename A, typename B>
|
||||
struct BitOrImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfBit<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -334,7 +329,6 @@ template <typename A, typename B>
|
||||
struct BitXorImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfBit<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -358,7 +352,6 @@ template <typename A, typename B>
|
||||
struct BitShiftLeftImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfBit<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -382,7 +375,6 @@ template <typename A, typename B>
|
||||
struct BitShiftRightImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfBit<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -406,7 +398,6 @@ template <typename A, typename B>
|
||||
struct BitRotateLeftImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfBit<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -433,7 +424,6 @@ template <typename A, typename B>
|
||||
struct BitRotateRightImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfBit<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -459,7 +449,6 @@ template <typename A, typename B>
|
||||
struct BitTestImpl
|
||||
{
|
||||
using ResultType = UInt8;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -476,7 +465,6 @@ template <typename A, typename B>
|
||||
struct LeastBaseImpl
|
||||
{
|
||||
using ResultType = NumberTraits::ResultOfLeast<A, B>;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -502,7 +490,6 @@ template <typename A, typename B>
|
||||
struct LeastSpecialImpl
|
||||
{
|
||||
using ResultType = std::make_signed_t<A>;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -524,7 +511,6 @@ template <typename A, typename B>
|
||||
struct GreatestBaseImpl
|
||||
{
|
||||
using ResultType = NumberTraits::ResultOfGreatest<A, B>;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -550,7 +536,6 @@ template <typename A, typename B>
|
||||
struct GreatestSpecialImpl
|
||||
{
|
||||
using ResultType = std::make_unsigned_t<A>;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -634,7 +619,6 @@ template <typename A, typename B>
|
||||
struct GCDImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfAdditionMultiplication<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -655,7 +639,6 @@ template <typename A, typename B>
|
||||
struct LCMImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfAdditionMultiplication<A, B>::Type;
|
||||
static const constexpr bool allow_decimal = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -715,15 +698,18 @@ struct IntExp10Impl
|
||||
/// * no agrs scale. ScaleR = Scale1 + Scale2;
|
||||
/// / first arg scale. ScaleR = Scale1 (scale_a = DecimalType<B>::getScale()).
|
||||
template <typename A, typename B, typename Op, typename ResultType_ = typename Op::ResultType>
|
||||
struct ScaledBinaryOperation
|
||||
struct DecimalBinaryOperation
|
||||
{
|
||||
using ResultType = ResultType_;
|
||||
static constexpr bool is_plus_minus = std::is_same_v<Op, PlusImpl<ResultType, ResultType>> ||
|
||||
std::is_same_v<Op, MinusImpl<ResultType, ResultType>>;
|
||||
static constexpr bool is_division = std::is_same_v<Op, DivideFloatingImpl<ResultType, ResultType>>;
|
||||
|
||||
static void NO_INLINE vector_vector(const PaddedPODArray<A> & a, const PaddedPODArray<B> & b, PaddedPODArray<ResultType> & c,
|
||||
ResultType scale_a [[maybe_unused]], ResultType scale_b [[maybe_unused]])
|
||||
{
|
||||
size_t size = a.size();
|
||||
if constexpr (std::is_same_v<Op, PlusImpl<A, B>> || std::is_same_v<Op, MinusImpl<A, B>>)
|
||||
if constexpr (is_plus_minus)
|
||||
{
|
||||
if (scale_a != 1)
|
||||
{
|
||||
@ -738,7 +724,7 @@ struct ScaledBinaryOperation
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_same_v<Op, DivideFloatingImpl<A, B>>)
|
||||
else if constexpr (is_division)
|
||||
{
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = Op::template apply<ResultType>(a[i] * scale_a, b[i]);
|
||||
@ -754,7 +740,7 @@ struct ScaledBinaryOperation
|
||||
ResultType scale_a [[maybe_unused]], ResultType scale_b [[maybe_unused]])
|
||||
{
|
||||
size_t size = a.size();
|
||||
if constexpr (std::is_same_v<Op, PlusImpl<A, B>> || std::is_same_v<Op, MinusImpl<A, B>>)
|
||||
if constexpr (is_plus_minus)
|
||||
{
|
||||
if (scale_a != 1)
|
||||
{
|
||||
@ -769,7 +755,7 @@ struct ScaledBinaryOperation
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_same_v<Op, DivideFloatingImpl<A, B>>)
|
||||
else if constexpr (is_division)
|
||||
{
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = Op::template apply<ResultType>(a[i] * scale_a, b);
|
||||
@ -785,7 +771,7 @@ struct ScaledBinaryOperation
|
||||
ResultType scale_a [[maybe_unused]], ResultType scale_b [[maybe_unused]])
|
||||
{
|
||||
size_t size = b.size();
|
||||
if constexpr (std::is_same_v<Op, PlusImpl<A, B>> || std::is_same_v<Op, MinusImpl<A, B>>)
|
||||
if constexpr (is_plus_minus)
|
||||
{
|
||||
if (scale_a != 1)
|
||||
{
|
||||
@ -800,7 +786,7 @@ struct ScaledBinaryOperation
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_same_v<Op, DivideFloatingImpl<A, B>>)
|
||||
else if constexpr (is_division)
|
||||
{
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
c[i] = Op::template apply<ResultType>(a * scale_a, b[i]);
|
||||
@ -814,9 +800,9 @@ struct ScaledBinaryOperation
|
||||
|
||||
static ResultType constant_constant(A a, B b, ResultType scale_a [[maybe_unused]], ResultType scale_b [[maybe_unused]])
|
||||
{
|
||||
if constexpr (std::is_same_v<Op, PlusImpl<A, B>> || std::is_same_v<Op, MinusImpl<A, B>>)
|
||||
if constexpr (is_plus_minus)
|
||||
return Op::template apply<ResultType>(a * scale_a, b * scale_b);
|
||||
else if constexpr (std::is_same_v<Op, DivideFloatingImpl<A, B>>)
|
||||
else if constexpr (is_division)
|
||||
return Op::template apply<ResultType>(a * scale_a, b);
|
||||
return Op::template apply<ResultType>(a, b);
|
||||
}
|
||||
@ -862,13 +848,21 @@ struct BinaryOperationTraits
|
||||
{
|
||||
using T0 = typename LeftDataType::FieldType;
|
||||
using T1 = typename RightDataType::FieldType;
|
||||
private: /// it's not correct for Decimal
|
||||
using Op = Operation<T0, T1>;
|
||||
public:
|
||||
|
||||
static constexpr bool allow_decimal =
|
||||
std::is_same_v<Operation<T0, T0>, PlusImpl<T0, T0>> ||
|
||||
std::is_same_v<Operation<T0, T0>, MinusImpl<T0, T0>> ||
|
||||
std::is_same_v<Operation<T0, T0>, MultiplyImpl<T0, T0>> ||
|
||||
std::is_same_v<Operation<T0, T0>, DivideFloatingImpl<T0, T0>>;
|
||||
|
||||
/// Appropriate result type for binary operator on numeric types. "Date" can also mean
|
||||
/// DateTime, but if both operands are Dates, their type must be the same (e.g. Date - DateTime is invalid).
|
||||
using ResultDataType = Switch<
|
||||
/// Decimal cases
|
||||
Case<!Operation<T0, T1>::allow_decimal && (IsDecimal<LeftDataType> || IsDecimal<RightDataType>), InvalidType>,
|
||||
Case<!allow_decimal && (IsDecimal<LeftDataType> || IsDecimal<RightDataType>), InvalidType>,
|
||||
Case<IsDecimal<LeftDataType> && IsDecimal<RightDataType> && UseLeftDecimal<LeftDataType, RightDataType>, LeftDataType>,
|
||||
Case<IsDecimal<LeftDataType> && IsDecimal<RightDataType>, RightDataType>,
|
||||
Case<IsDecimal<LeftDataType> && !IsDecimal<RightDataType> && IsIntegral<RightDataType>, LeftDataType>,
|
||||
@ -1022,11 +1016,9 @@ public:
|
||||
{
|
||||
if constexpr (IsDecimal<LeftDataType> && IsDecimal<RightDataType>)
|
||||
{
|
||||
using T0 = typename LeftDataType::FieldType;
|
||||
using T1 = typename RightDataType::FieldType;
|
||||
ResultDataType result_type = decimalResultType(left, right,
|
||||
std::is_same_v<Op<T0, T1>, MultiplyImpl<T0, T1>>,
|
||||
std::is_same_v<Op<T0, T1>, DivideFloatingImpl<T0, T1>>);
|
||||
constexpr bool is_multiply = std::is_same_v<Op<UInt8, UInt8>, MultiplyImpl<UInt8, UInt8>>;
|
||||
constexpr bool is_division = std::is_same_v<Op<UInt8, UInt8>, DivideFloatingImpl<UInt8, UInt8>>;
|
||||
ResultDataType result_type = decimalResultType(left, right, is_multiply, is_division);
|
||||
type_res = std::make_shared<ResultDataType>(result_type.getPrecision(), result_type.getScale());
|
||||
}
|
||||
else if constexpr (IsDecimal<LeftDataType>)
|
||||
@ -1080,6 +1072,9 @@ public:
|
||||
if constexpr (!std::is_same_v<ResultDataType, InvalidType>)
|
||||
{
|
||||
constexpr bool resultIsDecimal = IsDecimal<LeftDataType> || IsDecimal<RightDataType>;
|
||||
constexpr bool is_multiply = std::is_same_v<Op<UInt8, UInt8>, MultiplyImpl<UInt8, UInt8>>;
|
||||
constexpr bool is_division = std::is_same_v<Op<UInt8, UInt8>, DivideFloatingImpl<UInt8, UInt8>>;
|
||||
|
||||
using T0 = typename LeftDataType::FieldType;
|
||||
using T1 = typename RightDataType::FieldType;
|
||||
using ResultType = typename ResultDataType::FieldType;
|
||||
@ -1087,8 +1082,9 @@ public:
|
||||
using ColVecT1 = ColumnVector<T1, !IsDecimal<RightDataType>>;
|
||||
using ColVecResult = ColumnVector<ResultType, !resultIsDecimal>;
|
||||
|
||||
/// Decimal operations need scale. Operations are on result type.
|
||||
using OpImpl = std::conditional_t<IsDecimal<ResultDataType>,
|
||||
ScaledBinaryOperation<T0, T1, Op<T0, T1>, ResultType>,
|
||||
DecimalBinaryOperation<T0, T1, Op<ResultType, ResultType>, ResultType>,
|
||||
BinaryOperationImpl<T0, T1, Op<T0, T1>, ResultType>>;
|
||||
|
||||
auto col_left_raw = block.getByPosition(arguments[0]).column.get();
|
||||
@ -1100,13 +1096,15 @@ public:
|
||||
/// the only case with a non-vector result
|
||||
if constexpr (resultIsDecimal)
|
||||
{
|
||||
ResultDataType type = decimalResultType(left, right,
|
||||
std::is_same_v<Op<T0, T1>, MultiplyImpl<T0, T1>>,
|
||||
std::is_same_v<Op<T0, T1>, DivideFloatingImpl<T0, T1>>);
|
||||
typename ResultDataType::FieldType scale_a = type.scaleFactorFor(left);
|
||||
typename ResultDataType::FieldType scale_b = type.scaleFactorFor(right);
|
||||
if constexpr (IsDecimal<RightDataType> && std::is_same_v<Op<T0, T1>, DivideFloatingImpl<T0, T1>>)
|
||||
ResultDataType type = decimalResultType(left, right, is_multiply, is_division);
|
||||
typename ResultDataType::FieldType scale_a = type.scaleFactorFor(left, is_multiply);
|
||||
typename ResultDataType::FieldType scale_b = type.scaleFactorFor(right, is_multiply || is_division);
|
||||
if constexpr (IsDecimal<RightDataType> && is_division)
|
||||
{
|
||||
scale_a = right.getScaleMultiplier();
|
||||
if (!IsDecimal<LeftDataType>)
|
||||
scale_a *= scale_a;
|
||||
}
|
||||
auto res = OpImpl::constant_constant(col_left->template getValue<T0>(), col_right->template getValue<T1>(),
|
||||
scale_a, scale_b);
|
||||
block.getByPosition(result).column =
|
||||
@ -1130,13 +1128,15 @@ public:
|
||||
{
|
||||
if constexpr (resultIsDecimal)
|
||||
{
|
||||
ResultDataType type = decimalResultType(left, right,
|
||||
std::is_same_v<Op<T0, T1>, MultiplyImpl<T0, T1>>,
|
||||
std::is_same_v<Op<T0, T1>, DivideFloatingImpl<T0, T1>>);
|
||||
typename ResultDataType::FieldType scale_a = type.scaleFactorFor(left);
|
||||
typename ResultDataType::FieldType scale_b = type.scaleFactorFor(right);
|
||||
if constexpr (IsDecimal<RightDataType> && std::is_same_v<Op<T0, T1>, DivideFloatingImpl<T0, T1>>)
|
||||
ResultDataType type = decimalResultType(left, right, is_multiply, is_division);
|
||||
typename ResultDataType::FieldType scale_a = type.scaleFactorFor(left, is_multiply);
|
||||
typename ResultDataType::FieldType scale_b = type.scaleFactorFor(right, is_multiply || is_division);
|
||||
if constexpr (IsDecimal<RightDataType> && is_division)
|
||||
{
|
||||
scale_a = right.getScaleMultiplier();
|
||||
if (!IsDecimal<LeftDataType>)
|
||||
scale_a *= scale_a;
|
||||
}
|
||||
OpImpl::constant_vector(col_left->template getValue<T0>(), col_right->getData(), vec_res, scale_a, scale_b);
|
||||
}
|
||||
else
|
||||
@ -1149,13 +1149,15 @@ public:
|
||||
{
|
||||
if constexpr (resultIsDecimal)
|
||||
{
|
||||
ResultDataType type = decimalResultType(left, right,
|
||||
std::is_same_v<Op<T0, T1>, MultiplyImpl<T0, T1>>,
|
||||
std::is_same_v<Op<T0, T1>, DivideFloatingImpl<T0, T1>>);
|
||||
typename ResultDataType::FieldType scale_a = type.scaleFactorFor(left);
|
||||
typename ResultDataType::FieldType scale_b = type.scaleFactorFor(right);
|
||||
if constexpr (IsDecimal<RightDataType> && std::is_same_v<Op<T0, T1>, DivideFloatingImpl<T0, T1>>)
|
||||
ResultDataType type = decimalResultType(left, right, is_multiply, is_division);
|
||||
typename ResultDataType::FieldType scale_a = type.scaleFactorFor(left, is_multiply);
|
||||
typename ResultDataType::FieldType scale_b = type.scaleFactorFor(right, is_multiply || is_division);
|
||||
if constexpr (IsDecimal<RightDataType> && is_division)
|
||||
{
|
||||
scale_a = right.getScaleMultiplier();
|
||||
if (!IsDecimal<LeftDataType>)
|
||||
scale_a *= scale_a;
|
||||
}
|
||||
|
||||
if (auto col_right = checkAndGetColumn<ColVecT1>(col_right_raw))
|
||||
OpImpl::vector_vector(col_left->getData(), col_right->getData(), vec_res, scale_a, scale_b);
|
||||
|
@ -244,8 +244,8 @@ private:
|
||||
if (decimal0 && decimal1)
|
||||
{
|
||||
auto result_type = decimalResultType(*decimal0, *decimal1, false, false);
|
||||
shift.a = result_type.scaleFactorFor(*decimal0);
|
||||
shift.b = result_type.scaleFactorFor(*decimal1);
|
||||
shift.a = result_type.scaleFactorFor(*decimal0, false);
|
||||
shift.b = result_type.scaleFactorFor(*decimal1, false);
|
||||
}
|
||||
else if (decimal0)
|
||||
shift.b = decimal0->getScaleMultiplier();
|
||||
|
@ -0,0 +1,20 @@
|
||||
63.420000000 -21.420000000 41.580000000 890.820000000 -890.820000000 0.060189908 -0.194099961
|
||||
84 0 1764 1
|
||||
84 0 1764 1
|
||||
84 0 1764 1
|
||||
84.840 0.000 1799.456400 1.000
|
||||
84.84 0.00 1799.4564 1.00
|
||||
63 21 -42 882 -882 2 0
|
||||
63 21 -42 882 -882 2 0
|
||||
63 21 -42 882 -882 2 0
|
||||
63.420 21.420 -41.580 890.820 -890.820 2.020 0.505
|
||||
63.420000000 21.420000000 -41.580000000 890.820000000 -890.820000000 2.020000000 0.505000000
|
||||
63.420000000000000000 21.420000000000000000 -41.580000000000000000 890.820000000000000000 -890.820000000000000000 2.020000000000000000 0.505000000000000000
|
||||
63.42 21.42 -41.58 890.82 -890.82 2.02 0.50
|
||||
63 -21 42 882 -882 0 2
|
||||
63 -21 42 882 -882 0 2
|
||||
63 -21 42 882 -882 0 2
|
||||
63.420 -21.420 41.580 890.820 -890.820 0.495 1.980
|
||||
63.420000000 -21.420000000 41.580000000 890.820000000 -890.820000000
|
||||
63.420000000000000000 -21.420000000000000000 41.580000000000000000 890.820000000000000000 -890.820000000000000000 0.495049504950495049 1.980198019801980198
|
||||
63.42 -21.42 41.58 890.82 -890.82 0.49 1.98
|
54
dbms/tests/queries/0_stateless/00700_decimal_arithm.sql
Normal file
54
dbms/tests/queries/0_stateless/00700_decimal_arithm.sql
Normal file
@ -0,0 +1,54 @@
|
||||
CREATE DATABASE IF NOT EXISTS test;
|
||||
DROP TABLE IF EXISTS test.decimal;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS test.decimal
|
||||
(
|
||||
a DECIMAL(9,0),
|
||||
b DECIMAL(18,0),
|
||||
c DECIMAL(38,0),
|
||||
d DECIMAL(9, 9),
|
||||
e DEC(18, 18),
|
||||
f dec(38, 38),
|
||||
g Decimal(9, 3),
|
||||
h decimal(18, 9),
|
||||
i deciMAL(38, 18),
|
||||
j dec(4,2)
|
||||
) ENGINE = Memory;
|
||||
|
||||
INSERT INTO test.decimal (a, b, c, d, e, f, g, h, i, j) VALUES (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO test.decimal (a, b, c, d, e, f, g, h, i, j) VALUES (42, 42, 42, 0.42, 0.42, 0.42, 42.42, 42.42, 42.42, 42.42);
|
||||
INSERT INTO test.decimal (a, b, c, d, e, f, g, h, i, j) VALUES (-42, -42, -42, -0.42, -0.42, -0.42, -42.42, -42.42, -42.42, -42.42);
|
||||
|
||||
SELECT 21 + h, 21 - h, 84 - h, 21 * h, -21 * h, 21 / h, 84 / h FROM test.decimal WHERE h > 0;
|
||||
|
||||
SELECT a + a, a - a, a * a, a / a FROM test.decimal WHERE a = 42;
|
||||
SELECT b + b, b - b, b * b, b / b FROM test.decimal WHERE b = 42;
|
||||
SELECT c + c, c - c, c * c, c / c FROM test.decimal WHERE c = 42;
|
||||
SELECT e + e, e - e, e * e, e / e FROM test.decimal WHERE e > 0; -- { serverError 69 }
|
||||
SELECT f + f, f - f, f * f, f / f FROM test.decimal WHERE f > 0; -- { serverError 69 }
|
||||
SELECT g + g, g - g, g * g, g / g FROM test.decimal WHERE g > 0;
|
||||
--SELECT h + h, h - h, h * h, h / h FROM test.decimal WHERE h > 0; -- overflow
|
||||
--SELECT i + i, i - i, i * i, i / i FROM test.decimal WHERE i > 0; -- overflow
|
||||
SELECT j + j, j - j, j * j, j / j FROM test.decimal WHERE j > 0;
|
||||
|
||||
SELECT a + 21, a - 21, a - 84, a * 21, a * -21, a / 21, a / 84 FROM test.decimal WHERE a = 42;
|
||||
SELECT b + 21, b - 21, b - 84, b * 21, b * -21, b / 21, b / 84 FROM test.decimal WHERE b = 42;
|
||||
SELECT c + 21, c - 21, c - 84, c * 21, c * -21, c / 21, c / 84 FROM test.decimal WHERE c = 42;
|
||||
--SELECT e + 21, e - 21, e - 84, e * 21, e * -21, e / 21, e / 84 FROM test.decimal WHERE e > 0; -- overflow
|
||||
--SELECT f + 21, f - 21, f - 84, f * 21, f * -21, f / 21, f / 84 FROM test.decimal WHERE f > 0; -- { serverError 69 }
|
||||
SELECT g + 21, g - 21, g - 84, g * 21, g * -21, g / 21, g / 84 FROM test.decimal WHERE g > 0;
|
||||
SELECT h + 21, h - 21, h - 84, h * 21, h * -21, h / 21, h / 84 FROM test.decimal WHERE h > 0;
|
||||
SELECT i + 21, i - 21, i - 84, i * 21, i * -21, i / 21, i / 84 FROM test.decimal WHERE i > 0;
|
||||
SELECT j + 21, j - 21, j - 84, j * 21, j * -21, j / 21, j / 84 FROM test.decimal WHERE j > 0;
|
||||
|
||||
SELECT 21 + a, 21 - a, 84 - a, 21 * a, -21 * a, 21 / a, 84 / a FROM test.decimal WHERE a = 42;
|
||||
SELECT 21 + b, 21 - b, 84 - b, 21 * b, -21 * b, 21 / b, 84 / b FROM test.decimal WHERE b = 42;
|
||||
SELECT 21 + c, 21 - c, 84 - c, 21 * c, -21 * c, 21 / c, 84 / c FROM test.decimal WHERE c = 42;
|
||||
--SELECT 21 + e, 21 - e, 84 - e, 21 * e, -21 * e, 21 / e, 84 / e FROM test.decimal WHERE e > 0; -- overflow
|
||||
--SELECT 21 + f, 21 - f, 84 - f, 21 * f, -21 * f, 21 / f, 84 / f FROM test.decimal WHERE f > 0; -- { serverError 69 }
|
||||
SELECT 21 + g, 21 - g, 84 - g, 21 * g, -21 * g, 21 / g, 84 / g FROM test.decimal WHERE g > 0;
|
||||
SELECT 21 + h, 21 - h, 84 - h, 21 * h, -21 * h FROM test.decimal WHERE h > 0; --overflow 21 / h, 84 / h
|
||||
SELECT 21 + i, 21 - i, 84 - i, 21 * i, -21 * i, 21 / i, 84 / i FROM test.decimal WHERE i > 0;
|
||||
SELECT 21 + j, 21 - j, 84 - j, 21 * j, -21 * j, 21 / j, 84 / j FROM test.decimal WHERE j > 0;
|
||||
|
||||
--DROP TABLE IF EXISTS test.defaults;
|
@ -0,0 +1,17 @@
|
||||
-42 -42 1 0 0 0 1 1
|
||||
42 42 1 0 0 0 1 1
|
||||
-42 -42.42000 0 0 1 1 0 1
|
||||
42 42.42000 0 1 0 1 1 0
|
||||
1 1 1
|
||||
0 0 0
|
||||
-42 0 0 0 0
|
||||
42 1 1 1 1
|
||||
-42 0 0 0 0
|
||||
42 1 1 1 1
|
||||
0.420000000 0.420000000000000000 0.42000000000000000000000000000000000000
|
||||
42.42 42.420000000 42.420000000000000000 42.42
|
||||
-42.42 -42.420000000 -42.420000000000000000 -42.42
|
||||
42 42 42
|
||||
42 42 42
|
||||
42 42 42
|
||||
42 42 42
|
43
dbms/tests/queries/0_stateless/00700_decimal_compare.sql
Normal file
43
dbms/tests/queries/0_stateless/00700_decimal_compare.sql
Normal file
@ -0,0 +1,43 @@
|
||||
CREATE DATABASE IF NOT EXISTS test;
|
||||
DROP TABLE IF EXISTS test.decimal;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS test.decimal
|
||||
(
|
||||
a DECIMAL(9,0),
|
||||
b DECIMAL(18,0),
|
||||
c DECIMAL(38,0),
|
||||
d DECIMAL(9, 9),
|
||||
e DEC(18, 18),
|
||||
f dec(38, 38),
|
||||
g Decimal(9, 5),
|
||||
h decimal(18, 9),
|
||||
i deciMAL(38, 18),
|
||||
j dec(4,2)
|
||||
) ENGINE = Memory;
|
||||
|
||||
INSERT INTO test.decimal (a, b, c, d, e, f, g, h, i, j) VALUES (42, 42, 42, 0.42, 0.42, 0.42, 42.42, 42.42, 42.42, 42.42);
|
||||
INSERT INTO test.decimal (a, b, c, d, e, f, g, h, i, j) VALUES (-42, -42, -42, -0.42, -0.42, -0.42, -42.42, -42.42, -42.42, -42.42);
|
||||
|
||||
SELECT a > toFloat64(0) FROM test.decimal; -- { serverError 43 }
|
||||
SELECT g > toFloat32(0) FROM test.decimal; -- { serverError 43 }
|
||||
SELECT a > '0.0' FROM test.decimal; -- { serverError 43 }
|
||||
|
||||
SELECT a, b, a = b, a < b, a > b, a != b, a <= b, a >= b FROM test.decimal ORDER BY a;
|
||||
SELECT a, g, a = g, a < g, a > g, a != g, a <= g, a >= g FROM test.decimal ORDER BY a;
|
||||
SELECT a > 0, b > 0, g > 0 FROM test.decimal;
|
||||
SELECT a, g > toInt8(0), g > toInt16(0), g > toInt32(0), g > toInt64(0) FROM test.decimal ORDER BY a;
|
||||
SELECT a, g > toUInt8(0), g > toUInt16(0), g > toUInt32(0), g > toUInt64(0) FROM test.decimal ORDER BY a;
|
||||
SELECT a, b, g FROM test.decimal WHERE a IN(42) AND b IN(42) AND g IN(42);
|
||||
SELECT a, b, g FROM test.decimal WHERE a > 0 AND a <= 42 AND b <= 42 AND g <= 42;
|
||||
|
||||
SELECT d, e, f from test.decimal WHERE d > 0 AND d < 1 AND e > 0 AND e < 1 AND f > 0 AND f < 1;
|
||||
SELECT j, h, i, j from test.decimal WHERE j > 42 AND h > 42 AND h > 42 AND j > 42;
|
||||
SELECT j, h, i, j from test.decimal WHERE j < 42 AND h < 42 AND h < 42 AND j < 42;
|
||||
SELECT a, b, c FROM test.decimal WHERE a = toInt8(42) AND b = toInt8(42) AND c = toInt8(42);
|
||||
SELECT a, b, c FROM test.decimal WHERE a = toInt16(42) AND b = toInt16(42) AND c = toInt16(42);
|
||||
SELECT a, b, c FROM test.decimal WHERE a = toInt32(42) AND b = toInt32(42) AND c = toInt32(42);
|
||||
SELECT a, b, c FROM test.decimal WHERE a = toInt64(42) AND b = toInt64(42) AND c = toInt64(42);
|
||||
SELECT a, b, c FROM test.decimal WHERE a = toFloat32(42); -- { serverError 43 }
|
||||
SELECT a, b, c FROM test.decimal WHERE a = toFloat64(42); -- { serverError 43 }
|
||||
|
||||
DROP TABLE IF EXISTS test.defaults;
|
Loading…
Reference in New Issue
Block a user