Compare commits
1 Commits
main
...
4.0.0-deci
| Author | SHA1 | Date |
|---|---|---|
|
|
4cf2aba9f8 |
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "column/vectorized_fwd.h"
|
||||
#include "storage/uint24.h"
|
||||
#include "types/int256.h"
|
||||
|
||||
#ifdef __SSE4_2__
|
||||
#include <nmmintrin.h>
|
||||
|
|
@ -124,12 +125,34 @@ inline uint64_t hash_128(uint64_t seed, int128_t val) {
|
|||
return seed;
|
||||
}
|
||||
|
||||
inline uint64_t hash_256(uint64_t seed, const int256_t& val) {
|
||||
uint64_t parts[4];
|
||||
parts[0] = static_cast<uint64_t>(val.low);
|
||||
parts[1] = static_cast<uint64_t>(val.low >> 64);
|
||||
parts[2] = static_cast<uint64_t>(static_cast<uint128_t>(val.high));
|
||||
parts[3] = static_cast<uint64_t>(static_cast<uint128_t>(val.high) >> 64);
|
||||
|
||||
uint64_t hash = seed;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
hash_combine(hash, parts[i]);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
template <PhmapSeed seed>
|
||||
struct Hash128WithSeed {
|
||||
std::size_t operator()(int128_t value) const {
|
||||
return phmap_mix_with_seed<sizeof(size_t), seed>()(hash_128(seed, value));
|
||||
}
|
||||
};
|
||||
|
||||
template <PhmapSeed seed>
|
||||
struct Hash256WithSeed {
|
||||
std::size_t operator()(const int256_t& value) const {
|
||||
return phmap_mix_with_seed<sizeof(size_t), seed>()(hash_256(seed, value));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct HashTypeTraits {
|
||||
using HashFunc = StdHashWithSeed<T, PhmapSeed2>;
|
||||
|
|
@ -139,6 +162,11 @@ struct HashTypeTraits<int128_t> {
|
|||
using HashFunc = Hash128WithSeed<PhmapSeed2>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct HashTypeTraits<int256_t> {
|
||||
using HashFunc = Hash256WithSeed<PhmapSeed2>;
|
||||
};
|
||||
|
||||
template <LogicalType LT, PhmapSeed seed>
|
||||
struct PhmapDefaultHashFunc {
|
||||
std::size_t operator()(const RunTimeCppType<LT>& value) const {
|
||||
|
|
@ -146,6 +174,8 @@ struct PhmapDefaultHashFunc {
|
|||
|
||||
if constexpr (lt_is_largeint<LT> || lt_is_decimal128<LT>) {
|
||||
return Hash128WithSeed<seed>()(value);
|
||||
} else if constexpr (lt_is_decimal256<LT>) {
|
||||
return Hash256WithSeed<seed>()(value);
|
||||
} else if constexpr (lt_is_fixedlength<LT>) {
|
||||
return StdHashWithSeed<RunTimeCppType<LT>, seed>()(value);
|
||||
} else if constexpr (lt_is_string<LT> || lt_is_binary<LT>) {
|
||||
|
|
|
|||
|
|
@ -61,12 +61,13 @@ public:
|
|||
: Field(id, name, get_type_info(type, precision, scale), STORAGE_AGGREGATE_NONE, nullptr, 0, false,
|
||||
nullable) {}
|
||||
|
||||
// Non-key field of any type except for DECIMAL32, DECIMAL64, DECIMAL128, and ARRAY
|
||||
// Non-key field of any type except for DECIMAL32, DECIMAL64, DECIMAL128, DECIMAL256, and ARRAY
|
||||
Field(ColumnId id, std::string_view name, LogicalType type, bool nullable)
|
||||
: Field(id, name, type, -1, -1, nullable) {
|
||||
DCHECK(type != TYPE_DECIMAL32);
|
||||
DCHECK(type != TYPE_DECIMAL64);
|
||||
DCHECK(type != TYPE_DECIMAL128);
|
||||
DCHECK(type != TYPE_DECIMAL256);
|
||||
DCHECK(type != TYPE_ARRAY);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -399,6 +399,8 @@ std::string FixedLengthColumnBase<T>::get_name() const {
|
|||
return "timestamp";
|
||||
} else if constexpr (IsInt128<T>) {
|
||||
return "int128";
|
||||
} else if constexpr (IsInt256<T>) {
|
||||
return "int256";
|
||||
} else if constexpr (std::is_floating_point_v<T>) {
|
||||
return "float-" + std::to_string(sizeof(T));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,11 @@ constexpr bool IsInt128 = false;
|
|||
template <>
|
||||
inline constexpr bool IsInt128<int128_t> = true;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool IsInt256 = false;
|
||||
template <>
|
||||
inline constexpr bool IsInt256<int256_t> = true;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool IsSlice = false;
|
||||
template <>
|
||||
|
|
@ -54,7 +59,8 @@ template <>
|
|||
inline constexpr bool IsDateTime<DateValue> = true;
|
||||
|
||||
template <typename T>
|
||||
using is_starrocks_arithmetic = std::integral_constant<bool, std::is_arithmetic_v<T> || IsDecimal<T>>;
|
||||
using is_starrocks_arithmetic =
|
||||
std::integral_constant<bool, std::is_arithmetic_v<T> || IsDecimal<T> || std::is_same_v<T, int256_t>>;
|
||||
|
||||
// If isArithmeticLT is true, means this type support +,-,*,/
|
||||
template <LogicalType logical_type>
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ using Int64AggHashMap = phmap::flat_hash_map<int64_t, AggDataPtr, StdHashWithSee
|
|||
template <PhmapSeed seed>
|
||||
using Int128AggHashMap = phmap::flat_hash_map<int128_t, AggDataPtr, Hash128WithSeed<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using Int256AggHashMap = phmap::flat_hash_map<int256_t, AggDataPtr, Hash256WithSeed<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using DateAggHashMap = phmap::flat_hash_map<DateValue, AggDataPtr, StdHashWithSeed<DateValue, seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using TimeStampAggHashMap = phmap::flat_hash_map<TimestampValue, AggDataPtr, StdHashWithSeed<TimestampValue, seed>>;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ using Int64AggHashSet = phmap::flat_hash_set<int64_t, StdHashWithSeed<int64_t, s
|
|||
template <PhmapSeed seed>
|
||||
using Int128AggHashSet = phmap::flat_hash_set<int128_t, Hash128WithSeed<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using Int256AggHashSet = phmap::flat_hash_set<int256_t, Hash256WithSeed<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using DateAggHashSet = phmap::flat_hash_set<DateValue, StdHashWithSeed<DateValue, seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using TimeStampAggHashSet = phmap::flat_hash_set<TimestampValue, StdHashWithSeed<TimestampValue, seed>>;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_int128, Int128AggHashMapWithOneN
|
|||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_decimal32, Decimal32AggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_decimal64, Decimal64AggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_decimal128, Decimal128AggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_decimal256, Decimal256AggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_date, DateAggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_timestamp, TimeStampAggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_string, OneStringAggHashMap<PhmapSeed1>);
|
||||
|
|
@ -52,6 +53,7 @@ DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_null_int128, NullInt128AggHashMa
|
|||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_null_decimal32, NullDecimal32AggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_null_decimal64, NullDecimal64AggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_null_decimal128, NullDecimal128AggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_null_decimal256, NullDecimal256AggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_null_date, NullDateAggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_null_timestamp, NullTimeStampAggHashMapWithOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase1_null_string, NullOneStringAggHashMap<PhmapSeed1>);
|
||||
|
|
@ -72,6 +74,7 @@ DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_int128, Int128AggHashMapWithOneN
|
|||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_decimal32, Decimal32AggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_decimal64, Decimal64AggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_decimal128, Decimal128AggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_decimal256, Decimal256AggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_date, DateAggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_timestamp, TimeStampAggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_string, OneStringAggHashMap<PhmapSeed2>);
|
||||
|
|
@ -84,6 +87,7 @@ DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_null_int128, NullInt128AggHashMa
|
|||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_null_decimal32, NullDecimal32AggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_null_decimal64, NullDecimal64AggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_null_decimal128, NullDecimal128AggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_null_decimal256, NullDecimal256AggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_null_date, NullDateAggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_null_timestamp, NullTimeStampAggHashMapWithOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_MAP_TYPE(AggHashMapVariant::Type::phase2_null_string, NullOneStringAggHashMap<PhmapSeed2>);
|
||||
|
|
@ -114,6 +118,7 @@ DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_int128, Int128AggHashSetOfOneNum
|
|||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_decimal32, Decimal32AggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_decimal64, Decimal64AggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_decimal128, Decimal128AggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_decimal256, Decimal256AggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_date, DateAggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_timestamp, TimeStampAggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_string, OneStringAggHashSet<PhmapSeed1>);
|
||||
|
|
@ -126,6 +131,7 @@ DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_null_int128, NullInt128AggHashSe
|
|||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_null_decimal32, NullDecimal32AggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_null_decimal64, NullDecimal64AggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_null_decimal128, NullDecimal128AggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_null_decimal256, NullDecimal256AggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_null_date, NullDateAggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_null_timestamp, NullTimeStampAggHashSetOfOneNumberKey<PhmapSeed1>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase1_null_string, NullOneStringAggHashSet<PhmapSeed1>);
|
||||
|
|
@ -144,6 +150,7 @@ DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_int128, Int128AggHashSetOfOneNum
|
|||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_decimal32, Decimal32AggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_decimal64, Decimal64AggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_decimal128, Decimal128AggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_decimal256, Decimal256AggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_date, DateAggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_timestamp, TimeStampAggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_string, OneStringAggHashSet<PhmapSeed2>);
|
||||
|
|
@ -156,6 +163,7 @@ DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_null_int128, NullInt128AggHashSe
|
|||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_null_decimal32, NullDecimal32AggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_null_decimal64, NullDecimal64AggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_null_decimal128, NullDecimal128AggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_null_decimal256, NullDecimal256AggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_null_date, NullDateAggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_null_timestamp, NullTimeStampAggHashSetOfOneNumberKey<PhmapSeed2>);
|
||||
DEFINE_SET_TYPE(AggHashSetVariant::Type::phase2_null_string, NullOneStringAggHashSet<PhmapSeed2>);
|
||||
|
|
@ -370,6 +378,7 @@ HashVariantResolver<HashVariantType>::HashVariantResolver() {
|
|||
ADD_VARIANT_PHASE1_TYPE(TYPE_DATE, date);
|
||||
ADD_VARIANT_PHASE1_TYPE(TYPE_DATETIME, timestamp);
|
||||
ADD_VARIANT_PHASE1_TYPE(TYPE_DECIMAL128, decimal128);
|
||||
ADD_VARIANT_PHASE1_TYPE(TYPE_DECIMAL256, decimal256);
|
||||
ADD_VARIANT_PHASE1_TYPE(TYPE_LARGEINT, int128);
|
||||
ADD_VARIANT_PHASE1_TYPE(TYPE_CHAR, string);
|
||||
ADD_VARIANT_PHASE1_TYPE(TYPE_VARCHAR, string);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ enum AggrPhase { AggrPhase1, AggrPhase2 };
|
|||
M(phase1_decimal32) \
|
||||
M(phase1_decimal64) \
|
||||
M(phase1_decimal128) \
|
||||
M(phase1_decimal256) \
|
||||
M(phase1_date) \
|
||||
M(phase1_timestamp) \
|
||||
M(phase1_string) \
|
||||
|
|
@ -55,6 +56,7 @@ enum AggrPhase { AggrPhase1, AggrPhase2 };
|
|||
M(phase1_null_decimal32) \
|
||||
M(phase1_null_decimal64) \
|
||||
M(phase1_null_decimal128) \
|
||||
M(phase1_null_decimal256) \
|
||||
M(phase1_null_date) \
|
||||
M(phase1_null_timestamp) \
|
||||
M(phase1_null_string) \
|
||||
|
|
@ -72,6 +74,7 @@ enum AggrPhase { AggrPhase1, AggrPhase2 };
|
|||
M(phase2_decimal32) \
|
||||
M(phase2_decimal64) \
|
||||
M(phase2_decimal128) \
|
||||
M(phase2_decimal256) \
|
||||
M(phase2_date) \
|
||||
M(phase2_timestamp) \
|
||||
M(phase2_string) \
|
||||
|
|
@ -85,6 +88,7 @@ enum AggrPhase { AggrPhase1, AggrPhase2 };
|
|||
M(phase2_null_decimal32) \
|
||||
M(phase2_null_decimal64) \
|
||||
M(phase2_null_decimal128) \
|
||||
M(phase2_null_decimal256) \
|
||||
M(phase2_null_date) \
|
||||
M(phase2_null_timestamp) \
|
||||
M(phase2_null_string) \
|
||||
|
|
@ -122,6 +126,8 @@ using Decimal64AggHashMapWithOneNumberKey = AggHashMapWithOneNumberKey<TYPE_DECI
|
|||
template <PhmapSeed seed>
|
||||
using Decimal128AggHashMapWithOneNumberKey = AggHashMapWithOneNumberKey<TYPE_DECIMAL128, Int128AggHashMap<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using Decimal256AggHashMapWithOneNumberKey = AggHashMapWithOneNumberKey<TYPE_DECIMAL256, Int256AggHashMap<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using DateAggHashMapWithOneNumberKey = AggHashMapWithOneNumberKey<TYPE_DATE, DateAggHashMap<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using TimeStampAggHashMapWithOneNumberKey = AggHashMapWithOneNumberKey<TYPE_DATETIME, TimeStampAggHashMap<seed>>;
|
||||
|
|
@ -147,6 +153,9 @@ using NullDecimal64AggHashMapWithOneNumberKey =
|
|||
template <PhmapSeed seed>
|
||||
using NullDecimal128AggHashMapWithOneNumberKey =
|
||||
AggHashMapWithOneNullableNumberKey<TYPE_DECIMAL128, Int128AggHashMap<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using NullDecimal256AggHashMapWithOneNumberKey =
|
||||
AggHashMapWithOneNullableNumberKey<TYPE_DECIMAL256, Int256AggHashMap<seed>>;
|
||||
|
||||
template <PhmapSeed seed>
|
||||
using NullDateAggHashMapWithOneNumberKey = AggHashMapWithOneNullableNumberKey<TYPE_DATE, DateAggHashMap<seed>>;
|
||||
|
|
@ -198,6 +207,8 @@ template <PhmapSeed seed>
|
|||
using Decimal64AggHashSetOfOneNumberKey = AggHashSetOfOneNumberKey<TYPE_DECIMAL64, Int64AggHashSet<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using Decimal128AggHashSetOfOneNumberKey = AggHashSetOfOneNumberKey<TYPE_DECIMAL128, Int128AggHashSet<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using Decimal256AggHashSetOfOneNumberKey = AggHashSetOfOneNumberKey<TYPE_DECIMAL256, Int256AggHashSet<seed>>;
|
||||
|
||||
template <PhmapSeed seed>
|
||||
using DateAggHashSetOfOneNumberKey = AggHashSetOfOneNumberKey<TYPE_DATE, DateAggHashSet<seed>>;
|
||||
|
|
@ -225,6 +236,9 @@ template <PhmapSeed seed>
|
|||
using NullDecimal128AggHashSetOfOneNumberKey =
|
||||
AggHashSetOfOneNullableNumberKey<TYPE_DECIMAL128, Int128AggHashSet<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using NullDecimal256AggHashSetOfOneNumberKey =
|
||||
AggHashSetOfOneNullableNumberKey<TYPE_DECIMAL256, Int256AggHashSet<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using NullDateAggHashSetOfOneNumberKey = AggHashSetOfOneNullableNumberKey<TYPE_DATE, DateAggHashSet<seed>>;
|
||||
template <PhmapSeed seed>
|
||||
using NullTimeStampAggHashSetOfOneNumberKey =
|
||||
|
|
@ -303,6 +317,7 @@ using AggHashMapWithKeyPtr = std::variant<
|
|||
std::unique_ptr<Decimal32AggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<Decimal64AggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<Decimal128AggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<Decimal256AggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<DateAggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<TimeStampAggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<OneStringAggHashMap<PhmapSeed1>>,
|
||||
|
|
@ -315,6 +330,7 @@ using AggHashMapWithKeyPtr = std::variant<
|
|||
std::unique_ptr<NullDecimal32AggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullDecimal64AggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullDecimal128AggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullDecimal256AggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullDateAggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullTimeStampAggHashMapWithOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullOneStringAggHashMap<PhmapSeed1>>, std::unique_ptr<SerializedKeyAggHashMap<PhmapSeed1>>,
|
||||
|
|
@ -334,6 +350,7 @@ using AggHashMapWithKeyPtr = std::variant<
|
|||
std::unique_ptr<Decimal32AggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<Decimal64AggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<Decimal128AggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<Decimal256AggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<DateAggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<TimeStampAggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<OneStringAggHashMap<PhmapSeed2>>,
|
||||
|
|
@ -346,6 +363,7 @@ using AggHashMapWithKeyPtr = std::variant<
|
|||
std::unique_ptr<NullDecimal32AggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullDecimal64AggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullDecimal128AggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullDecimal256AggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullDateAggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullTimeStampAggHashMapWithOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullOneStringAggHashMap<PhmapSeed2>>, std::unique_ptr<SerializedKeyAggHashMap<PhmapSeed2>>,
|
||||
|
|
@ -367,6 +385,7 @@ using AggHashSetWithKeyPtr = std::variant<
|
|||
std::unique_ptr<Decimal32AggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<Decimal64AggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<Decimal128AggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<Decimal256AggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<DateAggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<TimeStampAggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<OneStringAggHashSet<PhmapSeed1>>,
|
||||
|
|
@ -379,6 +398,7 @@ using AggHashSetWithKeyPtr = std::variant<
|
|||
std::unique_ptr<NullDecimal32AggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullDecimal64AggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullDecimal128AggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullDecimal256AggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullDateAggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullTimeStampAggHashSetOfOneNumberKey<PhmapSeed1>>,
|
||||
std::unique_ptr<NullOneStringAggHashSet<PhmapSeed1>>, std::unique_ptr<SerializedKeyAggHashSet<PhmapSeed1>>,
|
||||
|
|
@ -395,6 +415,7 @@ using AggHashSetWithKeyPtr = std::variant<
|
|||
std::unique_ptr<Decimal32AggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<Decimal64AggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<Decimal128AggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<Decimal256AggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<DateAggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<TimeStampAggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<OneStringAggHashSet<PhmapSeed2>>,
|
||||
|
|
@ -407,6 +428,7 @@ using AggHashSetWithKeyPtr = std::variant<
|
|||
std::unique_ptr<NullDecimal32AggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullDecimal64AggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullDecimal128AggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullDecimal256AggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullDateAggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullTimeStampAggHashSetOfOneNumberKey<PhmapSeed2>>,
|
||||
std::unique_ptr<NullOneStringAggHashSet<PhmapSeed2>>, std::unique_ptr<SerializedKeyAggHashSet<PhmapSeed2>>,
|
||||
|
|
@ -432,6 +454,7 @@ struct AggHashMapVariant {
|
|||
phase1_decimal32,
|
||||
phase1_decimal64,
|
||||
phase1_decimal128,
|
||||
phase1_decimal256,
|
||||
phase1_date,
|
||||
phase1_timestamp,
|
||||
phase1_string,
|
||||
|
|
@ -444,6 +467,7 @@ struct AggHashMapVariant {
|
|||
phase1_null_decimal32,
|
||||
phase1_null_decimal64,
|
||||
phase1_null_decimal128,
|
||||
phase1_null_decimal256,
|
||||
phase1_null_date,
|
||||
phase1_null_timestamp,
|
||||
phase1_null_string,
|
||||
|
|
@ -466,6 +490,7 @@ struct AggHashMapVariant {
|
|||
phase2_decimal32,
|
||||
phase2_decimal64,
|
||||
phase2_decimal128,
|
||||
phase2_decimal256,
|
||||
phase2_date,
|
||||
phase2_timestamp,
|
||||
phase2_string,
|
||||
|
|
@ -478,6 +503,7 @@ struct AggHashMapVariant {
|
|||
phase2_null_decimal32,
|
||||
phase2_null_decimal64,
|
||||
phase2_null_decimal128,
|
||||
phase2_null_decimal256,
|
||||
phase2_null_date,
|
||||
phase2_null_timestamp,
|
||||
phase2_null_string,
|
||||
|
|
@ -542,6 +568,7 @@ struct AggHashSetVariant {
|
|||
phase1_decimal32,
|
||||
phase1_decimal64,
|
||||
phase1_decimal128,
|
||||
phase1_decimal256,
|
||||
phase1_date,
|
||||
phase1_timestamp,
|
||||
phase1_string,
|
||||
|
|
@ -554,6 +581,7 @@ struct AggHashSetVariant {
|
|||
phase1_null_decimal32,
|
||||
phase1_null_decimal64,
|
||||
phase1_null_decimal128,
|
||||
phase1_null_decimal256,
|
||||
phase1_null_date,
|
||||
phase1_null_timestamp,
|
||||
phase1_null_string,
|
||||
|
|
@ -572,6 +600,7 @@ struct AggHashSetVariant {
|
|||
phase2_decimal32,
|
||||
phase2_decimal64,
|
||||
phase2_decimal128,
|
||||
phase2_decimal256,
|
||||
phase2_date,
|
||||
phase2_timestamp,
|
||||
phase2_string,
|
||||
|
|
@ -584,6 +613,7 @@ struct AggHashSetVariant {
|
|||
phase2_null_decimal32,
|
||||
phase2_null_decimal64,
|
||||
phase2_null_decimal128,
|
||||
phase2_null_decimal256,
|
||||
phase2_null_date,
|
||||
phase2_null_timestamp,
|
||||
phase2_null_string,
|
||||
|
|
|
|||
|
|
@ -62,6 +62,15 @@ inline size_t difference<Slice>(const Slice& low, const Slice& high) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline size_t difference<int256_t>(const int256_t& low, const int256_t& high) {
|
||||
DCHECK_LE(low, high);
|
||||
if (high - low > static_cast<int256_t>(SIZE_MAX)) {
|
||||
return SIZE_MAX;
|
||||
}
|
||||
return static_cast<size_t>(high - low);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline size_t difference<DateValue>(const DateValue& low, const DateValue& high) {
|
||||
DCHECK_LE(low, high);
|
||||
|
|
@ -140,6 +149,14 @@ inline std::string cast_to_string(T value, [[maybe_unused]] LogicalType lt, [[ma
|
|||
return DecimalV3Cast::to_string<CppType>(*reinterpret_cast<CppType*>(&value), precision, scale);
|
||||
}
|
||||
}
|
||||
case TYPE_DECIMAL256: {
|
||||
using CppType = RunTimeCppType<TYPE_DECIMAL256>;
|
||||
if constexpr (use_static_cast) {
|
||||
return DecimalV3Cast::to_string<CppType>(static_cast<CppType>(value), precision, scale);
|
||||
} else {
|
||||
return DecimalV3Cast::to_string<CppType>(*reinterpret_cast<CppType*>(&value), precision, scale);
|
||||
}
|
||||
}
|
||||
default:
|
||||
return cast_to_string<T>(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ struct AvgResultTrait<LT, DecimalLTGuard<LT>> {
|
|||
static const LogicalType value = TYPE_DECIMAL128;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct AvgResultTrait<TYPE_DECIMAL256, DecimalLTGuard<TYPE_DECIMAL256>> {
|
||||
static const LogicalType value = TYPE_DECIMAL256;
|
||||
};
|
||||
|
||||
template <LogicalType LT>
|
||||
inline constexpr LogicalType AvgResultLT = AvgResultTrait<LT>::value;
|
||||
|
||||
|
|
@ -230,7 +235,8 @@ public:
|
|||
} else if constexpr (lt_is_arithmetic<LT>) {
|
||||
result = this->data(state).sum / this->data(state).count;
|
||||
} else if constexpr (lt_is_decimal<LT>) {
|
||||
static_assert(lt_is_decimal128<ResultLT>, "Result type of avg on decimal32/64/128 is decimal 128");
|
||||
static_assert(lt_is_decimal128<ResultLT> || lt_is_decimal256<ResultLT>,
|
||||
"Result type of avg on decimal32/64/128/256 is decimal 128 or 256");
|
||||
auto sum = ResultType(this->data(state).sum);
|
||||
auto count = ResultType(this->data(state).count);
|
||||
result = decimal_div_integer<ResultType>(sum, count, ctx->get_arg_type(0)->scale);
|
||||
|
|
@ -256,7 +262,8 @@ public:
|
|||
} else if constexpr (lt_is_arithmetic<LT>) {
|
||||
result = this->data(state).sum / this->data(state).count;
|
||||
} else if constexpr (lt_is_decimal<LT>) {
|
||||
static_assert(lt_is_decimal128<ResultLT>, "Result type of avg on decimal32/64/128 is decimal 128");
|
||||
static_assert(lt_is_decimal128<ResultLT> || lt_is_decimal256<ResultLT>,
|
||||
"Result type of avg on decimal32/64/128/256 is decimal 128 or 256");
|
||||
auto sum = ResultType(this->data(state).sum);
|
||||
auto count = ResultType(this->data(state).count);
|
||||
result = decimal_div_integer<ResultType>(sum, count, ctx->get_arg_type(0)->scale);
|
||||
|
|
@ -270,8 +277,9 @@ public:
|
|||
|
||||
std::string get_name() const override { return "avg"; }
|
||||
};
|
||||
|
||||
template <LogicalType LT, typename = DecimalLTGuard<LT>>
|
||||
using DecimalAvgAggregateFunction =
|
||||
AvgAggregateFunction<LT, RunTimeCppType<LT>, TYPE_DECIMAL128, RunTimeCppType<TYPE_DECIMAL128>>;
|
||||
AvgAggregateFunction<LT, RunTimeCppType<LT>, (LT == TYPE_DECIMAL256) ? TYPE_DECIMAL256 : TYPE_DECIMAL128>;
|
||||
|
||||
} // namespace starrocks
|
||||
|
|
|
|||
|
|
@ -179,8 +179,8 @@ public:
|
|||
|
||||
int64_t count = 1;
|
||||
for (size_t i = 0; i < chunk_size; ++i) {
|
||||
meanX = src_column0->get_data()[i];
|
||||
meanY = src_column1->get_data()[i];
|
||||
meanX = static_cast<double>(src_column0->get_data()[i]);
|
||||
meanY = static_cast<double>(src_column1->get_data()[i]);
|
||||
memcpy(bytes.data() + old_size, &meanX, sizeof(double));
|
||||
memcpy(bytes.data() + old_size + sizeof(double), &meanY, sizeof(double));
|
||||
memcpy(bytes.data() + old_size + sizeof(double) * 2, &c2, sizeof(double));
|
||||
|
|
|
|||
|
|
@ -534,7 +534,8 @@ using DistinctAggregateFunctionV2 =
|
|||
|
||||
template <LogicalType LT, AggDistinctType DistinctType, typename T = RunTimeCppType<LT>>
|
||||
using DecimalDistinctAggregateFunction =
|
||||
TDistinctAggregateFunction<LT, TYPE_DECIMAL128, DistinctAggregateStateV2, DistinctType, T>;
|
||||
TDistinctAggregateFunction<LT, lt_is_decimal256<LT> ? TYPE_DECIMAL256 : TYPE_DECIMAL128,
|
||||
DistinctAggregateStateV2, DistinctType, T>;
|
||||
|
||||
// now we only support String
|
||||
struct DictMergeState : DistinctAggregateStateV2<TYPE_VARCHAR, SumResultLT<TYPE_VARCHAR>> {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ static const AggregateFunction* get_function(const std::string& name, LogicalTyp
|
|||
}
|
||||
|
||||
auto is_decimal_type = [](LogicalType lt) {
|
||||
return lt == TYPE_DECIMAL32 || lt == TYPE_DECIMAL64 || lt == TYPE_DECIMAL128;
|
||||
return lt == TYPE_DECIMAL32 || lt == TYPE_DECIMAL64 || lt == TYPE_DECIMAL128 || lt == TYPE_DECIMAL256;
|
||||
};
|
||||
if (func_version > 2 && is_decimal_type(arg_type)) {
|
||||
if (name == "sum") {
|
||||
|
|
|
|||
|
|
@ -70,10 +70,11 @@ public:
|
|||
void register_hypothesis_testing();
|
||||
|
||||
const std::vector<LogicalType>& aggregate_types() const {
|
||||
const static std::vector<LogicalType> kTypes{
|
||||
TYPE_BOOLEAN, TYPE_TINYINT, TYPE_SMALLINT, TYPE_INT, TYPE_BIGINT, TYPE_LARGEINT,
|
||||
TYPE_FLOAT, TYPE_DOUBLE, TYPE_VARCHAR, TYPE_CHAR, TYPE_DATE, TYPE_DATETIME,
|
||||
TYPE_DECIMALV2, TYPE_DECIMAL32, TYPE_DECIMAL64, TYPE_DECIMAL128, TYPE_HLL, TYPE_OBJECT};
|
||||
const static std::vector<LogicalType> kTypes{TYPE_BOOLEAN, TYPE_TINYINT, TYPE_SMALLINT, TYPE_INT,
|
||||
TYPE_BIGINT, TYPE_LARGEINT, TYPE_FLOAT, TYPE_DOUBLE,
|
||||
TYPE_VARCHAR, TYPE_CHAR, TYPE_DATE, TYPE_DATETIME,
|
||||
TYPE_DECIMALV2, TYPE_DECIMAL32, TYPE_DECIMAL64, TYPE_DECIMAL128,
|
||||
TYPE_DECIMAL256, TYPE_HLL, TYPE_OBJECT};
|
||||
return kTypes;
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +222,7 @@ public:
|
|||
|
||||
template <LogicalType ArgLT, LogicalType ResultLT, bool IsWindowFunc, bool IsNull>
|
||||
std::enable_if_t<isArithmeticLT<ArgLT>, AggregateFunctionPtr> create_decimal_function(std::string& name) {
|
||||
static_assert(lt_is_decimal128<ResultLT>);
|
||||
static_assert(lt_is_decimal128<ResultLT> || lt_is_decimal256<ResultLT>);
|
||||
if constexpr (IsNull) {
|
||||
using ResultType = RunTimeCppType<ResultLT>;
|
||||
if (name == "decimal_avg") {
|
||||
|
|
|
|||
|
|
@ -133,15 +133,18 @@ struct MapAggDispatcher {
|
|||
void AggregateFuncResolver::register_avg() {
|
||||
for (auto type : aggregate_types()) {
|
||||
type_dispatch_all(type, AvgDispatcher(), this);
|
||||
type_dispatch_all(type, ArrayAggDispatcher(), this);
|
||||
type_dispatch_all(type, ArrayAggDistinctDispatcher(), this);
|
||||
type_dispatch_all(type, ArrayUniqueAggDispatcher(), this);
|
||||
type_dispatch_all(type, MapAggDispatcher(), this);
|
||||
if (type != TYPE_DECIMAL256) {
|
||||
type_dispatch_all(type, ArrayAggDispatcher(), this);
|
||||
type_dispatch_all(type, ArrayAggDistinctDispatcher(), this);
|
||||
type_dispatch_all(type, ArrayUniqueAggDispatcher(), this);
|
||||
type_dispatch_all(type, MapAggDispatcher(), this);
|
||||
}
|
||||
}
|
||||
type_dispatch_all(TYPE_JSON, ArrayAggDispatcher(), this);
|
||||
add_decimal_mapping<TYPE_DECIMAL32, TYPE_DECIMAL128, true>("decimal_avg");
|
||||
add_decimal_mapping<TYPE_DECIMAL64, TYPE_DECIMAL128, true>("decimal_avg");
|
||||
add_decimal_mapping<TYPE_DECIMAL128, TYPE_DECIMAL128, true>("decimal_avg");
|
||||
add_decimal_mapping<TYPE_DECIMAL256, TYPE_DECIMAL256, true>("decimal_avg");
|
||||
}
|
||||
|
||||
} // namespace starrocks
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ void AggregateFuncResolver::register_others() {
|
|||
add_decimal_mapping<TYPE_DECIMAL32, TYPE_DECIMAL128>("decimal_multi_distinct_sum");
|
||||
add_decimal_mapping<TYPE_DECIMAL64, TYPE_DECIMAL128>("decimal_multi_distinct_sum");
|
||||
add_decimal_mapping<TYPE_DECIMAL128, TYPE_DECIMAL128>("decimal_multi_distinct_sum");
|
||||
add_decimal_mapping<TYPE_DECIMAL256, TYPE_DECIMAL256>("decimal_multi_distinct_sum");
|
||||
|
||||
// This first type is the 4th type input of windowfunnel.
|
||||
// And the 1st type is BigInt, 2nd is datetime, 3rd is mode(default 0).
|
||||
|
|
|
|||
|
|
@ -24,8 +24,10 @@ namespace starrocks {
|
|||
struct SumDispatcher {
|
||||
template <LogicalType lt>
|
||||
void operator()(AggregateFuncResolver* resolver) {
|
||||
if constexpr (lt_is_decimal<lt>) {
|
||||
if constexpr (lt_is_decimal<lt> && !lt_is_decimal256<lt>) {
|
||||
resolver->add_decimal_mapping<lt, TYPE_DECIMAL128, true>("decimal_sum");
|
||||
} else if constexpr (lt_is_decimal256<lt>) {
|
||||
resolver->add_decimal_mapping<lt, TYPE_DECIMAL256, true>("decimal_sum");
|
||||
} else if constexpr (lt_is_numeric<lt> || lt_is_decimalv2<lt>) {
|
||||
using SumState = SumAggregateState<RunTimeCppType<SumResultLT<lt>>>;
|
||||
resolver->add_aggregate_mapping<lt, SumResultLT<lt>, SumState>(
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace starrocks {
|
|||
struct StdDispatcher {
|
||||
template <LogicalType lt>
|
||||
void operator()(AggregateFuncResolver* resolver) {
|
||||
if constexpr (lt_is_numeric<lt>) {
|
||||
if constexpr (lt_is_numeric<lt> && lt != TYPE_DECIMAL256) {
|
||||
using VarState = DevFromAveAggregateState<RunTimeCppType<DevFromAveResultLT<lt>>>;
|
||||
resolver->add_aggregate_mapping<lt, DevFromAveResultLT<lt>, VarState>(
|
||||
"variance", true, AggregateFactory::MakeVarianceAggregateFunction<lt, false>());
|
||||
|
|
@ -56,7 +56,7 @@ struct StdDispatcher {
|
|||
struct CorVarDispatcher {
|
||||
template <LogicalType lt>
|
||||
void operator()(AggregateFuncResolver* resolver) {
|
||||
if constexpr (lt_is_numeric<lt>) {
|
||||
if constexpr (lt_is_numeric<lt> && lt != TYPE_DECIMAL256) {
|
||||
using VarState = CovarianceCorelationAggregateState<false>;
|
||||
resolver->add_aggregate_mapping_variadic<lt, TYPE_DOUBLE, VarState>(
|
||||
"covar_pop", true, AggregateFactory::MakeCovarianceAggregateFunction<lt, false>());
|
||||
|
|
|
|||
|
|
@ -177,6 +177,5 @@ public:
|
|||
|
||||
template <LogicalType LT, typename = DecimalLTGuard<LT>>
|
||||
using DecimalSumAggregateFunction =
|
||||
SumAggregateFunction<LT, RunTimeCppType<LT>, TYPE_DECIMAL128, RunTimeCppType<TYPE_DECIMAL128>>;
|
||||
|
||||
SumAggregateFunction<LT, RunTimeCppType<LT>, lt_is_decimal256<LT> ? TYPE_DECIMAL256 : TYPE_DECIMAL128>;
|
||||
} // namespace starrocks
|
||||
|
|
|
|||
|
|
@ -486,10 +486,11 @@ public:
|
|||
|
||||
#define CASE_DECIMAL_TYPE(OP) CASE_TYPE(TYPE_DECIMALV2, OP);
|
||||
|
||||
#define CASE_DECIMAL_V3_TYPE(OP) \
|
||||
CASE_TYPE(TYPE_DECIMAL32, OP) \
|
||||
CASE_TYPE(TYPE_DECIMAL64, OP) \
|
||||
CASE_TYPE(TYPE_DECIMAL128, OP)
|
||||
#define CASE_DECIMAL_V3_TYPE(OP) \
|
||||
CASE_TYPE(TYPE_DECIMAL32, OP) \
|
||||
CASE_TYPE(TYPE_DECIMAL64, OP) \
|
||||
CASE_TYPE(TYPE_DECIMAL128, OP) \
|
||||
CASE_TYPE(TYPE_DECIMAL256, OP)
|
||||
|
||||
#define SWITCH_INT_TYPE(OP) \
|
||||
switch (resultType) { \
|
||||
|
|
|
|||
|
|
@ -408,6 +408,10 @@ static inline std::tuple<int, int, int> compute_decimal_result_type(int lhs_scal
|
|||
DCHECK(scale <= max_precision);
|
||||
} else if constexpr (is_div_op<Op>) {
|
||||
precision = decimal_precision_limit<int128_t>;
|
||||
if (std::is_same_v<int256_t, T>) {
|
||||
precision = decimal_precision_limit<int256_t>;
|
||||
}
|
||||
|
||||
if (lhs_scale <= 6) {
|
||||
scale = lhs_scale + 6;
|
||||
} else if (lhs_scale <= 12) {
|
||||
|
|
|
|||
|
|
@ -676,6 +676,7 @@ private:
|
|||
CASE_WHEN_RESULT_TYPE(TYPE_DECIMAL32, RESULT_TYPE); \
|
||||
CASE_WHEN_RESULT_TYPE(TYPE_DECIMAL64, RESULT_TYPE); \
|
||||
CASE_WHEN_RESULT_TYPE(TYPE_DECIMAL128, RESULT_TYPE); \
|
||||
CASE_WHEN_RESULT_TYPE(TYPE_DECIMAL256, RESULT_TYPE); \
|
||||
CASE_WHEN_RESULT_TYPE(TYPE_JSON, RESULT_TYPE); \
|
||||
CASE_WHEN_RESULT_TYPE(TYPE_ARRAY, RESULT_TYPE); \
|
||||
CASE_WHEN_RESULT_TYPE(TYPE_MAP, RESULT_TYPE); \
|
||||
|
|
|
|||
|
|
@ -1477,6 +1477,7 @@ private:
|
|||
CASE_FROM_TYPE(TYPE_DECIMAL32, TO_TYPE, ALLOWTHROWEXCEPTION); \
|
||||
CASE_FROM_TYPE(TYPE_DECIMAL64, TO_TYPE, ALLOWTHROWEXCEPTION); \
|
||||
CASE_FROM_TYPE(TYPE_DECIMAL128, TO_TYPE, ALLOWTHROWEXCEPTION); \
|
||||
CASE_FROM_TYPE(TYPE_DECIMAL256, TO_TYPE, ALLOWTHROWEXCEPTION); \
|
||||
default: \
|
||||
LOG(WARNING) << "Not support cast from type: " << type_to_string(from_type) \
|
||||
<< " to type: " << type_to_string(to_type); \
|
||||
|
|
@ -1683,6 +1684,7 @@ Expr* VectorizedCastExprFactory::create_primitive_cast(ObjectPool* pool, const T
|
|||
CASE_TO_STRING_FROM(TYPE_DECIMAL32, allow_throw_exception);
|
||||
CASE_TO_STRING_FROM(TYPE_DECIMAL64, allow_throw_exception);
|
||||
CASE_TO_STRING_FROM(TYPE_DECIMAL128, allow_throw_exception);
|
||||
CASE_TO_STRING_FROM(TYPE_DECIMAL256, allow_throw_exception);
|
||||
CASE_TO_STRING_FROM(TYPE_JSON, allow_throw_exception);
|
||||
CASE_TO_STRING_FROM(TYPE_VARBINARY, allow_throw_exception);
|
||||
default:
|
||||
|
|
@ -1758,6 +1760,7 @@ Expr* VectorizedCastExprFactory::create_primitive_cast(ObjectPool* pool, const T
|
|||
CASE_TO_TYPE(TYPE_DECIMAL32, allow_throw_exception);
|
||||
CASE_TO_TYPE(TYPE_DECIMAL64, allow_throw_exception);
|
||||
CASE_TO_TYPE(TYPE_DECIMAL128, allow_throw_exception);
|
||||
CASE_TO_TYPE(TYPE_DECIMAL256, allow_throw_exception);
|
||||
default:
|
||||
LOG(WARNING) << "Not support cast " << type_to_string(from_type) << " to " << type_to_string(to_type);
|
||||
return nullptr;
|
||||
|
|
|
|||
|
|
@ -291,6 +291,9 @@ struct CastToString {
|
|||
} else if constexpr (IsInt128<Type>) {
|
||||
// int128_t
|
||||
return LargeIntValue::to_string(v);
|
||||
} else if constexpr (IsInt256<Type>) {
|
||||
// int256_t
|
||||
return v.to_string();
|
||||
} else {
|
||||
// int8_t ~ int64_t, boolean
|
||||
return SimpleItoa(v);
|
||||
|
|
|
|||
|
|
@ -513,7 +513,8 @@ private:
|
|||
CASE_TYPE(TYPE_JSON, CLASS); \
|
||||
CASE_TYPE(TYPE_DECIMAL32, CLASS); \
|
||||
CASE_TYPE(TYPE_DECIMAL64, CLASS); \
|
||||
CASE_TYPE(TYPE_DECIMAL128, CLASS);
|
||||
CASE_TYPE(TYPE_DECIMAL128, CLASS); \
|
||||
CASE_TYPE(TYPE_DECIMAL256, CLASS);
|
||||
|
||||
Expr* VectorizedConditionExprFactory::create_if_null_expr(const starrocks::TExprNode& node) {
|
||||
LogicalType resultType = TypeDescriptor::from_thrift(node.type).type;
|
||||
|
|
|
|||
|
|
@ -265,6 +265,7 @@ DEFINE_MATH_UNARY_FN_CAST_WITH_IMPL(abs_tinyint, TYPE_TINYINT, TYPE_SMALLINT, st
|
|||
DEFINE_MATH_UNARY_FN_WITH_IMPL(abs_decimal32, TYPE_DECIMAL32, TYPE_DECIMAL32, std::abs);
|
||||
DEFINE_MATH_UNARY_FN_WITH_IMPL(abs_decimal64, TYPE_DECIMAL64, TYPE_DECIMAL64, std::abs);
|
||||
DEFINE_MATH_UNARY_FN_WITH_IMPL(abs_decimal128, TYPE_DECIMAL128, TYPE_DECIMAL128, std::abs);
|
||||
DEFINE_MATH_UNARY_FN_WITH_IMPL(abs_decimal256, TYPE_DECIMAL256, TYPE_DECIMAL256, std::abs);
|
||||
|
||||
// degrees
|
||||
DEFINE_UNARY_FN_WITH_IMPL(abs_decimalv2valImpl, v) {
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ public:
|
|||
DEFINE_VECTORIZED_FN(abs_decimal32);
|
||||
DEFINE_VECTORIZED_FN(abs_decimal64);
|
||||
DEFINE_VECTORIZED_FN(abs_decimal128);
|
||||
DEFINE_VECTORIZED_FN(abs_decimal256);
|
||||
|
||||
/**
|
||||
* @param columns: [DoubleColumn]
|
||||
* @return DoubleColumn
|
||||
|
|
|
|||
|
|
@ -56,5 +56,6 @@ bool DecimalV3Converter<T>::read_quoted_string(Column* column, const Slice& s, c
|
|||
template class DecimalV3Converter<int32_t>;
|
||||
template class DecimalV3Converter<int64_t>;
|
||||
template class DecimalV3Converter<int128_t>;
|
||||
template class DecimalV3Converter<int256_t>;
|
||||
|
||||
} // namespace starrocks::csv
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ namespace starrocks {
|
|||
TYPE_GUARD(Decimal32Guard, is_decimal32, int32_t)
|
||||
TYPE_GUARD(Decimal64Guard, is_decimal64, int64_t)
|
||||
TYPE_GUARD(Decimal128Guard, is_decimal128, int128_t)
|
||||
TYPE_GUARD(DecimalGuard, is_decimal, int32_t, int64_t, int128_t)
|
||||
TYPE_GUARD(Decimal256Guard, is_decimal256, int256_t)
|
||||
TYPE_GUARD(DecimalGuard, is_decimal, int32_t, int64_t, int128_t, int256_t)
|
||||
|
||||
template <typename ST>
|
||||
struct unsigned_type {
|
||||
|
|
@ -226,7 +227,7 @@ public:
|
|||
// (https://www.felixcloutier.com/x86/cvttsd2si)
|
||||
return (*dec_value == float_lower_overflow_indicator<To>) ||
|
||||
(*dec_value == float_upper_overflow_indicator<To>);
|
||||
} else if constexpr (is_decimal128<To>) {
|
||||
} else if constexpr (is_decimal128<To> || is_decimal256<To>) {
|
||||
// std::abs(value)<1.0 -> 0: Acceptable
|
||||
// std::abs(value)>=1.0 -> 0 or different sign: Overflow!!
|
||||
return std::abs(value) >= From(1) && (*dec_value == To(0) || ((value < From(0)) ^ (*dec_value < To(0))));
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ inline bool int128_add_overflow(int128_t a, int128_t b, int128_t* c) {
|
|||
return ((a < 0) == (b < 0)) && ((*c < 0) != (a < 0));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool add_overflow(int256_t a, int256_t b, int256_t* c) {
|
||||
*c = a + b;
|
||||
return ((a < 0) == (b < 0)) && ((*c < 0) != (a < 0));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool add_overflow(int128_t a, int128_t b, int128_t* c) {
|
||||
#if defined(__x86_64__) && defined(__GNUC__)
|
||||
|
|
@ -74,6 +80,12 @@ inline bool int128_sub_overflow(int128_t a, int128_t b, int128_t* c) {
|
|||
return ((a < 0) == (0 < b)) && ((*c < 0) != (a < 0));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool sub_overflow(int256_t a, int256_t b, int256_t* c) {
|
||||
*c = a - b;
|
||||
return ((a < 0) == (0 < b)) && ((*c < 0) != (a < 0));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool sub_overflow(int128_t a, int128_t b, int128_t* c) {
|
||||
#if defined(__x86_64__) && defined(__GNUC__)
|
||||
|
|
@ -125,4 +137,92 @@ inline bool mul_overflow(int128_t a, int128_t b, int128_t* c) {
|
|||
#endif
|
||||
}
|
||||
|
||||
inline int count_bits(const int256_t& x) noexcept {
|
||||
if (x == 0) return 0;
|
||||
|
||||
for (int shift = 192; shift >= 0; shift -= 64) {
|
||||
uint64_t segment = static_cast<uint64_t>(x >> shift);
|
||||
if (segment != 0) {
|
||||
return shift + 64 - __builtin_clzll(segment);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool mul_overflow(const int256_t a, const int256_t b, int256_t* c) {
|
||||
if (a == 0 || b == 0) {
|
||||
*c = int256_t(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a == int256_t(1)) {
|
||||
*c = b;
|
||||
return false;
|
||||
}
|
||||
if (b == int256_t(1)) {
|
||||
*c = a;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a == int256_t(-1)) {
|
||||
if (b == INT256_MIN) return true;
|
||||
*c = -b;
|
||||
return false;
|
||||
}
|
||||
if (b == int256_t(-1)) {
|
||||
if (a == INT256_MIN) return true;
|
||||
*c = -a;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a == INT256_MIN || b == INT256_MIN) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a == INT256_MAX || b == INT256_MAX) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool negative = (a < 0) ^ (b < 0);
|
||||
const int256_t abs_a = (a.high < 0) ? -a : a;
|
||||
const int256_t abs_b = (b.high < 0) ? -b : b;
|
||||
|
||||
const int abs_a_bits = count_bits(abs_a);
|
||||
const int abs_b_bits = count_bits(abs_b);
|
||||
|
||||
if (abs_a_bits + abs_b_bits <= 255) {
|
||||
*c = a * b;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (abs_a_bits + abs_b_bits > 256) {
|
||||
if (negative) {
|
||||
if (abs_a_bits + abs_b_bits == 257) {
|
||||
const int256_t product_abs = abs_a * abs_b;
|
||||
if (product_abs == INT256_MIN) {
|
||||
*c = INT256_MIN;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const int256_t& larger = (abs_a >= abs_b) ? abs_a : abs_b;
|
||||
const int256_t& smaller = (abs_a >= abs_b) ? abs_b : abs_a;
|
||||
|
||||
const int256_t quotient = INT256_MAX / smaller;
|
||||
|
||||
if (larger > quotient) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const int256_t result = abs_a * abs_b;
|
||||
*c = negative ? -result : result;
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace starrocks
|
||||
|
|
|
|||
|
|
@ -645,11 +645,11 @@ ColumnPredicate* new_column_in_predicate_generic(const TypeInfoPtr& type_info, C
|
|||
SetType values = predicate_internal::strings_to_decimal_set<TYPE_DECIMAL128>(scale, strs);
|
||||
return new ColumnInPredicate<TYPE_DECIMAL128, SetType>(type_info, id, std::move(values));
|
||||
}
|
||||
// TODO(stephen): implement decimal256 and int256
|
||||
case TYPE_DECIMAL256:
|
||||
return nullptr;
|
||||
case TYPE_INT256:
|
||||
return nullptr;
|
||||
case TYPE_DECIMAL256: {
|
||||
using SetType = Set<CppTypeTraits<TYPE_DECIMAL256>::CppType, (Args)...>;
|
||||
SetType values = predicate_internal::strings_to_decimal_set<TYPE_DECIMAL256>(scale, strs);
|
||||
return new ColumnInPredicate<TYPE_DECIMAL256, SetType>(type_info, id, std::move(values));
|
||||
}
|
||||
case TYPE_CHAR:
|
||||
return new BinaryColumnInPredicate<TYPE_CHAR>(type_info, id, strs);
|
||||
case TYPE_VARCHAR:
|
||||
|
|
@ -704,6 +704,7 @@ ColumnPredicate* new_column_in_predicate_generic(const TypeInfoPtr& type_info, C
|
|||
case TYPE_BINARY:
|
||||
case TYPE_VARBINARY:
|
||||
case TYPE_MAX_VALUE:
|
||||
case TYPE_INT256:
|
||||
return nullptr;
|
||||
// No default to ensure newly added enumerator will be handled.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -359,10 +359,12 @@ ColumnPredicate* new_column_not_in_predicate(const TypeInfoPtr& type_info, Colum
|
|||
SetType values = predicate_internal::strings_to_decimal_set<TYPE_DECIMAL128>(scale, strs);
|
||||
return new ColumnNotInPredicate<TYPE_DECIMAL128>(type_info, id, std::move(values));
|
||||
}
|
||||
// TODO(stephen): implement it later
|
||||
case TYPE_DECIMAL256:
|
||||
case TYPE_INT256:
|
||||
return nullptr;
|
||||
case TYPE_DECIMAL256: {
|
||||
const auto scale = type_info->scale();
|
||||
using SetType = ItemHashSet<CppTypeTraits<TYPE_DECIMAL256>::CppType>;
|
||||
SetType values = predicate_internal::strings_to_decimal_set<TYPE_DECIMAL256>(scale, strs);
|
||||
return new ColumnNotInPredicate<TYPE_DECIMAL256>(type_info, id, std::move(values));
|
||||
}
|
||||
case TYPE_CHAR:
|
||||
return new BinaryColumnNotInPredicate<TYPE_CHAR>(type_info, id, strs);
|
||||
case TYPE_VARCHAR:
|
||||
|
|
@ -399,6 +401,7 @@ ColumnPredicate* new_column_not_in_predicate(const TypeInfoPtr& type_info, Colum
|
|||
case TYPE_BINARY:
|
||||
case TYPE_MAX_VALUE:
|
||||
case TYPE_VARBINARY:
|
||||
case TYPE_INT256:
|
||||
return nullptr;
|
||||
// No default to ensure newly added enumerator will be handled.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,10 +138,13 @@ static ColumnPredicate* new_column_predicate(const TypeInfoPtr& type_info, Colum
|
|||
DCHECK(st.ok());
|
||||
return new Predicate<TYPE_DECIMAL128>(type_info, id, value);
|
||||
}
|
||||
// TODO(stephen): implement it later
|
||||
case TYPE_DECIMAL256:
|
||||
case TYPE_INT256:
|
||||
return nullptr;
|
||||
case TYPE_DECIMAL256: {
|
||||
int256_t value;
|
||||
auto st = type_info->from_string(&value, operand.to_string());
|
||||
DCHECK(st.ok());
|
||||
return new Predicate<TYPE_DECIMAL256>(type_info, id, value);
|
||||
}
|
||||
case TYPE_DATE_V1: {
|
||||
uint24_t value = 0;
|
||||
auto st = type_info->from_string(&value, operand.to_string());
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ public:
|
|||
|
||||
void set_to_min(void* buf) const override {
|
||||
auto* data = reinterpret_cast<CppType*>(buf);
|
||||
*data = 1 - get_scale_factor<CppType>(_precision);
|
||||
*data = CppType(1) - get_scale_factor<CppType>(_precision);
|
||||
}
|
||||
|
||||
size_t size() const override { return _delegate->size(); }
|
||||
|
|
|
|||
|
|
@ -548,6 +548,55 @@ struct ScalarTypeInfoImpl<TYPE_LARGEINT> : public ScalarTypeInfoImplBase<TYPE_LA
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ScalarTypeInfoImpl<TYPE_INT256> : public ScalarTypeInfoImplBase<TYPE_INT256> {
|
||||
static Status from_string(void* buf, const std::string& scan_key) {
|
||||
try {
|
||||
int256_t value = parse_int256(scan_key);
|
||||
unaligned_store<int256_t>(buf, value);
|
||||
return Status::OK();
|
||||
} catch (const std::exception& e) {
|
||||
// Fallback to zero on parse error
|
||||
unaligned_store<int256_t>(buf, int256_t(0));
|
||||
return Status::InternalError(fmt::format("Fail to parse int256 from string: {}", scan_key));
|
||||
}
|
||||
}
|
||||
|
||||
static std::string to_string(const void* src) {
|
||||
auto value = unaligned_load<int256_t>(src);
|
||||
return value.to_string();
|
||||
}
|
||||
|
||||
static void shallow_copy(void* dest, const void* src) {
|
||||
unaligned_store<int256_t>(dest, unaligned_load<int256_t>(src));
|
||||
}
|
||||
|
||||
static void deep_copy(void* dest, const void* src, MemPool* mem_pool __attribute__((unused))) {
|
||||
unaligned_store<int256_t>(dest, unaligned_load<int256_t>(src));
|
||||
}
|
||||
|
||||
static void direct_copy(void* dest, const void* src) {
|
||||
unaligned_store<int256_t>(dest, unaligned_load<int256_t>(src));
|
||||
}
|
||||
|
||||
static void set_to_max(void* buf) { unaligned_store<int256_t>(buf, INT256_MAX); }
|
||||
static void set_to_min(void* buf) { unaligned_store<int256_t>(buf, INT256_MIN); }
|
||||
|
||||
static Status convert_from(void* dest, const void* src, const TypeInfoPtr& src_type,
|
||||
MemPool* mem_pool __attribute__((unused))) {
|
||||
if (src_type->type() == TYPE_VARCHAR) {
|
||||
return convert_int_from_varchar<CppType>(dest, src);
|
||||
}
|
||||
return Status::InternalError("Fail to cast to bigint.");
|
||||
}
|
||||
|
||||
static int datum_cmp(const Datum& left, const Datum& right) {
|
||||
const int256_t& v1 = left.get<int256_t>();
|
||||
const int256_t& v2 = right.get<int256_t>();
|
||||
return (v1 < v2) ? -1 : (v2 < v1) ? 1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ScalarTypeInfoImpl<TYPE_FLOAT> : public ScalarTypeInfoImplBase<TYPE_FLOAT> {
|
||||
static Status from_string(void* buf, const std::string& scan_key) {
|
||||
|
|
@ -1055,10 +1104,4 @@ int TypeComparator<ftype>::cmp(const void* lhs, const void* rhs) {
|
|||
#define M(ftype) template struct TypeComparator<ftype>;
|
||||
APPLY_FOR_SUPPORTED_FIELD_TYPE(M)
|
||||
#undef M
|
||||
|
||||
// TODO(stephen): support this trait in next patch
|
||||
// template <>
|
||||
// struct ScalarTypeInfoImplBase<TYPE_INT256> {
|
||||
// };
|
||||
|
||||
} // namespace starrocks
|
||||
|
|
|
|||
|
|
@ -21,10 +21,6 @@
|
|||
|
||||
namespace starrocks {
|
||||
|
||||
// =============================================================================
|
||||
// Anonymous namespace for internal utilities
|
||||
// =============================================================================
|
||||
|
||||
namespace {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -244,46 +240,221 @@ int256_t divide_positive(const int256_t& dividend, const int256_t& divisor) {
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
// Constructor from floating point types
|
||||
int256_t::int256_t(float value) {
|
||||
if (std::isnan(value) || std::isinf(value)) {
|
||||
low = 0;
|
||||
high = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value == 0.0f) {
|
||||
low = 0;
|
||||
high = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
bool negative = std::signbit(value);
|
||||
float abs_value = std::abs(value);
|
||||
|
||||
if (abs_value < 1.0f) {
|
||||
low = 0;
|
||||
high = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr float max_safe_float = 16777216.0f; // 2^24
|
||||
|
||||
constexpr float max_float = 3.4028235e38f;
|
||||
|
||||
high = 0;
|
||||
|
||||
if (abs_value >= max_safe_float) {
|
||||
int exponent;
|
||||
float mantissa = std::frexp(abs_value, &exponent);
|
||||
|
||||
mantissa *= 2.0f;
|
||||
exponent -= 1;
|
||||
|
||||
uint32_t mantissa_bits = static_cast<uint32_t>((mantissa - 1.0f) * (1U << 23));
|
||||
|
||||
uint32_t significand = (1U << 23) | mantissa_bits;
|
||||
|
||||
if (exponent <= 64) {
|
||||
if (exponent >= 23) {
|
||||
low = static_cast<uint128_t>(significand) << (exponent - 23);
|
||||
} else {
|
||||
low = static_cast<uint128_t>(significand) >> (23 - exponent);
|
||||
}
|
||||
} else if (exponent <= 128) {
|
||||
if (exponent >= 87) {
|
||||
int high_shift = exponent - 87;
|
||||
if (high_shift >= 64) {
|
||||
low = static_cast<uint128_t>(max_float);
|
||||
high = 0;
|
||||
} else {
|
||||
low = static_cast<uint128_t>(significand) << 64;
|
||||
high = static_cast<int128_t>(static_cast<uint64_t>(significand) >> (64 - high_shift));
|
||||
}
|
||||
} else if (exponent >= 23) {
|
||||
low = static_cast<uint128_t>(significand) << (exponent - 23);
|
||||
high = 0;
|
||||
} else {
|
||||
low = static_cast<uint128_t>(significand) >> (23 - exponent);
|
||||
high = 0;
|
||||
}
|
||||
} else {
|
||||
low = static_cast<uint128_t>(max_float);
|
||||
high = 0;
|
||||
}
|
||||
} else {
|
||||
if (abs_value <= static_cast<float>(UINT64_MAX)) {
|
||||
low = static_cast<uint128_t>(static_cast<uint64_t>(abs_value));
|
||||
} else {
|
||||
low = static_cast<uint128_t>(abs_value);
|
||||
}
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
*this = -*this;
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor from floating double types with proper overflow detection
|
||||
int256_t::int256_t(double value) {
|
||||
if (std::isnan(value) || std::isinf(value) || value == 0.0) {
|
||||
low = 0;
|
||||
high = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
double abs_value = std::abs(value);
|
||||
|
||||
if (abs_value < 1.0) {
|
||||
low = 0;
|
||||
high = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr double max_safe_double = 9007199254740992.0; // 2^53
|
||||
|
||||
constexpr double max_int256_double =
|
||||
5.7896044618658097711785492504343953926634992332820282019728792003956564819968e+76;
|
||||
|
||||
if (abs_value >= max_int256_double) {
|
||||
low = 0;
|
||||
high = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (abs_value >= max_safe_double) {
|
||||
constexpr double pow_128 = 340282366920938463463374607431768211456.0; // 2^128
|
||||
|
||||
bool negative = value < 0.0;
|
||||
double abs_val = std::abs(value);
|
||||
|
||||
double high_part = std::floor(abs_val / pow_128);
|
||||
double low_part = abs_val - (high_part * pow_128);
|
||||
|
||||
if (high_part > 0) {
|
||||
high = static_cast<int128_t>(high_part);
|
||||
} else {
|
||||
high = 0;
|
||||
}
|
||||
|
||||
low = static_cast<uint128_t>(low_part);
|
||||
|
||||
if (negative) {
|
||||
*this = -*this;
|
||||
}
|
||||
|
||||
} else {
|
||||
int64_t int_value = static_cast<int64_t>(value);
|
||||
|
||||
if (int_value >= 0) {
|
||||
low = static_cast<uint128_t>(int_value);
|
||||
high = 0;
|
||||
} else {
|
||||
uint64_t abs_int = static_cast<uint64_t>(-int_value);
|
||||
low = static_cast<uint128_t>(abs_int);
|
||||
high = 0;
|
||||
*this = -*this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Type Conversion Operators Implementation
|
||||
// =============================================================================
|
||||
int256_t::operator double() const {
|
||||
if (*this == 0) return 0.0;
|
||||
|
||||
// int256_t::operator double() const {
|
||||
// if (*this == 0) return 0.0;
|
||||
//
|
||||
// const bool negative = (high < 0);
|
||||
// const int256_t abs_val = negative ? -*this : *this;
|
||||
//
|
||||
// // Find the position of the most significant bit
|
||||
// int bit_count = 0;
|
||||
// int256_t temp = abs_val;
|
||||
// while (temp > 0) {
|
||||
// temp >>= 1;
|
||||
// bit_count++;
|
||||
// }
|
||||
//
|
||||
// if (bit_count <= 53) {
|
||||
// // Can represent exactly in double
|
||||
// double result = static_cast<double>(static_cast<uint64_t>(abs_val.low));
|
||||
// if (abs_val.high != 0) {
|
||||
// result += static_cast<double>(static_cast<uint64_t>(abs_val.high)) * (1ULL << 32) * (1ULL << 32) *
|
||||
// (1ULL << 32) * (1ULL << 32);
|
||||
// }
|
||||
// return negative ? -result : result;
|
||||
// } else {
|
||||
// // Need to round to fit in double precision
|
||||
// const int shift = bit_count - 53;
|
||||
// const int256_t rounded = (abs_val + (int256_t(1) << (shift - 1))) >> shift;
|
||||
// const double mantissa = static_cast<double>(static_cast<uint64_t>(rounded.low));
|
||||
// const double result = mantissa * pow(2.0, shift);
|
||||
// return negative ? -result : result;
|
||||
// }
|
||||
// }
|
||||
const bool negative = (high < 0);
|
||||
const int256_t abs_val = negative ? -*this : *this;
|
||||
|
||||
const int leading_zeros = count_leading_zeros(abs_val);
|
||||
if (leading_zeros == 256) return 0.0;
|
||||
|
||||
const int msb_pos = 255 - leading_zeros;
|
||||
|
||||
const int double_precision = 53;
|
||||
|
||||
if (msb_pos < double_precision) {
|
||||
double result = static_cast<double>(static_cast<uint64_t>(abs_val.low));
|
||||
return negative ? -result : result;
|
||||
} else if (msb_pos < 128) {
|
||||
const int excess_bits = msb_pos + 1 - double_precision;
|
||||
uint128_t shifted = static_cast<uint128_t>(abs_val.low) >> excess_bits;
|
||||
|
||||
if (excess_bits > 0) {
|
||||
uint128_t remainder = static_cast<uint128_t>(abs_val.low) - (shifted << excess_bits);
|
||||
uint128_t half = uint128_t(1) << (excess_bits - 1);
|
||||
|
||||
if (remainder > half || (remainder == half && (shifted & 1) == 1)) {
|
||||
shifted += 1;
|
||||
}
|
||||
}
|
||||
|
||||
double mantissa = static_cast<double>(static_cast<uint64_t>(shifted));
|
||||
double result = mantissa * pow(2.0, excess_bits);
|
||||
return negative ? -result : result;
|
||||
|
||||
} else {
|
||||
const int excess_bits = msb_pos + 1 - double_precision;
|
||||
|
||||
int256_t shifted = abs_val >> excess_bits;
|
||||
|
||||
if (excess_bits > 0) {
|
||||
int256_t remainder = abs_val - (shifted << excess_bits);
|
||||
int256_t half = int256_t(1) << (excess_bits - 1);
|
||||
|
||||
if (remainder > half || (remainder == half && (shifted.low & 1) == 1)) {
|
||||
shifted = shifted + 1;
|
||||
}
|
||||
}
|
||||
|
||||
double mantissa;
|
||||
if (shifted.high == 0) {
|
||||
mantissa = static_cast<double>(static_cast<uint64_t>(shifted.low));
|
||||
} else {
|
||||
mantissa = static_cast<double>(static_cast<uint64_t>(shifted.low));
|
||||
constexpr double pow_128 = 340282366920938463463374607431768211456.0; // 2^128
|
||||
mantissa += static_cast<double>(static_cast<uint64_t>(shifted.high)) * pow_128;
|
||||
}
|
||||
|
||||
double result = mantissa * pow(2.0, excess_bits);
|
||||
|
||||
if (std::isinf(result)) {
|
||||
result = negative ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
return negative ? -result : result;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Multiplication Runtime Implementation - Helper Functions
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @brief Multiply two 64-bit unsigned integers to produce a 256-bit result
|
||||
*
|
||||
|
|
@ -502,7 +673,6 @@ int256_t int256_t::operator/(const int256_t& other) const {
|
|||
if (other.high == 0 && other.low == 0) {
|
||||
throw std::domain_error("Division by zero");
|
||||
}
|
||||
|
||||
if (high == 0 && low == 0) return int256_t(0);
|
||||
if (*this == other) return int256_t(1);
|
||||
|
||||
|
|
|
|||
|
|
@ -153,38 +153,33 @@ public:
|
|||
|
||||
/// Constructor from floating point types
|
||||
/// @param value Floating point value to convert (truncated to integer)
|
||||
constexpr int256_t(float value)
|
||||
: low(static_cast<uint128_t>(static_cast<long long>(value))), high(value < 0 ? -1 : 0) {}
|
||||
constexpr int256_t(double value)
|
||||
: low(static_cast<uint128_t>(static_cast<long long>(value))), high(value < 0 ? -1 : 0) {}
|
||||
explicit int256_t(float value);
|
||||
explicit int256_t(double value);
|
||||
|
||||
// =============================================================================
|
||||
// Type Conversion Operators
|
||||
// =============================================================================
|
||||
|
||||
/// Convert to boolean (true if non-zero)
|
||||
operator bool() const { return high != 0 || low != 0; }
|
||||
//
|
||||
// /// High precision conversion using bit manipulation
|
||||
// operator double() const;
|
||||
//
|
||||
// /// Convert to size_t (safe conversion with overflow checking)
|
||||
// operator size_t() const {
|
||||
// if (high < 0) {
|
||||
// throw std::out_of_range("Cannot convert negative int256_t to size_t");
|
||||
// }
|
||||
//
|
||||
// if (high > 0) {
|
||||
// throw std::out_of_range("int256_t value too large for size_t");
|
||||
// }
|
||||
//
|
||||
// constexpr uint128_t max_size_t = std::numeric_limits<size_t>::max();
|
||||
// if (low > max_size_t) {
|
||||
// throw std::out_of_range("int256_t value too large for size_t");
|
||||
// }
|
||||
//
|
||||
// return static_cast<size_t>(low);
|
||||
// }
|
||||
explicit operator bool() const { return high != 0 || low != 0; }
|
||||
|
||||
/// High precision conversion using bit manipulation
|
||||
explicit operator double() const;
|
||||
|
||||
explicit operator int() const { return static_cast<int>(static_cast<uint32_t>(low)); }
|
||||
|
||||
explicit operator long() const { return static_cast<long>(static_cast<uint64_t>(low)); }
|
||||
|
||||
explicit operator int128_t() const { return static_cast<__int128>(low); }
|
||||
|
||||
/// Convert to signed char
|
||||
explicit operator signed char() const { return static_cast<signed char>(static_cast<int64_t>(low)); }
|
||||
|
||||
/// Convert to short int
|
||||
explicit operator short int() const { return static_cast<short>(static_cast<int64_t>(low)); }
|
||||
|
||||
/// Convert to size_t
|
||||
explicit operator size_t() const { return static_cast<size_t>(low); }
|
||||
|
||||
// =============================================================================
|
||||
// Unary Operators
|
||||
|
|
@ -197,6 +192,7 @@ public:
|
|||
return int256_t(-high, 0);
|
||||
} else {
|
||||
uint128_t new_low = ~low + 1;
|
||||
|
||||
int128_t new_high = ~high;
|
||||
if (new_low == 0) {
|
||||
new_high++;
|
||||
|
|
@ -276,6 +272,93 @@ public:
|
|||
/// @return true if this value is greater than or equal to other
|
||||
constexpr bool operator>=(int other) const { return *this >= int256_t(other); }
|
||||
|
||||
/// Equality comparison with double
|
||||
/// @param other Double value to compare with
|
||||
/// @return true if values are equal (within floating point precision)
|
||||
bool operator==(double other) const {
|
||||
if (std::floor(other) != other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int256_t INT256_MAX{static_cast<int128_t>((static_cast<uint128_t>(1) << 127) - 1), static_cast<uint128_t>(-1)};
|
||||
int256_t INT256_MIN{static_cast<int128_t>(static_cast<uint128_t>(1) << 127), static_cast<uint128_t>(0)};
|
||||
|
||||
if (other > static_cast<double>(INT256_MAX) || other < static_cast<double>(INT256_MIN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return *this == int256_t(other);
|
||||
}
|
||||
|
||||
/// Inequality comparison with double
|
||||
/// @param other Double value to compare with
|
||||
/// @return true if values are not equal
|
||||
bool operator!=(double other) const { return !(*this == other); }
|
||||
|
||||
/// Less than comparison with double
|
||||
/// @param other Double value to compare with
|
||||
/// @return true if this value is less than other
|
||||
bool operator<(double other) const { return static_cast<double>(*this) < other; }
|
||||
|
||||
/// Less than or equal comparison with double
|
||||
/// @param other Double value to compare with
|
||||
/// @return true if this value is less than or equal to other
|
||||
bool operator<=(double other) const { return static_cast<double>(*this) <= other; }
|
||||
|
||||
/// Greater than comparison with double
|
||||
/// @param other Double value to compare with
|
||||
/// @return true if this value is greater than other
|
||||
bool operator>(double other) const { return static_cast<double>(*this) > other; }
|
||||
|
||||
/// Greater than or equal comparison with double
|
||||
/// @param other Double value to compare with
|
||||
/// @return true if this value is greater than or equal to other
|
||||
bool operator>=(double other) const { return static_cast<double>(*this) >= other; }
|
||||
|
||||
// =============================================================================
|
||||
// Friend Comparison Operators (for reverse operand order)
|
||||
// =============================================================================
|
||||
|
||||
/// Equality comparison: int == int256_t
|
||||
friend constexpr bool operator==(int lhs, const int256_t& rhs) { return int256_t(lhs) == rhs; }
|
||||
|
||||
/// Inequality comparison: int != int256_t
|
||||
friend constexpr bool operator!=(int lhs, const int256_t& rhs) { return int256_t(lhs) != rhs; }
|
||||
|
||||
/// Less than comparison: int < int256_t
|
||||
friend constexpr bool operator<(int lhs, const int256_t& rhs) { return int256_t(lhs) < rhs; }
|
||||
|
||||
/// Less than or equal comparison: int <= int256_t
|
||||
friend constexpr bool operator<=(int lhs, const int256_t& rhs) { return int256_t(lhs) <= rhs; }
|
||||
|
||||
/// Greater than comparison: int > int256_t
|
||||
friend constexpr bool operator>(int lhs, const int256_t& rhs) { return int256_t(lhs) > rhs; }
|
||||
|
||||
/// Greater than or equal comparison: int >= int256_t
|
||||
friend constexpr bool operator>=(int lhs, const int256_t& rhs) { return int256_t(lhs) >= rhs; }
|
||||
|
||||
// =============================================================================
|
||||
// Friend Comparison Operators (for reverse operand order with double)
|
||||
// =============================================================================
|
||||
|
||||
/// Equality comparison: double == int256_t
|
||||
friend bool operator==(double lhs, const int256_t& rhs) { return rhs == lhs; }
|
||||
|
||||
/// Inequality comparison: double != int256_t
|
||||
friend bool operator!=(double lhs, const int256_t& rhs) { return rhs != lhs; }
|
||||
|
||||
/// Less than comparison: double < int256_t
|
||||
friend bool operator<(double lhs, const int256_t& rhs) { return lhs < static_cast<double>(rhs); }
|
||||
|
||||
/// Less than or equal comparison: double <= int256_t
|
||||
friend bool operator<=(double lhs, const int256_t& rhs) { return lhs <= static_cast<double>(rhs); }
|
||||
|
||||
/// Greater than comparison: double > int256_t
|
||||
friend bool operator>(double lhs, const int256_t& rhs) { return lhs > static_cast<double>(rhs); }
|
||||
|
||||
/// Greater than or equal comparison: double >= int256_t
|
||||
friend bool operator>=(double lhs, const int256_t& rhs) { return lhs >= static_cast<double>(rhs); }
|
||||
|
||||
// =============================================================================
|
||||
// Arithmetic Operators - Addition
|
||||
// =============================================================================
|
||||
|
|
@ -298,6 +381,21 @@ public:
|
|||
/// @return Sum of this value and other
|
||||
constexpr int256_t operator+(int other) const { return *this + int256_t(other); }
|
||||
|
||||
/// Addition with double (returns double)
|
||||
/// @param other Double value to add
|
||||
/// @return Sum as double
|
||||
double operator+(double other) const { return static_cast<double>(*this) + other; }
|
||||
|
||||
// =============================================================================
|
||||
// Friend Arithmetic Operators - Addition
|
||||
// =============================================================================
|
||||
|
||||
/// Addition: double + int256_t (returns double)
|
||||
/// @param lhs Double value
|
||||
/// @param rhs int256_t value
|
||||
/// @return Sum as double
|
||||
friend double operator+(double lhs, const int256_t& rhs) { return lhs + static_cast<double>(rhs); }
|
||||
|
||||
// =============================================================================
|
||||
// Arithmetic Operators - Subtraction
|
||||
// =============================================================================
|
||||
|
|
@ -322,6 +420,16 @@ public:
|
|||
/// @return Difference as double
|
||||
double operator-(double other) const { return static_cast<double>(*this) - other; }
|
||||
|
||||
// =============================================================================
|
||||
// Friend Arithmetic Operators - Subtraction
|
||||
// =============================================================================
|
||||
|
||||
/// Subtraction: double - int256_t (returns double)
|
||||
/// @param lhs Double value
|
||||
/// @param rhs int256_t value
|
||||
/// @return Difference as double
|
||||
friend double operator-(double lhs, const int256_t& rhs) { return lhs - static_cast<double>(rhs); }
|
||||
|
||||
// =============================================================================
|
||||
// Arithmetic Operators - Multiplication
|
||||
// =============================================================================
|
||||
|
|
@ -341,8 +449,23 @@ public:
|
|||
/// @return Product of this value and other
|
||||
int256_t operator*(int other) const { return *this * int256_t(other); }
|
||||
|
||||
/// Multiplication with double (returns double)
|
||||
/// @param other Double value to multiply by
|
||||
/// @return Product as double
|
||||
double operator*(double other) const { return static_cast<double>(*this) * other; }
|
||||
|
||||
// =============================================================================
|
||||
// Arithmetic Operators - Division (Declaration only)
|
||||
// Friend Arithmetic Operators - Multiplication
|
||||
// =============================================================================
|
||||
|
||||
/// Multiplication: double * int256_t (returns double)
|
||||
/// @param lhs Double value
|
||||
/// @param rhs int256_t value
|
||||
/// @return Product as double
|
||||
friend double operator*(double lhs, const int256_t& rhs) { return lhs * static_cast<double>(rhs); }
|
||||
|
||||
// =============================================================================
|
||||
// Arithmetic Operators - Division
|
||||
// =============================================================================
|
||||
|
||||
/// Division with another int256_t
|
||||
|
|
@ -351,8 +474,57 @@ public:
|
|||
/// @throws std::domain_error if other is zero
|
||||
int256_t operator/(const int256_t& other) const;
|
||||
|
||||
/// @brief Division with int
|
||||
/// @param other Integer value to divide by
|
||||
/// @return Quotient of this value divided by other
|
||||
/// @throws std::domain_error if other is zero
|
||||
int256_t operator/(int other) const {
|
||||
if (other == 0) {
|
||||
throw std::domain_error("Division by zero");
|
||||
}
|
||||
return *this / int256_t(other);
|
||||
}
|
||||
|
||||
/// Division with double (returns double)
|
||||
/// @param other Double value to divide by
|
||||
/// @return Quotient as double
|
||||
/// @throws std::domain_error if other is zero
|
||||
double operator/(double other) const {
|
||||
if (other == 0.0) {
|
||||
throw std::domain_error("Division by zero");
|
||||
}
|
||||
return static_cast<double>(*this) / other;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Arithmetic Operators - Modulo (Declaration only)
|
||||
// Friend Arithmetic Operators - Division
|
||||
// =============================================================================
|
||||
/// @brief Division: int / int256_t
|
||||
/// @param lhs Integer value
|
||||
/// @param rhs int256_t value to divide by
|
||||
/// @return Quotient as int256_t
|
||||
/// @throws std::domain_error if rhs is zero
|
||||
friend int256_t operator/(int lhs, const int256_t& rhs) {
|
||||
if (rhs == int256_t(0)) {
|
||||
throw std::domain_error("Division by zero");
|
||||
}
|
||||
return int256_t(lhs) / rhs;
|
||||
}
|
||||
|
||||
/// Division: double / int256_t (returns double)
|
||||
/// @param lhs Double value
|
||||
/// @param rhs int256_t value
|
||||
/// @return Quotient as double
|
||||
/// @throws std::domain_error if rhs is zero
|
||||
friend double operator/(double lhs, const int256_t& rhs) {
|
||||
if (rhs == int256_t(0)) {
|
||||
throw std::domain_error("Division by zero");
|
||||
}
|
||||
return lhs / static_cast<double>(rhs);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Arithmetic Operators - Modulo
|
||||
// =============================================================================
|
||||
|
||||
/// Modulo operation with another int256_t
|
||||
|
|
@ -361,6 +533,55 @@ public:
|
|||
/// @throws std::domain_error if other is zero
|
||||
int256_t operator%(const int256_t& other) const;
|
||||
|
||||
/// Modulo operation with int
|
||||
/// @param other Integer value to take modulo by
|
||||
/// @return Remainder of this value divided by other
|
||||
/// @throws std::domain_error if other is zero
|
||||
int256_t operator%(int other) const {
|
||||
if (other == 0) {
|
||||
throw std::domain_error("Modulo by zero");
|
||||
}
|
||||
return *this % int256_t(other);
|
||||
}
|
||||
|
||||
/// Modulo operation with double (using fmod semantics)
|
||||
/// @param other Double value to take modulo by
|
||||
/// @return Remainder as double (using fmod semantics)
|
||||
/// @throws std::domain_error if other is zero
|
||||
double operator%(double other) const {
|
||||
if (other == 0.0) {
|
||||
throw std::domain_error("Modulo by zero");
|
||||
}
|
||||
return std::fmod(static_cast<double>(*this), other);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Friend Arithmetic Operators - Modulo
|
||||
// =============================================================================
|
||||
/// Modulo operation: int % int256_t
|
||||
/// @param lhs Integer value
|
||||
/// @param rhs int256_t value to take modulo by
|
||||
/// @return Remainder as int256_t
|
||||
/// @throws std::domain_error if rhs is zero
|
||||
friend int256_t operator%(int lhs, const int256_t& rhs) {
|
||||
if (rhs == int256_t(0)) {
|
||||
throw std::domain_error("Modulo by zero");
|
||||
}
|
||||
return int256_t(lhs) % rhs;
|
||||
}
|
||||
|
||||
/// Modulo operation: double % int256_t (using fmod semantics)
|
||||
/// @param lhs Double value
|
||||
/// @param rhs int256_t value to take modulo by
|
||||
/// @return Remainder as double (using fmod semantics)
|
||||
/// @throws std::domain_error if rhs is zero
|
||||
friend double operator%(double lhs, const int256_t& rhs) {
|
||||
if (rhs == int256_t(0)) {
|
||||
throw std::domain_error("Modulo by zero");
|
||||
}
|
||||
return std::fmod(lhs, static_cast<double>(rhs));
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Assignment Operators
|
||||
// =============================================================================
|
||||
|
|
@ -480,7 +701,57 @@ public:
|
|||
/// Left shift assignment operator
|
||||
/// @param shift Number of bits to shift left
|
||||
/// @return Reference to this after shifting
|
||||
constexpr int256_t& operator<<=(int shift) { return *this = *this << shift; }
|
||||
int256_t& operator<<=(int shift) { return *this = *this << shift; }
|
||||
|
||||
// =============================================================================
|
||||
// Bitwise Operators
|
||||
// =============================================================================
|
||||
|
||||
/// Bitwise AND operator
|
||||
/// @param other Value to perform AND with
|
||||
/// @return Bitwise AND result
|
||||
int256_t operator&(const int256_t& other) const { return int256_t(high & other.high, low & other.low); }
|
||||
|
||||
/// Bitwise OR operator
|
||||
/// @param other Value to perform OR with
|
||||
/// @return Bitwise OR result
|
||||
int256_t operator|(const int256_t& other) const { return int256_t(high | other.high, low | other.low); }
|
||||
|
||||
/// Bitwise XOR operator
|
||||
/// @param other Value to perform XOR with
|
||||
/// @return Bitwise XOR result
|
||||
int256_t operator^(const int256_t& other) const { return int256_t(high ^ other.high, low ^ other.low); }
|
||||
|
||||
/// Bitwise NOT operator
|
||||
/// @return Bitwise complement of this value
|
||||
int256_t operator~() const { return int256_t(~high, ~low); }
|
||||
|
||||
/// Bitwise AND assignment operator
|
||||
/// @param other Value to perform AND with
|
||||
/// @return Reference to this after AND operation
|
||||
int256_t& operator&=(const int256_t& other) {
|
||||
high &= other.high;
|
||||
low &= other.low;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Bitwise OR assignment operator
|
||||
/// @param other Value to perform OR with
|
||||
/// @return Reference to this after OR operation
|
||||
int256_t& operator|=(const int256_t& other) {
|
||||
high |= other.high;
|
||||
low |= other.low;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Bitwise XOR assignment operator
|
||||
/// @param other Value to perform XOR with
|
||||
/// @return Reference to this after XOR operation
|
||||
int256_t& operator^=(const int256_t& other) {
|
||||
high ^= other.high;
|
||||
low ^= other.low;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Utility Methods
|
||||
|
|
@ -636,6 +907,12 @@ int256_t parse_int256(const std::string& str);
|
|||
|
||||
namespace std {
|
||||
|
||||
/// Specialization of make_signed for int256_t
|
||||
template <>
|
||||
struct make_signed<starrocks::int256_t> {
|
||||
using type = starrocks::int256_t;
|
||||
};
|
||||
|
||||
/// Specialization of make_unsigned for int256_t
|
||||
template <>
|
||||
struct make_unsigned<starrocks::int256_t> {
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ constexpr bool support_column_expr_predicate(LogicalType ltype) {
|
|||
case TYPE_DECIMAL32: /* 24 */
|
||||
case TYPE_DECIMAL64: /* 25 */
|
||||
case TYPE_DECIMAL128: /* 26 */
|
||||
case TYPE_DECIMAL256: /* 27 */
|
||||
case TYPE_STRUCT:
|
||||
return true;
|
||||
default:
|
||||
|
|
@ -318,6 +319,7 @@ VALUE_GUARD(LogicalType, FloatLTGuard, lt_is_float, TYPE_FLOAT, TYPE_DOUBLE)
|
|||
VALUE_GUARD(LogicalType, Decimal32LTGuard, lt_is_decimal32, TYPE_DECIMAL32)
|
||||
VALUE_GUARD(LogicalType, Decimal64LTGuard, lt_is_decimal64, TYPE_DECIMAL64)
|
||||
VALUE_GUARD(LogicalType, Decimal128LTGuard, lt_is_decimal128, TYPE_DECIMAL128)
|
||||
VALUE_GUARD(LogicalType, Decimal256LTGuard, lt_is_decimal256, TYPE_DECIMAL256)
|
||||
VALUE_GUARD(LogicalType, DecimalLTGuard, lt_is_decimal, TYPE_DECIMAL32, TYPE_DECIMAL64, TYPE_DECIMAL128,
|
||||
TYPE_DECIMAL256)
|
||||
VALUE_GUARD(LogicalType, SumDecimal64LTGuard, lt_is_sum_decimal64, TYPE_DECIMAL32, TYPE_DECIMAL64)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
#include "common/logging.h"
|
||||
#include "gutil/strings/fastmem.h"
|
||||
#include "types/int256.h"
|
||||
#include "types/large_int_value.h"
|
||||
#include "util/mysql_global.h"
|
||||
|
||||
|
|
@ -126,6 +127,9 @@ void MysqlRowBuffer::push_number_binary_format(T data) {
|
|||
} else if constexpr (std::is_same_v<std::make_signed_t<T>, __int128>) {
|
||||
std::string value = LargeIntValue::to_string(data);
|
||||
_push_string_normal(value.data(), value.size());
|
||||
} else if constexpr (std::is_same_v<T, int256_t>) {
|
||||
std::string value = data.to_string();
|
||||
_push_string_normal(value.data(), value.size());
|
||||
} else {
|
||||
CHECK(false) << "unhandled data type";
|
||||
}
|
||||
|
|
@ -133,7 +137,7 @@ void MysqlRowBuffer::push_number_binary_format(T data) {
|
|||
|
||||
template <typename T>
|
||||
void MysqlRowBuffer::push_number(T data, bool is_binary_protocol) {
|
||||
static_assert(std::is_arithmetic_v<T> || std::is_same_v<T, __int128>);
|
||||
static_assert(std::is_arithmetic_v<T> || std::is_same_v<T, __int128> || std::is_same_v<T, int256_t>);
|
||||
|
||||
if (is_binary_protocol) {
|
||||
return push_number_binary_format(data);
|
||||
|
|
@ -171,6 +175,10 @@ void MysqlRowBuffer::push_number(T data, bool is_binary_protocol) {
|
|||
pos = _resize_extra(2 + 40);
|
||||
end = fmt::format_to(pos + length_prefix_bytes, FMT_COMPILE("{}"), data);
|
||||
length = end - pos - length_prefix_bytes;
|
||||
} else if constexpr (std::is_same_v<T, int256_t>) {
|
||||
pos = _resize_extra(2 + 80);
|
||||
end = fmt::format_to(pos + length_prefix_bytes, FMT_COMPILE("{}"), data);
|
||||
length = end - pos - length_prefix_bytes;
|
||||
} else {
|
||||
CHECK(false) << "unhandled data type";
|
||||
}
|
||||
|
|
@ -346,6 +354,7 @@ template void MysqlRowBuffer::push_number<uint16_t>(uint16_t, bool);
|
|||
template void MysqlRowBuffer::push_number<uint32_t>(uint32_t, bool);
|
||||
template void MysqlRowBuffer::push_number<uint64_t>(uint64_t, bool);
|
||||
template void MysqlRowBuffer::push_number<__int128>(__int128, bool);
|
||||
template void MysqlRowBuffer::push_number<int256_t>(int256_t, bool);
|
||||
template void MysqlRowBuffer::push_number<float>(float, bool);
|
||||
template void MysqlRowBuffer::push_number<double>(double, bool);
|
||||
|
||||
|
|
|
|||
|
|
@ -608,6 +608,11 @@ inline int StringParser::StringParseTraits<__int128>::max_ascii_len() {
|
|||
return 39;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int StringParser::StringParseTraits<int256_t>::max_ascii_len() {
|
||||
return 77;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T StringParser::string_to_decimal(const char* s, int len, int type_precision, int type_scale,
|
||||
ParseResult* result) {
|
||||
|
|
|
|||
|
|
@ -947,4 +947,289 @@ TEST_F(Int256ArithmeticTest, division_truncation_behavior) {
|
|||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
TEST_F(Int256ArithmeticTest, multiplication_both_over_128bit) {
|
||||
// Test cases where both operands are over 128 bits
|
||||
// These tests focus on multiply_core_256bit logic coverage
|
||||
|
||||
// Test case 1: Both operands have significant high parts
|
||||
{
|
||||
int256_t a(0x123456789ABCDEF0ULL, 0xFEDCBA9876543210ULL); // > 128 bit
|
||||
int256_t b(0x0FEDCBA987654321ULL, 0x123456789ABCDEF0ULL); // > 128 bit
|
||||
|
||||
int256_t result = a * b;
|
||||
|
||||
// Since this will overflow, we mainly check that:
|
||||
// 1. The operation doesn't crash
|
||||
// 2. The result is deterministic
|
||||
int256_t result2 = a * b;
|
||||
ASSERT_EQ(result, result2); // Should be deterministic
|
||||
|
||||
// Check commutativity (even with overflow)
|
||||
int256_t result_comm = b * a;
|
||||
ASSERT_EQ(result, result_comm);
|
||||
}
|
||||
|
||||
// Test case 2: Large positive numbers
|
||||
{
|
||||
int256_t large1(0x7FFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL);
|
||||
int256_t large2(0x3FFFFFFFFFFFFFFFULL, 0x8000000000000000ULL);
|
||||
|
||||
int256_t result = large1 * large2;
|
||||
|
||||
// Verify the multiplication is consistent
|
||||
ASSERT_EQ(result, large1 * large2);
|
||||
ASSERT_EQ(result, large2 * large1);
|
||||
|
||||
// The result should not be zero (unless there's a specific overflow pattern)
|
||||
// This is a sanity check for the core multiplication logic
|
||||
ASSERT_NE(result, int256_t(0));
|
||||
}
|
||||
|
||||
// Test case 3: Mixed sign large numbers
|
||||
{
|
||||
int256_t pos_large(0x1234567890ABCDEFULL, 0xFEDCBA0987654321ULL);
|
||||
int256_t neg_large = -pos_large;
|
||||
|
||||
int256_t result_pos_neg = pos_large * neg_large;
|
||||
int256_t result_neg_pos = neg_large * pos_large;
|
||||
|
||||
// Should be commutative
|
||||
ASSERT_EQ(result_pos_neg, result_neg_pos);
|
||||
}
|
||||
|
||||
// Test case 4: Numbers close to 2^128
|
||||
{
|
||||
int256_t just_over_128(1, 0x1000000000000000ULL); // Slightly over 2^128
|
||||
int256_t another_large(0x8000000000000000ULL, 0); // 2^127 * 2^64
|
||||
|
||||
int256_t result = just_over_128 * another_large;
|
||||
|
||||
// Check deterministic behavior
|
||||
ASSERT_EQ(result, just_over_128 * another_large);
|
||||
ASSERT_EQ(result, another_large * just_over_128);
|
||||
}
|
||||
|
||||
// Test case 5: Maximum high parts
|
||||
{
|
||||
int256_t max_high1(0xFFFFFFFFFFFFFFFFULL, 0x123456789ABCDEF0ULL);
|
||||
int256_t max_high2(0xFFFFFFFFFFFFFFFFULL, 0xFEDCBA0987654321ULL);
|
||||
|
||||
int256_t result = max_high1 * max_high2;
|
||||
|
||||
// This will definitely overflow, but should be consistent
|
||||
ASSERT_EQ(result, max_high1 * max_high2);
|
||||
ASSERT_EQ(result, max_high2 * max_high1);
|
||||
}
|
||||
|
||||
// Test case 6: Patterns that test different code paths in multiply_core_256bit
|
||||
{
|
||||
// Test with alternating bit patterns
|
||||
int256_t pattern1(0xAAAAAAAAAAAAAAAAULL, 0x5555555555555555ULL);
|
||||
int256_t pattern2(0x5555555555555555ULL, 0xAAAAAAAAAAAAAAAAULL);
|
||||
|
||||
int256_t result = pattern1 * pattern2;
|
||||
|
||||
// Verify consistency
|
||||
ASSERT_EQ(result, pattern1 * pattern2);
|
||||
ASSERT_EQ(result, pattern2 * pattern1);
|
||||
}
|
||||
|
||||
// Test case 7: Powers of 2 over 128 bits
|
||||
{
|
||||
int256_t power_129(2, 0); // 2^129
|
||||
int256_t power_130(4, 0); // 2^130
|
||||
|
||||
int256_t result = power_129 * power_130;
|
||||
// This should be 2^259, which will overflow significantly
|
||||
|
||||
// Check that it's consistent
|
||||
ASSERT_EQ(result, power_129 * power_130);
|
||||
ASSERT_EQ(result, power_130 * power_129);
|
||||
}
|
||||
|
||||
// Test case 8: Large numbers with specific bit positions set
|
||||
{
|
||||
int256_t sparse1(0x8000000000000001ULL, 0x0000000000000001ULL);
|
||||
int256_t sparse2(0x0000000000000001ULL, 0x8000000000000001ULL);
|
||||
|
||||
int256_t result = sparse1 * sparse2;
|
||||
|
||||
// Verify deterministic behavior
|
||||
ASSERT_EQ(result, sparse1 * sparse2);
|
||||
ASSERT_EQ(result, sparse2 * sparse1);
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
TEST_F(Int256ArithmeticTest, multiplication_overflow_patterns) {
|
||||
// Test specific overflow patterns to ensure multiply_core_256bit handles them correctly
|
||||
|
||||
// Test case 1: Multiplication that causes carry propagation
|
||||
{
|
||||
int256_t carry_test1(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL);
|
||||
int256_t carry_test2(0x0000000000000002ULL, 0x0000000000000001ULL);
|
||||
|
||||
int256_t result = carry_test1 * carry_test2;
|
||||
|
||||
// This tests carry propagation through all 64-bit chunks
|
||||
ASSERT_EQ(result, carry_test1 * carry_test2);
|
||||
ASSERT_EQ(result, carry_test2 * carry_test1);
|
||||
}
|
||||
|
||||
// Test case 2: Multiplication with maximum values
|
||||
{
|
||||
int256_t near_max(INT256_MAX.high, INT256_MAX.low - 1000);
|
||||
int256_t multiplier(0x0000000000000001ULL, 0x0000000000000002ULL);
|
||||
|
||||
int256_t result = near_max * multiplier;
|
||||
|
||||
// Should handle near-maximum values without crashing
|
||||
ASSERT_EQ(result, near_max * multiplier);
|
||||
ASSERT_EQ(result, multiplier * near_max);
|
||||
}
|
||||
|
||||
// Test case 3: Test all four 64-bit chunk combinations
|
||||
{
|
||||
int256_t chunk_test(0x123456789ABCDEF0ULL, 0xFEDCBA9876543210ULL);
|
||||
int256_t chunk_mult(0x0FEDCBA987654321ULL, 0x0123456789ABCDEFULL);
|
||||
|
||||
int256_t result = chunk_test * chunk_mult;
|
||||
|
||||
// This exercises all combinations of 64-bit chunk multiplications
|
||||
// in multiply_core_256bit
|
||||
ASSERT_EQ(result, chunk_test * chunk_mult);
|
||||
ASSERT_EQ(result, chunk_mult * chunk_test);
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
TEST_F(Int256ArithmeticTest, multiplication_edge_bit_boundaries) {
|
||||
// Test multiplications at various bit boundaries to ensure proper handling
|
||||
|
||||
// Test at 129-bit boundary
|
||||
{
|
||||
int256_t just_129_bit(1, 1); // 2^128 + 1
|
||||
int256_t multiplier(0, 0x8000000000000000ULL); // 2^63
|
||||
|
||||
int256_t result = just_129_bit * multiplier;
|
||||
|
||||
ASSERT_EQ(result, just_129_bit * multiplier);
|
||||
ASSERT_EQ(result, multiplier * just_129_bit);
|
||||
}
|
||||
|
||||
// Test at 192-bit boundary
|
||||
{
|
||||
int256_t val_192(0x1000000000000000ULL, 0); // 2^192
|
||||
int256_t val_128(1, 0); // 2^128
|
||||
|
||||
int256_t result = val_192 * val_128;
|
||||
|
||||
ASSERT_EQ(result, val_192 * val_128);
|
||||
ASSERT_EQ(result, val_128 * val_192);
|
||||
}
|
||||
|
||||
// Test with values that span multiple 64-bit boundaries
|
||||
{
|
||||
int256_t span_test(0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL);
|
||||
int256_t span_mult(0xFFFFFFFF00000000ULL, 0x00000000FFFFFFFFULL);
|
||||
|
||||
int256_t result = span_test * span_mult;
|
||||
|
||||
ASSERT_EQ(result, span_test * span_mult);
|
||||
ASSERT_EQ(result, span_mult * span_test);
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
TEST_F(Int256ArithmeticTest, multiplication_stress_large_numbers) {
|
||||
// Stress test with various large number combinations
|
||||
|
||||
std::vector<int256_t> large_test_values = {
|
||||
int256_t(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), // Near max positive
|
||||
int256_t(0x8000000000000000ULL, 0x0000000000000000ULL), // 2^191
|
||||
int256_t(0x7FFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), // Large positive
|
||||
int256_t(0x1234567890ABCDEFULL, 0xFEDCBA9876543210ULL), // Random large
|
||||
int256_t(0xFEDCBA9876543210ULL, 0x1234567890ABCDEFULL), // Random large 2
|
||||
int256_t(0xAAAAAAAAAAAAAAAAULL, 0x5555555555555555ULL), // Alternating bits
|
||||
int256_t(0x5555555555555555ULL, 0xAAAAAAAAAAAAAAAAULL), // Alternating bits 2
|
||||
};
|
||||
|
||||
// Test all combinations
|
||||
for (size_t i = 0; i < large_test_values.size(); ++i) {
|
||||
for (size_t j = i; j < large_test_values.size(); ++j) {
|
||||
const auto& a = large_test_values[i];
|
||||
const auto& b = large_test_values[j];
|
||||
|
||||
int256_t result = a * b;
|
||||
|
||||
// Basic consistency checks
|
||||
ASSERT_EQ(result, a * b) << "Multiplication not deterministic for values at indices " << i << ", " << j;
|
||||
ASSERT_EQ(result, b * a) << "Multiplication not commutative for values at indices " << i << ", " << j;
|
||||
|
||||
// Test with negatives
|
||||
int256_t neg_a = -a;
|
||||
int256_t neg_b = -b;
|
||||
|
||||
int256_t result_neg_pos = neg_a * b;
|
||||
int256_t result_pos_neg = a * neg_b;
|
||||
// These should be equal (both negative * positive)
|
||||
ASSERT_EQ(result_neg_pos, result_pos_neg) << "Sign handling inconsistent for indices " << i << ", " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
TEST_F(Int256ArithmeticTest, multiplication_256bit_core_coverage) {
|
||||
// Specific tests to ensure multiply_core_256bit gets proper coverage
|
||||
|
||||
// Test case 1: Force all partial products to be non-zero
|
||||
{
|
||||
int256_t full_bits(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL);
|
||||
int256_t partial_bits(0x0F0F0F0F0F0F0F0FULL, 0xF0F0F0F0F0F0F0F0ULL);
|
||||
|
||||
int256_t result = full_bits * partial_bits;
|
||||
|
||||
// This should exercise all partial product calculations
|
||||
ASSERT_EQ(result, full_bits * partial_bits);
|
||||
ASSERT_EQ(result, partial_bits * full_bits);
|
||||
}
|
||||
|
||||
// Test case 2: Test carry chain propagation
|
||||
{
|
||||
int256_t carry_gen(0x8000000000000000ULL, 0x8000000000000000ULL);
|
||||
int256_t carry_prop(0x0000000000000002ULL, 0x0000000000000002ULL);
|
||||
|
||||
int256_t result = carry_gen * carry_prop;
|
||||
|
||||
// This should test carry propagation between 64-bit chunks
|
||||
ASSERT_EQ(result, carry_gen * carry_prop);
|
||||
ASSERT_EQ(result, carry_prop * carry_gen);
|
||||
}
|
||||
|
||||
// Test case 3: Mixed zero and non-zero chunks
|
||||
{
|
||||
int256_t mixed1(0xFFFFFFFFFFFFFFFFULL, 0x0000000000000000ULL);
|
||||
int256_t mixed2(0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFFULL);
|
||||
|
||||
int256_t result = mixed1 * mixed2;
|
||||
|
||||
// This tests the case where some 64-bit chunks are zero
|
||||
ASSERT_EQ(result, mixed1 * mixed2);
|
||||
ASSERT_EQ(result, mixed2 * mixed1);
|
||||
}
|
||||
|
||||
// Test case 4: Boundary values for each 64-bit chunk
|
||||
{
|
||||
int256_t boundary1(0x7FFFFFFFFFFFFFFFULL, 0x8000000000000000ULL);
|
||||
int256_t boundary2(0x8000000000000000ULL, 0x7FFFFFFFFFFFFFFFULL);
|
||||
|
||||
int256_t result = boundary1 * boundary2;
|
||||
|
||||
// This tests sign bit boundaries in each chunk
|
||||
ASSERT_EQ(result, boundary1 * boundary2);
|
||||
ASSERT_EQ(result, boundary2 * boundary1);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace starrocks
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -141,6 +141,11 @@ public class ArithmeticExpr extends Expr {
|
|||
Operator.DIVIDE.getName(),
|
||||
Lists.<Type>newArrayList(Type.DECIMAL128, Type.DECIMAL128),
|
||||
Type.DECIMAL128));
|
||||
functionSet.addBuiltin(ScalarFunction.createBuiltinOperator(
|
||||
Operator.DIVIDE.getName(),
|
||||
Lists.<Type>newArrayList(Type.DECIMAL256, Type.DECIMAL256),
|
||||
Type.DECIMAL256));
|
||||
|
||||
|
||||
// MOD(), FACTORIAL(), BITAND(), BITOR(), BITXOR(), and BITNOT() are registered as
|
||||
// builtins, see starrocks_functions.py
|
||||
|
|
@ -208,13 +213,18 @@ public class ArithmeticExpr extends Expr {
|
|||
final int lhsScale = lhsType.getScalarScale();
|
||||
final int rhsScale = rhsType.getScalarScale();
|
||||
|
||||
int maxRetPrecision = 38;
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (triple.lhsTargetType.isDecimal256() || triple.rhsTargetType.isDecimal256()) {
|
||||
maxRetPrecision = 76;
|
||||
}
|
||||
// decimal(p1, s1) + decimal(p2, s2)
|
||||
// result type = decimal(max(p1 - s1, p2 - s2) + max(s1, s2) + 1, max(s1, s2))
|
||||
int maxIntLength = Math.max(lhsPrecision - lhsScale, rhsPrecision - rhsScale);
|
||||
int retPrecision = maxIntLength + Math.max(lhsScale, rhsScale) + 1;
|
||||
int retScale = Math.max(lhsScale, rhsScale);
|
||||
// precision
|
||||
retPrecision = Math.min(retPrecision, 38);
|
||||
retPrecision = Math.min(retPrecision, maxRetPrecision);
|
||||
PrimitiveType decimalType = PrimitiveType.getDecimalPrimitiveType(retPrecision);
|
||||
decimalType = PrimitiveType.getWiderDecimalV3Type(decimalType, lhsType.getPrimitiveType());
|
||||
decimalType = PrimitiveType.getWiderDecimalV3Type(decimalType, rhsType.getPrimitiveType());
|
||||
|
|
@ -257,7 +267,12 @@ public class ArithmeticExpr extends Expr {
|
|||
case MULTIPLY:
|
||||
returnScale = lhsScale + rhsScale;
|
||||
returnPrecision = lhsPrecision + rhsPrecision;
|
||||
final int maxDecimalPrecision = PrimitiveType.getMaxPrecisionOfDecimal(PrimitiveType.DECIMAL128);
|
||||
PrimitiveType defaultMaxDecimalType = PrimitiveType.DECIMAL128;
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (result.lhsTargetType.isDecimal256() || result.rhsTargetType.isDecimal256()) {
|
||||
defaultMaxDecimalType = PrimitiveType.DECIMAL256;
|
||||
}
|
||||
final int maxDecimalPrecision = PrimitiveType.getMaxPrecisionOfDecimal(defaultMaxDecimalType);
|
||||
if (returnPrecision <= maxDecimalPrecision) {
|
||||
// returnPrecision <= 38, result never overflows, use the narrowest decimal type that can holds the result.
|
||||
// for examples:
|
||||
|
|
@ -265,6 +280,11 @@ public class ArithmeticExpr extends Expr {
|
|||
// decimal64(15,3) * decimal32(9,4) => decimal128(24,7).
|
||||
PrimitiveType commonPtype =
|
||||
ScalarType.createDecimalV3NarrowestType(returnPrecision, returnScale).getPrimitiveType();
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (defaultMaxDecimalType == PrimitiveType.DECIMAL128 && commonPtype == PrimitiveType.DECIMAL256) {
|
||||
commonPtype = PrimitiveType.DECIMAL128;
|
||||
}
|
||||
|
||||
// a common type shall never be narrower than type of lhs and rhs
|
||||
commonPtype = PrimitiveType.getWiderDecimalV3Type(commonPtype, lhsPtype);
|
||||
commonPtype = PrimitiveType.getWiderDecimalV3Type(commonPtype, rhsPtype);
|
||||
|
|
@ -279,11 +299,11 @@ public class ArithmeticExpr extends Expr {
|
|||
// for examples:
|
||||
// decimal128(23,5) * decimal64(18,4) => decimal128(38, 9).
|
||||
result.returnType =
|
||||
ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL128, maxDecimalPrecision, returnScale);
|
||||
ScalarType.createDecimalV3Type(defaultMaxDecimalType, maxDecimalPrecision, returnScale);
|
||||
result.lhsTargetType =
|
||||
ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL128, lhsPrecision, lhsScale);
|
||||
ScalarType.createDecimalV3Type(defaultMaxDecimalType, lhsPrecision, lhsScale);
|
||||
result.rhsTargetType =
|
||||
ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL128, rhsPrecision, rhsScale);
|
||||
ScalarType.createDecimalV3Type(defaultMaxDecimalType, rhsPrecision, rhsScale);
|
||||
return result;
|
||||
} else {
|
||||
// returnScale > 38, so it is cannot be represented as decimal.
|
||||
|
|
@ -292,6 +312,7 @@ public class ArithmeticExpr extends Expr {
|
|||
"Return scale(%d) exceeds maximum value(%d), please cast decimal type to low-precision one",
|
||||
returnScale, maxDecimalPrecision));
|
||||
}
|
||||
|
||||
case INT_DIVIDE:
|
||||
case DIVIDE:
|
||||
if (lhsScale <= 6) {
|
||||
|
|
@ -302,6 +323,11 @@ public class ArithmeticExpr extends Expr {
|
|||
returnScale = lhsScale;
|
||||
}
|
||||
widerType = PrimitiveType.DECIMAL128;
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (result.lhsTargetType.isDecimal256() || result.rhsTargetType.isDecimal256()) {
|
||||
widerType = PrimitiveType.DECIMAL256;
|
||||
}
|
||||
|
||||
maxPrecision = PrimitiveType.getMaxPrecisionOfDecimal(widerType);
|
||||
result.lhsTargetType = ScalarType.createDecimalV3Type(widerType, maxPrecision, lhsScale);
|
||||
result.rhsTargetType = ScalarType.createDecimalV3Type(widerType, maxPrecision, rhsScale);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ public abstract class LiteralExpr extends Expr implements Comparable<LiteralExpr
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
literalExpr = new DecimalLiteral(value);
|
||||
break;
|
||||
case CHAR:
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ public class StringLiteral extends LiteralExpr {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
return new DecimalLiteral(value).uncheckedCastTo(targetType);
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -159,7 +159,8 @@ public class TypeDef implements ParseNode {
|
|||
case DECIMALV2:
|
||||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128: {
|
||||
case DECIMAL128:
|
||||
case DECIMAL256: {
|
||||
final String name = scalarType.getPrimitiveType().name();
|
||||
final int precision = scalarType.decimalPrecision();
|
||||
final int scale = scalarType.decimalScale();
|
||||
|
|
|
|||
|
|
@ -1381,8 +1381,13 @@ public class FunctionSet {
|
|||
}
|
||||
}
|
||||
for (ScalarType type : Type.DECIMAL_TYPES) {
|
||||
Type retType = Type.DECIMAL128;
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (type.isDecimal256()) {
|
||||
retType = Type.DECIMAL256;
|
||||
}
|
||||
addBuiltin(AggregateFunction.createBuiltin(name,
|
||||
Lists.newArrayList(type), Type.DECIMAL128, Type.DECIMAL128,
|
||||
Lists.newArrayList(type), retType, retType,
|
||||
false, true, false));
|
||||
}
|
||||
addBuiltin(AggregateFunction.createBuiltin(name,
|
||||
|
|
@ -1407,8 +1412,13 @@ public class FunctionSet {
|
|||
}
|
||||
}
|
||||
for (ScalarType type : Type.DECIMAL_TYPES) {
|
||||
Type retType = Type.DECIMAL128;
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (type.isDecimal256()) {
|
||||
retType = Type.DECIMAL256;
|
||||
}
|
||||
addBuiltin(AggregateFunction.createBuiltin(MULTI_DISTINCT_SUM,
|
||||
Lists.newArrayList(type), Type.DECIMAL128, Type.VARBINARY,
|
||||
Lists.newArrayList(type), retType, Type.VARBINARY,
|
||||
false, true, false));
|
||||
}
|
||||
addBuiltin(AggregateFunction.createBuiltin(MULTI_DISTINCT_SUM,
|
||||
|
|
@ -1501,8 +1511,13 @@ public class FunctionSet {
|
|||
false, true, false));
|
||||
}
|
||||
for (ScalarType type : Type.DECIMAL_TYPES) {
|
||||
Type retType = Type.DECIMAL128;
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (type.isDecimal256()) {
|
||||
retType = Type.DECIMAL256;
|
||||
}
|
||||
addBuiltin(AggregateFunction.createBuiltin(AVG,
|
||||
Lists.newArrayList(type), Type.DECIMAL128, Type.VARBINARY,
|
||||
Lists.newArrayList(type), retType, Type.VARBINARY,
|
||||
false, true, false));
|
||||
}
|
||||
addBuiltin(AggregateFunction.createBuiltin(AVG,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ package com.starrocks.catalog;
|
|||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.starrocks.mysql.MysqlColType;
|
||||
import com.starrocks.thrift.TPrimitiveType;
|
||||
|
|
@ -144,25 +143,6 @@ public enum PrimitiveType {
|
|||
.addAll(STRING_TYPE_LIST)
|
||||
.build();
|
||||
|
||||
private static final ImmutableSortedSet<String> VARIABLE_TYPE_SET =
|
||||
ImmutableSortedSet.orderedBy(String.CASE_INSENSITIVE_ORDER)
|
||||
.add(PrimitiveType.CHAR.toString())
|
||||
.add(PrimitiveType.VARCHAR.toString())
|
||||
.add(PrimitiveType.DECIMALV2.toString())
|
||||
.add(PrimitiveType.DECIMAL32.toString())
|
||||
.add(PrimitiveType.DECIMAL64.toString())
|
||||
.add(PrimitiveType.DECIMAL128.toString())
|
||||
.add("DECIMAL") // generic name for all decimal types
|
||||
.build();
|
||||
|
||||
public static boolean isVariableType(String typeName) {
|
||||
return VARIABLE_TYPE_SET.contains(typeName);
|
||||
}
|
||||
|
||||
public static boolean isStaticType(String typeName) {
|
||||
return !VARIABLE_TYPE_SET.contains(typeName);
|
||||
}
|
||||
|
||||
static {
|
||||
ImmutableSetMultimap.Builder<PrimitiveType, PrimitiveType> builder = ImmutableSetMultimap.builder();
|
||||
builder.putAll(NULL_TYPE, BASIC_TYPE_LIST);
|
||||
|
|
@ -312,6 +292,10 @@ public enum PrimitiveType {
|
|||
*/
|
||||
public static PrimitiveType getWiderDecimalV3Type(PrimitiveType t1, PrimitiveType t2) {
|
||||
Preconditions.checkState(t1.isDecimalV3Type() && t2.isDecimalV3Type());
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (t1.equals(DECIMAL256) || t2.equals(DECIMAL256)) {
|
||||
return DECIMAL256;
|
||||
}
|
||||
if (t1.equals(DECIMAL32)) {
|
||||
return t2;
|
||||
} else if (t2.equals(DECIMAL32)) {
|
||||
|
|
@ -382,6 +366,8 @@ public enum PrimitiveType {
|
|||
return DECIMAL64;
|
||||
} else if (precision <= getMaxPrecisionOfDecimal(DECIMAL128)) {
|
||||
return DECIMAL128;
|
||||
} else if (precision <= getMaxPrecisionOfDecimal(DECIMAL256)) {
|
||||
return DECIMAL256;
|
||||
}
|
||||
Preconditions.checkState(type.isDecimalOfAnyVersion());
|
||||
return type;
|
||||
|
|
|
|||
|
|
@ -385,7 +385,9 @@ public class ScalarType extends Type implements Cloneable {
|
|||
int integerPartWidth = Math.max(lhsIntegerPartWidth, rhsIntegerPartWidth);
|
||||
int scale = Math.max(lhsScale, rhsScale);
|
||||
int precision = integerPartWidth + scale;
|
||||
if (precision > 38) {
|
||||
boolean hasDecimal256 = lhs.isDecimal256() || rhs.isDecimal256();
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if ((precision > 38 && !hasDecimal256) || (precision > 76)) {
|
||||
return ScalarType.DOUBLE;
|
||||
} else {
|
||||
// the common type's PrimitiveType of two decimal types should wide enough, i.e
|
||||
|
|
@ -422,6 +424,7 @@ public class ScalarType extends Type implements Cloneable {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
return getCommonTypeForDecimalV3(decimalType, otherType);
|
||||
|
||||
case BOOLEAN:
|
||||
|
|
|
|||
|
|
@ -318,6 +318,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[TINYINT.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[TINYINT.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[TINYINT.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[TINYINT.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[TINYINT.ordinal()][JSON.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[TINYINT.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
|
|
@ -340,6 +341,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[SMALLINT.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[SMALLINT.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[SMALLINT.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[SMALLINT.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[SMALLINT.ordinal()][JSON.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[SMALLINT.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
|
|
@ -360,6 +362,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[INT.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[INT.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[INT.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[INT.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[INT.ordinal()][JSON.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[INT.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
|
|
@ -380,6 +383,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[BIGINT.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[BIGINT.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[BIGINT.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[BIGINT.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[BIGINT.ordinal()][JSON.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[BIGINT.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
|
|
@ -398,6 +402,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[LARGEINT.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.DECIMAL32;
|
||||
compatibilityMatrix[LARGEINT.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.DECIMAL64;
|
||||
compatibilityMatrix[LARGEINT.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.DECIMAL128;
|
||||
compatibilityMatrix[LARGEINT.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.DECIMAL256;
|
||||
compatibilityMatrix[LARGEINT.ordinal()][JSON.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[LARGEINT.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
|
|
@ -415,6 +420,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[FLOAT.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[FLOAT.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[FLOAT.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[FLOAT.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[FLOAT.ordinal()][JSON.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[FLOAT.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
|
|
@ -431,6 +437,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[DOUBLE.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[DOUBLE.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[DOUBLE.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[DOUBLE.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[DOUBLE.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
// DATE
|
||||
|
|
@ -471,6 +478,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[CHAR.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[CHAR.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[CHAR.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[CHAR.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[CHAR.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
// VARCHAR
|
||||
|
|
@ -482,6 +490,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[VARCHAR.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[VARCHAR.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[VARCHAR.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[VARCHAR.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[VARCHAR.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
// DECIMALV2
|
||||
|
|
@ -502,6 +511,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[DECIMAL32.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.DECIMAL32;
|
||||
compatibilityMatrix[DECIMAL32.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.DECIMAL64;
|
||||
compatibilityMatrix[DECIMAL32.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.DECIMAL128;
|
||||
compatibilityMatrix[DECIMAL32.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.DECIMAL256;
|
||||
compatibilityMatrix[DECIMAL32.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
// DECIMAL64
|
||||
|
|
@ -512,6 +522,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[DECIMAL64.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.DECIMAL32;
|
||||
compatibilityMatrix[DECIMAL64.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.DECIMAL64;
|
||||
compatibilityMatrix[DECIMAL64.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.DECIMAL128;
|
||||
compatibilityMatrix[DECIMAL64.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.DECIMAL256;
|
||||
compatibilityMatrix[DECIMAL64.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
// DECIMAL128
|
||||
|
|
@ -524,6 +535,16 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[DECIMAL128.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.DECIMAL128;
|
||||
compatibilityMatrix[DECIMAL128.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
// DECIMAL256
|
||||
compatibilityMatrix[DECIMAL256.ordinal()][HLL.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[DECIMAL256.ordinal()][TIME.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[DECIMAL256.ordinal()][BITMAP.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[DECIMAL256.ordinal()][PERCENTILE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[DECIMAL256.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.DECIMAL32;
|
||||
compatibilityMatrix[DECIMAL256.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.DECIMAL64;
|
||||
compatibilityMatrix[DECIMAL256.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.DECIMAL128;
|
||||
compatibilityMatrix[DECIMAL256.ordinal()][UNKNOWN_TYPE.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
// HLL
|
||||
compatibilityMatrix[HLL.ordinal()][TIME.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[HLL.ordinal()][BITMAP.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
|
@ -556,6 +577,7 @@ public abstract class Type implements Cloneable {
|
|||
compatibilityMatrix[JSON.ordinal()][DECIMAL32.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[JSON.ordinal()][DECIMAL64.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[JSON.ordinal()][DECIMAL128.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
compatibilityMatrix[JSON.ordinal()][DECIMAL256.ordinal()] = PrimitiveType.INVALID_TYPE;
|
||||
|
||||
// binary type
|
||||
for (PrimitiveType type : PrimitiveType.BINARY_INCOMPATIBLE_TYPE_LIST) {
|
||||
|
|
@ -695,6 +717,10 @@ public abstract class Type implements Cloneable {
|
|||
return isDecimalV2() || isDecimalV3();
|
||||
}
|
||||
|
||||
public boolean isDecimal256() {
|
||||
return this.getPrimitiveType() == PrimitiveType.DECIMAL256;
|
||||
}
|
||||
|
||||
public boolean isStringType() {
|
||||
return PrimitiveType.STRING_TYPE_LIST.contains(this.getPrimitiveType());
|
||||
}
|
||||
|
|
@ -760,6 +786,8 @@ public abstract class Type implements Cloneable {
|
|||
return Type.DECIMAL64;
|
||||
case DECIMAL128:
|
||||
return Type.DECIMAL128;
|
||||
case DECIMAL256:
|
||||
return Type.DECIMAL256;
|
||||
case JSON:
|
||||
return Type.JSON;
|
||||
case FUNCTION:
|
||||
|
|
@ -1283,7 +1311,8 @@ public abstract class Type implements Cloneable {
|
|||
scalarType.getScale());
|
||||
} else if (scalarType.getType() == TPrimitiveType.DECIMAL32 ||
|
||||
scalarType.getType() == TPrimitiveType.DECIMAL64 ||
|
||||
scalarType.getType() == TPrimitiveType.DECIMAL128) {
|
||||
scalarType.getType() == TPrimitiveType.DECIMAL128 ||
|
||||
scalarType.getType() == TPrimitiveType.DECIMAL256) {
|
||||
Preconditions.checkState(scalarType.isSetPrecision() && scalarType.isSetScale());
|
||||
type = ScalarType.createDecimalV3Type(
|
||||
PrimitiveType.fromThrift(scalarType.getType()),
|
||||
|
|
@ -1446,6 +1475,7 @@ public abstract class Type implements Cloneable {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
return t.decimalPrecision();
|
||||
default:
|
||||
return null;
|
||||
|
|
@ -1478,6 +1508,7 @@ public abstract class Type implements Cloneable {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
return t.decimalScale();
|
||||
default:
|
||||
return null;
|
||||
|
|
@ -1512,6 +1543,7 @@ public abstract class Type implements Cloneable {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
return this;
|
||||
case FUNCTION:
|
||||
return FUNCTION;
|
||||
|
|
@ -1586,6 +1618,7 @@ public abstract class Type implements Cloneable {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
return this;
|
||||
default:
|
||||
return Type.INVALID;
|
||||
|
|
@ -1640,6 +1673,7 @@ public abstract class Type implements Cloneable {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
// precision + (scale > 0 ? 1 : 0) + (unsigned_flag || !precision ? 0 : 1));
|
||||
ScalarType decimalType = (ScalarType) this;
|
||||
int length = decimalType.getScalarPrecision();
|
||||
|
|
@ -1690,6 +1724,7 @@ public abstract class Type implements Cloneable {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
return ((ScalarType) this).getScalarScale();
|
||||
case FLOAT:
|
||||
case DOUBLE:
|
||||
|
|
|
|||
|
|
@ -416,6 +416,7 @@ public class FeExecuteCoordinator extends Coordinator {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
int scale = ((ScalarType) constantOperator.getType()).getScalarScale();
|
||||
BigDecimal val1 = constantOperator.getDecimal();
|
||||
DecimalFormat df = new DecimalFormat((scale == 0 ? "0" : "0.") + StringUtils.repeat("0", scale));
|
||||
|
|
|
|||
|
|
@ -1257,7 +1257,8 @@ public class AnalyzerUtils {
|
|||
if (convertDouble) {
|
||||
newType = ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL128, 38, 9);
|
||||
}
|
||||
} else if (PrimitiveType.DECIMAL128 == srcType.getPrimitiveType() ||
|
||||
} else if (PrimitiveType.DECIMAL256 == srcType.getPrimitiveType() ||
|
||||
PrimitiveType.DECIMAL128 == srcType.getPrimitiveType() ||
|
||||
PrimitiveType.DECIMAL64 == srcType.getPrimitiveType() ||
|
||||
PrimitiveType.DECIMAL32 == srcType.getPrimitiveType()) {
|
||||
newType = ScalarType.createDecimalV3Type(srcType.getPrimitiveType(),
|
||||
|
|
|
|||
|
|
@ -94,8 +94,9 @@ public class DecimalV3FunctionAnalyzer {
|
|||
.add(FunctionSet.MULTI_DISTINCT_SUM).build();
|
||||
|
||||
private static final ScalarType DECIMAL128P38S0 = ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL128, 38, 0);
|
||||
private static final ScalarType DECIMAL256P76S0 = ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL256, 76, 0);
|
||||
|
||||
// For decimal32/64/128 types, normalize argType's scale and precision
|
||||
// For decimal32/64/128/256 types, normalize argType's scale and precision
|
||||
private static Type[] normalizeDecimalArgTypes(final Type[] argTypes, String fnName) {
|
||||
if (argTypes == null || argTypes.length == 0) {
|
||||
return argTypes;
|
||||
|
|
@ -230,12 +231,17 @@ public class DecimalV3FunctionAnalyzer {
|
|||
// avg on decimal complies with Snowflake-style
|
||||
// avg actual processed like sum()/count(), it also has a risk of overflow if the scale is too large,
|
||||
// so we limit the maximum scale for this case
|
||||
if (((ScalarType) argType).getScalarScale() > 18) {
|
||||
int scale = ((ScalarType) argType).getScalarScale();
|
||||
ScalarType rhsType = argType.isDecimal256() ? DECIMAL256P76S0 : DECIMAL128P38S0;
|
||||
|
||||
if (argType.isDecimal256() && scale > 36) {
|
||||
argType = ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL256, 76, 36);
|
||||
} else if (!argType.isDecimal256() && scale > 18) {
|
||||
argType = ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL128, 38, 18);
|
||||
}
|
||||
|
||||
final ArithmeticExpr.TypeTriple triple =
|
||||
ArithmeticExpr.getReturnTypeOfDecimal(ArithmeticExpr.Operator.DIVIDE, (ScalarType) argType,
|
||||
DECIMAL128P38S0);
|
||||
ArithmeticExpr.getReturnTypeOfDecimal(ArithmeticExpr.Operator.DIVIDE, (ScalarType) argType, rhsType);
|
||||
returnType = triple.returnType;
|
||||
} else if (fn.functionName().equals(FunctionSet.APPROX_TOP_K)) {
|
||||
returnType = FunctionSet.APPROX_TOP_N_RET_TYPE_BUILDER.apply(argType);
|
||||
|
|
@ -244,7 +250,11 @@ public class DecimalV3FunctionAnalyzer {
|
|||
} else if (argType.isDecimalV3() && DECIMAL_SUM_FUNCTION_TYPE.contains(fn.functionName())) {
|
||||
// For decimal aggregation sum, there is a risk of overflow if the scale is too large,
|
||||
// so we limit the maximum scale for this case
|
||||
if (((ScalarType) argType).getScalarScale() > 18) {
|
||||
int scale = ((ScalarType) argType).getScalarScale();
|
||||
if (argType.isDecimal256() && scale > 36) {
|
||||
argType = ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL256, 76, 36);
|
||||
returnType = argType;
|
||||
} else if (!argType.isDecimal256() && scale > 18) {
|
||||
argType = ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL128, 38, 18);
|
||||
returnType = argType;
|
||||
}
|
||||
|
|
@ -278,10 +288,13 @@ public class DecimalV3FunctionAnalyzer {
|
|||
if (!argType.isDecimalV3()) {
|
||||
return fn;
|
||||
}
|
||||
ScalarType decimal128Type =
|
||||
ScalarType decimalType =
|
||||
ScalarType.createDecimalV3NarrowestType(38, ((ScalarType) argType).getScalarScale());
|
||||
if (argType.isDecimal256()) {
|
||||
decimalType = ScalarType.createDecimalV3NarrowestType(76, ((ScalarType) argType).getScalarScale());
|
||||
}
|
||||
AggregateFunction newFn = new AggregateFunction(
|
||||
fn.getFunctionName(), Arrays.asList(sumFn.getArgs()), decimal128Type,
|
||||
fn.getFunctionName(), Arrays.asList(sumFn.getArgs()), decimalType,
|
||||
fn.getIntermediateType(), fn.hasVarArgs());
|
||||
|
||||
newFn.setFunctionId(fn.getFunctionId());
|
||||
|
|
@ -302,10 +315,14 @@ public class DecimalV3FunctionAnalyzer {
|
|||
}
|
||||
ScalarType decimalType = (ScalarType) argType;
|
||||
AggregateFunction fn = (AggregateFunction) sumFn;
|
||||
ScalarType decimal128Type = ScalarType.createDecimalV3Type(
|
||||
ScalarType retType = ScalarType.createDecimalV3Type(
|
||||
PrimitiveType.DECIMAL128, 38, decimalType.getScalarScale());
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (argType.isDecimal256()) {
|
||||
retType = ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL256, 76, decimalType.getScalarScale());
|
||||
}
|
||||
AggregateFunction newFn = new AggregateFunction(
|
||||
fn.getFunctionName(), Collections.singletonList(decimalType), decimal128Type,
|
||||
fn.getFunctionName(), Collections.singletonList(decimalType), retType,
|
||||
fn.getIntermediateType(), fn.hasVarArgs());
|
||||
newFn.setFunctionId(fn.getFunctionId());
|
||||
newFn.setChecksum(fn.getChecksum());
|
||||
|
|
@ -421,10 +438,16 @@ public class DecimalV3FunctionAnalyzer {
|
|||
} else if (DECIMAL_AGG_FUNCTION_WIDER_TYPE.contains(fnName) && argumentTypes[0].isDecimalV3()) {
|
||||
ScalarType argScalarType = (ScalarType) argumentTypes[0];
|
||||
int precision = PrimitiveType.getMaxPrecisionOfDecimal(PrimitiveType.DECIMAL128);
|
||||
if (argScalarType.isDecimal256()) {
|
||||
precision = PrimitiveType.getMaxPrecisionOfDecimal(PrimitiveType.DECIMAL256);
|
||||
}
|
||||
int scale = argScalarType.getScalarScale();
|
||||
// TODO(by satanson): Maybe accumulating narrower decimal types to wider decimal types directly w/o
|
||||
// casting the narrower type to the wider type is sound and efficient.
|
||||
commonType = ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL128, precision, scale);
|
||||
PrimitiveType commonPrimitiveType = argScalarType.isDecimal256() ? PrimitiveType.DECIMAL256 :
|
||||
PrimitiveType.DECIMAL128;
|
||||
commonType = ScalarType.createDecimalV3Type(commonPrimitiveType, precision, scale);
|
||||
|
||||
}
|
||||
|
||||
Type argType = argumentTypes[0];
|
||||
|
|
|
|||
|
|
@ -459,6 +459,7 @@ public class ColumnDef implements ParseNode {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
DecimalLiteral decimalLiteral = new DecimalLiteral(defaultValue);
|
||||
decimalLiteral.checkPrecisionAndScale(scalarType,
|
||||
scalarType.getScalarPrecision(), scalarType.getScalarScale());
|
||||
|
|
|
|||
|
|
@ -285,6 +285,10 @@ public class TypeManager {
|
|||
if (ConnectContext.get() != null && SessionVariableConstants.DECIMAL.equalsIgnoreCase(ConnectContext.get()
|
||||
.getSessionVariable().getCboEqBaseType())) {
|
||||
baseType = Type.DEFAULT_DECIMAL128;
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
if (type1.isDecimal256() || type2.isDecimal256()) {
|
||||
baseType = Type.DEFAULT_DECIMAL256;
|
||||
}
|
||||
if (type1.isDecimalOfAnyVersion() || type2.isDecimalOfAnyVersion()) {
|
||||
baseType = type1.isDecimalOfAnyVersion() ? type1 : type2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -500,6 +500,7 @@ public class ColumnFilterConverter {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
literalExpr = new DecimalLiteral(operator.getDecimal());
|
||||
break;
|
||||
case CHAR:
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ import static com.starrocks.catalog.PrimitiveType.BOOLEAN;
|
|||
import static com.starrocks.catalog.PrimitiveType.DATE;
|
||||
import static com.starrocks.catalog.PrimitiveType.DATETIME;
|
||||
import static com.starrocks.catalog.PrimitiveType.DECIMAL128;
|
||||
import static com.starrocks.catalog.PrimitiveType.DECIMAL256;
|
||||
import static com.starrocks.catalog.PrimitiveType.DECIMAL32;
|
||||
import static com.starrocks.catalog.PrimitiveType.DECIMAL64;
|
||||
import static com.starrocks.catalog.PrimitiveType.DECIMALV2;
|
||||
|
|
@ -1037,7 +1038,8 @@ public class ScalarOperatorFunctions {
|
|||
@ConstantFunction(name = "add", argTypes = {DECIMALV2, DECIMALV2}, returnType = DECIMALV2),
|
||||
@ConstantFunction(name = "add", argTypes = {DECIMAL32, DECIMAL32}, returnType = DECIMAL32),
|
||||
@ConstantFunction(name = "add", argTypes = {DECIMAL64, DECIMAL64}, returnType = DECIMAL64),
|
||||
@ConstantFunction(name = "add", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128)
|
||||
@ConstantFunction(name = "add", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128),
|
||||
@ConstantFunction(name = "add", argTypes = {DECIMAL256, DECIMAL256}, returnType = DECIMAL256)
|
||||
})
|
||||
public static ConstantOperator addDecimal(ConstantOperator first, ConstantOperator second) {
|
||||
return createDecimalConstant(first.getDecimal().add(second.getDecimal()));
|
||||
|
|
@ -1072,7 +1074,8 @@ public class ScalarOperatorFunctions {
|
|||
@ConstantFunction(name = "subtract", argTypes = {DECIMALV2, DECIMALV2}, returnType = DECIMALV2),
|
||||
@ConstantFunction(name = "subtract", argTypes = {DECIMAL32, DECIMAL32}, returnType = DECIMAL32),
|
||||
@ConstantFunction(name = "subtract", argTypes = {DECIMAL64, DECIMAL64}, returnType = DECIMAL64),
|
||||
@ConstantFunction(name = "subtract", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128)
|
||||
@ConstantFunction(name = "subtract", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128),
|
||||
@ConstantFunction(name = "subtract", argTypes = {DECIMAL256, DECIMAL256}, returnType = DECIMAL256)
|
||||
})
|
||||
public static ConstantOperator subtractDecimal(ConstantOperator first, ConstantOperator second) {
|
||||
return createDecimalConstant(first.getDecimal().subtract(second.getDecimal()));
|
||||
|
|
@ -1103,11 +1106,13 @@ public class ScalarOperatorFunctions {
|
|||
return ConstantOperator.createDouble(first.getDouble() * second.getDouble());
|
||||
}
|
||||
|
||||
// TODO(stephen): support auto scale up decimal precision
|
||||
@ConstantFunction.List(list = {
|
||||
@ConstantFunction(name = "multiply", argTypes = {DECIMALV2, DECIMALV2}, returnType = DECIMALV2),
|
||||
@ConstantFunction(name = "multiply", argTypes = {DECIMAL32, DECIMAL32}, returnType = DECIMAL32),
|
||||
@ConstantFunction(name = "multiply", argTypes = {DECIMAL64, DECIMAL64}, returnType = DECIMAL64),
|
||||
@ConstantFunction(name = "multiply", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128)
|
||||
@ConstantFunction(name = "multiply", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128),
|
||||
@ConstantFunction(name = "multiply", argTypes = {DECIMAL256, DECIMAL256}, returnType = DECIMAL256)
|
||||
})
|
||||
public static ConstantOperator multiplyDecimal(ConstantOperator first, ConstantOperator second) {
|
||||
return createDecimalConstant(first.getDecimal().multiply(second.getDecimal()));
|
||||
|
|
@ -1130,7 +1135,8 @@ public class ScalarOperatorFunctions {
|
|||
@ConstantFunction(name = "divide", argTypes = {DECIMALV2, DECIMALV2}, returnType = DECIMALV2),
|
||||
@ConstantFunction(name = "divide", argTypes = {DECIMAL32, DECIMAL32}, returnType = DECIMAL32),
|
||||
@ConstantFunction(name = "divide", argTypes = {DECIMAL64, DECIMAL64}, returnType = DECIMAL64),
|
||||
@ConstantFunction(name = "divide", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128)
|
||||
@ConstantFunction(name = "divide", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128),
|
||||
@ConstantFunction(name = "divide", argTypes = {DECIMAL256, DECIMAL256}, returnType = DECIMAL256)
|
||||
})
|
||||
public static ConstantOperator divideDecimal(ConstantOperator first, ConstantOperator second) {
|
||||
if (BigDecimal.ZERO.compareTo(second.getDecimal()) == 0) {
|
||||
|
|
@ -1208,7 +1214,8 @@ public class ScalarOperatorFunctions {
|
|||
@ConstantFunction(name = "mod", argTypes = {DECIMALV2, DECIMALV2}, returnType = DECIMALV2),
|
||||
@ConstantFunction(name = "mod", argTypes = {DECIMAL32, DECIMAL32}, returnType = DECIMAL32),
|
||||
@ConstantFunction(name = "mod", argTypes = {DECIMAL64, DECIMAL64}, returnType = DECIMAL64),
|
||||
@ConstantFunction(name = "mod", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128)
|
||||
@ConstantFunction(name = "mod", argTypes = {DECIMAL128, DECIMAL128}, returnType = DECIMAL128),
|
||||
@ConstantFunction(name = "mod", argTypes = {DECIMAL256, DECIMAL256}, returnType = DECIMAL256)
|
||||
})
|
||||
public static ConstantOperator modDecimal(ConstantOperator first, ConstantOperator second) {
|
||||
if (BigDecimal.ZERO.compareTo(second.getDecimal()) == 0) {
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ public class FilterSelectivityEvaluator {
|
|||
case DECIMAL32:
|
||||
case DECIMAL64:
|
||||
case DECIMAL128:
|
||||
case DECIMAL256:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -282,9 +282,12 @@ public class MultiDistinctByCTERewriter {
|
|||
if (avgCallOperator.getType().isDecimalV3()) {
|
||||
// There is not need to apply ImplicitCastRule to divide operator of decimal types.
|
||||
// but we should cast BIGINT-typed countColRef into DECIMAL(38,0).
|
||||
ScalarType decimal128p38s0 = ScalarType.createDecimalV3NarrowestType(38, 0);
|
||||
ScalarType decimalType = ScalarType.createDecimalV3NarrowestType(38, 0);
|
||||
if (avgCallOperator.getType().isDecimal256()) {
|
||||
decimalType = ScalarType.createDecimalV3NarrowestType(76, 0);
|
||||
}
|
||||
distinctAvgCallOperator.getChildren().set(
|
||||
1, new CastOperator(decimal128p38s0, distinctAvgCallOperator.getChild(1), true));
|
||||
1, new CastOperator(decimalType, distinctAvgCallOperator.getChild(1), true));
|
||||
} else {
|
||||
distinctAvgCallOperator = (CallOperator) scalarRewriter.rewrite(distinctAvgCallOperator,
|
||||
Lists.newArrayList(new ImplicitCastRule()));
|
||||
|
|
|
|||
|
|
@ -119,9 +119,12 @@ public class MultiDistinctByMultiFuncRewriter {
|
|||
if (multiAvg.getType().isDecimalV3()) {
|
||||
// There is not need to apply ImplicitCastRule to divide operator of decimal types.
|
||||
// but we should cast BIGINT-typed countColRef into DECIMAL(38,0).
|
||||
ScalarType decimal128p38s0 = ScalarType.createDecimalV3NarrowestType(38, 0);
|
||||
ScalarType decimalType = ScalarType.createDecimalV3NarrowestType(38, 0);
|
||||
if (multiAvg.getType().isDecimal256()) {
|
||||
decimalType = ScalarType.createDecimalV3NarrowestType(76, 0);
|
||||
}
|
||||
multiAvg.getChildren().set(
|
||||
1, new CastOperator(decimal128p38s0, multiAvg.getChild(1), true));
|
||||
1, new CastOperator(decimalType, multiAvg.getChild(1), true));
|
||||
} else {
|
||||
multiAvg = (CallOperator) scalarRewriter.rewrite(multiAvg,
|
||||
Lists.newArrayList(new ImplicitCastRule()));
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ vectorized_functions = [
|
|||
[100470, "abs", True, False, "DECIMAL32", ["DECIMAL32"], "MathFunctions::abs_decimal32"],
|
||||
[100471, "abs", True, False, "DECIMAL64", ["DECIMAL64"], "MathFunctions::abs_decimal64"],
|
||||
[100472, "abs", True, False, "DECIMAL128", ["DECIMAL128"], "MathFunctions::abs_decimal128"],
|
||||
[100473, "abs", True, False, "DECIMAL256", ["DECIMAL256"], "MathFunctions::abs_decimal256"],
|
||||
|
||||
[10050, "sin", True, False, "DOUBLE", ["DOUBLE"], "MathFunctions::sin"],
|
||||
[10060, "asin", True, False, "DOUBLE", ["DOUBLE"], "MathFunctions::asin"],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,667 @@
|
|||
-- name: test_decimal256_aggregate_function
|
||||
DROP DATABASE IF EXISTS test_decimal256_agg_func;
|
||||
-- result:
|
||||
-- !result
|
||||
CREATE DATABASE test_decimal256_agg_func;
|
||||
-- result:
|
||||
-- !result
|
||||
USE test_decimal256_agg_func;
|
||||
-- result:
|
||||
-- !result
|
||||
DROP TABLE IF EXISTS decimal256_agg_test;
|
||||
-- result:
|
||||
-- !result
|
||||
CREATE TABLE decimal256_agg_test (
|
||||
id INT,
|
||||
category VARCHAR(10),
|
||||
p40s10 DECIMAL(40,10), -- 30 integer digits + 10 decimal digits
|
||||
p50s15 DECIMAL(50,15), -- 35 integer digits + 15 decimal digits
|
||||
p76s20 DECIMAL(76,20), -- 56 integer digits + 20 decimal digits
|
||||
p76s0 DECIMAL(76,0) -- 76 integer digits + 0 decimal digits
|
||||
) properties("replication_num"="1");
|
||||
-- result:
|
||||
-- !result
|
||||
INSERT INTO decimal256_agg_test VALUES
|
||||
(1, 'A', 100.1234567890, 100.123456789012345, 100.12345678901234567890, 100),
|
||||
(2, 'A', 100.1234567890, 100.123456789012345, 100.12345678901234567890, 100),
|
||||
(3, 'A', 100.1234567890, 100.123456789012345, 100.12345678901234567890, 100),
|
||||
|
||||
(4, 'B', 200.5555555555, 200.555555555555555, 200.55555555555555555555, 200),
|
||||
(5, 'B', 200.5555555555, 200.555555555555555, 200.55555555555555555555, 200),
|
||||
|
||||
(6, 'C', 0.0000000000, 0.000000000000000, 0.00000000000000000000, 0),
|
||||
(7, 'C', 0.0000000000, 0.000000000000000, 0.00000000000000000000, 0),
|
||||
(8, 'C', 0.0000000000, 0.000000000000000, 0.00000000000000000000, 0),
|
||||
|
||||
(9, 'D', -50.9876543210, -50.987654321098765, -50.98765432109876543210, -50),
|
||||
(10, 'D', -50.9876543210, -50.987654321098765, -50.98765432109876543210, -50),
|
||||
|
||||
(11, 'E', 300.1111111111, 300.111111111111111, 300.11111111111111111111, 300),
|
||||
(12, 'F', 400.2222222222, 400.222222222222222, 400.22222222222222222222, 400),
|
||||
(13, 'G', 500.3333333333, 500.333333333333333, 500.33333333333333333333, 500),
|
||||
|
||||
(14, 'H', 999999999999999999999999999999.9999999999,
|
||||
99999999999999999999999999999999999.999999999999999,
|
||||
99999999999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999),
|
||||
(15, 'H', 999999999999999999999999999999.9999999999,
|
||||
99999999999999999999999999999999999.999999999999999,
|
||||
99999999999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999),
|
||||
|
||||
(16, 'I', 0.0000000001, 0.000000000000001, 0.00000000000000000001, 1),
|
||||
(17, 'I', 0.0000000001, 0.000000000000001, 0.00000000000000000001, 1),
|
||||
|
||||
(18, 'J', NULL, NULL, NULL, NULL),
|
||||
(19, 'J', 600.4444444444, 600.444444444444444, 600.44444444444444444444, 600),
|
||||
|
||||
(20, 'K', 777.7777777777, 777.777777777777777, 777.77777777777777777777, 777),
|
||||
(21, 'K', 777.7777777777, 888.888888888888888, 999.99999999999999999999, 777),
|
||||
(22, 'K', 777.7777777777, 777.777777777777777, 777.77777777777777777777, 888);
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT 'Test1_COUNT_BASIC' as test_name, COUNT(*) as total_rows FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test1_COUNT_BASIC 22
|
||||
-- !result
|
||||
SELECT
|
||||
'Test1_COUNT_NON_NULL' as test_name,
|
||||
COUNT(p40s10) as count_p40s10,
|
||||
COUNT(p50s15) as count_p50s15,
|
||||
COUNT(p76s20) as count_p76s20,
|
||||
COUNT(p76s0) as count_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test1_COUNT_NON_NULL 21 21 21 21
|
||||
-- !result
|
||||
SELECT
|
||||
'Test2_SUM' as test_name,
|
||||
SUM(p40s10) as sum_p40s10,
|
||||
SUM(p50s15) as sum_p50s15,
|
||||
SUM(p76s20) as sum_p76s20,
|
||||
SUM(p76s0) as sum_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test2_SUM 2000000000000000000000000004733.9506172801 200000000000000000000000000000004845.061728391506167 200000000000000000000000000000000000000000000000000004956.17283950261728395023 20000000000000000000000000000000000000000000000000000000000000000000000004842
|
||||
-- !result
|
||||
SELECT
|
||||
'Test3_AVG' as test_name,
|
||||
AVG(p40s10) as avg_p40s10,
|
||||
AVG(p50s15) as avg_p50s15,
|
||||
AVG(p76s20) as avg_p76s20,
|
||||
AVG(p76s0) as avg_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test3_AVG 95238095238095238095238095463.521457965719 9523809523809523809523809523809754.526748971024103 9523809523809523809523809523809523809523809523809524045.53203997631510875953 2046222049275135930893159257071040935639933169755114893700828629548287.777822
|
||||
-- !result
|
||||
SELECT
|
||||
'Test4_MIN_MAX' as test_name,
|
||||
MIN(p40s10) as min_p40s10,
|
||||
MAX(p40s10) as max_p40s10,
|
||||
MIN(p50s15) as min_p50s15,
|
||||
MAX(p50s15) as max_p50s15,
|
||||
MIN(p76s20) as min_p76s20,
|
||||
MAX(p76s20) as max_p76s20,
|
||||
MIN(p76s0) as min_p76s0,
|
||||
MAX(p76s0) as max_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test4_MIN_MAX -50.9876543210 999999999999999999999999999999.9999999999 -50.987654321098765 99999999999999999999999999999999999.999999999999999 -50.98765432109876543210 99999999999999999999999999999999999999999999999999999999.99999999999999999999 -50 9999999999999999999999999999999999999999999999999999999999999999999999999999
|
||||
-- !result
|
||||
SELECT
|
||||
'Test5_GROUP_BY_CATEGORY' as test_name,
|
||||
category,
|
||||
COUNT(*) as row_count,
|
||||
SUM(p40s10) as sum_p40s10,
|
||||
AVG(p40s10) as avg_p40s10,
|
||||
MIN(p50s15) as min_p50s15,
|
||||
MAX(p76s20) as max_p76s20
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
-- result:
|
||||
Test5_GROUP_BY_CATEGORY A 3 300.3703703670 100.123456789000 100.123456789012345 100.12345678901234567890
|
||||
Test5_GROUP_BY_CATEGORY B 2 401.1111111110 200.555555555500 200.555555555555555 200.55555555555555555555
|
||||
Test5_GROUP_BY_CATEGORY C 3 0E-10 0E-12 0E-15 0E-20
|
||||
Test5_GROUP_BY_CATEGORY D 2 -101.9753086420 -50.987654321000 -50.987654321098765 -50.98765432109876543210
|
||||
Test5_GROUP_BY_CATEGORY E 1 300.1111111111 300.111111111100 300.111111111111111 300.11111111111111111111
|
||||
Test5_GROUP_BY_CATEGORY F 1 400.2222222222 400.222222222200 400.222222222222222 400.22222222222222222222
|
||||
Test5_GROUP_BY_CATEGORY G 1 500.3333333333 500.333333333300 500.333333333333333 500.33333333333333333333
|
||||
Test5_GROUP_BY_CATEGORY H 2 1999999999999999999999999999999.9999999998 999999999999999999999999999999.999999999900 99999999999999999999999999999999999.999999999999999 99999999999999999999999999999999999999999999999999999999.99999999999999999999
|
||||
Test5_GROUP_BY_CATEGORY I 2 2E-10 1.00E-10 1E-15 1E-20
|
||||
Test5_GROUP_BY_CATEGORY J 2 600.4444444444 600.444444444400 600.444444444444444 600.44444444444444444444
|
||||
Test5_GROUP_BY_CATEGORY K 3 2333.3333333331 777.777777777700 777.777777777777777 999.99999999999999999999
|
||||
-- !result
|
||||
SELECT
|
||||
'Test6_GROUP_BY_P40S10' as test_name,
|
||||
p40s10,
|
||||
COUNT(*) as row_count,
|
||||
SUM(p50s15) as sum_p50s15,
|
||||
AVG(p50s15) as avg_p50s15,
|
||||
MIN(p76s0) as min_p76s0,
|
||||
MAX(p76s0) as max_p76s0
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
GROUP BY p40s10
|
||||
ORDER BY p40s10;
|
||||
-- result:
|
||||
Test6_GROUP_BY_P40S10 -50.9876543210 2 -101.975308642197530 -50.987654321098765 -50 -50
|
||||
Test6_GROUP_BY_P40S10 0E-10 3 0E-15 0E-15 0 0
|
||||
Test6_GROUP_BY_P40S10 1E-10 2 2E-15 1E-15 1 1
|
||||
Test6_GROUP_BY_P40S10 100.1234567890 3 300.370370367037035 100.123456789012345 100 100
|
||||
Test6_GROUP_BY_P40S10 200.5555555555 2 401.111111111111110 200.555555555555555 200 200
|
||||
Test6_GROUP_BY_P40S10 300.1111111111 1 300.111111111111111 300.111111111111111 300 300
|
||||
Test6_GROUP_BY_P40S10 400.2222222222 1 400.222222222222222 400.222222222222222 400 400
|
||||
Test6_GROUP_BY_P40S10 500.3333333333 1 500.333333333333333 500.333333333333333 500 500
|
||||
Test6_GROUP_BY_P40S10 600.4444444444 1 600.444444444444444 600.444444444444444 600 600
|
||||
Test6_GROUP_BY_P40S10 777.7777777777 3 2444.444444444444442 814.814814814814814 777 888
|
||||
Test6_GROUP_BY_P40S10 999999999999999999999999999999.9999999999 2 199999999999999999999999999999999999.999999999999998 99999999999999999999999999999999999.999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test7_COUNT_DISTINCT_planner0' as test_name,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
COUNT(DISTINCT p50s15) as distinct_p50s15,
|
||||
COUNT(DISTINCT p76s20) as distinct_p76s20,
|
||||
COUNT(DISTINCT p76s0) as distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test7_COUNT_DISTINCT_planner0 11 12 12 12
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test7_COUNT_DISTINCT_planner2' as test_name,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
COUNT(DISTINCT p50s15) as distinct_p50s15,
|
||||
COUNT(DISTINCT p76s20) as distinct_p76s20,
|
||||
COUNT(DISTINCT p76s0) as distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test7_COUNT_DISTINCT_planner2 11 12 12 12
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test8_SUM_DISTINCT_planner0' as test_name,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15,
|
||||
SUM(DISTINCT p76s20) as sum_distinct_p76s20,
|
||||
SUM(DISTINCT p76s0) as sum_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test8_SUM_DISTINCT_planner0 1000000000000000000000000002828.5802469122 100000000000000000000000000000003717.469135801246910 100000000000000000000000000000000000000000000000000003828.58024691235802469121 10000000000000000000000000000000000000000000000000000000000000000000000003715
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test8_SUM_DISTINCT_planner2' as test_name,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15,
|
||||
SUM(DISTINCT p76s20) as sum_distinct_p76s20,
|
||||
SUM(DISTINCT p76s0) as sum_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test8_SUM_DISTINCT_planner2 1000000000000000000000000002828.5802469122 100000000000000000000000000000003717.469135801246910 100000000000000000000000000000000000000000000000000003828.58024691235802469121 10000000000000000000000000000000000000000000000000000000000000000000000003715
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test9_AVG_DISTINCT_planner0' as test_name,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
AVG(DISTINCT p50s15) as avg_distinct_p50s15,
|
||||
AVG(DISTINCT p76s20) as avg_distinct_p76s20,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test9_AVG_DISTINCT_planner0 90909090909090909090909091166.234567901109 8333333333333333333333333333333643.122427983437243 8333333333333333333333333333333333333333333333333333652.38168724269650205760 None
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test9_AVG_DISTINCT_planner2' as test_name,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
AVG(DISTINCT p50s15) as avg_distinct_p50s15,
|
||||
AVG(DISTINCT p76s20) as avg_distinct_p76s20,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test9_AVG_DISTINCT_planner2 90909090909090909090909091166.234567901109 8333333333333333333333333333333643.122427983437243 8333333333333333333333333333333333333333333333333333652.38168724269650205760 None
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test10_GROUP_COUNT_DISTINCT_planner0' as test_name,
|
||||
category,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
COUNT(DISTINCT p76s0) as distinct_p76s0
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
-- result:
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 A 3 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 B 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 C 3 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 D 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 E 1 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 F 1 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 G 1 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 H 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 I 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 J 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner0 K 3 1 2
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test10_GROUP_COUNT_DISTINCT_planner2' as test_name,
|
||||
category,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
COUNT(DISTINCT p76s0) as distinct_p76s0
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
-- result:
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 A 3 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 B 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 C 3 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 D 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 E 1 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 F 1 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 G 1 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 H 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 I 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 J 2 1 1
|
||||
Test10_GROUP_COUNT_DISTINCT_planner2 K 3 1 2
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test11_GROUP_SUM_DISTINCT_planner0' as test_name,
|
||||
category,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
-- result:
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 A 100.1234567890 100.123456789012345
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 B 200.5555555555 200.555555555555555
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 C 0E-10 0E-15
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 D -50.9876543210 -50.987654321098765
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 E 300.1111111111 300.111111111111111
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 F 400.2222222222 400.222222222222222
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 G 500.3333333333 500.333333333333333
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 H 999999999999999999999999999999.9999999999 99999999999999999999999999999999999.999999999999999
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 I 1E-10 1E-15
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 J 600.4444444444 600.444444444444444
|
||||
Test11_GROUP_SUM_DISTINCT_planner0 K 777.7777777777 1666.666666666666665
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test11_GROUP_SUM_DISTINCT_planner2' as test_name,
|
||||
category,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
-- result:
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 A 100.1234567890 100.123456789012345
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 B 200.5555555555 200.555555555555555
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 C 0E-10 0E-15
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 D -50.9876543210 -50.987654321098765
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 E 300.1111111111 300.111111111111111
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 F 400.2222222222 400.222222222222222
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 G 500.3333333333 500.333333333333333
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 H 999999999999999999999999999999.9999999999 99999999999999999999999999999999999.999999999999999
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 I 1E-10 1E-15
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 J 600.4444444444 600.444444444444444
|
||||
Test11_GROUP_SUM_DISTINCT_planner2 K 777.7777777777 1666.666666666666665
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test12_GROUP_AVG_DISTINCT_planner0' as test_name,
|
||||
category,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
-- result:
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 A 100.123456789000 100.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 B 200.555555555500 200.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 C 0E-12 0.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 D -50.987654321000 -50.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 E 300.111111111100 300.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 F 400.222222222200 400.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 G 500.333333333300 500.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 H 999999999999999999999999999999.999999999900 None
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 I 1.00E-10 1.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 J 600.444444444400 600.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner0 K 777.777777777700 832.500000
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test12_GROUP_AVG_DISTINCT_planner2' as test_name,
|
||||
category,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
-- result:
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 A 100.123456789000 100.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 B 200.555555555500 200.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 C 0E-12 0.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 D -50.987654321000 -50.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 E 300.111111111100 300.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 F 400.222222222200 400.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 G 500.333333333300 500.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 H 999999999999999999999999999999.999999999900 None
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 I 1.00E-10 1.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 J 600.444444444400 600.000000
|
||||
Test12_GROUP_AVG_DISTINCT_planner2 K 777.777777777700 832.500000
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test13_GROUP_BY_DECIMAL_DISTINCT_planner0' as test_name,
|
||||
p76s0,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10
|
||||
FROM decimal256_agg_test
|
||||
WHERE p76s0 IS NOT NULL
|
||||
GROUP BY p76s0
|
||||
ORDER BY p76s0;
|
||||
-- result:
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 -50 2 1 -50.9876543210 -50.987654321000
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 0 3 1 0E-10 0E-12
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 1 2 1 1E-10 1.00E-10
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 100 3 1 100.1234567890 100.123456789000
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 200 2 1 200.5555555555 200.555555555500
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 300 1 1 300.1111111111 300.111111111100
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 400 1 1 400.2222222222 400.222222222200
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 500 1 1 500.3333333333 500.333333333300
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 600 1 1 600.4444444444 600.444444444400
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 777 2 1 777.7777777777 777.777777777700
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 888 1 1 777.7777777777 777.777777777700
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner0 9999999999999999999999999999999999999999999999999999999999999999999999999999 2 1 999999999999999999999999999999.9999999999 999999999999999999999999999999.999999999900
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test13_GROUP_BY_DECIMAL_DISTINCT_planner2' as test_name,
|
||||
p76s0,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10
|
||||
FROM decimal256_agg_test
|
||||
WHERE p76s0 IS NOT NULL
|
||||
GROUP BY p76s0
|
||||
ORDER BY p76s0;
|
||||
-- result:
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 -50 2 1 -50.9876543210 -50.987654321000
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 0 3 1 0E-10 0E-12
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 1 2 1 1E-10 1.00E-10
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 100 3 1 100.1234567890 100.123456789000
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 200 2 1 200.5555555555 200.555555555500
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 300 1 1 300.1111111111 300.111111111100
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 400 1 1 400.2222222222 400.222222222200
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 500 1 1 500.3333333333 500.333333333300
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 600 1 1 600.4444444444 600.444444444400
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 777 2 1 777.7777777777 777.777777777700
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 888 1 1 777.7777777777 777.777777777700
|
||||
Test13_GROUP_BY_DECIMAL_DISTINCT_planner2 9999999999999999999999999999999999999999999999999999999999999999999999999999 2 1 999999999999999999999999999999.9999999999 999999999999999999999999999999.999999999900
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT DISTINCT 'Test14_SELECT_DISTINCT_SINGLE_planner0' as test_name, p40s10
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
ORDER BY p40s10;
|
||||
-- result:
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 -50.9876543210
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 0E-10
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 1E-10
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 100.1234567890
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 200.5555555555
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 300.1111111111
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 400.2222222222
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 500.3333333333
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 600.4444444444
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 777.7777777777
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner0 999999999999999999999999999999.9999999999
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT DISTINCT 'Test14_SELECT_DISTINCT_SINGLE_planner2' as test_name, p40s10
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
ORDER BY p40s10;
|
||||
-- result:
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 -50.9876543210
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 0E-10
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 1E-10
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 100.1234567890
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 200.5555555555
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 300.1111111111
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 400.2222222222
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 500.3333333333
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 600.4444444444
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 777.7777777777
|
||||
Test14_SELECT_DISTINCT_SINGLE_planner2 999999999999999999999999999999.9999999999
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT DISTINCT 'Test15_SELECT_DISTINCT_MULTI_planner0' as test_name, p40s10, p50s15, p76s0
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
ORDER BY p40s10, p50s15;
|
||||
-- result:
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 -50.9876543210 -50.987654321098765 -50
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 0E-10 0E-15 0
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 1E-10 1E-15 1
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 100.1234567890 100.123456789012345 100
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 200.5555555555 200.555555555555555 200
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 300.1111111111 300.111111111111111 300
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 400.2222222222 400.222222222222222 400
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 500.3333333333 500.333333333333333 500
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 600.4444444444 600.444444444444444 600
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 777.7777777777 777.777777777777777 777
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 777.7777777777 777.777777777777777 888
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 777.7777777777 888.888888888888888 777
|
||||
Test15_SELECT_DISTINCT_MULTI_planner0 999999999999999999999999999999.9999999999 99999999999999999999999999999999999.999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT DISTINCT 'Test15_SELECT_DISTINCT_MULTI_planner2' as test_name, p40s10, p50s15, p76s0
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
ORDER BY p40s10, p50s15;
|
||||
-- result:
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 -50.9876543210 -50.987654321098765 -50
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 0E-10 0E-15 0
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 1E-10 1E-15 1
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 100.1234567890 100.123456789012345 100
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 200.5555555555 200.555555555555555 200
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 300.1111111111 300.111111111111111 300
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 400.2222222222 400.222222222222222 400
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 500.3333333333 500.333333333333333 500
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 600.4444444444 600.444444444444444 600
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 777.7777777777 777.777777777777777 777
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 777.7777777777 777.777777777777777 888
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 777.7777777777 888.888888888888888 777
|
||||
Test15_SELECT_DISTINCT_MULTI_planner2 999999999999999999999999999999.9999999999 99999999999999999999999999999999999.999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test16_COMPLEX_DISTINCT_planner0' as test_name,
|
||||
COUNT(DISTINCT p40s10) as count_distinct_p40s10,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
COUNT(DISTINCT p76s0) as count_distinct_p76s0,
|
||||
SUM(DISTINCT p76s0) as sum_distinct_p76s0,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test16_COMPLEX_DISTINCT_planner0 11 1000000000000000000000000002828.5802469122 90909090909090909090909091166.234567901109 12 10000000000000000000000000000000000000000000000000000000000000000000000003715 None
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test16_COMPLEX_DISTINCT_planner2' as test_name,
|
||||
COUNT(DISTINCT p40s10) as count_distinct_p40s10,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
COUNT(DISTINCT p76s0) as count_distinct_p76s0,
|
||||
SUM(DISTINCT p76s0) as sum_distinct_p76s0,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
-- result:
|
||||
Test16_COMPLEX_DISTINCT_planner2 11 1000000000000000000000000002828.5802469122 90909090909090909090909091166.234567901109 12 10000000000000000000000000000000000000000000000000000000000000000000000003715 None
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test17_HAVING_DISTINCT_planner0' as test_name,
|
||||
p40s10,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p50s15) as distinct_p50s15,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
GROUP BY p40s10
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY p40s10;
|
||||
-- result:
|
||||
Test17_HAVING_DISTINCT_planner0 -50.9876543210 2 1 -50.987654321098765
|
||||
Test17_HAVING_DISTINCT_planner0 0E-10 3 1 0E-15
|
||||
Test17_HAVING_DISTINCT_planner0 1E-10 2 1 1E-15
|
||||
Test17_HAVING_DISTINCT_planner0 100.1234567890 3 1 100.123456789012345
|
||||
Test17_HAVING_DISTINCT_planner0 200.5555555555 2 1 200.555555555555555
|
||||
Test17_HAVING_DISTINCT_planner0 777.7777777777 3 2 1666.666666666666665
|
||||
Test17_HAVING_DISTINCT_planner0 999999999999999999999999999999.9999999999 2 1 99999999999999999999999999999999999.999999999999999
|
||||
-- !result
|
||||
set new_planner_agg_stage=2;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test17_HAVING_DISTINCT_planner2' as test_name,
|
||||
p40s10,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p50s15) as distinct_p50s15,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
GROUP BY p40s10
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY p40s10;
|
||||
-- result:
|
||||
Test17_HAVING_DISTINCT_planner2 -50.9876543210 2 1 -50.987654321098765
|
||||
Test17_HAVING_DISTINCT_planner2 0E-10 3 1 0E-15
|
||||
Test17_HAVING_DISTINCT_planner2 1E-10 2 1 1E-15
|
||||
Test17_HAVING_DISTINCT_planner2 100.1234567890 3 1 100.123456789012345
|
||||
Test17_HAVING_DISTINCT_planner2 200.5555555555 2 1 200.555555555555555
|
||||
Test17_HAVING_DISTINCT_planner2 777.7777777777 3 2 1666.666666666666665
|
||||
Test17_HAVING_DISTINCT_planner2 999999999999999999999999999999.9999999999 2 1 99999999999999999999999999999999999.999999999999999
|
||||
-- !result
|
||||
set new_planner_agg_stage=0;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test18_EMPTY_RESULT' as test_name,
|
||||
COUNT(*) as count_all,
|
||||
SUM(p40s10) as sum_p40s10,
|
||||
AVG(p40s10) as avg_p40s10,
|
||||
MIN(p50s15) as min_p50s15,
|
||||
MAX(p76s20) as max_p76s20
|
||||
FROM decimal256_agg_test
|
||||
WHERE id > 1000;
|
||||
-- result:
|
||||
Test18_EMPTY_RESULT 0 None None None None
|
||||
-- !result
|
||||
SELECT
|
||||
'Test19_NULL_ONLY' as test_name,
|
||||
COUNT(*) as count_all,
|
||||
COUNT(p40s10) as count_p40s10,
|
||||
SUM(p50s15) as sum_p50s15,
|
||||
AVG(p50s15) as avg_p50s15
|
||||
FROM decimal256_agg_test
|
||||
WHERE id = 18;
|
||||
-- result:
|
||||
Test19_NULL_ONLY 1 0 None None
|
||||
-- !result
|
||||
SELECT
|
||||
'Test20_SINGLE_ROW' as test_name,
|
||||
COUNT(*) as count_all,
|
||||
SUM(p40s10) as sum_p40s10,
|
||||
AVG(p40s10) as avg_p40s10,
|
||||
MIN(p50s15) as min_p50s15,
|
||||
MAX(p76s20) as max_p76s20
|
||||
FROM decimal256_agg_test
|
||||
WHERE id = 11;
|
||||
-- result:
|
||||
Test20_SINGLE_ROW 1 300.1111111111 300.111111111100 300.111111111111111 300.11111111111111111111
|
||||
-- !result
|
||||
|
|
@ -0,0 +1,439 @@
|
|||
-- name: test_decimal256_arithmetic_overflow
|
||||
DROP DATABASE IF EXISTS test_decimal256_overflow;
|
||||
-- result:
|
||||
-- !result
|
||||
CREATE DATABASE test_decimal256_overflow;
|
||||
-- result:
|
||||
-- !result
|
||||
USE test_decimal256_overflow;
|
||||
-- result:
|
||||
-- !result
|
||||
CREATE TABLE powers_of_2 (
|
||||
power_250 DECIMAL(76, 0)
|
||||
) PROPERTIES("replication_num"="1");
|
||||
-- result:
|
||||
-- !result
|
||||
insert into powers_of_2 select 1809251394333065553493296640760748560207343510400633813116524750123642650624;
|
||||
-- result:
|
||||
-- !result
|
||||
select cast(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495 as string) from powers_of_2;
|
||||
-- result:
|
||||
57896044618658097711785492504343953926634992332820282019728792003956564819967
|
||||
-- !result
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) as string) from powers_of_2;
|
||||
-- result:
|
||||
--57896044618658097711785492504343953926634992332820282019728792003956564819968
|
||||
-- !result
|
||||
select cast(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495 + 1 as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
select cast(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495 - 1 as string) from powers_of_2;
|
||||
-- result:
|
||||
57896044618658097711785492504343953926634992332820282019728792003956564819966
|
||||
-- !result
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * 0 as string) from powers_of_2;
|
||||
-- result:
|
||||
0
|
||||
-- !result
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * -1 as string) from powers_of_2;
|
||||
-- result:
|
||||
-57896044618658097711785492504343953926634992332820282019728792003956564819967
|
||||
-- !result
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * 2 as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * -2 as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) - 1 as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) + 1 as string) from powers_of_2;
|
||||
-- result:
|
||||
-57896044618658097711785492504343953926634992332820282019728792003956564819967
|
||||
-- !result
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * 1 as string) from powers_of_2;
|
||||
-- result:
|
||||
--57896044618658097711785492504343953926634992332820282019728792003956564819968
|
||||
-- !result
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * -1 as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * -2 as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * 2 as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * 0 as string) from powers_of_2;
|
||||
-- result:
|
||||
0
|
||||
-- !result
|
||||
select cast(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495 + (-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) as string) from powers_of_2;
|
||||
-- result:
|
||||
-1
|
||||
-- !result
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * (-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * (power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * (-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) as string) from powers_of_2;
|
||||
-- result:
|
||||
None
|
||||
-- !result
|
||||
create table test_256max_result(d1 decimal(76, 0)) PROPERTIES("replication_num"="1");
|
||||
-- result:
|
||||
-- !result
|
||||
insert into test_256max_result select 1496577676626844588240573307387100039795808514605057;
|
||||
-- result:
|
||||
-- !result
|
||||
select cast(d1 * 38685626227668133590597631 as string) from test_256max_result;
|
||||
-- result:
|
||||
57896044618658097711785492504343953926634992332820282019728792003956564819967
|
||||
-- !result
|
||||
create table test_256min_result(d1 decimal(76, 0), d2 decimal(76, 0)) PROPERTIES("replication_num"="1");
|
||||
-- result:
|
||||
-- !result
|
||||
insert into test_256min_result select 340282366920938463463374607431768211456, -170141183460469231731687303715884105728;
|
||||
-- result:
|
||||
-- !result
|
||||
select cast(d1 * d2 as string) from test_256min_result; -- 2^128 * -2^127
|
||||
|
||||
CREATE TABLE test_decimal_multiply_overflow (
|
||||
id INT,
|
||||
case_desc VARCHAR(200),
|
||||
d60_30 DECIMAL(60, 30),
|
||||
d70_20 DECIMAL(70, 20),
|
||||
d76_10 DECIMAL(76, 10),
|
||||
d76_38 DECIMAL(76, 38),
|
||||
d50_0 DECIMAL(50, 0),
|
||||
d38_0 DECIMAL(38, 0) -- Maximum 38-digit decimal number
|
||||
) PROPERTIES("replication_num"="1");
|
||||
-- result:
|
||||
--57896044618658097711785492504343953926634992332820282019728792003956564819968
|
||||
-- !result
|
||||
INSERT INTO test_decimal_multiply_overflow VALUES
|
||||
(1, 'Small values',
|
||||
1.123456789012345678901234567890,
|
||||
12.12345678901234567890,
|
||||
123.1234567890,
|
||||
0.12345678901234567890123456789012345678,
|
||||
1000,
|
||||
12345),
|
||||
|
||||
(2, 'Medium values',
|
||||
123456789012345678901234567890.123456789012345678901234567890, -- 60 digits
|
||||
12345678901234567890123456789012345678901234567890.12345678901234567890, -- 70 digits
|
||||
1234567890123456789012345678901234567890123456789012345678901234.1234567890, -- 76 digits
|
||||
12345678901234567890123456789012345678.12345678901234567890123456789012345678, -- 76 digits
|
||||
12345678901234567890123456789012345678901234567890, -- 50 digits
|
||||
12345678901234567890123456789012345678), -- 38 digits
|
||||
|
||||
(3, 'Near max positive values',
|
||||
999999999999999999999999999999.999999999999999999999999999999, -- d60_30 maximum
|
||||
99999999999999999999999999999999999999999999999999.99999999999999999999, -- d70_20 maximum
|
||||
9999999999999999999999999999999999999999999999999999999999999999.9999999999, -- d76_10 maximum
|
||||
99999999999999999999999999999999999999.99999999999999999999999999999999999999, -- d76_38 maximum
|
||||
99999999999999999999999999999999999999999999999999, -- d50_0 maximum
|
||||
99999999999999999999999999999999999999), -- d38_0 maximum (38 nines)
|
||||
|
||||
(4, 'Near max negative values',
|
||||
-999999999999999999999999999999.999999999999999999999999999999,
|
||||
-99999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
-9999999999999999999999999999999999999999999999999999999999999999.9999999999,
|
||||
-99999999999999999999999999999999999999.99999999999999999999999999999999999999,
|
||||
-99999999999999999999999999999999999999999999999999,
|
||||
-99999999999999999999999999999999999999);
|
||||
-- result:
|
||||
-- !result
|
||||
CREATE TABLE test_boundary_values (
|
||||
id INT,
|
||||
case_desc VARCHAR(200),
|
||||
-- Designed based on actual DECIMAL precision limits
|
||||
val_76_0 DECIMAL(76, 0),
|
||||
val_38_0 DECIMAL(38, 0),
|
||||
val_19_0 DECIMAL(19, 0),
|
||||
val_25_0 DECIMAL(25, 0),
|
||||
val_high_scale DECIMAL(76, 50)
|
||||
) PROPERTIES("replication_num"="1");
|
||||
-- result:
|
||||
-- !result
|
||||
INSERT INTO test_boundary_values VALUES
|
||||
(1, 'Near 76-digit decimal max',
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999, -- 76 nines
|
||||
99999999999999999999999999999999999999, -- 38 nines
|
||||
9999999999999999999, -- 19 nines
|
||||
9999999999999999999999999, -- 25 nines
|
||||
0.00000000000000000000000000000000000000000000000001),
|
||||
|
||||
(2, 'Near 76-digit decimal min',
|
||||
-9999999999999999999999999999999999999999999999999999999999999999999999999999,
|
||||
-99999999999999999999999999999999999999,
|
||||
-9999999999999999999,
|
||||
-9999999999999999999999999,
|
||||
-0.00000000000000000000000000000000000000000000000001),
|
||||
|
||||
(3, 'Multiplication overflow test values',
|
||||
1000000000000000000000000000000000000000000000000000000000000000000000000000, -- 76-digit 10^75
|
||||
10000000000000000000000000000000000000, -- 38-digit 10^37
|
||||
1000000000000000000, -- 19-digit 10^18
|
||||
1000000000000000000000000, -- 25-digit 10^24
|
||||
0.00000000000000000000000000000000000000000000000001),
|
||||
|
||||
(4, 'Medium size values',
|
||||
5000000000000000000000000000000000000000000000000000000000000000000000000000, -- 76-digit 5*10^75
|
||||
50000000000000000000000000000000000000, -- 38-digit 5*10^37
|
||||
5000000000000000000, -- 19-digit 5*10^18
|
||||
5000000000000000000000000, -- 25-digit 5*10^24
|
||||
0.50000000000000000000000000000000000000000000000000);
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 1.1: 76-digit max * 76-digit max (definite overflow)' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * val_76_0 as string) as result,
|
||||
'Should overflow: 10^75 * 10^75 = 10^150, way beyond int256' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 1.1: 76-digit max * 76-digit max (definite overflow) 9999999999999999999999999999999999999999999999999999999999999999999999999999 None Should overflow: 10^75 * 10^75 = 10^150, way beyond int256
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 1.2: 38-digit max * 38-digit max (may overflow)' as test_case,
|
||||
cast(val_38_0 as string),
|
||||
cast(cast(val_38_0 as decimal(76, 0)) * val_38_0 as string) as result,
|
||||
'not overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 1.2: 38-digit max * 38-digit max (may overflow) 99999999999999999999999999999999999999 9999999999999999999999999999999999999800000000000000000000000000000000000001 not overflow
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 1.3: 19-digit * 19-digit (should not overflow)' as test_case,
|
||||
cast(val_19_0 as string),
|
||||
cast(val_19_0 * val_19_0 as string) as result,
|
||||
'Should not overflow: 10^18 * 10^18 = 10^36, within int256' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 1.3: 19-digit * 19-digit (should not overflow) 9999999999999999999 99999999999999999980000000000000000001 Should not overflow: 10^18 * 10^18 = 10^36, within int256
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 1.4: Large value * 2' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 2 as string) as result,
|
||||
'Should overflow: near-max * 2' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 1.4: Large value * 2 9999999999999999999999999999999999999999999999999999999999999999999999999999 19999999999999999999999999999999999999999999999999999999999999999999999999998 Should overflow: near-max * 2
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 1.5: Large value * 5' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 5 as string) as result,
|
||||
'Should overflow: near-max * 5' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 1.5: Large value * 5 9999999999999999999999999999999999999999999999999999999999999999999999999999 49999999999999999999999999999999999999999999999999999999999999999999999999995 Should overflow: near-max * 5
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 1.6: Large value * 5.1' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 5.1 as string) as result,
|
||||
'Should overflow: near-max * 5.1' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 1.6: Large value * 5.1 9999999999999999999999999999999999999999999999999999999999999999999999999999 None Should overflow: near-max * 5.1
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 1.7: Large value * 6' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 6 as string) as result,
|
||||
'Should overflow: near-max * 6' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 1.7: Large value * 6 9999999999999999999999999999999999999999999999999999999999999999999999999999 None Should overflow: near-max * 6
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 2.1: Large negative * Large negative (positive overflow)' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * val_76_0 as string) as result,
|
||||
'Should overflow: (-10^75) * (-10^75) = +10^150' as expected
|
||||
FROM test_boundary_values WHERE id = 2;
|
||||
-- result:
|
||||
Test 2.1: Large negative * Large negative (positive overflow) -9999999999999999999999999999999999999999999999999999999999999999999999999999 None Should overflow: (-10^75) * (-10^75) = +10^150
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 2.2: Large negative * Large positive (negative overflow)' as test_case,
|
||||
cast(a.val_76_0 as string) as neg_val,
|
||||
cast(b.val_76_0 as string) as pos_val,
|
||||
cast(a.val_76_0 * b.val_76_0 as string) as result,
|
||||
'Should overflow: (-10^75) * (+10^75) = -10^150' as expected
|
||||
FROM test_boundary_values a, test_boundary_values b
|
||||
WHERE a.id = 2 AND b.id = 1;
|
||||
-- result:
|
||||
Test 2.2: Large negative * Large positive (negative overflow) -9999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999 None Should overflow: (-10^75) * (+10^75) = -10^150
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 2.3: Negative boundary * 5' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 5 as string) as result,
|
||||
'Should not overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 2;
|
||||
-- result:
|
||||
Test 2.3: Negative boundary * 5 -9999999999999999999999999999999999999999999999999999999999999999999999999999 -49999999999999999999999999999999999999999999999999999999999999999999999999995 Should not overflow
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 2.4: Negative boundary * 6' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 6 as string) as result,
|
||||
'Should overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 2;
|
||||
-- result:
|
||||
Test 2.4: Negative boundary * 6 -9999999999999999999999999999999999999999999999999999999999999999999999999999 None Should overflow
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 3.1: 76-digit * 38-digit' as test_case,
|
||||
cast(a.val_76_0 as string),
|
||||
cast(b.val_38_0 as string),
|
||||
cast(a.val_76_0 * b.val_38_0 as string) as result,
|
||||
'Should overflow: 10^75 * 10^37 = 10^112' as expected
|
||||
FROM test_boundary_values a, test_boundary_values b
|
||||
WHERE a.id = 1 AND b.id = 1;
|
||||
-- result:
|
||||
Test 3.1: 76-digit * 38-digit 9999999999999999999999999999999999999999999999999999999999999999999999999999 99999999999999999999999999999999999999 None Should overflow: 10^75 * 10^37 = 10^112
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 3.2: 38-digit * 25-digit' as test_case,
|
||||
cast(a.val_38_0 as string),
|
||||
cast(b.val_25_0 as string),
|
||||
cast(a.val_38_0 * b.val_25_0 as string) as result,
|
||||
'overflow' as expected
|
||||
FROM test_boundary_values a, test_boundary_values b
|
||||
WHERE a.id = 1 AND b.id = 1;
|
||||
-- result:
|
||||
Test 3.2: 38-digit * 25-digit 99999999999999999999999999999999999999 9999999999999999999999999 None overflow
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 3.2: 38-digit * 25-digit' as test_case,
|
||||
cast(a.val_38_0 as string),
|
||||
cast(b.val_25_0 as string),
|
||||
cast(cast(a.val_38_0 as decimal(50, 10)) * b.val_25_0 as string) as result,
|
||||
'should not overflow' as expected
|
||||
FROM test_boundary_values a, test_boundary_values b
|
||||
WHERE a.id = 1 AND b.id = 1;
|
||||
-- result:
|
||||
Test 3.2: 38-digit * 25-digit 99999999999999999999999999999999999999 9999999999999999999999999 999999999999999999999999899999999999990000000000000000000000001.0000000000 should not overflow
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 3.3: 25-digit * 25-digit' as test_case,
|
||||
cast(val_25_0 as string),
|
||||
cast(val_25_0 * val_25_0 as string) as result,
|
||||
'overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 3.3: 25-digit * 25-digit 9999999999999999999999999 None overflow
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 3.3: 25-digit * 25-digit' as test_case,
|
||||
cast(val_25_0 as string),
|
||||
cast(val_25_0 * cast(val_25_0 as decimal(39, 0)) as string) as result,
|
||||
'should not overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 3.3: 25-digit * 25-digit 9999999999999999999999999 99999999999999999999999980000000000000000000000001 should not overflow
|
||||
-- !result
|
||||
CREATE TABLE test_progressive_boundary (
|
||||
id INT,
|
||||
digits INT,
|
||||
test_val DECIMAL(76, 0)
|
||||
) PROPERTIES("replication_num"="1");
|
||||
-- result:
|
||||
-- !result
|
||||
INSERT INTO test_progressive_boundary VALUES
|
||||
(1, 10, 9999999999), -- 10 digits
|
||||
(2, 15, 999999999999999), -- 15 digits
|
||||
(3, 20, 99999999999999999999), -- 20 digits
|
||||
(4, 25, 9999999999999999999999999), -- 25 digits
|
||||
(5, 30, 999999999999999999999999999999), -- 30 digits
|
||||
(6, 35, 99999999999999999999999999999999999), -- 35 digits
|
||||
(7, 38, 99999999999999999999999999999999999999); -- 38 digits
|
||||
|
||||
SELECT
|
||||
id,
|
||||
digits,
|
||||
cast(test_val as string),
|
||||
cast(test_val * test_val as string) as result,
|
||||
CASE
|
||||
WHEN digits <= 19 THEN 'Should succeed'
|
||||
WHEN digits <= 25 THEN 'May succeed'
|
||||
WHEN digits > 30 THEN 'Should succeed'
|
||||
ELSE 'Boundary case'
|
||||
END as expected
|
||||
FROM test_progressive_boundary ORDER BY id;
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 5.1: Scale overflow, tiny value' as test_case,
|
||||
cast(val_high_scale * val_high_scale as string) as result,
|
||||
'Should fail due to scale=100 > 76' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
E: (1064, 'Getting analyzing error. Detail message: Return scale(100) exceeds maximum value(76), please cast decimal type to low-precision one.')
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 5.2: Value overflow, scale OK' as test_case,
|
||||
cast(val_38_0 * val_38_0 as string) as result,
|
||||
'Should fail due to value overflow, scale=0 is fine' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 5.2: Value overflow, scale OK None Should fail due to value overflow, scale=0 is fine
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 6.1: Large * 0' as test_case,
|
||||
cast(val_76_0 * 0 as string) as result,
|
||||
'Should return 0, no overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 6.1: Large * 0 0 Should return 0, no overflow
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 6.2: Large * 1' as test_case,
|
||||
cast(val_76_0 * 1 as string) as result,
|
||||
'Should return original value' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 6.2: Large * 1 9999999999999999999999999999999999999999999999999999999999999999999999999999 Should return original value
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 6.3: Large * 0.1' as test_case,
|
||||
cast(val_76_0 * 0.1 as string) as result,
|
||||
'Should succeed, reduces magnitude' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 6.3: Large * 0.1 999999999999999999999999999999999999999999999999999999999999999999999999999.9 Should succeed, reduces magnitude
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 6.4: Large * -1' as test_case,
|
||||
cast(val_76_0 * (-1) as string) as result,
|
||||
'Should return negative of original' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
-- result:
|
||||
Test 6.4: Large * -1 -9999999999999999999999999999999999999999999999999999999999999999999999999999 Should return negative of original
|
||||
-- !result
|
||||
SELECT
|
||||
'Test 7.2: Scientific calculation' as test_case,
|
||||
cast(d76_10 * d76_10 as string) as result,
|
||||
'Simulates scientific computation overflow' as expected
|
||||
FROM test_decimal_multiply_overflow WHERE id = 3;
|
||||
-- result:
|
||||
Test 7.2: Scientific calculation None Simulates scientific computation overflow
|
||||
-- !result
|
||||
|
|
@ -0,0 +1,656 @@
|
|||
-- name: test_decimal256_cast_operations
|
||||
DROP DATABASE IF EXISTS test_decimal256_cast;
|
||||
-- result:
|
||||
-- !result
|
||||
CREATE DATABASE test_decimal256_cast;
|
||||
-- result:
|
||||
-- !result
|
||||
USE test_decimal256_cast;
|
||||
-- result:
|
||||
-- !result
|
||||
CREATE TABLE cast_test_source (
|
||||
id int,
|
||||
bool_val boolean,
|
||||
tinyint_val tinyint,
|
||||
smallint_val smallint,
|
||||
int_val int,
|
||||
bigint_val bigint,
|
||||
largeint_val largeint,
|
||||
float_val float,
|
||||
double_val double,
|
||||
varchar_val varchar(100),
|
||||
-- decimal256 columns for testing (precision > 38, <= 76)
|
||||
decimal256_50_15 decimal(50,15), -- 50 digits total, 15 after decimal
|
||||
decimal256_76_20 decimal(76,20), -- 76 digits total, 20 after decimal
|
||||
decimal256_76_0 decimal(76,0), -- 76 digits total, 0 after decimal
|
||||
-- regular decimal columns for comparison (precision <= 38)
|
||||
decimal_38_10 decimal(38,10), -- 38 digits total, 10 after decimal
|
||||
decimal_20_5 decimal(20,5) -- 20 digits total, 5 after decimal
|
||||
) ENGINE=OLAP
|
||||
DUPLICATE KEY(id)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
);
|
||||
-- result:
|
||||
-- !result
|
||||
INSERT INTO cast_test_source VALUES
|
||||
(1, true, 127, 32767, 2147483647, 9223372036854775807, 170141183460469231731687303715884105727,
|
||||
3.14159, 2.718281828459045, '12345678901234567890123456789012345.123456789012345',
|
||||
12345678901234567890123456789012345.123456789012345, -- 35+15=50 digits
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890, -- 56+20=76 digits
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456, -- 76 digits
|
||||
1234567890123456789012345678.1234567890, -- 28+10=38 digits
|
||||
123456789012345.12345), -- 15+5=20 digits
|
||||
|
||||
(2, false, 0, 0, 0, 0, 0, 0.0, 0.0, '0',
|
||||
0.000000000000000,
|
||||
0.00000000000000000000,
|
||||
0,
|
||||
0.0000000000,
|
||||
0.00000),
|
||||
|
||||
(3, false, -128, -32768, -2147483648, -9223372036854775808, -170141183460469231731687303715884105728,
|
||||
-3.14159, -2.718281828459045, '-87654321098765432109876543210987654.987654321098765',
|
||||
-87654321098765432109876543210987654.987654321098765, -- 35+15=50 digits
|
||||
-87654321098765432109876543210987654321098765432109876543.98765432109876543210, -- 56+20=76 digits
|
||||
-8765432109876543210987654321098765432109876543210987654321098765432109876543, -- 76 digits
|
||||
-8765432109876543210987654321.9876543210, -- 28+10=38 digits
|
||||
-876543210987654.98765), -- 15+5=20 digits
|
||||
|
||||
(4, true, 127, 32767, 2147483647, 9223372036854775807, 170141183460469231731687303715884105727,
|
||||
1.7976931348623157e+308, 1.7976931348623157e+308, '99999999999999999999999999999999999.999999999999999',
|
||||
99999999999999999999999999999999999.999999999999999, -- 35+15=50 digits
|
||||
99999999999999999999999999999999999999999999999999999999.99999999999999999999, -- 56+20=76 digits
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999, -- 76 digits
|
||||
9999999999999999999999999999.9999999999, -- 28+10=38 digits
|
||||
999999999999999.99999), -- 15+5=20 digits
|
||||
|
||||
(5, false, -128, -32768, -2147483648, -9223372036854775808, -170141183460469231731687303715884105728,
|
||||
-1.7976931348623157e+308, -1.7976931348623157e+308, '-99999999999999999999999999999999999.999999999999999',
|
||||
-99999999999999999999999999999999999.999999999999999, -- 35+15=50 digits
|
||||
-99999999999999999999999999999999999999999999999999999999.99999999999999999999, -- 56+20=76 digits
|
||||
-9999999999999999999999999999999999999999999999999999999999999999999999999999, -- 76 digits
|
||||
-9999999999999999999999999999.9999999999, -- 28+10=38 digits
|
||||
-999999999999999.99999), -- 15+5=20 digits
|
||||
|
||||
(6, true, 1, 1, 1, 1, 1, 0.000001, 0.000000000000001, '0.000000000000001',
|
||||
0.000000000000001,
|
||||
0.00000000000000000001,
|
||||
1,
|
||||
0.0000000001,
|
||||
0.00001),
|
||||
|
||||
(7, false, 42, 1234, 567890, 123456789012345, 987654321098765432109876543210,
|
||||
123.456789, 987.654321123456789, '555555555555555555555555555555555.555555555555555',
|
||||
55555555555555555555555555555555555.555555555555555, -- 35+15=50 digits
|
||||
55555555555555555555555555555555555555555555555555555555.55555555555555555555, -- 56+20=76 digits
|
||||
5555555555555555555555555555555555555555555555555555555555555555555555555555, -- 76 digits
|
||||
5555555555555555555555555555.5555555555, -- 28+10=38 digits
|
||||
555555555555555.55555), -- 15+5=20 digits
|
||||
|
||||
(8, true, 1, 10, 100, 1000, 10000,
|
||||
1e-10, 1e-15, '0.000000000000001',
|
||||
0.000000000000001,
|
||||
0.00000000000000000001,
|
||||
1,
|
||||
0.0000000001,
|
||||
0.00001),
|
||||
|
||||
(9, false, 99, 9999, 999999999, 999999999999999999, 99999999999999999999999999999999999999,
|
||||
999999.999999, 999999999.999999999999, '77777777777777777777777777777777777.777777777777777',
|
||||
77777777777777777777777777777777777.777777777777777, -- 35+15=50 digits
|
||||
77777777777777777777777777777777777777777777777777777777.77777777777777777777, -- 56+20=76 digits
|
||||
7777777777777777777777777777777777777777777777777777777777777777777777777777, -- 76 digits
|
||||
7777777777777777777777777777.7777777777, -- 28+10=38 digits
|
||||
777777777777777.77777), -- 15+5=20 digits
|
||||
|
||||
(10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
bool_val,
|
||||
CAST(bool_val AS decimal(50,15)) as bool_to_decimal256_50_15,
|
||||
CAST(bool_val AS decimal(76,20)) as bool_to_decimal256_76_20,
|
||||
CAST(bool_val AS decimal(76,0)) as bool_to_decimal256_76_0,
|
||||
CAST(bool_val AS decimal(38,10)) as bool_to_decimal_38_10
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 1 1.000000000000000 1.00000000000000000000 1 1.0000000000
|
||||
2 0 0E-15 0E-20 0 0E-10
|
||||
3 0 0E-15 0E-20 0 0E-10
|
||||
4 1 1.000000000000000 1.00000000000000000000 1 1.0000000000
|
||||
5 0 0E-15 0E-20 0 0E-10
|
||||
6 1 1.000000000000000 1.00000000000000000000 1 1.0000000000
|
||||
7 0 0E-15 0E-20 0 0E-10
|
||||
8 1 1.000000000000000 1.00000000000000000000 1 1.0000000000
|
||||
9 0 0E-15 0E-20 0 0E-10
|
||||
10 None None None None None
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
tinyint_val,
|
||||
CAST(tinyint_val AS decimal(50,15)) as tinyint_to_decimal256,
|
||||
smallint_val,
|
||||
CAST(smallint_val AS decimal(50,15)) as smallint_to_decimal256,
|
||||
int_val,
|
||||
CAST(int_val AS decimal(50,15)) as int_to_decimal256
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 127 127.000000000000000 32767 32767.000000000000000 2147483647 2147483647.000000000000000
|
||||
2 0 0E-15 0 0E-15 0 0E-15
|
||||
3 -128 -128.000000000000000 -32768 -32768.000000000000000 -2147483648 -2147483648.000000000000000
|
||||
4 127 127.000000000000000 32767 32767.000000000000000 2147483647 2147483647.000000000000000
|
||||
5 -128 -128.000000000000000 -32768 -32768.000000000000000 -2147483648 -2147483648.000000000000000
|
||||
6 1 1.000000000000000 1 1.000000000000000 1 1.000000000000000
|
||||
7 42 42.000000000000000 1234 1234.000000000000000 567890 567890.000000000000000
|
||||
8 1 1.000000000000000 10 10.000000000000000 100 100.000000000000000
|
||||
9 99 99.000000000000000 9999 9999.000000000000000 999999999 999999999.000000000000000
|
||||
10 None None None None None None
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
bigint_val,
|
||||
CAST(bigint_val AS decimal(76,20)) as bigint_to_decimal256,
|
||||
largeint_val,
|
||||
CAST(largeint_val AS decimal(76,0)) as largeint_to_decimal256
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 9223372036854775807 9223372036854775807.00000000000000000000 170141183460469231731687303715884105727 170141183460469231731687303715884105727
|
||||
2 0 0E-20 0 0
|
||||
3 -9223372036854775808 -9223372036854775808.00000000000000000000 -170141183460469231731687303715884105728 -170141183460469231731687303715884105728
|
||||
4 9223372036854775807 9223372036854775807.00000000000000000000 170141183460469231731687303715884105727 170141183460469231731687303715884105727
|
||||
5 -9223372036854775808 -9223372036854775808.00000000000000000000 -170141183460469231731687303715884105728 -170141183460469231731687303715884105728
|
||||
6 1 1.00000000000000000000 1 1
|
||||
7 123456789012345 123456789012345.00000000000000000000 987654321098765432109876543210 987654321098765432109876543210
|
||||
8 1000 1000.00000000000000000000 10000 10000
|
||||
9 999999999999999999 999999999999999999.00000000000000000000 99999999999999999999999999999999999999 99999999999999999999999999999999999999
|
||||
10 None None None None
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
float_val,
|
||||
CAST(float_val AS decimal(50,15)) as float_to_decimal256_50_15,
|
||||
CAST(float_val AS decimal(76,20)) as float_to_decimal256_76_20,
|
||||
double_val,
|
||||
CAST(double_val AS decimal(50,15)) as double_to_decimal256_50_15,
|
||||
CAST(double_val AS decimal(76,20)) as double_to_decimal256_76_20
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 3.14159 3.141590118408203 3.14159011840820314112 2.718281828459045 2.718281828459045 2.71828182845904519168
|
||||
2 0.0 0E-15 0E-20 0.0 0E-15 0E-20
|
||||
3 -3.14159 -3.141590118408203 -3.14159011840820314112 -2.718281828459045 -2.718281828459045 -2.71828182845904519168
|
||||
4 inf None None 1.7976931348623157e+308 None None
|
||||
5 -inf None None -1.7976931348623157e+308 None None
|
||||
6 1e-06 9.99999997E-7 9.9999999747524E-7 1e-15 1E-15 1.00000E-15
|
||||
7 123.45679 123.456787109375008 123.45678710937499992064 987.6543211234568 987.654321123456896 987.65432112345690144768
|
||||
8 1e-10 1.00000E-10 1.0000000134E-10 1e-15 1E-15 1.00000E-15
|
||||
9 1000000.0 1000000.000000000000000 1000000.00000000004764729344 1000000000.0 999999999.999999983222784 999999999.99999991433150857216
|
||||
10 None None None None None None
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
varchar_val,
|
||||
CAST(varchar_val AS decimal(50,15)) as varchar_to_decimal256_50_15,
|
||||
CAST(varchar_val AS decimal(76,20)) as varchar_to_decimal256_76_20,
|
||||
CAST(varchar_val AS decimal(76,0)) as varchar_to_decimal256_76_0
|
||||
FROM cast_test_source
|
||||
WHERE varchar_val IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 12345678901234567890123456789012345.123456789012345 12345678901234567890123456789012345.123456789012345 12345678901234567890123456789012345.12345678901234500000 12345678901234567890123456789012345
|
||||
2 0 0E-15 0E-20 0
|
||||
3 -87654321098765432109876543210987654.987654321098765 -87654321098765432109876543210987654.987654321098765 -87654321098765432109876543210987654.98765432109876500000 -87654321098765432109876543210987655
|
||||
4 99999999999999999999999999999999999.999999999999999 99999999999999999999999999999999999.999999999999999 99999999999999999999999999999999999.99999999999999900000 100000000000000000000000000000000000
|
||||
5 -99999999999999999999999999999999999.999999999999999 -99999999999999999999999999999999999.999999999999999 -99999999999999999999999999999999999.99999999999999900000 -100000000000000000000000000000000000
|
||||
6 0.000000000000001 1E-15 1.00000E-15 0
|
||||
7 555555555555555555555555555555555.555555555555555 555555555555555555555555555555555.555555555555555 555555555555555555555555555555555.55555555555555500000 555555555555555555555555555555556
|
||||
8 0.000000000000001 1E-15 1.00000E-15 0
|
||||
9 77777777777777777777777777777777777.777777777777777 77777777777777777777777777777777777.777777777777777 77777777777777777777777777777777777.77777777777777700000 77777777777777777777777777777777778
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15,
|
||||
CAST(decimal256_50_15 AS boolean) as decimal256_to_bool,
|
||||
CAST(decimal256_50_15 AS tinyint) as decimal256_to_tinyint,
|
||||
CAST(decimal256_50_15 AS smallint) as decimal256_to_smallint,
|
||||
CAST(decimal256_50_15 AS int) as decimal256_to_int,
|
||||
CAST(decimal256_50_15 AS bigint) as decimal256_to_bigint,
|
||||
CAST(decimal256_50_15 AS largeint) as decimal256_to_largeint
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 12345678901234567890123456789012345.123456789012345 1 None None None None 12345678901234567890123456789012345
|
||||
2 0E-15 0 0 0 0 0 0
|
||||
3 -87654321098765432109876543210987654.987654321098765 1 None None None None -87654321098765432109876543210987654
|
||||
4 99999999999999999999999999999999999.999999999999999 1 None None None None 99999999999999999999999999999999999
|
||||
5 -99999999999999999999999999999999999.999999999999999 1 None None None None -99999999999999999999999999999999999
|
||||
6 1E-15 1 0 0 0 0 0
|
||||
7 55555555555555555555555555555555555.555555555555555 1 None None None None 55555555555555555555555555555555555
|
||||
8 1E-15 1 0 0 0 0 0
|
||||
9 77777777777777777777777777777777777.777777777777777 1 None None None None 77777777777777777777777777777777777
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_76_20,
|
||||
CAST(decimal256_76_20 AS float) as decimal256_to_float,
|
||||
CAST(decimal256_76_20 AS double) as decimal256_to_double,
|
||||
CAST(decimal256_76_20 AS varchar(100)) as decimal256_to_varchar
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_76_20 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 12345678901234567890123456789012345678901234567890123456.12345678901234567890 inf 1.234567890123457e+55 12345678901234567890123456789012345678901234567890123456.12345678901234567890
|
||||
2 0E-20 0.0 0.0 0.00000000000000000000
|
||||
3 -87654321098765432109876543210987654321098765432109876543.98765432109876543210 -inf -8.765432109876543e+55 -87654321098765432109876543210987654321098765432109876543.98765432109876543210
|
||||
4 99999999999999999999999999999999999999999999999999999999.99999999999999999999 inf 1e+56 99999999999999999999999999999999999999999999999999999999.99999999999999999999
|
||||
5 -99999999999999999999999999999999999999999999999999999999.99999999999999999999 -inf -1e+56 -99999999999999999999999999999999999999999999999999999999.99999999999999999999
|
||||
6 1E-20 1e-20 1e-20 0.00000000000000000001
|
||||
7 55555555555555555555555555555555555555555555555555555555.55555555555555555555 inf 5.555555555555556e+55 55555555555555555555555555555555555555555555555555555555.55555555555555555555
|
||||
8 1E-20 1e-20 1e-20 0.00000000000000000001
|
||||
9 77777777777777777777777777777777777777777777777777777777.77777777777777777777 inf 7.777777777777777e+55 77777777777777777777777777777777777777777777777777777777.77777777777777777777
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15,
|
||||
CAST(decimal256_50_15 AS decimal(76,20)) as decimal256_50_15_to_76_20,
|
||||
CAST(decimal256_50_15 AS decimal(76,0)) as decimal256_50_15_to_76_0,
|
||||
CAST(decimal256_50_15 AS decimal(38,10)) as decimal256_50_15_to_38_10,
|
||||
decimal256_76_20,
|
||||
CAST(decimal256_76_20 AS decimal(50,15)) as decimal256_76_20_to_50_15,
|
||||
CAST(decimal256_76_20 AS decimal(76,0)) as decimal256_76_20_to_76_0
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 12345678901234567890123456789012345.123456789012345 12345678901234567890123456789012345.12345678901234500000 12345678901234567890123456789012345 None 12345678901234567890123456789012345678901234567890123456.12345678901234567890 12345678901234567890123456789012345678901234567890123456.123456789012346 12345678901234567890123456789012345678901234567890123456
|
||||
2 0E-15 0E-20 0 0E-10 0E-20 0E-15 0
|
||||
3 -87654321098765432109876543210987654.987654321098765 -87654321098765432109876543210987654.98765432109876500000 -87654321098765432109876543210987655 None -87654321098765432109876543210987654321098765432109876543.98765432109876543210 -87654321098765432109876543210987654321098765432109876543.987654321098765 -87654321098765432109876543210987654321098765432109876544
|
||||
4 99999999999999999999999999999999999.999999999999999 99999999999999999999999999999999999.99999999999999900000 100000000000000000000000000000000000 None 99999999999999999999999999999999999999999999999999999999.99999999999999999999 100000000000000000000000000000000000000000000000000000000.000000000000000 100000000000000000000000000000000000000000000000000000000
|
||||
5 -99999999999999999999999999999999999.999999999999999 -99999999999999999999999999999999999.99999999999999900000 -100000000000000000000000000000000000 None -99999999999999999999999999999999999999999999999999999999.99999999999999999999 -100000000000000000000000000000000000000000000000000000000.000000000000000 -100000000000000000000000000000000000000000000000000000000
|
||||
6 1E-15 1.00000E-15 0 0E-10 1E-20 0E-15 0
|
||||
7 55555555555555555555555555555555555.555555555555555 55555555555555555555555555555555555.55555555555555500000 55555555555555555555555555555555556 None 55555555555555555555555555555555555555555555555555555555.55555555555555555555 55555555555555555555555555555555555555555555555555555555.555555555555556 55555555555555555555555555555555555555555555555555555556
|
||||
8 1E-15 1.00000E-15 0 0E-10 1E-20 0E-15 0
|
||||
9 77777777777777777777777777777777777.777777777777777 77777777777777777777777777777777777.77777777777777700000 77777777777777777777777777777777778 None 77777777777777777777777777777777777777777777777777777777.77777777777777777777 77777777777777777777777777777777777777777777777777777777.777777777777778 77777777777777777777777777777777777777777777777777777778
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal_38_10,
|
||||
CAST(decimal_38_10 AS decimal(50,15)) as decimal_38_10_to_decimal256_50_15,
|
||||
CAST(decimal_38_10 AS decimal(76,20)) as decimal_38_10_to_decimal256_76_20,
|
||||
decimal256_50_15,
|
||||
CAST(decimal256_50_15 AS decimal(38,10)) as decimal256_50_15_to_decimal_38_10,
|
||||
CAST(decimal256_50_15 AS decimal(20,5)) as decimal256_50_15_to_decimal_20_5
|
||||
FROM cast_test_source
|
||||
WHERE decimal_38_10 IS NOT NULL AND decimal256_50_15 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 1234567890123456789012345678.1234567890 1234567890123456789012345678.123456789000000 1234567890123456789012345678.12345678900000000000 12345678901234567890123456789012345.123456789012345 None None
|
||||
2 0E-10 0E-15 0E-20 0E-15 0E-10 0.00000
|
||||
3 -8765432109876543210987654321.9876543210 -8765432109876543210987654321.987654321000000 -8765432109876543210987654321.98765432100000000000 -87654321098765432109876543210987654.987654321098765 None None
|
||||
4 9999999999999999999999999999.9999999999 9999999999999999999999999999.999999999900000 9999999999999999999999999999.99999999990000000000 99999999999999999999999999999999999.999999999999999 None None
|
||||
5 -9999999999999999999999999999.9999999999 -9999999999999999999999999999.999999999900000 -9999999999999999999999999999.99999999990000000000 -99999999999999999999999999999999999.999999999999999 None None
|
||||
6 1E-10 1.00000E-10 1.0000000000E-10 1E-15 0E-10 0.00000
|
||||
7 5555555555555555555555555555.5555555555 5555555555555555555555555555.555555555500000 5555555555555555555555555555.55555555550000000000 55555555555555555555555555555555555.555555555555555 None None
|
||||
8 1E-10 1.00000E-10 1.0000000000E-10 1E-15 0E-10 0.00000
|
||||
9 7777777777777777777777777777.7777777777 7777777777777777777777777777.777777777700000 7777777777777777777777777777.77777777770000000000 77777777777777777777777777777777777.777777777777777 None None
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 + tinyint_val as decimal256_plus_tinyint,
|
||||
decimal256_50_15 + smallint_val as decimal256_plus_smallint,
|
||||
decimal256_50_15 + int_val as decimal256_plus_int,
|
||||
decimal256_50_15 + bigint_val as decimal256_plus_bigint,
|
||||
decimal256_50_15 + largeint_val as decimal256_plus_largeint
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND tinyint_val IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 12345678901234567890123456789012472.123456789012345 12345678901234567890123456789045112.123456789012345 12345678901234567890123458936495992.123456789012345 12345678901234577113495493643788152.123456789012345 170153529139370466299577427172673118072.123456789012345
|
||||
2 0E-15 0E-15 0E-15 0E-15 0E-15
|
||||
3 -87654321098765432109876543210987782.987654321098765 -87654321098765432109876543211020422.987654321098765 -87654321098765432109876545358471302.987654321098765 -87654321098765441333248580065763462.987654321098765 -170228837781567997163797180259095093382.987654321098765
|
||||
4 100000000000000000000000000000000126.999999999999999 100000000000000000000000000000032766.999999999999999 100000000000000000000000002147483646.999999999999999 100000000000000009223372036854775806.999999999999999 170241183460469231731687303715884105726.999999999999999
|
||||
5 -100000000000000000000000000000000127.999999999999999 -100000000000000000000000000000032767.999999999999999 -100000000000000000000000002147483647.999999999999999 -100000000000000009223372036854775807.999999999999999 -170241183460469231731687303715884105727.999999999999999
|
||||
6 1.000000000000001 1.000000000000001 1.000000000000001 1.000000000000001 1.000000000000001
|
||||
7 55555555555555555555555555555555597.555555555555555 55555555555555555555555555555556789.555555555555555 55555555555555555555555555556123445.555555555555555 55555555555555555555679012344567900.555555555555555 55556543209876654320987665432098765.555555555555555
|
||||
8 1.000000000000001 10.000000000000001 100.000000000000001 1000.000000000000001 10000.000000000000001
|
||||
9 77777777777777777777777777777777876.777777777777777 77777777777777777777777777777787776.777777777777777 77777777777777777777777778777777776.777777777777777 77777777777777778777777777777777776.777777777777777 100077777777777777777777777777777777776.777777777777777
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_76_20 + float_val as decimal256_plus_float,
|
||||
decimal256_76_20 + double_val as decimal256_plus_double,
|
||||
decimal256_50_15 + decimal_38_10 as decimal256_plus_decimal38
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_76_20 IS NOT NULL AND float_val IS NOT NULL AND decimal256_50_15 IS NOT NULL AND decimal_38_10 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 1.234567890123457e+55 1.234567890123457e+55 12345680135802458013580245801358023.246913578012345
|
||||
2 0.0 0.0 0E-15
|
||||
3 -8.765432109876543e+55 -8.765432109876543e+55 -87654329864197541986419754198641976.975308642098765
|
||||
4 inf 1.7976931348623157e+308 100000009999999999999999999999999999.999999999899999
|
||||
5 -inf -1.7976931348623157e+308 -100000009999999999999999999999999999.999999999899999
|
||||
6 9.999999974752527e-07 1.00001e-15 1.00001E-10
|
||||
7 5.555555555555556e+55 5.555555555555556e+55 55555561111111111111111111111111111.111111111055555
|
||||
8 1.000000013451432e-10 1.00001e-15 1.00001E-10
|
||||
9 7.777777777777777e+55 7.777777777777777e+55 77777785555555555555555555555555555.555555555477777
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 - tinyint_val as decimal256_minus_tinyint,
|
||||
decimal256_50_15 - smallint_val as decimal256_minus_smallint,
|
||||
decimal256_50_15 - int_val as decimal256_minus_int,
|
||||
decimal256_50_15 - bigint_val as decimal256_minus_bigint,
|
||||
decimal256_76_20 - decimal_38_10 as decimal256_minus_decimal38
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND tinyint_val IS NOT NULL AND decimal256_76_20 IS NOT NULL AND decimal_38_10 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 12345678901234567890123456789012218.123456789012345 12345678901234567890123456788979578.123456789012345 12345678901234567890123454641528698.123456789012345 12345678901234558666751419934236538.123456789012345 12345678901234567890123456787777777788777777778877777778.00000000001234567890
|
||||
2 0E-15 0E-15 0E-15 0E-15 0E-20
|
||||
3 -87654321098765432109876543210987526.987654321098765 -87654321098765432109876543210954886.987654321098765 -87654321098765432109876541063504006.987654321098765 -87654321098765422886504506356211846.987654321098765 -87654321098765432109876543202222222211222222221122222222.00000000009876543210
|
||||
4 99999999999999999999999999999999872.999999999999999 99999999999999999999999999999967232.999999999999999 99999999999999999999999997852516352.999999999999999 99999999999999990776627963145224192.999999999999999 99999999999999999999999999990000000000000000000000000000.00000000009999999999
|
||||
5 -99999999999999999999999999999999871.999999999999999 -99999999999999999999999999999967231.999999999999999 -99999999999999999999999997852516351.999999999999999 -99999999999999990776627963145224191.999999999999999 -99999999999999999999999999990000000000000000000000000000.00000000009999999999
|
||||
6 -0.999999999999999 -0.999999999999999 -0.999999999999999 -0.999999999999999 -9.999999999E-11
|
||||
7 55555555555555555555555555555555513.555555555555555 55555555555555555555555555555554321.555555555555555 55555555555555555555555555554987665.555555555555555 55555555555555555555432098766543210.555555555555555 55555555555555555555555555550000000000000000000000000000.00000000005555555555
|
||||
8 -0.999999999999999 -9.999999999999999 -99.999999999999999 -999.999999999999999 -9.999999999E-11
|
||||
9 77777777777777777777777777777777678.777777777777777 77777777777777777777777777777767778.777777777777777 77777777777777777777777776777777778.777777777777777 77777777777777776777777777777777778.777777777777777 77777777777777777777777777770000000000000000000000000000.00000000007777777777
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 * tinyint_val as decimal256_multiply_tinyint,
|
||||
decimal256_50_15 * smallint_val as decimal256_multiply_smallint,
|
||||
decimal256_76_20 * float_val as decimal256_multiply_float,
|
||||
decimal256_76_20 * double_val as decimal256_multiply_double,
|
||||
decimal256_50_15 * decimal_20_5 as decimal256_multiply_decimal20
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL AND tinyint_val IS NOT NULL
|
||||
AND float_val IS NOT NULL AND decimal_20_5 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 1567901220456790122045679012204567830.679012204567815 404530860556753086055675308605567512660.308605567508615 3.878506284115917e+55 3.3559034617216163e+55 1524157875323876817626947886762694720102881755837.67461130300259899025
|
||||
2 0E-15 0E-15 0.0 0.0 0E-20
|
||||
3 11219753100641975310064197531006419838.419753100641920 2872256793764345679376434567937643478635.456793764331520 2.753739489996612e+56 2.3826914822868836e+56 76832800072854806320898565170589857101323732717416.38954291988050525225
|
||||
4 12699999999999999999999999999999999999.999999999999873 3276699999999999999999999999999999999999.999999999967233 inf inf 99999999999999999998999999999999999999999999999999.00000000000000000001
|
||||
5 12799999999999999999999999999999999999.999999999999872 3276799999999999999999999999999999999999.999999999967232 inf inf 99999999999999999998999999999999999999999999999999.00000000000000000001
|
||||
6 1E-15 1E-15 9.999999974752427e-27 1e-35 1E-20
|
||||
7 2333333333333333333333333333333333333.333333333333310 68555555555555555555555555555555555555.555555555554870 6.858710394965278e+57 5.486968450685872e+58 30864197530864197530555555555555555555555555555555.24691358024691358025
|
||||
8 1E-15 1.0E-14 1.0000000133514319e-30 1e-35 1E-20
|
||||
9 7699999999999999999999999999999999999.999999999999923 777699999999999999999999999999999999999.999999999992223 7.777777777777778e+61 7.777777777777778e+64 60493827160493827159888888888888888888888888888888.28395061728395061729
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 / tinyint_val as decimal256_divide_tinyint,
|
||||
decimal256_50_15 / smallint_val as decimal256_divide_smallint,
|
||||
decimal256_76_20 / float_val as decimal256_divide_float,
|
||||
decimal256_76_20 / double_val as decimal256_divide_double,
|
||||
decimal256_50_15 / decimal_20_5 as decimal256_divide_decimal20
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL
|
||||
AND tinyint_val IS NOT NULL AND tinyint_val != 0 AND smallint_val != 0
|
||||
AND float_val IS NOT NULL AND float_val != 0 AND double_val IS NOT NULL AND double_val != 0
|
||||
AND decimal_20_5 IS NOT NULL AND decimal_20_5 != 0
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 97210070088461164489161077078837.363176825110333 376771718534945765255392827814.946291191039430 3.929754817121064e+54 4.54172145506824e+54 100000000000000449915.504049232561083
|
||||
3 684799383584104938358410493835841.054591049383584 2674997592125409915462540991546.254119496286655 2.790125948803868e+55 3.2246222662075993e+55 99999999999999923956.831082309567732
|
||||
4 787401574803149606299212598425196.850393700787402 3051850947599719229712820825830.866420484023560 0.0 5.562684646268005e-253 100000000000000000001.000000000000000
|
||||
5 781250000000000000000000000000000.000000000000000 3051757812500000000000000000000.000000000000000 0.0 5.562684646268005e-253 100000000000000000001.000000000000000
|
||||
6 1E-15 1E-15 1.0000000025247572e-14 9.999999999999999e-06 1.00000E-10
|
||||
7 1322751322751322751322751322751322.751322751322751 45020709526382135782459931568521.519899153610661 4.5000001098632844e+53 5.624999999226563e+52 100000000000000000001.000000000000000
|
||||
8 1E-15 0E-15 9.999999866485681e-11 9.999999999999999e-06 1.00000E-10
|
||||
9 785634118967452300785634118967452.300785634118967 7778555633341111888966674445222.300007778555633 7.777777777777778e+49 7.777777777777778e+46 100000000000000000001.000000000000000
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 + decimal256_76_20 as decimal256_addition,
|
||||
decimal256_50_15 - decimal256_76_20 as decimal256_subtraction,
|
||||
decimal256_50_15 * decimal256_76_0 as decimal256_multiplication,
|
||||
decimal256_76_20 / decimal256_76_0 as decimal256_division
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL
|
||||
AND decimal256_76_0 IS NOT NULL AND decimal256_76_0 != 0
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 12345678901234567890135802467913580246791358024679135801.24691357802469067890 -12345678901234567890111111110111111111011111111101111111.00000000000000067890 None 1E-20
|
||||
3 -87654321098765432109964197532086419753208641975320864198.97530864219753043210 87654321098765432109788888889888888888988888888898888889.00000000000000043210 None 1E-20
|
||||
4 100000000000000000000099999999999999999999999999999999999.99999999999999899999 -99999999999999999999900000000000000000000000000000000000.00000000000000099999 None 1E-20
|
||||
5 -100000000000000000000099999999999999999999999999999999999.99999999999999899999 99999999999999999999900000000000000000000000000000000000.00000000000000099999 None 1E-20
|
||||
6 1.00001E-15 9.9999E-16 1E-15 1E-20
|
||||
7 55555555555555555555611111111111111111111111111111111111.11111111111111055555 -55555555555555555555500000000000000000000000000000000000.00000000000000055555 None 1E-20
|
||||
8 1.00001E-15 9.9999E-16 1E-15 1E-20
|
||||
9 77777777777777777777855555555555555555555555555555555555.55555555555555477777 -77777777777777777777700000000000000000000000000000000000.00000000000000077777 None 1E-20
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
(decimal256_50_15 + CAST(int_val AS decimal(50,15))) * CAST(float_val AS decimal(50,15)) as complex_expr1,
|
||||
(decimal256_76_20 - CAST(bigint_val AS decimal(76,20))) / CAST(double_val AS decimal(76,20)) as complex_expr2,
|
||||
CAST(tinyint_val AS decimal(76,0)) + decimal256_76_0 - CAST(smallint_val AS decimal(76,0)) as complex_expr3,
|
||||
(decimal256_50_15 + decimal_38_10) * CAST(decimal_20_5 AS decimal(50,15)) as complex_expr4
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL AND decimal256_76_0 IS NOT NULL
|
||||
AND int_val IS NOT NULL AND float_val IS NOT NULL AND float_val != 0
|
||||
AND bigint_val IS NOT NULL AND double_val IS NOT NULL AND double_val != 0
|
||||
AND tinyint_val IS NOT NULL AND smallint_val IS NOT NULL
|
||||
AND decimal_38_10 IS NOT NULL AND decimal_20_5 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 38785062841159159648132622711326664.709912157833965463651916266035 None 1234567890123456789012345678901234567890123456789012345678901234567890090816 None
|
||||
3 275373948999661140351867390781700148.497562752457348482839749169295 None -8765432109876543210987654321098765432109876543210987654321098765432109843903 None
|
||||
4 None None 9999999999999999999999999999999999999999999999999999999999999999999999967359 None
|
||||
5 None None -9999999999999999999999999999999999999999999999999999999999999999999999967359 None
|
||||
6 9.99999997000000999999997E-7 -999999999999999.99999000000000000000 1 1.000010000000000E-15
|
||||
7 6858710394965278222222222222292332097.053765195515273635118272569440 None 5555555555555555555555555555555555555555555555555555555555555555555555554363 None
|
||||
8 1.0000000000000000100000E-8 -999999999999999999.99999000000000000000 -8 1.000010000000000E-15
|
||||
9 77777777777777777777777778777777776777777.777777777000000000000000000000 None 7777777777777777777777777777777777777777777777777777777777777777777777767877 None
|
||||
-- !result
|
||||
SELECT
|
||||
SUM(CAST(tinyint_val AS decimal(76,20))) as sum_tinyint_as_decimal256,
|
||||
AVG(CAST(int_val AS decimal(76,20))) as avg_int_as_decimal256,
|
||||
MIN(CAST(bigint_val AS decimal(76,20))) as min_bigint_as_decimal256,
|
||||
MAX(CAST(largeint_val AS decimal(76,0))) as max_largeint_as_decimal256
|
||||
FROM cast_test_source
|
||||
WHERE tinyint_val IS NOT NULL;
|
||||
-- result:
|
||||
141.00000000000000000000 111174220.88888888888888888889 -9223372036854775808.00000000000000000000 170141183460469231731687303715884105727
|
||||
-- !result
|
||||
SELECT
|
||||
SUM(decimal256_50_15) as sum_decimal256_50_15,
|
||||
AVG(decimal256_76_20) as avg_decimal256_76_20,
|
||||
MIN(decimal256_76_0) as min_decimal256_76_0,
|
||||
MAX(decimal256_76_0) as max_decimal256_76_0,
|
||||
SUM(decimal_38_10) as sum_decimal_38_10,
|
||||
AVG(decimal_20_5) as avg_decimal_20_5
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL;
|
||||
-- result:
|
||||
58024691135802469113580246911358023.469135801246914 6447187903978052123731138545706447187903978052123731138.38545953347187928668 -9999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999 5802469113580246911358024689.4691358014 64471879039780.38546000000
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
CASE
|
||||
WHEN tinyint_val > 0 THEN CAST(tinyint_val AS decimal(50,15))
|
||||
WHEN tinyint_val < 0 THEN CAST(ABS(tinyint_val) AS decimal(50,15))
|
||||
ELSE 0.000000000000000
|
||||
END as case_tinyint_to_decimal256,
|
||||
CASE
|
||||
WHEN decimal256_50_15 > 0 THEN CAST(decimal256_50_15 AS varchar(100))
|
||||
WHEN decimal256_50_15 < 0 THEN CONCAT('negative: ', CAST(ABS(decimal256_50_15) AS varchar(100)))
|
||||
ELSE 'zero'
|
||||
END as case_decimal256_to_varchar,
|
||||
CASE
|
||||
WHEN decimal_38_10 > decimal256_50_15 THEN 'decimal38_larger'
|
||||
WHEN decimal_38_10 < decimal256_50_15 THEN 'decimal256_larger'
|
||||
ELSE 'equal'
|
||||
END as case_decimal_comparison
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal_38_10 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 127.000000000000000 12345678901234567890123456789012345.123456789012345 decimal256_larger
|
||||
2 0E-15 zero equal
|
||||
3 128.000000000000000 negative: 87654321098765432109876543210987654.987654321098765 decimal38_larger
|
||||
4 127.000000000000000 99999999999999999999999999999999999.999999999999999 decimal256_larger
|
||||
5 128.000000000000000 negative: 99999999999999999999999999999999999.999999999999999 decimal38_larger
|
||||
6 1.000000000000000 0.000000000000001 decimal38_larger
|
||||
7 42.000000000000000 55555555555555555555555555555555555.555555555555555 decimal256_larger
|
||||
8 1.000000000000000 0.000000000000001 decimal38_larger
|
||||
9 99.000000000000000 77777777777777777777777777777777777.777777777777777 decimal256_larger
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 > CAST(int_val AS decimal(50,15)) as decimal256_gt_int,
|
||||
decimal256_76_20 = CAST(float_val AS decimal(76,20)) as decimal256_eq_float,
|
||||
decimal256_76_0 < CAST(largeint_val AS decimal(76,0)) as decimal256_lt_largeint,
|
||||
CAST(bigint_val AS decimal(76,20)) BETWEEN decimal256_76_20 - 1000 AND decimal256_76_20 + 1000 as bigint_between_decimal256,
|
||||
decimal256_50_15 > decimal_38_10 as decimal256_gt_decimal38,
|
||||
decimal_20_5 = CAST(decimal256_50_15 AS decimal(20,5)) as decimal20_eq_decimal256_cast
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL AND decimal256_76_0 IS NOT NULL
|
||||
AND int_val IS NOT NULL AND float_val IS NOT NULL AND largeint_val IS NOT NULL AND bigint_val IS NOT NULL
|
||||
AND decimal_38_10 IS NOT NULL AND decimal_20_5 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 1 0 0 0 1 None
|
||||
2 0 1 0 1 0 1
|
||||
3 0 0 1 0 0 None
|
||||
4 1 None 0 0 1 None
|
||||
5 0 None 1 0 0 None
|
||||
6 0 0 0 1 0 0
|
||||
7 1 0 0 0 1 None
|
||||
8 0 0 1 1 0 0
|
||||
9 1 0 0 0 1 None
|
||||
-- !result
|
||||
SELECT id, CAST(tinyint_val AS decimal(76,20)) as unified_decimal256, 'tinyint' as source_type FROM cast_test_source WHERE tinyint_val IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT id, CAST(int_val AS decimal(76,20)) as unified_decimal256, 'int' as source_type FROM cast_test_source WHERE int_val IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT id, decimal256_76_20 as unified_decimal256, 'decimal256_76_20' as source_type FROM cast_test_source WHERE decimal256_76_20 IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT id, CAST(decimal_38_10 AS decimal(76,20)) as unified_decimal256, 'decimal_38_10' as source_type FROM cast_test_source WHERE decimal_38_10 IS NOT NULL
|
||||
ORDER BY id, unified_decimal256;
|
||||
-- result:
|
||||
1 127.00000000000000000000 tinyint
|
||||
1 2147483647.00000000000000000000 int
|
||||
1 1234567890123456789012345678.12345678900000000000 decimal_38_10
|
||||
1 12345678901234567890123456789012345678901234567890123456.12345678901234567890 decimal256_76_20
|
||||
2 0E-20 int
|
||||
2 0E-20 decimal_38_10
|
||||
2 0E-20 tinyint
|
||||
2 0E-20 decimal256_76_20
|
||||
3 -87654321098765432109876543210987654321098765432109876543.98765432109876543210 decimal256_76_20
|
||||
3 -8765432109876543210987654321.98765432100000000000 decimal_38_10
|
||||
3 -2147483648.00000000000000000000 int
|
||||
3 -128.00000000000000000000 tinyint
|
||||
4 127.00000000000000000000 tinyint
|
||||
4 2147483647.00000000000000000000 int
|
||||
4 9999999999999999999999999999.99999999990000000000 decimal_38_10
|
||||
4 99999999999999999999999999999999999999999999999999999999.99999999999999999999 decimal256_76_20
|
||||
5 -99999999999999999999999999999999999999999999999999999999.99999999999999999999 decimal256_76_20
|
||||
5 -9999999999999999999999999999.99999999990000000000 decimal_38_10
|
||||
5 -2147483648.00000000000000000000 int
|
||||
5 -128.00000000000000000000 tinyint
|
||||
6 1E-20 decimal256_76_20
|
||||
6 1.0000000000E-10 decimal_38_10
|
||||
6 1.00000000000000000000 int
|
||||
6 1.00000000000000000000 tinyint
|
||||
7 42.00000000000000000000 tinyint
|
||||
7 567890.00000000000000000000 int
|
||||
7 5555555555555555555555555555.55555555550000000000 decimal_38_10
|
||||
7 55555555555555555555555555555555555555555555555555555555.55555555555555555555 decimal256_76_20
|
||||
8 1E-20 decimal256_76_20
|
||||
8 1.0000000000E-10 decimal_38_10
|
||||
8 1.00000000000000000000 tinyint
|
||||
8 100.00000000000000000000 int
|
||||
9 99.00000000000000000000 tinyint
|
||||
9 999999999.00000000000000000000 int
|
||||
9 7777777777777777777777777777.77777777770000000000 decimal_38_10
|
||||
9 77777777777777777777777777777777777777777777777777777777.77777777777777777777 decimal256_76_20
|
||||
-- !result
|
||||
CREATE TABLE cast_test_target (
|
||||
id int,
|
||||
target_decimal256 decimal(76,20),
|
||||
target_decimal38 decimal(38,10),
|
||||
target_int bigint
|
||||
) ENGINE=OLAP
|
||||
DUPLICATE KEY(id)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
);
|
||||
-- result:
|
||||
-- !result
|
||||
INSERT INTO cast_test_target VALUES
|
||||
(1, 12345678901234567890123456789012345678901234567890123456.12345678901234567890, 1234567890123456789012345678.1234567890, 9223372036854775807),
|
||||
(2, 0.00000000000000000000, 0.0000000000, 0),
|
||||
(3, -87654321098765432109876543210987654321098765432109876543.98765432109876543210, -8765432109876543210987654321.9876543210, -9223372036854775808),
|
||||
(4, 99999999999999999999999999999999999999999999999999999999.99999999999999999999, 9999999999999999999999999999.9999999999, 9223372036854775807),
|
||||
(5, -99999999999999999999999999999999999999999999999999999999.99999999999999999999, -9999999999999999999999999999.9999999999, -9223372036854775808);
|
||||
-- result:
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS decimal(76,0)) as max_decimal256_76_0,
|
||||
CAST('99999999999999999999999999999999999999999999999999999999.99999999999999999999' AS decimal(76,20)) as max_decimal256_76_20,
|
||||
CAST('99999999999999999999999999999999999.999999999999999' AS decimal(50,15)) as max_decimal256_50_15
|
||||
FROM cast_test_source
|
||||
WHERE id = 1;
|
||||
-- result:
|
||||
1 9999999999999999999999999999999999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999999999999.99999999999999999999 99999999999999999999999999999999999.999999999999999
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
CAST('0.00000000000000000001' AS decimal(76,20)) as min_decimal256_76_20,
|
||||
CAST('0.000000000000001' AS decimal(50,15)) as min_decimal256_50_15,
|
||||
CAST('0.0000000001' AS decimal(38,10)) as min_decimal_38_10
|
||||
FROM cast_test_source
|
||||
WHERE id = 1;
|
||||
-- result:
|
||||
1 1E-20 1E-15 1E-10
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
decimal256_76_20,
|
||||
CAST(decimal256_76_20 AS decimal(50,10)) as decimal256_with_precision_loss,
|
||||
CAST(decimal256_50_15 AS decimal(38,5)) as decimal256_with_scale_loss,
|
||||
CAST(decimal_38_10 AS decimal(20,5)) as decimal38_with_precision_loss
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_76_20 IS NOT NULL AND decimal256_50_15 IS NOT NULL AND decimal_38_10 IS NOT NULL
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 12345678901234567890123456789012345678901234567890123456.12345678901234567890 12345678901234567890123456789012345678901234567890123456.1234567890 None 1234567890123456789012345678.12346
|
||||
2 0E-20 0E-10 0.00000 0.00000
|
||||
3 -87654321098765432109876543210987654321098765432109876543.98765432109876543210 -87654321098765432109876543210987654321098765432109876543.9876543211 None -8765432109876543210987654321.98765
|
||||
4 99999999999999999999999999999999999999999999999999999999.99999999999999999999 100000000000000000000000000000000000000000000000000000000.0000000000 None 10000000000000000000000000000.00000
|
||||
5 -99999999999999999999999999999999999999999999999999999999.99999999999999999999 -100000000000000000000000000000000000000000000000000000000.0000000000 None -10000000000000000000000000000.00000
|
||||
6 1E-20 0E-10 0.00000 0.00000
|
||||
7 55555555555555555555555555555555555555555555555555555555.55555555555555555555 55555555555555555555555555555555555555555555555555555555.5555555556 None 5555555555555555555555555555.55556
|
||||
8 1E-20 0E-10 0.00000 0.00000
|
||||
9 77777777777777777777777777777777777777777777777777777777.77777777777777777777 77777777777777777777777777777777777777777777777777777777.7777777778 None 7777777777777777777777777777.77778
|
||||
-- !result
|
||||
SELECT
|
||||
id,
|
||||
CAST(NULL AS decimal(76,20)) as null_to_decimal256,
|
||||
CAST(decimal256_50_15 AS varchar(100)) as decimal256_to_varchar_with_null,
|
||||
COALESCE(CAST(tinyint_val AS decimal(50,15)), 0.000000000000000) as coalesce_cast_tinyint,
|
||||
COALESCE(CAST(decimal_38_10 AS decimal(76,20)), 0.00000000000000000000) as coalesce_cast_decimal38
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
-- result:
|
||||
1 None 12345678901234567890123456789012345.123456789012345 127.0 1.2345678901234569e+27
|
||||
2 None 0.000000000000000 0.0 0.0
|
||||
3 None -87654321098765432109876543210987654.987654321098765 -128.0 -8.765432109876543e+27
|
||||
4 None 99999999999999999999999999999999999.999999999999999 127.0 1e+28
|
||||
5 None -99999999999999999999999999999999999.999999999999999 -128.0 -1e+28
|
||||
6 None 0.000000000000001 1.0 1e-10
|
||||
7 None 55555555555555555555555555555555555.555555555555555 42.0 5.555555555555556e+27
|
||||
8 None 0.000000000000001 1.0 1e-10
|
||||
9 None 77777777777777777777777777777777777.777777777777777 99.0 7.777777777777777e+27
|
||||
10 None None 0.0 0.0
|
||||
-- !result
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,413 @@
|
|||
-- name: test_decimal256_aggregate_function
|
||||
|
||||
DROP DATABASE IF EXISTS test_decimal256_agg_func;
|
||||
CREATE DATABASE test_decimal256_agg_func;
|
||||
USE test_decimal256_agg_func;
|
||||
|
||||
DROP TABLE IF EXISTS decimal256_agg_test;
|
||||
CREATE TABLE decimal256_agg_test (
|
||||
id INT,
|
||||
category VARCHAR(10),
|
||||
p40s10 DECIMAL(40,10), -- 30 integer digits + 10 decimal digits
|
||||
p50s15 DECIMAL(50,15), -- 35 integer digits + 15 decimal digits
|
||||
p76s20 DECIMAL(76,20), -- 56 integer digits + 20 decimal digits
|
||||
p76s0 DECIMAL(76,0) -- 76 integer digits + 0 decimal digits
|
||||
) properties("replication_num"="1");
|
||||
|
||||
-- Insert test data (simple values with duplicates for testing)
|
||||
INSERT INTO decimal256_agg_test VALUES
|
||||
-- Duplicate group 1 - for testing distinct
|
||||
(1, 'A', 100.1234567890, 100.123456789012345, 100.12345678901234567890, 100),
|
||||
(2, 'A', 100.1234567890, 100.123456789012345, 100.12345678901234567890, 100),
|
||||
(3, 'A', 100.1234567890, 100.123456789012345, 100.12345678901234567890, 100),
|
||||
|
||||
-- Duplicate group 2
|
||||
(4, 'B', 200.5555555555, 200.555555555555555, 200.55555555555555555555, 200),
|
||||
(5, 'B', 200.5555555555, 200.555555555555555, 200.55555555555555555555, 200),
|
||||
|
||||
-- Duplicate group 3 - zero values
|
||||
(6, 'C', 0.0000000000, 0.000000000000000, 0.00000000000000000000, 0),
|
||||
(7, 'C', 0.0000000000, 0.000000000000000, 0.00000000000000000000, 0),
|
||||
(8, 'C', 0.0000000000, 0.000000000000000, 0.00000000000000000000, 0),
|
||||
|
||||
-- Duplicate group 4 - negative values
|
||||
(9, 'D', -50.9876543210, -50.987654321098765, -50.98765432109876543210, -50),
|
||||
(10, 'D', -50.9876543210, -50.987654321098765, -50.98765432109876543210, -50),
|
||||
|
||||
-- Unique data
|
||||
(11, 'E', 300.1111111111, 300.111111111111111, 300.11111111111111111111, 300),
|
||||
(12, 'F', 400.2222222222, 400.222222222222222, 400.22222222222222222222, 400),
|
||||
(13, 'G', 500.3333333333, 500.333333333333333, 500.33333333333333333333, 500),
|
||||
|
||||
-- Large number duplicates
|
||||
(14, 'H', 999999999999999999999999999999.9999999999,
|
||||
99999999999999999999999999999999999.999999999999999,
|
||||
99999999999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999),
|
||||
(15, 'H', 999999999999999999999999999999.9999999999,
|
||||
99999999999999999999999999999999999.999999999999999,
|
||||
99999999999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999),
|
||||
|
||||
-- Small decimal duplicates
|
||||
(16, 'I', 0.0000000001, 0.000000000000001, 0.00000000000000000001, 1),
|
||||
(17, 'I', 0.0000000001, 0.000000000000001, 0.00000000000000000001, 1),
|
||||
|
||||
-- NULL values
|
||||
(18, 'J', NULL, NULL, NULL, NULL),
|
||||
(19, 'J', 600.4444444444, 600.444444444444444, 600.44444444444444444444, 600),
|
||||
|
||||
-- Mixed duplicates (partial column duplicates)
|
||||
(20, 'K', 777.7777777777, 777.777777777777777, 777.77777777777777777777, 777),
|
||||
(21, 'K', 777.7777777777, 888.888888888888888, 999.99999999999999999999, 777),
|
||||
(22, 'K', 777.7777777777, 777.777777777777777, 777.77777777777777777777, 888);
|
||||
|
||||
-- =====================================================
|
||||
-- Non-DISTINCT aggregate function test cases
|
||||
-- =====================================================
|
||||
|
||||
-- Test 1: Basic COUNT test
|
||||
SELECT 'Test1_COUNT_BASIC' as test_name, COUNT(*) as total_rows FROM decimal256_agg_test;
|
||||
|
||||
SELECT
|
||||
'Test1_COUNT_NON_NULL' as test_name,
|
||||
COUNT(p40s10) as count_p40s10,
|
||||
COUNT(p50s15) as count_p50s15,
|
||||
COUNT(p76s20) as count_p76s20,
|
||||
COUNT(p76s0) as count_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
|
||||
-- Test 2: SUM test
|
||||
SELECT
|
||||
'Test2_SUM' as test_name,
|
||||
SUM(p40s10) as sum_p40s10,
|
||||
SUM(p50s15) as sum_p50s15,
|
||||
SUM(p76s20) as sum_p76s20,
|
||||
SUM(p76s0) as sum_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
|
||||
-- Test 3: AVG test
|
||||
SELECT
|
||||
'Test3_AVG' as test_name,
|
||||
AVG(p40s10) as avg_p40s10,
|
||||
AVG(p50s15) as avg_p50s15,
|
||||
AVG(p76s20) as avg_p76s20,
|
||||
AVG(p76s0) as avg_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
|
||||
-- Test 4: MIN/MAX test
|
||||
SELECT
|
||||
'Test4_MIN_MAX' as test_name,
|
||||
MIN(p40s10) as min_p40s10,
|
||||
MAX(p40s10) as max_p40s10,
|
||||
MIN(p50s15) as min_p50s15,
|
||||
MAX(p50s15) as max_p50s15,
|
||||
MIN(p76s20) as min_p76s20,
|
||||
MAX(p76s20) as max_p76s20,
|
||||
MIN(p76s0) as min_p76s0,
|
||||
MAX(p76s0) as max_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
|
||||
-- Test 5: Group by aggregation (non-DISTINCT)
|
||||
SELECT
|
||||
'Test5_GROUP_BY_CATEGORY' as test_name,
|
||||
category,
|
||||
COUNT(*) as row_count,
|
||||
SUM(p40s10) as sum_p40s10,
|
||||
AVG(p40s10) as avg_p40s10,
|
||||
MIN(p50s15) as min_p50s15,
|
||||
MAX(p76s20) as max_p76s20
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
|
||||
-- Test 6: Group by decimal column (non-DISTINCT)
|
||||
SELECT
|
||||
'Test6_GROUP_BY_P40S10' as test_name,
|
||||
p40s10,
|
||||
COUNT(*) as row_count,
|
||||
SUM(p50s15) as sum_p50s15,
|
||||
AVG(p50s15) as avg_p50s15,
|
||||
MIN(p76s0) as min_p76s0,
|
||||
MAX(p76s0) as max_p76s0
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
GROUP BY p40s10
|
||||
ORDER BY p40s10;
|
||||
|
||||
-- =====================================================
|
||||
-- DISTINCT test cases - each case tests both planners
|
||||
-- =====================================================
|
||||
|
||||
-- Test 7: COUNT DISTINCT test
|
||||
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT
|
||||
'Test7_COUNT_DISTINCT_planner0' as test_name,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
COUNT(DISTINCT p50s15) as distinct_p50s15,
|
||||
COUNT(DISTINCT p76s20) as distinct_p76s20,
|
||||
COUNT(DISTINCT p76s0) as distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT
|
||||
'Test7_COUNT_DISTINCT_planner2' as test_name,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
COUNT(DISTINCT p50s15) as distinct_p50s15,
|
||||
COUNT(DISTINCT p76s20) as distinct_p76s20,
|
||||
COUNT(DISTINCT p76s0) as distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 8: SUM DISTINCT test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT
|
||||
'Test8_SUM_DISTINCT_planner0' as test_name,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15,
|
||||
SUM(DISTINCT p76s20) as sum_distinct_p76s20,
|
||||
SUM(DISTINCT p76s0) as sum_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT
|
||||
'Test8_SUM_DISTINCT_planner2' as test_name,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15,
|
||||
SUM(DISTINCT p76s20) as sum_distinct_p76s20,
|
||||
SUM(DISTINCT p76s0) as sum_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 9: AVG DISTINCT test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT
|
||||
'Test9_AVG_DISTINCT_planner0' as test_name,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
AVG(DISTINCT p50s15) as avg_distinct_p50s15,
|
||||
AVG(DISTINCT p76s20) as avg_distinct_p76s20,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT
|
||||
'Test9_AVG_DISTINCT_planner2' as test_name,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
AVG(DISTINCT p50s15) as avg_distinct_p50s15,
|
||||
AVG(DISTINCT p76s20) as avg_distinct_p76s20,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 10: Group by COUNT DISTINCT test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT
|
||||
'Test10_GROUP_COUNT_DISTINCT_planner0' as test_name,
|
||||
category,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
COUNT(DISTINCT p76s0) as distinct_p76s0
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT
|
||||
'Test10_GROUP_COUNT_DISTINCT_planner2' as test_name,
|
||||
category,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
COUNT(DISTINCT p76s0) as distinct_p76s0
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 11: Group by SUM DISTINCT test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT
|
||||
'Test11_GROUP_SUM_DISTINCT_planner0' as test_name,
|
||||
category,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT
|
||||
'Test11_GROUP_SUM_DISTINCT_planner2' as test_name,
|
||||
category,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 12: Group by AVG DISTINCT test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT
|
||||
'Test12_GROUP_AVG_DISTINCT_planner0' as test_name,
|
||||
category,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT
|
||||
'Test12_GROUP_AVG_DISTINCT_planner2' as test_name,
|
||||
category,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test
|
||||
GROUP BY category
|
||||
ORDER BY category;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 13: Group by decimal column DISTINCT test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT
|
||||
'Test13_GROUP_BY_DECIMAL_DISTINCT_planner0' as test_name,
|
||||
p76s0,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10
|
||||
FROM decimal256_agg_test
|
||||
WHERE p76s0 IS NOT NULL
|
||||
GROUP BY p76s0
|
||||
ORDER BY p76s0;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT
|
||||
'Test13_GROUP_BY_DECIMAL_DISTINCT_planner2' as test_name,
|
||||
p76s0,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p40s10) as distinct_p40s10,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10
|
||||
FROM decimal256_agg_test
|
||||
WHERE p76s0 IS NOT NULL
|
||||
GROUP BY p76s0
|
||||
ORDER BY p76s0;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 14: SELECT DISTINCT single column test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT DISTINCT 'Test14_SELECT_DISTINCT_SINGLE_planner0' as test_name, p40s10
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
ORDER BY p40s10;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT DISTINCT 'Test14_SELECT_DISTINCT_SINGLE_planner2' as test_name, p40s10
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
ORDER BY p40s10;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 15: SELECT DISTINCT multiple columns test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT DISTINCT 'Test15_SELECT_DISTINCT_MULTI_planner0' as test_name, p40s10, p50s15, p76s0
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
ORDER BY p40s10, p50s15;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT DISTINCT 'Test15_SELECT_DISTINCT_MULTI_planner2' as test_name, p40s10, p50s15, p76s0
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
ORDER BY p40s10, p50s15;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 16: Complex DISTINCT query test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT
|
||||
'Test16_COMPLEX_DISTINCT_planner0' as test_name,
|
||||
COUNT(DISTINCT p40s10) as count_distinct_p40s10,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
COUNT(DISTINCT p76s0) as count_distinct_p76s0,
|
||||
SUM(DISTINCT p76s0) as sum_distinct_p76s0,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT
|
||||
'Test16_COMPLEX_DISTINCT_planner2' as test_name,
|
||||
COUNT(DISTINCT p40s10) as count_distinct_p40s10,
|
||||
SUM(DISTINCT p40s10) as sum_distinct_p40s10,
|
||||
AVG(DISTINCT p40s10) as avg_distinct_p40s10,
|
||||
COUNT(DISTINCT p76s0) as count_distinct_p76s0,
|
||||
SUM(DISTINCT p76s0) as sum_distinct_p76s0,
|
||||
AVG(DISTINCT p76s0) as avg_distinct_p76s0
|
||||
FROM decimal256_agg_test;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- Test 17: HAVING with DISTINCT test
|
||||
set new_planner_agg_stage=0;
|
||||
SELECT
|
||||
'Test17_HAVING_DISTINCT_planner0' as test_name,
|
||||
p40s10,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p50s15) as distinct_p50s15,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
GROUP BY p40s10
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY p40s10;
|
||||
|
||||
set new_planner_agg_stage=2;
|
||||
SELECT
|
||||
'Test17_HAVING_DISTINCT_planner2' as test_name,
|
||||
p40s10,
|
||||
COUNT(*) as row_count,
|
||||
COUNT(DISTINCT p50s15) as distinct_p50s15,
|
||||
SUM(DISTINCT p50s15) as sum_distinct_p50s15
|
||||
FROM decimal256_agg_test
|
||||
WHERE p40s10 IS NOT NULL
|
||||
GROUP BY p40s10
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY p40s10;
|
||||
set new_planner_agg_stage=0;
|
||||
|
||||
-- =====================================================
|
||||
-- Edge case tests
|
||||
-- =====================================================
|
||||
|
||||
-- Test 18: Empty result set
|
||||
SELECT
|
||||
'Test18_EMPTY_RESULT' as test_name,
|
||||
COUNT(*) as count_all,
|
||||
SUM(p40s10) as sum_p40s10,
|
||||
AVG(p40s10) as avg_p40s10,
|
||||
MIN(p50s15) as min_p50s15,
|
||||
MAX(p76s20) as max_p76s20
|
||||
FROM decimal256_agg_test
|
||||
WHERE id > 1000;
|
||||
|
||||
-- Test 19: NULL values only
|
||||
SELECT
|
||||
'Test19_NULL_ONLY' as test_name,
|
||||
COUNT(*) as count_all,
|
||||
COUNT(p40s10) as count_p40s10,
|
||||
SUM(p50s15) as sum_p50s15,
|
||||
AVG(p50s15) as avg_p50s15
|
||||
FROM decimal256_agg_test
|
||||
WHERE id = 18;
|
||||
|
||||
-- Test 20: Single row result
|
||||
SELECT
|
||||
'Test20_SINGLE_ROW' as test_name,
|
||||
COUNT(*) as count_all,
|
||||
SUM(p40s10) as sum_p40s10,
|
||||
AVG(p40s10) as avg_p40s10,
|
||||
MIN(p50s15) as min_p50s15,
|
||||
MAX(p76s20) as max_p76s20
|
||||
FROM decimal256_agg_test
|
||||
WHERE id = 11;
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
-- name: test_decimal256_arithmetic_overflow
|
||||
DROP DATABASE IF EXISTS test_decimal256_overflow;
|
||||
CREATE DATABASE test_decimal256_overflow;
|
||||
USE test_decimal256_overflow;
|
||||
|
||||
-- =============================================================================
|
||||
-- TEST-0: int256 boundary values extreme cases
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE powers_of_2 (
|
||||
power_250 DECIMAL(76, 0)
|
||||
) PROPERTIES("replication_num"="1");
|
||||
|
||||
-- pow(2, 250)
|
||||
insert into powers_of_2 select 1809251394333065553493296640760748560207343510400633813116524750123642650624;
|
||||
|
||||
-- INT_256MAX
|
||||
select cast(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) as string) from powers_of_2;
|
||||
|
||||
-- INT_256MAX + 1 (overflow)
|
||||
select cast(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495 + 1 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MAX - 1 (INT_256MAX - 1)
|
||||
select cast(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495 - 1 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MAX * 0 (0)
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * 0 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MAX * -1 (-INT_256MAX)
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * -1 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MAX * 2 (overflow)
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * 2 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MAX * -2 (overflow)
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * -2 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN - 1 (overflow)
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) - 1 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN + 1 (not overflow)
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) + 1 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN * 1 (INT_256MIN)
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * 1 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN * -1 (overflow. special case)
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * -1 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN * -2 (overflow)
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * -2 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN * 2 (overflow)
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * 2 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN * 0 (0)
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * 0 as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN + INT256_MAX(-1)
|
||||
select cast(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495 + (-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) as string) from powers_of_2;
|
||||
|
||||
-- INT_256MAX * INT_256MIN (overflow)
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * (-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) as string) from powers_of_2;
|
||||
|
||||
-- INT_256MAX * INT_256MAX (overflow)
|
||||
select cast((power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) * (power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) as string) from powers_of_2;
|
||||
|
||||
-- INT_256MIN * INT_256MIN (overflow)
|
||||
select cast((-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) * (-(power_250 * 16 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602496 + 7237005577332262213973186563042994240829374041602535252466099000494570602495) - 1) as string) from powers_of_2;
|
||||
|
||||
-- TEST INT_256MAX result (bit count is 256)
|
||||
create table test_256max_result(d1 decimal(76, 0)) PROPERTIES("replication_num"="1");
|
||||
insert into test_256max_result select 1496577676626844588240573307387100039795808514605057;
|
||||
select cast(d1 * 38685626227668133590597631 as string) from test_256max_result;
|
||||
|
||||
-- TEST INT_256MIN result (bit count is 257)
|
||||
create table test_256min_result(d1 decimal(76, 0), d2 decimal(76, 0)) PROPERTIES("replication_num"="1");
|
||||
insert into test_256min_result select 340282366920938463463374607431768211456, -170141183460469231731687303715884105728;
|
||||
select cast(d1 * d2 as string) from test_256min_result; -- 2^128 * -2^127
|
||||
|
||||
CREATE TABLE test_decimal_multiply_overflow (
|
||||
id INT,
|
||||
case_desc VARCHAR(200),
|
||||
d60_30 DECIMAL(60, 30),
|
||||
d70_20 DECIMAL(70, 20),
|
||||
d76_10 DECIMAL(76, 10),
|
||||
d76_38 DECIMAL(76, 38),
|
||||
d50_0 DECIMAL(50, 0),
|
||||
d38_0 DECIMAL(38, 0) -- Maximum 38-digit decimal number
|
||||
) PROPERTIES("replication_num"="1");
|
||||
|
||||
-- Insert test data
|
||||
INSERT INTO test_decimal_multiply_overflow VALUES
|
||||
-- 1. Small values
|
||||
(1, 'Small values',
|
||||
1.123456789012345678901234567890,
|
||||
12.12345678901234567890,
|
||||
123.1234567890,
|
||||
0.12345678901234567890123456789012345678,
|
||||
1000,
|
||||
12345),
|
||||
|
||||
-- 2. Medium values
|
||||
(2, 'Medium values',
|
||||
123456789012345678901234567890.123456789012345678901234567890, -- 60 digits
|
||||
12345678901234567890123456789012345678901234567890.12345678901234567890, -- 70 digits
|
||||
1234567890123456789012345678901234567890123456789012345678901234.1234567890, -- 76 digits
|
||||
12345678901234567890123456789012345678.12345678901234567890123456789012345678, -- 76 digits
|
||||
12345678901234567890123456789012345678901234567890, -- 50 digits
|
||||
12345678901234567890123456789012345678), -- 38 digits
|
||||
|
||||
-- 3. Near maximum values for each type
|
||||
(3, 'Near max positive values',
|
||||
999999999999999999999999999999.999999999999999999999999999999, -- d60_30 maximum
|
||||
99999999999999999999999999999999999999999999999999.99999999999999999999, -- d70_20 maximum
|
||||
9999999999999999999999999999999999999999999999999999999999999999.9999999999, -- d76_10 maximum
|
||||
99999999999999999999999999999999999999.99999999999999999999999999999999999999, -- d76_38 maximum
|
||||
99999999999999999999999999999999999999999999999999, -- d50_0 maximum
|
||||
99999999999999999999999999999999999999), -- d38_0 maximum (38 nines)
|
||||
|
||||
-- 4. Corresponding negative values
|
||||
(4, 'Near max negative values',
|
||||
-999999999999999999999999999999.999999999999999999999999999999,
|
||||
-99999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
-9999999999999999999999999999999999999999999999999999999999999999.9999999999,
|
||||
-99999999999999999999999999999999999999.99999999999999999999999999999999999999,
|
||||
-99999999999999999999999999999999999999999999999999,
|
||||
-99999999999999999999999999999999999999);
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- Create dedicated boundary value test table
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE test_boundary_values (
|
||||
id INT,
|
||||
case_desc VARCHAR(200),
|
||||
-- Designed based on actual DECIMAL precision limits
|
||||
val_76_0 DECIMAL(76, 0),
|
||||
val_38_0 DECIMAL(38, 0),
|
||||
val_19_0 DECIMAL(19, 0),
|
||||
val_25_0 DECIMAL(25, 0),
|
||||
val_high_scale DECIMAL(76, 50)
|
||||
) PROPERTIES("replication_num"="1");
|
||||
|
||||
INSERT INTO test_boundary_values VALUES
|
||||
-- 1. Near 76-digit decimal maximum
|
||||
(1, 'Near 76-digit decimal max',
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999, -- 76 nines
|
||||
99999999999999999999999999999999999999, -- 38 nines
|
||||
9999999999999999999, -- 19 nines
|
||||
9999999999999999999999999, -- 25 nines
|
||||
0.00000000000000000000000000000000000000000000000001),
|
||||
|
||||
-- 2. Corresponding negative values
|
||||
(2, 'Near 76-digit decimal min',
|
||||
-9999999999999999999999999999999999999999999999999999999999999999999999999999,
|
||||
-99999999999999999999999999999999999999,
|
||||
-9999999999999999999,
|
||||
-9999999999999999999999999,
|
||||
-0.00000000000000000000000000000000000000000000000001),
|
||||
|
||||
-- 3. Values for testing multiplication overflow
|
||||
(3, 'Multiplication overflow test values',
|
||||
1000000000000000000000000000000000000000000000000000000000000000000000000000, -- 76-digit 10^75
|
||||
10000000000000000000000000000000000000, -- 38-digit 10^37
|
||||
1000000000000000000, -- 19-digit 10^18
|
||||
1000000000000000000000000, -- 25-digit 10^24
|
||||
0.00000000000000000000000000000000000000000000000001),
|
||||
|
||||
-- 4. Medium size values
|
||||
(4, 'Medium size values',
|
||||
5000000000000000000000000000000000000000000000000000000000000000000000000000, -- 76-digit 5*10^75
|
||||
50000000000000000000000000000000000000, -- 38-digit 5*10^37
|
||||
5000000000000000000, -- 19-digit 5*10^18
|
||||
5000000000000000000000000, -- 25-digit 5*10^24
|
||||
0.50000000000000000000000000000000000000000000000000);
|
||||
|
||||
-- =============================================================================
|
||||
-- Test 1: Positive number multiplication overflow
|
||||
-- =============================================================================
|
||||
|
||||
-- Test 76-digit max multiplication (definite overflow)
|
||||
SELECT
|
||||
'Test 1.1: 76-digit max * 76-digit max (definite overflow)' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * val_76_0 as string) as result,
|
||||
'Should overflow: 10^75 * 10^75 = 10^150, way beyond int256' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Test 38-digit max multiplication (may overflow)
|
||||
SELECT
|
||||
'Test 1.2: 38-digit max * 38-digit max (may overflow)' as test_case,
|
||||
cast(val_38_0 as string),
|
||||
cast(cast(val_38_0 as decimal(76, 0)) * val_38_0 as string) as result,
|
||||
'not overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Test 19-digit multiplication (should not overflow)
|
||||
SELECT
|
||||
'Test 1.3: 19-digit * 19-digit (should not overflow)' as test_case,
|
||||
cast(val_19_0 as string),
|
||||
cast(val_19_0 * val_19_0 as string) as result,
|
||||
'Should not overflow: 10^18 * 10^18 = 10^36, within int256' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Test large number multiplied by 2
|
||||
SELECT
|
||||
'Test 1.4: Large value * 2' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 2 as string) as result,
|
||||
'Should overflow: near-max * 2' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Test large number multiplied by 5 (not overflow)
|
||||
SELECT
|
||||
'Test 1.5: Large value * 5' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 5 as string) as result,
|
||||
'Should overflow: near-max * 5' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Test large number multiplied by 5.1 (overflow)
|
||||
SELECT
|
||||
'Test 1.6: Large value * 5.1' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 5.1 as string) as result,
|
||||
'Should overflow: near-max * 5.1' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Test large number multiplied by 6 (overflow)
|
||||
SELECT
|
||||
'Test 1.7: Large value * 6' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 6 as string) as result,
|
||||
'Should overflow: near-max * 6' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- =============================================================================
|
||||
-- Test 2: Negative number multiplication overflow
|
||||
-- =============================================================================
|
||||
|
||||
-- Test large negative * large negative = positive overflow
|
||||
SELECT
|
||||
'Test 2.1: Large negative * Large negative (positive overflow)' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * val_76_0 as string) as result,
|
||||
'Should overflow: (-10^75) * (-10^75) = +10^150' as expected
|
||||
FROM test_boundary_values WHERE id = 2;
|
||||
|
||||
-- Test large negative * positive = negative overflow
|
||||
SELECT
|
||||
'Test 2.2: Large negative * Large positive (negative overflow)' as test_case,
|
||||
cast(a.val_76_0 as string) as neg_val,
|
||||
cast(b.val_76_0 as string) as pos_val,
|
||||
cast(a.val_76_0 * b.val_76_0 as string) as result,
|
||||
'Should overflow: (-10^75) * (+10^75) = -10^150' as expected
|
||||
FROM test_boundary_values a, test_boundary_values b
|
||||
WHERE a.id = 2 AND b.id = 1;
|
||||
|
||||
-- Test negative boundary case
|
||||
SELECT
|
||||
'Test 2.3: Negative boundary * 5' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 5 as string) as result,
|
||||
'Should not overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 2;
|
||||
|
||||
-- Test negative boundary case
|
||||
SELECT
|
||||
'Test 2.4: Negative boundary * 6' as test_case,
|
||||
cast(val_76_0 as string),
|
||||
cast(val_76_0 * 6 as string) as result,
|
||||
'Should overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 2;
|
||||
|
||||
-- =============================================================================
|
||||
-- Test 3: Different precision combination overflow tests
|
||||
-- =============================================================================
|
||||
|
||||
-- 76-digit * 38-digit
|
||||
SELECT
|
||||
'Test 3.1: 76-digit * 38-digit' as test_case,
|
||||
cast(a.val_76_0 as string),
|
||||
cast(b.val_38_0 as string),
|
||||
cast(a.val_76_0 * b.val_38_0 as string) as result,
|
||||
'Should overflow: 10^75 * 10^37 = 10^112' as expected
|
||||
FROM test_boundary_values a, test_boundary_values b
|
||||
WHERE a.id = 1 AND b.id = 1;
|
||||
|
||||
-- 38-digit * 25-digit
|
||||
-- can't auto scale up now
|
||||
SELECT
|
||||
'Test 3.2: 38-digit * 25-digit' as test_case,
|
||||
cast(a.val_38_0 as string),
|
||||
cast(b.val_25_0 as string),
|
||||
cast(a.val_38_0 * b.val_25_0 as string) as result,
|
||||
'overflow' as expected
|
||||
FROM test_boundary_values a, test_boundary_values b
|
||||
WHERE a.id = 1 AND b.id = 1;
|
||||
|
||||
-- 38-digit * 25-digit
|
||||
SELECT
|
||||
'Test 3.2: 38-digit * 25-digit' as test_case,
|
||||
cast(a.val_38_0 as string),
|
||||
cast(b.val_25_0 as string),
|
||||
cast(cast(a.val_38_0 as decimal(50, 10)) * b.val_25_0 as string) as result,
|
||||
'should not overflow' as expected
|
||||
FROM test_boundary_values a, test_boundary_values b
|
||||
WHERE a.id = 1 AND b.id = 1;
|
||||
|
||||
-- 25-digit * 25-digit
|
||||
-- can't auto scale up now
|
||||
SELECT
|
||||
'Test 3.3: 25-digit * 25-digit' as test_case,
|
||||
cast(val_25_0 as string),
|
||||
cast(val_25_0 * val_25_0 as string) as result,
|
||||
'overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- 25-digit * 25-digit
|
||||
SELECT
|
||||
'Test 3.3: 25-digit * 25-digit' as test_case,
|
||||
cast(val_25_0 as string),
|
||||
cast(val_25_0 * cast(val_25_0 as decimal(39, 0)) as string) as result,
|
||||
'should not overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- =============================================================================
|
||||
-- Test 4: Progressive boundary testing
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE test_progressive_boundary (
|
||||
id INT,
|
||||
digits INT,
|
||||
test_val DECIMAL(76, 0)
|
||||
) PROPERTIES("replication_num"="1");
|
||||
|
||||
-- Insert different digit count test values
|
||||
INSERT INTO test_progressive_boundary VALUES
|
||||
(1, 10, 9999999999), -- 10 digits
|
||||
(2, 15, 999999999999999), -- 15 digits
|
||||
(3, 20, 99999999999999999999), -- 20 digits
|
||||
(4, 25, 9999999999999999999999999), -- 25 digits
|
||||
(5, 30, 999999999999999999999999999999), -- 30 digits
|
||||
(6, 35, 99999999999999999999999999999999999), -- 35 digits
|
||||
(7, 38, 99999999999999999999999999999999999999); -- 38 digits
|
||||
|
||||
-- Test self-multiplication, observe overflow boundary
|
||||
SELECT
|
||||
id,
|
||||
digits,
|
||||
cast(test_val as string),
|
||||
cast(test_val * test_val as string) as result,
|
||||
CASE
|
||||
WHEN digits <= 19 THEN 'Should succeed'
|
||||
WHEN digits <= 25 THEN 'May succeed'
|
||||
WHEN digits > 30 THEN 'Should succeed'
|
||||
ELSE 'Boundary case'
|
||||
END as expected
|
||||
FROM test_progressive_boundary ORDER BY id;
|
||||
|
||||
-- =============================================================================
|
||||
-- Test 5: Scale overflow vs value overflow distinction
|
||||
-- =============================================================================
|
||||
|
||||
-- throw exception
|
||||
SELECT
|
||||
'Test 5.1: Scale overflow, tiny value' as test_case,
|
||||
cast(val_high_scale * val_high_scale as string) as result,
|
||||
'Should fail due to scale=100 > 76' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Value overflow but reasonable scale
|
||||
SELECT
|
||||
'Test 5.2: Value overflow, scale OK' as test_case,
|
||||
cast(val_38_0 * val_38_0 as string) as result,
|
||||
'Should fail due to value overflow, scale=0 is fine' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- =============================================================================
|
||||
-- Test 6: Special values and boundary cases
|
||||
-- =============================================================================
|
||||
|
||||
-- Multiply by 0
|
||||
SELECT
|
||||
'Test 6.1: Large * 0' as test_case,
|
||||
cast(val_76_0 * 0 as string) as result,
|
||||
'Should return 0, no overflow' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Multiply by 1
|
||||
SELECT
|
||||
'Test 6.2: Large * 1' as test_case,
|
||||
cast(val_76_0 * 1 as string) as result,
|
||||
'Should return original value' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Multiply by decimal
|
||||
SELECT
|
||||
'Test 6.3: Large * 0.1' as test_case,
|
||||
cast(val_76_0 * 0.1 as string) as result,
|
||||
'Should succeed, reduces magnitude' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- Multiply by -1
|
||||
SELECT
|
||||
'Test 6.4: Large * -1' as test_case,
|
||||
cast(val_76_0 * (-1) as string) as result,
|
||||
'Should return negative of original' as expected
|
||||
FROM test_boundary_values WHERE id = 1;
|
||||
|
||||
-- =============================================================================
|
||||
-- Test 7: Real-world scenario boundary tests
|
||||
-- =============================================================================
|
||||
-- Test scientific computation scenario
|
||||
SELECT
|
||||
'Test 7.2: Scientific calculation' as test_case,
|
||||
cast(d76_10 * d76_10 as string) as result,
|
||||
'Simulates scientific computation overflow' as expected
|
||||
FROM test_decimal_multiply_overflow WHERE id = 3;
|
||||
|
|
@ -0,0 +1,437 @@
|
|||
-- name: test_decimal256_cast_operations
|
||||
DROP DATABASE IF EXISTS test_decimal256_cast;
|
||||
CREATE DATABASE test_decimal256_cast;
|
||||
USE test_decimal256_cast;
|
||||
|
||||
-- Create test table with various data types
|
||||
CREATE TABLE cast_test_source (
|
||||
id int,
|
||||
bool_val boolean,
|
||||
tinyint_val tinyint,
|
||||
smallint_val smallint,
|
||||
int_val int,
|
||||
bigint_val bigint,
|
||||
largeint_val largeint,
|
||||
float_val float,
|
||||
double_val double,
|
||||
varchar_val varchar(100),
|
||||
-- decimal256 columns for testing (precision > 38, <= 76)
|
||||
decimal256_50_15 decimal(50,15), -- 50 digits total, 15 after decimal
|
||||
decimal256_76_20 decimal(76,20), -- 76 digits total, 20 after decimal
|
||||
decimal256_76_0 decimal(76,0), -- 76 digits total, 0 after decimal
|
||||
-- regular decimal columns for comparison (precision <= 38)
|
||||
decimal_38_10 decimal(38,10), -- 38 digits total, 10 after decimal
|
||||
decimal_20_5 decimal(20,5) -- 20 digits total, 5 after decimal
|
||||
) ENGINE=OLAP
|
||||
DUPLICATE KEY(id)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
);
|
||||
|
||||
-- Insert comprehensive test data with correct digit limits
|
||||
INSERT INTO cast_test_source VALUES
|
||||
-- Basic values - decimal256 (50,15): max 35 digits before decimal, 15 after
|
||||
-- decimal256 (76,20): max 56 digits before decimal, 20 after
|
||||
-- decimal256 (76,0): max 76 digits before decimal, 0 after
|
||||
(1, true, 127, 32767, 2147483647, 9223372036854775807, 170141183460469231731687303715884105727,
|
||||
3.14159, 2.718281828459045, '12345678901234567890123456789012345.123456789012345',
|
||||
12345678901234567890123456789012345.123456789012345, -- 35+15=50 digits
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890, -- 56+20=76 digits
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456, -- 76 digits
|
||||
1234567890123456789012345678.1234567890, -- 28+10=38 digits
|
||||
123456789012345.12345), -- 15+5=20 digits
|
||||
|
||||
-- Zero values
|
||||
(2, false, 0, 0, 0, 0, 0, 0.0, 0.0, '0',
|
||||
0.000000000000000,
|
||||
0.00000000000000000000,
|
||||
0,
|
||||
0.0000000000,
|
||||
0.00000),
|
||||
|
||||
-- Negative values
|
||||
(3, false, -128, -32768, -2147483648, -9223372036854775808, -170141183460469231731687303715884105728,
|
||||
-3.14159, -2.718281828459045, '-87654321098765432109876543210987654.987654321098765',
|
||||
-87654321098765432109876543210987654.987654321098765, -- 35+15=50 digits
|
||||
-87654321098765432109876543210987654321098765432109876543.98765432109876543210, -- 56+20=76 digits
|
||||
-8765432109876543210987654321098765432109876543210987654321098765432109876543, -- 76 digits
|
||||
-8765432109876543210987654321.9876543210, -- 28+10=38 digits
|
||||
-876543210987654.98765), -- 15+5=20 digits
|
||||
|
||||
-- Maximum positive values within limits
|
||||
(4, true, 127, 32767, 2147483647, 9223372036854775807, 170141183460469231731687303715884105727,
|
||||
1.7976931348623157e+308, 1.7976931348623157e+308, '99999999999999999999999999999999999.999999999999999',
|
||||
99999999999999999999999999999999999.999999999999999, -- 35+15=50 digits
|
||||
99999999999999999999999999999999999999999999999999999999.99999999999999999999, -- 56+20=76 digits
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999, -- 76 digits
|
||||
9999999999999999999999999999.9999999999, -- 28+10=38 digits
|
||||
999999999999999.99999), -- 15+5=20 digits
|
||||
|
||||
-- Minimum values (most negative) within limits
|
||||
(5, false, -128, -32768, -2147483648, -9223372036854775808, -170141183460469231731687303715884105728,
|
||||
-1.7976931348623157e+308, -1.7976931348623157e+308, '-99999999999999999999999999999999999.999999999999999',
|
||||
-99999999999999999999999999999999999.999999999999999, -- 35+15=50 digits
|
||||
-99999999999999999999999999999999999999999999999999999999.99999999999999999999, -- 56+20=76 digits
|
||||
-9999999999999999999999999999999999999999999999999999999999999999999999999999, -- 76 digits
|
||||
-9999999999999999999999999999.9999999999, -- 28+10=38 digits
|
||||
-999999999999999.99999), -- 15+5=20 digits
|
||||
|
||||
-- Small fractional values
|
||||
(6, true, 1, 1, 1, 1, 1, 0.000001, 0.000000000000001, '0.000000000000001',
|
||||
0.000000000000001,
|
||||
0.00000000000000000001,
|
||||
1,
|
||||
0.0000000001,
|
||||
0.00001),
|
||||
|
||||
-- Mid-range values
|
||||
(7, false, 42, 1234, 567890, 123456789012345, 987654321098765432109876543210,
|
||||
123.456789, 987.654321123456789, '555555555555555555555555555555555.555555555555555',
|
||||
55555555555555555555555555555555555.555555555555555, -- 35+15=50 digits
|
||||
55555555555555555555555555555555555555555555555555555555.55555555555555555555, -- 56+20=76 digits
|
||||
5555555555555555555555555555555555555555555555555555555555555555555555555555, -- 76 digits
|
||||
5555555555555555555555555555.5555555555, -- 28+10=38 digits
|
||||
555555555555555.55555), -- 15+5=20 digits
|
||||
|
||||
-- Edge case: very small positive numbers
|
||||
(8, true, 1, 10, 100, 1000, 10000,
|
||||
1e-10, 1e-15, '0.000000000000001',
|
||||
0.000000000000001,
|
||||
0.00000000000000000001,
|
||||
1,
|
||||
0.0000000001,
|
||||
0.00001),
|
||||
|
||||
-- Edge case: numbers with many digits but within limits
|
||||
(9, false, 99, 9999, 999999999, 999999999999999999, 99999999999999999999999999999999999999,
|
||||
999999.999999, 999999999.999999999999, '77777777777777777777777777777777777.777777777777777',
|
||||
77777777777777777777777777777777777.777777777777777, -- 35+15=50 digits
|
||||
77777777777777777777777777777777777777777777777777777777.77777777777777777777, -- 56+20=76 digits
|
||||
7777777777777777777777777777777777777777777777777777777777777777777777777777, -- 76 digits
|
||||
7777777777777777777777777777.7777777777, -- 28+10=38 digits
|
||||
777777777777777.77777), -- 15+5=20 digits
|
||||
|
||||
-- NULL values for testing
|
||||
(10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
-- Test 1: CAST from boolean to decimal256
|
||||
SELECT
|
||||
id,
|
||||
bool_val,
|
||||
CAST(bool_val AS decimal(50,15)) as bool_to_decimal256_50_15,
|
||||
CAST(bool_val AS decimal(76,20)) as bool_to_decimal256_76_20,
|
||||
CAST(bool_val AS decimal(76,0)) as bool_to_decimal256_76_0,
|
||||
CAST(bool_val AS decimal(38,10)) as bool_to_decimal_38_10
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 2: CAST from integer types to decimal256
|
||||
SELECT
|
||||
id,
|
||||
tinyint_val,
|
||||
CAST(tinyint_val AS decimal(50,15)) as tinyint_to_decimal256,
|
||||
smallint_val,
|
||||
CAST(smallint_val AS decimal(50,15)) as smallint_to_decimal256,
|
||||
int_val,
|
||||
CAST(int_val AS decimal(50,15)) as int_to_decimal256
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
|
||||
SELECT
|
||||
id,
|
||||
bigint_val,
|
||||
CAST(bigint_val AS decimal(76,20)) as bigint_to_decimal256,
|
||||
largeint_val,
|
||||
CAST(largeint_val AS decimal(76,0)) as largeint_to_decimal256
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 3: CAST from floating point types to decimal256
|
||||
SELECT
|
||||
id,
|
||||
float_val,
|
||||
CAST(float_val AS decimal(50,15)) as float_to_decimal256_50_15,
|
||||
CAST(float_val AS decimal(76,20)) as float_to_decimal256_76_20,
|
||||
double_val,
|
||||
CAST(double_val AS decimal(50,15)) as double_to_decimal256_50_15,
|
||||
CAST(double_val AS decimal(76,20)) as double_to_decimal256_76_20
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 4: CAST from varchar to decimal256
|
||||
SELECT
|
||||
id,
|
||||
varchar_val,
|
||||
CAST(varchar_val AS decimal(50,15)) as varchar_to_decimal256_50_15,
|
||||
CAST(varchar_val AS decimal(76,20)) as varchar_to_decimal256_76_20,
|
||||
CAST(varchar_val AS decimal(76,0)) as varchar_to_decimal256_76_0
|
||||
FROM cast_test_source
|
||||
WHERE varchar_val IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 5: CAST from decimal256 to other types
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15,
|
||||
CAST(decimal256_50_15 AS boolean) as decimal256_to_bool,
|
||||
CAST(decimal256_50_15 AS tinyint) as decimal256_to_tinyint,
|
||||
CAST(decimal256_50_15 AS smallint) as decimal256_to_smallint,
|
||||
CAST(decimal256_50_15 AS int) as decimal256_to_int,
|
||||
CAST(decimal256_50_15 AS bigint) as decimal256_to_bigint,
|
||||
CAST(decimal256_50_15 AS largeint) as decimal256_to_largeint
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
SELECT
|
||||
id,
|
||||
decimal256_76_20,
|
||||
CAST(decimal256_76_20 AS float) as decimal256_to_float,
|
||||
CAST(decimal256_76_20 AS double) as decimal256_to_double,
|
||||
CAST(decimal256_76_20 AS varchar(100)) as decimal256_to_varchar
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_76_20 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 6: CAST between different decimal precisions
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15,
|
||||
CAST(decimal256_50_15 AS decimal(76,20)) as decimal256_50_15_to_76_20,
|
||||
CAST(decimal256_50_15 AS decimal(76,0)) as decimal256_50_15_to_76_0,
|
||||
CAST(decimal256_50_15 AS decimal(38,10)) as decimal256_50_15_to_38_10,
|
||||
decimal256_76_20,
|
||||
CAST(decimal256_76_20 AS decimal(50,15)) as decimal256_76_20_to_50_15,
|
||||
CAST(decimal256_76_20 AS decimal(76,0)) as decimal256_76_20_to_76_0
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 7: CAST between decimal256 and regular decimal
|
||||
SELECT
|
||||
id,
|
||||
decimal_38_10,
|
||||
CAST(decimal_38_10 AS decimal(50,15)) as decimal_38_10_to_decimal256_50_15,
|
||||
CAST(decimal_38_10 AS decimal(76,20)) as decimal_38_10_to_decimal256_76_20,
|
||||
decimal256_50_15,
|
||||
CAST(decimal256_50_15 AS decimal(38,10)) as decimal256_50_15_to_decimal_38_10,
|
||||
CAST(decimal256_50_15 AS decimal(20,5)) as decimal256_50_15_to_decimal_20_5
|
||||
FROM cast_test_source
|
||||
WHERE decimal_38_10 IS NOT NULL AND decimal256_50_15 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 8: Arithmetic operations with automatic casting
|
||||
-- Addition with different types
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 + tinyint_val as decimal256_plus_tinyint,
|
||||
decimal256_50_15 + smallint_val as decimal256_plus_smallint,
|
||||
decimal256_50_15 + int_val as decimal256_plus_int,
|
||||
decimal256_50_15 + bigint_val as decimal256_plus_bigint,
|
||||
decimal256_50_15 + largeint_val as decimal256_plus_largeint
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND tinyint_val IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
SELECT
|
||||
id,
|
||||
decimal256_76_20 + float_val as decimal256_plus_float,
|
||||
decimal256_76_20 + double_val as decimal256_plus_double,
|
||||
decimal256_50_15 + decimal_38_10 as decimal256_plus_decimal38
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_76_20 IS NOT NULL AND float_val IS NOT NULL AND decimal256_50_15 IS NOT NULL AND decimal_38_10 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Subtraction with different types
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 - tinyint_val as decimal256_minus_tinyint,
|
||||
decimal256_50_15 - smallint_val as decimal256_minus_smallint,
|
||||
decimal256_50_15 - int_val as decimal256_minus_int,
|
||||
decimal256_50_15 - bigint_val as decimal256_minus_bigint,
|
||||
decimal256_76_20 - decimal_38_10 as decimal256_minus_decimal38
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND tinyint_val IS NOT NULL AND decimal256_76_20 IS NOT NULL AND decimal_38_10 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Multiplication with different types
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 * tinyint_val as decimal256_multiply_tinyint,
|
||||
decimal256_50_15 * smallint_val as decimal256_multiply_smallint,
|
||||
decimal256_76_20 * float_val as decimal256_multiply_float,
|
||||
decimal256_76_20 * double_val as decimal256_multiply_double,
|
||||
decimal256_50_15 * decimal_20_5 as decimal256_multiply_decimal20
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL AND tinyint_val IS NOT NULL
|
||||
AND float_val IS NOT NULL AND decimal_20_5 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Division with different types
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 / tinyint_val as decimal256_divide_tinyint,
|
||||
decimal256_50_15 / smallint_val as decimal256_divide_smallint,
|
||||
decimal256_76_20 / float_val as decimal256_divide_float,
|
||||
decimal256_76_20 / double_val as decimal256_divide_double,
|
||||
decimal256_50_15 / decimal_20_5 as decimal256_divide_decimal20
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL
|
||||
AND tinyint_val IS NOT NULL AND tinyint_val != 0 AND smallint_val != 0
|
||||
AND float_val IS NOT NULL AND float_val != 0 AND double_val IS NOT NULL AND double_val != 0
|
||||
AND decimal_20_5 IS NOT NULL AND decimal_20_5 != 0
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 9: Mixed arithmetic operations between decimal256 columns
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 + decimal256_76_20 as decimal256_addition,
|
||||
decimal256_50_15 - decimal256_76_20 as decimal256_subtraction,
|
||||
decimal256_50_15 * decimal256_76_0 as decimal256_multiplication,
|
||||
decimal256_76_20 / decimal256_76_0 as decimal256_division
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL
|
||||
AND decimal256_76_0 IS NOT NULL AND decimal256_76_0 != 0
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 10: Complex arithmetic expressions with casting
|
||||
SELECT
|
||||
id,
|
||||
(decimal256_50_15 + CAST(int_val AS decimal(50,15))) * CAST(float_val AS decimal(50,15)) as complex_expr1,
|
||||
(decimal256_76_20 - CAST(bigint_val AS decimal(76,20))) / CAST(double_val AS decimal(76,20)) as complex_expr2,
|
||||
CAST(tinyint_val AS decimal(76,0)) + decimal256_76_0 - CAST(smallint_val AS decimal(76,0)) as complex_expr3,
|
||||
(decimal256_50_15 + decimal_38_10) * CAST(decimal_20_5 AS decimal(50,15)) as complex_expr4
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL AND decimal256_76_0 IS NOT NULL
|
||||
AND int_val IS NOT NULL AND float_val IS NOT NULL AND float_val != 0
|
||||
AND bigint_val IS NOT NULL AND double_val IS NOT NULL AND double_val != 0
|
||||
AND tinyint_val IS NOT NULL AND smallint_val IS NOT NULL
|
||||
AND decimal_38_10 IS NOT NULL AND decimal_20_5 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 11: Aggregation functions with casting
|
||||
SELECT
|
||||
SUM(CAST(tinyint_val AS decimal(76,20))) as sum_tinyint_as_decimal256,
|
||||
AVG(CAST(int_val AS decimal(76,20))) as avg_int_as_decimal256,
|
||||
MIN(CAST(bigint_val AS decimal(76,20))) as min_bigint_as_decimal256,
|
||||
MAX(CAST(largeint_val AS decimal(76,0))) as max_largeint_as_decimal256
|
||||
FROM cast_test_source
|
||||
WHERE tinyint_val IS NOT NULL;
|
||||
|
||||
SELECT
|
||||
SUM(decimal256_50_15) as sum_decimal256_50_15,
|
||||
AVG(decimal256_76_20) as avg_decimal256_76_20,
|
||||
MIN(decimal256_76_0) as min_decimal256_76_0,
|
||||
MAX(decimal256_76_0) as max_decimal256_76_0,
|
||||
SUM(decimal_38_10) as sum_decimal_38_10,
|
||||
AVG(decimal_20_5) as avg_decimal_20_5
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL;
|
||||
|
||||
-- Test 12: CASE expressions with casting
|
||||
SELECT
|
||||
id,
|
||||
CASE
|
||||
WHEN tinyint_val > 0 THEN CAST(tinyint_val AS decimal(50,15))
|
||||
WHEN tinyint_val < 0 THEN CAST(ABS(tinyint_val) AS decimal(50,15))
|
||||
ELSE 0.000000000000000
|
||||
END as case_tinyint_to_decimal256,
|
||||
CASE
|
||||
WHEN decimal256_50_15 > 0 THEN CAST(decimal256_50_15 AS varchar(100))
|
||||
WHEN decimal256_50_15 < 0 THEN CONCAT('negative: ', CAST(ABS(decimal256_50_15) AS varchar(100)))
|
||||
ELSE 'zero'
|
||||
END as case_decimal256_to_varchar,
|
||||
CASE
|
||||
WHEN decimal_38_10 > decimal256_50_15 THEN 'decimal38_larger'
|
||||
WHEN decimal_38_10 < decimal256_50_15 THEN 'decimal256_larger'
|
||||
ELSE 'equal'
|
||||
END as case_decimal_comparison
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal_38_10 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 13: Comparison operations with automatic casting
|
||||
SELECT
|
||||
id,
|
||||
decimal256_50_15 > CAST(int_val AS decimal(50,15)) as decimal256_gt_int,
|
||||
decimal256_76_20 = CAST(float_val AS decimal(76,20)) as decimal256_eq_float,
|
||||
decimal256_76_0 < CAST(largeint_val AS decimal(76,0)) as decimal256_lt_largeint,
|
||||
CAST(bigint_val AS decimal(76,20)) BETWEEN decimal256_76_20 - 1000 AND decimal256_76_20 + 1000 as bigint_between_decimal256,
|
||||
decimal256_50_15 > decimal_38_10 as decimal256_gt_decimal38,
|
||||
decimal_20_5 = CAST(decimal256_50_15 AS decimal(20,5)) as decimal20_eq_decimal256_cast
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_50_15 IS NOT NULL AND decimal256_76_20 IS NOT NULL AND decimal256_76_0 IS NOT NULL
|
||||
AND int_val IS NOT NULL AND float_val IS NOT NULL AND largeint_val IS NOT NULL AND bigint_val IS NOT NULL
|
||||
AND decimal_38_10 IS NOT NULL AND decimal_20_5 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 14: UNION operations with casting
|
||||
SELECT id, CAST(tinyint_val AS decimal(76,20)) as unified_decimal256, 'tinyint' as source_type FROM cast_test_source WHERE tinyint_val IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT id, CAST(int_val AS decimal(76,20)) as unified_decimal256, 'int' as source_type FROM cast_test_source WHERE int_val IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT id, decimal256_76_20 as unified_decimal256, 'decimal256_76_20' as source_type FROM cast_test_source WHERE decimal256_76_20 IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT id, CAST(decimal_38_10 AS decimal(76,20)) as unified_decimal256, 'decimal_38_10' as source_type FROM cast_test_source WHERE decimal_38_10 IS NOT NULL
|
||||
ORDER BY id, unified_decimal256;
|
||||
|
||||
-- Test 15
|
||||
CREATE TABLE cast_test_target (
|
||||
id int,
|
||||
target_decimal256 decimal(76,20),
|
||||
target_decimal38 decimal(38,10),
|
||||
target_int bigint
|
||||
) ENGINE=OLAP
|
||||
DUPLICATE KEY(id)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
);
|
||||
|
||||
INSERT INTO cast_test_target VALUES
|
||||
(1, 12345678901234567890123456789012345678901234567890123456.12345678901234567890, 1234567890123456789012345678.1234567890, 9223372036854775807),
|
||||
(2, 0.00000000000000000000, 0.0000000000, 0),
|
||||
(3, -87654321098765432109876543210987654321098765432109876543.98765432109876543210, -8765432109876543210987654321.9876543210, -9223372036854775808),
|
||||
(4, 99999999999999999999999999999999999999999999999999999999.99999999999999999999, 9999999999999999999999999999.9999999999, 9223372036854775807),
|
||||
(5, -99999999999999999999999999999999999999999999999999999999.99999999999999999999, -9999999999999999999999999999.9999999999, -9223372036854775808);
|
||||
|
||||
|
||||
-- Test 16: Error handling and boundary tests
|
||||
SELECT
|
||||
id,
|
||||
CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS decimal(76,0)) as max_decimal256_76_0,
|
||||
CAST('99999999999999999999999999999999999999999999999999999999.99999999999999999999' AS decimal(76,20)) as max_decimal256_76_20,
|
||||
CAST('99999999999999999999999999999999999.999999999999999' AS decimal(50,15)) as max_decimal256_50_15
|
||||
FROM cast_test_source
|
||||
WHERE id = 1;
|
||||
|
||||
-- Test casting very small numbers
|
||||
SELECT
|
||||
id,
|
||||
CAST('0.00000000000000000001' AS decimal(76,20)) as min_decimal256_76_20,
|
||||
CAST('0.000000000000001' AS decimal(50,15)) as min_decimal256_50_15,
|
||||
CAST('0.0000000001' AS decimal(38,10)) as min_decimal_38_10
|
||||
FROM cast_test_source
|
||||
WHERE id = 1;
|
||||
|
||||
-- Test casting with precision loss
|
||||
SELECT
|
||||
id,
|
||||
decimal256_76_20,
|
||||
CAST(decimal256_76_20 AS decimal(50,10)) as decimal256_with_precision_loss,
|
||||
CAST(decimal256_50_15 AS decimal(38,5)) as decimal256_with_scale_loss,
|
||||
CAST(decimal_38_10 AS decimal(20,5)) as decimal38_with_precision_loss
|
||||
FROM cast_test_source
|
||||
WHERE decimal256_76_20 IS NOT NULL AND decimal256_50_15 IS NOT NULL AND decimal_38_10 IS NOT NULL
|
||||
ORDER BY id;
|
||||
|
||||
-- Test 17: NULL handling in casting
|
||||
SELECT
|
||||
id,
|
||||
CAST(NULL AS decimal(76,20)) as null_to_decimal256,
|
||||
CAST(decimal256_50_15 AS varchar(100)) as decimal256_to_varchar_with_null,
|
||||
COALESCE(CAST(tinyint_val AS decimal(50,15)), 0.000000000000000) as coalesce_cast_tinyint,
|
||||
COALESCE(CAST(decimal_38_10 AS decimal(76,20)), 0.00000000000000000000) as coalesce_cast_decimal38
|
||||
FROM cast_test_source
|
||||
ORDER BY id;
|
||||
|
|
@ -0,0 +1,657 @@
|
|||
-- name: test_decimal256_predicate
|
||||
DROP DATABASE IF EXISTS test_decimal256_predicate;
|
||||
CREATE DATABASE test_decimal256_predicate;
|
||||
USE test_decimal256_predicate;
|
||||
|
||||
-- Create decimal256 test table with only precision > 38 columns
|
||||
CREATE TABLE decimal_test (
|
||||
id int,
|
||||
big_decimal decimal(50,15), -- decimal256: max 35 integer digits + 15 decimal digits
|
||||
huge_decimal decimal(76,20), -- decimal256: max 56 integer digits + 20 decimal digits
|
||||
max_decimal decimal(76,0) -- decimal256: max 76 integer digits + 0 decimal digits
|
||||
) ENGINE=OLAP
|
||||
DUPLICATE KEY(id)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
);
|
||||
|
||||
-- Insert test data with strict precision limits
|
||||
INSERT INTO decimal_test VALUES
|
||||
-- id=1: normal values
|
||||
(1, 12345678901234567890123456789012345.123456789012345,
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890,
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456),
|
||||
|
||||
-- id=2: another set of values
|
||||
(2, 87654321098765432109876543210987654.987654321098765,
|
||||
87654321098765432109876543210987654321098765432109876543.98765432109876543210,
|
||||
8765432109876543210987654321098765432109876543210987654321098765432109876543),
|
||||
|
||||
-- id=3: repeating digits
|
||||
(3, 55555555555555555555555555555555555.555555555555555,
|
||||
55555555555555555555555555555555555555555555555555555555.55555555555555555555,
|
||||
5555555555555555555555555555555555555555555555555555555555555555555555555555),
|
||||
|
||||
-- id=4: all ones
|
||||
(4, 11111111111111111111111111111111111.111111111111111,
|
||||
11111111111111111111111111111111111111111111111111111111.11111111111111111111,
|
||||
1111111111111111111111111111111111111111111111111111111111111111111111111111),
|
||||
|
||||
-- id=5: near maximum values
|
||||
(5, 99999999999999999999999999999999999.999999999999999,
|
||||
99999999999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999),
|
||||
|
||||
-- id=6: minimum positive numbers
|
||||
(6, 0.000000000000001,
|
||||
0.00000000000000000001,
|
||||
1),
|
||||
|
||||
-- id=7: negative numbers
|
||||
(7, -12345678901234567890123456789012345.123456789012345,
|
||||
-12345678901234567890123456789012345678901234567890123456.12345678901234567890,
|
||||
-1234567890123456789012345678901234567890123456789012345678901234567890123456),
|
||||
|
||||
-- id=8: large negative numbers
|
||||
(8, -99999999999999999999999999999999999.999999999999999,
|
||||
-99999999999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
-9999999999999999999999999999999999999999999999999999999999999999999999999999),
|
||||
|
||||
-- id=9: NULL values
|
||||
(9, NULL, NULL, NULL),
|
||||
|
||||
-- id=10: sevens pattern
|
||||
(10, 77777777777777777777777777777777777.777777777777777,
|
||||
77777777777777777777777777777777777777777777777777777777.77777777777777777777,
|
||||
7777777777777777777777777777777777777777777777777777777777777777777777777777);
|
||||
|
||||
-- Insert boundary test values for each column
|
||||
INSERT INTO decimal_test VALUES
|
||||
-- id=11: maximum positive values for each column
|
||||
(11, 99999999999999999999999999999999999.999999999999999,
|
||||
99999999999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
9999999999999999999999999999999999999999999999999999999999999999999999999999),
|
||||
|
||||
-- id=12: maximum negative values for each column
|
||||
(12, -99999999999999999999999999999999999.999999999999999,
|
||||
-99999999999999999999999999999999999999999999999999999999.99999999999999999999,
|
||||
-9999999999999999999999999999999999999999999999999999999999999999999999999999),
|
||||
|
||||
-- id=13: zero values
|
||||
(13, 0.000000000000000,
|
||||
0.00000000000000000000,
|
||||
0),
|
||||
|
||||
-- id=14: minimum precision positive values
|
||||
(14, 0.000000000000001,
|
||||
0.00000000000000000001,
|
||||
1),
|
||||
|
||||
-- id=15: minimum precision negative values
|
||||
(15, -0.000000000000001,
|
||||
-0.00000000000000000001,
|
||||
-1);
|
||||
|
||||
-- Use CAST to ensure correct precision
|
||||
INSERT INTO decimal_test VALUES
|
||||
(16, CAST('12345678901234567890123456789012345.123456789012345' AS decimal(50,15)), -- 35+15=50 digits
|
||||
CAST('12345678901234567890123456789012345678901234567890123456.12345678901234567890' AS decimal(76,20)), -- 56+20=76 digits
|
||||
CAST('1234567890123456789012345678901234567890123456789012345678901234567890123456' AS decimal(76,0))); -- 76+0=76 digits
|
||||
|
||||
-- Verify data insertion
|
||||
SELECT
|
||||
id,
|
||||
big_decimal,
|
||||
huge_decimal,
|
||||
max_decimal
|
||||
FROM decimal_test
|
||||
ORDER BY id;
|
||||
|
||||
-- Check data types and precision
|
||||
SELECT
|
||||
id,
|
||||
TYPEOF(big_decimal) as big_decimal_type,
|
||||
TYPEOF(huge_decimal) as huge_decimal_type,
|
||||
TYPEOF(max_decimal) as max_decimal_type
|
||||
FROM decimal_test
|
||||
WHERE id = 1
|
||||
ORDER BY id;
|
||||
|
||||
-- Equality tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal = 12345678901234567890123456789012345.123456789012345 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal = 12345678901234567890123456789012345678901234567890123456.12345678901234567890 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal = 1234567890123456789012345678901234567890123456789012345678901234567890123456 ORDER BY id;
|
||||
|
||||
-- Greater than tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal > 50000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal > 50000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal > 5000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Less than tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal < 50000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal < 50000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal < 5000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- IN tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal IN (
|
||||
12345678901234567890123456789012345.123456789012345,
|
||||
87654321098765432109876543210987654.987654321098765
|
||||
) ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IN (
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890,
|
||||
87654321098765432109876543210987654321098765432109876543.98765432109876543210
|
||||
) ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE max_decimal IN (
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456,
|
||||
8765432109876543210987654321098765432109876543210987654321098765432109876543
|
||||
) ORDER BY id;
|
||||
|
||||
-- NOT IN tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal NOT IN (
|
||||
12345678901234567890123456789012345.123456789012345,
|
||||
87654321098765432109876543210987654.987654321098765
|
||||
) ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE huge_decimal NOT IN (
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890,
|
||||
87654321098765432109876543210987654321098765432109876543.98765432109876543210
|
||||
) ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE max_decimal NOT IN (
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456,
|
||||
8765432109876543210987654321098765432109876543210987654321098765432109876543
|
||||
) ORDER BY id;
|
||||
|
||||
-- BETWEEN tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal BETWEEN
|
||||
10000000000000000000000000000000000.000000000000000 AND
|
||||
90000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE huge_decimal BETWEEN
|
||||
10000000000000000000000000000000000000000000000000000000.00000000000000000000 AND
|
||||
90000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE max_decimal BETWEEN
|
||||
1000000000000000000000000000000000000000000000000000000000000000000000000000 AND
|
||||
9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- NOT BETWEEN tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal NOT BETWEEN
|
||||
10000000000000000000000000000000000.000000000000000 AND
|
||||
90000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE huge_decimal NOT BETWEEN
|
||||
10000000000000000000000000000000000000000000000000000000.00000000000000000000 AND
|
||||
90000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE max_decimal NOT BETWEEN
|
||||
1000000000000000000000000000000000000000000000000000000000000000000000000000 AND
|
||||
9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Greater than or equal (>=) tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal >= 12345678901234567890123456789012345.123456789012345 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal >= 12345678901234567890123456789012345678901234567890123456.12345678901234567890 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal >= 1234567890123456789012345678901234567890123456789012345678901234567890123456 ORDER BY id;
|
||||
|
||||
-- Boundary value >= tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal >= 99999999999999999999999999999999999.999999999999999 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal >= 99999999999999999999999999999999999999999999999999999999.99999999999999999999 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal >= 9999999999999999999999999999999999999999999999999999999999999999999999999999 ORDER BY id;
|
||||
|
||||
-- Zero value >= tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal >= 0.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal >= 0.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal >= 0 ORDER BY id;
|
||||
|
||||
-- Negative number >= tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal >= -50000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal >= -50000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal >= -5000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Small value >= tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal >= 0.000000000000001 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal >= 0.00000000000000000001 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal >= 1 ORDER BY id;
|
||||
|
||||
-- Less than or equal (<=) tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal <= 87654321098765432109876543210987654.987654321098765 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal <= 87654321098765432109876543210987654321098765432109876543.98765432109876543210 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal <= 8765432109876543210987654321098765432109876543210987654321098765432109876543 ORDER BY id;
|
||||
|
||||
-- Maximum value <= tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal <= 99999999999999999999999999999999999.999999999999999 ORDER BY id;
|
||||
|
||||
-- Zero value <= tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal <= 0.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal <= 0.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal <= 0 ORDER BY id;
|
||||
|
||||
-- Negative number <= tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal <= -10000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal <= -10000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal <= -1000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Middle value <= tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal <= 50000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal <= 50000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal <= 5000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Two-condition AND tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal >= 10000000000000000000000000000000000.000000000000000
|
||||
AND big_decimal <= 90000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal >= 10000000000000000000000000000000000000000000000000000000.00000000000000000000
|
||||
AND huge_decimal <= 90000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal >= 1000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
AND max_decimal <= 9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Cross-column AND tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal >= 10000000000000000000000000000000000.000000000000000 AND huge_decimal <= 90000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal >= 10000000000000000000000000000000000000000000000000000000.00000000000000000000 AND max_decimal <= 9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE big_decimal >= 0.000000000000000 AND max_decimal >= 0 ORDER BY id;
|
||||
|
||||
-- Three-condition AND tests
|
||||
SELECT * FROM decimal_test WHERE
|
||||
big_decimal >= 10000000000000000000000000000000000.000000000000000 AND
|
||||
huge_decimal >= 10000000000000000000000000000000000000000000000000000000.00000000000000000000 AND
|
||||
max_decimal >= 1000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Mixed comparison AND tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal > 10000000000000000000000000000000000.000000000000000 AND huge_decimal <= 90000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal >= 10000000000000000000000000000000000000000000000000000000.00000000000000000000 AND max_decimal < 9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE big_decimal < 90000000000000000000000000000000000.000000000000000 AND max_decimal >= 1000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- NULL handling AND tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NOT NULL AND huge_decimal IS NOT NULL AND max_decimal IS NOT NULL ORDER BY id;
|
||||
|
||||
-- Two-condition OR tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal <= 10000000000000000000000000000000000.000000000000000
|
||||
OR big_decimal >= 90000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal <= 10000000000000000000000000000000000000000000000000000000.00000000000000000000
|
||||
OR huge_decimal >= 90000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal <= 1000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
OR max_decimal >= 9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Cross-column OR tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal >= 90000000000000000000000000000000000.000000000000000 OR huge_decimal <= 10000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal <= 10000000000000000000000000000000000000000000000000000000.00000000000000000000 OR max_decimal >= 9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE big_decimal <= 0.000000000000000 OR max_decimal >= 9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Three-condition OR tests
|
||||
SELECT * FROM decimal_test WHERE
|
||||
big_decimal <= 10000000000000000000000000000000000.000000000000000 OR
|
||||
huge_decimal <= 10000000000000000000000000000000000000000000000000000000.00000000000000000000 OR
|
||||
max_decimal <= 1000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Mixed comparison OR tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal < 10000000000000000000000000000000000.000000000000000 OR huge_decimal >= 90000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal <= 10000000000000000000000000000000000000000000000000000000.00000000000000000000 OR max_decimal > 9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE big_decimal > 90000000000000000000000000000000000.000000000000000 OR max_decimal < 1000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Extreme value OR tests
|
||||
SELECT * FROM decimal_test WHERE
|
||||
big_decimal = 99999999999999999999999999999999999.999999999999999 OR
|
||||
big_decimal = -99999999999999999999999999999999999.999999999999999 OR
|
||||
big_decimal = 0.000000000000000 ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE
|
||||
huge_decimal = 99999999999999999999999999999999999999999999999999999999.99999999999999999999 OR
|
||||
huge_decimal = -99999999999999999999999999999999999999999999999999999999.99999999999999999999 OR
|
||||
huge_decimal = 0.00000000000000000000 ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE
|
||||
max_decimal = 9999999999999999999999999999999999999999999999999999999999999999999999999999 OR
|
||||
max_decimal = -9999999999999999999999999999999999999999999999999999999999999999999999999999 OR
|
||||
max_decimal = 0 ORDER BY id;
|
||||
|
||||
-- NULL handling OR tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL OR huge_decimal IS NULL OR max_decimal IS NULL ORDER BY id;
|
||||
|
||||
-- AND and OR mixed tests
|
||||
SELECT * FROM decimal_test WHERE
|
||||
(big_decimal >= 10000000000000000000000000000000000.000000000000000 OR huge_decimal <= 10000000000000000000000000000000000000000000000000000000.00000000000000000000) AND
|
||||
max_decimal >= 1000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Complex nested conditions
|
||||
SELECT * FROM decimal_test WHERE
|
||||
((big_decimal >= 50000000000000000000000000000000000.000000000000000 OR big_decimal <= 10000000000000000000000000000000000.000000000000000) AND
|
||||
(huge_decimal >= 50000000000000000000000000000000000000000000000000000000.00000000000000000000)) OR
|
||||
max_decimal = 0 ORDER BY id;
|
||||
|
||||
-- Multi-level nested AND OR tests
|
||||
SELECT * FROM decimal_test WHERE
|
||||
(big_decimal BETWEEN 10000000000000000000000000000000000.000000000000000 AND 90000000000000000000000000000000000.000000000000000 AND
|
||||
(huge_decimal >= 50000000000000000000000000000000000000000000000000000000.00000000000000000000 OR huge_decimal <= 10000000000000000000000000000000000000000000000000000000.00000000000000000000)) OR
|
||||
(max_decimal >= 8000000000000000000000000000000000000000000000000000000000000000000000000000 AND
|
||||
big_decimal BETWEEN 10000000000000000000000000000000000.000000000000000 AND 90000000000000000000000000000000000.000000000000000) ORDER BY id;
|
||||
|
||||
-- Positive and negative mixed conditions
|
||||
SELECT * FROM decimal_test WHERE
|
||||
(big_decimal >= 0.000000000000000 AND huge_decimal >= 0.00000000000000000000 AND max_decimal >= 0) OR
|
||||
(big_decimal <= 0.000000000000000 AND huge_decimal <= 0.00000000000000000000 AND max_decimal <= 0) ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE
|
||||
(big_decimal >= 0.000000000000000 OR huge_decimal >= 0.00000000000000000000) AND
|
||||
(max_decimal >= 0 OR max_decimal <= -1000000000000000000000000000000000000000000000000000000000000000000000000000) ORDER BY id;
|
||||
|
||||
-- Range query performance tests
|
||||
SELECT COUNT(*) FROM decimal_test WHERE
|
||||
big_decimal >= 10000000000000000000000000000000000.000000000000000 OR
|
||||
huge_decimal >= 10000000000000000000000000000000000000000000000000000000.00000000000000000000 OR
|
||||
max_decimal >= 1000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
|
||||
-- Single column IS NULL tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IS NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal IS NULL ORDER BY id;
|
||||
|
||||
-- Count NULL values for each column
|
||||
SELECT COUNT(*) as null_big_decimal_count FROM decimal_test WHERE big_decimal IS NULL;
|
||||
SELECT COUNT(*) as null_huge_decimal_count FROM decimal_test WHERE huge_decimal IS NULL;
|
||||
SELECT COUNT(*) as null_max_decimal_count FROM decimal_test WHERE max_decimal IS NULL;
|
||||
|
||||
-- Use aggregate functions to count NULL values for all columns
|
||||
SELECT
|
||||
SUM(CASE WHEN big_decimal IS NULL THEN 1 ELSE 0 END) as big_decimal_nulls,
|
||||
SUM(CASE WHEN huge_decimal IS NULL THEN 1 ELSE 0 END) as huge_decimal_nulls,
|
||||
SUM(CASE WHEN max_decimal IS NULL THEN 1 ELSE 0 END) as max_decimal_nulls
|
||||
FROM decimal_test;
|
||||
|
||||
-- Single column IS NOT NULL tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NOT NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IS NOT NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal IS NOT NULL ORDER BY id;
|
||||
|
||||
-- Count non-NULL values for each column
|
||||
SELECT COUNT(*) as not_null_big_decimal_count FROM decimal_test WHERE big_decimal IS NOT NULL;
|
||||
SELECT COUNT(*) as not_null_huge_decimal_count FROM decimal_test WHERE huge_decimal IS NOT NULL;
|
||||
SELECT COUNT(*) as not_null_max_decimal_count FROM decimal_test WHERE max_decimal IS NOT NULL;
|
||||
|
||||
-- Use aggregate functions to count non-NULL values for all columns
|
||||
SELECT
|
||||
SUM(CASE WHEN big_decimal IS NOT NULL THEN 1 ELSE 0 END) as big_decimal_not_nulls,
|
||||
SUM(CASE WHEN huge_decimal IS NOT NULL THEN 1 ELSE 0 END) as huge_decimal_not_nulls,
|
||||
SUM(CASE WHEN max_decimal IS NOT NULL THEN 1 ELSE 0 END) as max_decimal_not_nulls
|
||||
FROM decimal_test;
|
||||
|
||||
-- Insert various NULL combination test data
|
||||
INSERT INTO decimal_test VALUES
|
||||
-- id=17: only big_decimal is NULL
|
||||
(17, NULL,
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890,
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456),
|
||||
|
||||
-- id=18: only huge_decimal is NULL
|
||||
(18, 12345678901234567890123456789012345.123456789012345,
|
||||
NULL,
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456),
|
||||
|
||||
-- id=19: only max_decimal is NULL
|
||||
(19, 12345678901234567890123456789012345.123456789012345,
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890,
|
||||
NULL),
|
||||
|
||||
-- id=20: big_decimal and huge_decimal are NULL
|
||||
(20, NULL, NULL,
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456),
|
||||
|
||||
-- id=21: big_decimal and max_decimal are NULL
|
||||
(21, NULL,
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890,
|
||||
NULL),
|
||||
|
||||
-- id=22: huge_decimal and max_decimal are NULL
|
||||
(22, 12345678901234567890123456789012345.123456789012345,
|
||||
NULL, NULL),
|
||||
|
||||
-- id=23: alternating NULL (columns 1 and 3)
|
||||
(23, NULL,
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890,
|
||||
NULL),
|
||||
|
||||
-- id=24: alternating NULL (column 2)
|
||||
(24, 12345678901234567890123456789012345.123456789012345,
|
||||
NULL,
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456),
|
||||
|
||||
-- id=25: all columns NULL except id
|
||||
(25, NULL, NULL, NULL);
|
||||
|
||||
-- Two columns both NULL AND tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL AND huge_decimal IS NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL AND max_decimal IS NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IS NULL AND max_decimal IS NULL ORDER BY id;
|
||||
|
||||
-- Two columns both NULL OR tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL OR huge_decimal IS NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL OR max_decimal IS NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IS NULL OR max_decimal IS NULL ORDER BY id;
|
||||
|
||||
-- All three columns NULL test
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL AND huge_decimal IS NULL AND max_decimal IS NULL ORDER BY id;
|
||||
|
||||
-- Any of three columns NULL test
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL OR huge_decimal IS NULL OR max_decimal IS NULL ORDER BY id;
|
||||
|
||||
-- All columns NULL test
|
||||
SELECT * FROM decimal_test WHERE
|
||||
big_decimal IS NULL AND
|
||||
huge_decimal IS NULL AND
|
||||
max_decimal IS NULL ORDER BY id;
|
||||
|
||||
-- Any column NULL test
|
||||
SELECT * FROM decimal_test WHERE
|
||||
big_decimal IS NULL OR
|
||||
huge_decimal IS NULL OR
|
||||
max_decimal IS NULL ORDER BY id;
|
||||
|
||||
-- Two columns both NOT NULL AND tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NOT NULL AND huge_decimal IS NOT NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NOT NULL AND max_decimal IS NOT NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IS NOT NULL AND max_decimal IS NOT NULL ORDER BY id;
|
||||
|
||||
-- Two columns both NOT NULL OR tests
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NOT NULL OR huge_decimal IS NOT NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NOT NULL OR max_decimal IS NOT NULL ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IS NOT NULL OR max_decimal IS NOT NULL ORDER BY id;
|
||||
|
||||
-- All three columns NOT NULL test
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NOT NULL AND huge_decimal IS NOT NULL AND max_decimal IS NOT NULL ORDER BY id;
|
||||
|
||||
-- Any of three columns NOT NULL test
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NOT NULL OR huge_decimal IS NOT NULL OR max_decimal IS NOT NULL ORDER BY id;
|
||||
|
||||
-- Complex mixed conditions
|
||||
SELECT * FROM decimal_test WHERE
|
||||
(big_decimal IS NULL AND huge_decimal IS NOT NULL) OR
|
||||
(max_decimal IS NOT NULL AND big_decimal IS NULL) ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE
|
||||
(huge_decimal IS NULL OR max_decimal IS NULL) AND
|
||||
(big_decimal IS NOT NULL) ORDER BY id;
|
||||
|
||||
-- Alternating NULL and NOT NULL patterns
|
||||
SELECT * FROM decimal_test WHERE
|
||||
big_decimal IS NULL AND
|
||||
huge_decimal IS NOT NULL AND
|
||||
max_decimal IS NULL ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE
|
||||
big_decimal IS NOT NULL AND
|
||||
huge_decimal IS NULL AND
|
||||
max_decimal IS NOT NULL ORDER BY id;
|
||||
|
||||
-- NULL with equality condition combinations
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL OR big_decimal = 12345678901234567890123456789012345.123456789012345 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IS NULL OR huge_decimal = 12345678901234567890123456789012345678901234567890123456.12345678901234567890 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal IS NULL OR max_decimal = 1234567890123456789012345678901234567890123456789012345678901234567890123456 ORDER BY id;
|
||||
|
||||
-- NULL with range condition combinations
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NULL OR (big_decimal >= 10000000000000000000000000000000000.000000000000000 AND big_decimal <= 90000000000000000000000000000000000.000000000000000) ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IS NULL OR (huge_decimal >= 10000000000000000000000000000000000000000000000000000000.00000000000000000000 AND huge_decimal <= 90000000000000000000000000000000000000000000000000000000.00000000000000000000) ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal IS NULL OR max_decimal >= 5000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- NOT NULL with numeric condition combinations
|
||||
SELECT * FROM decimal_test WHERE big_decimal IS NOT NULL AND big_decimal >= 50000000000000000000000000000000000.000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE huge_decimal IS NOT NULL AND huge_decimal <= 50000000000000000000000000000000000000000000000000000000.00000000000000000000 ORDER BY id;
|
||||
SELECT * FROM decimal_test WHERE max_decimal IS NOT NULL AND max_decimal BETWEEN 1000000000000000000000000000000000000000000000000000000000000000000000000000 AND 9000000000000000000000000000000000000000000000000000000000000000000000000000 ORDER BY id;
|
||||
|
||||
-- Complex NULL with numeric condition combinations
|
||||
SELECT * FROM decimal_test WHERE
|
||||
(big_decimal IS NULL OR big_decimal >= 50000000000000000000000000000000000.000000000000000) AND
|
||||
(huge_decimal IS NOT NULL AND huge_decimal <= 50000000000000000000000000000000000000000000000000000000.00000000000000000000) ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE
|
||||
(max_decimal IS NULL OR max_decimal >= 5000000000000000000000000000000000000000000000000000000000000000000000000000) AND
|
||||
(big_decimal IS NOT NULL OR huge_decimal IS NULL) ORDER BY id;
|
||||
|
||||
-- NULL with IN condition combinations
|
||||
SELECT * FROM decimal_test WHERE
|
||||
big_decimal IS NULL OR
|
||||
big_decimal IN (
|
||||
12345678901234567890123456789012345.123456789012345,
|
||||
87654321098765432109876543210987654.987654321098765
|
||||
) ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE
|
||||
huge_decimal IS NULL OR
|
||||
huge_decimal IN (
|
||||
12345678901234567890123456789012345678901234567890123456.12345678901234567890,
|
||||
87654321098765432109876543210987654321098765432109876543.98765432109876543210
|
||||
) ORDER BY id;
|
||||
|
||||
SELECT * FROM decimal_test WHERE
|
||||
max_decimal IS NULL OR
|
||||
max_decimal IN (
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456,
|
||||
8765432109876543210987654321098765432109876543210987654321098765432109876543
|
||||
) ORDER BY id;
|
||||
|
||||
-- COUNT with NULL
|
||||
SELECT COUNT(*) as total_rows FROM decimal_test;
|
||||
SELECT COUNT(big_decimal) as non_null_big_decimal FROM decimal_test;
|
||||
SELECT COUNT(huge_decimal) as non_null_huge_decimal FROM decimal_test;
|
||||
SELECT COUNT(max_decimal) as non_null_max_decimal FROM decimal_test;
|
||||
|
||||
-- SUM with NULL (NULL values are ignored)
|
||||
SELECT SUM(big_decimal) as sum_big_decimal FROM decimal_test;
|
||||
SELECT SUM(huge_decimal) as sum_huge_decimal FROM decimal_test;
|
||||
SELECT SUM(max_decimal) as sum_max_decimal FROM decimal_test;
|
||||
|
||||
-- AVG with NULL (NULL values are ignored)
|
||||
SELECT AVG(big_decimal) as avg_big_decimal FROM decimal_test;
|
||||
SELECT AVG(huge_decimal) as avg_huge_decimal FROM decimal_test;
|
||||
SELECT AVG(max_decimal) as avg_max_decimal FROM decimal_test;
|
||||
|
||||
-- MIN/MAX with NULL (NULL values are ignored)
|
||||
SELECT
|
||||
MIN(big_decimal) as min_big_decimal, MAX(big_decimal) as max_big_decimal,
|
||||
MIN(huge_decimal) as min_huge_decimal, MAX(huge_decimal) as max_huge_decimal,
|
||||
MIN(max_decimal) as min_max_decimal, MAX(max_decimal) as max_max_decimal
|
||||
FROM decimal_test;
|
||||
|
||||
-- Group by NULL status
|
||||
SELECT
|
||||
CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as big_decimal_status,
|
||||
COUNT(*) as count
|
||||
FROM decimal_test
|
||||
GROUP BY CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END
|
||||
ORDER BY big_decimal_status;
|
||||
|
||||
SELECT
|
||||
CASE WHEN huge_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as huge_decimal_status,
|
||||
COUNT(*) as count
|
||||
FROM decimal_test
|
||||
GROUP BY CASE WHEN huge_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END
|
||||
ORDER BY huge_decimal_status;
|
||||
|
||||
SELECT
|
||||
CASE WHEN max_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as max_decimal_status,
|
||||
COUNT(*) as count
|
||||
FROM decimal_test
|
||||
GROUP BY CASE WHEN max_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END
|
||||
ORDER BY max_decimal_status;
|
||||
|
||||
-- Multi-column NULL status combination grouping
|
||||
SELECT
|
||||
CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as big_decimal_status,
|
||||
CASE WHEN huge_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as huge_decimal_status,
|
||||
COUNT(*) as count
|
||||
FROM decimal_test
|
||||
GROUP BY
|
||||
CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END,
|
||||
CASE WHEN huge_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END
|
||||
ORDER BY big_decimal_status, huge_decimal_status;
|
||||
|
||||
SELECT
|
||||
CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as big_decimal_status,
|
||||
CASE WHEN max_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as max_decimal_status,
|
||||
COUNT(*) as count
|
||||
FROM decimal_test
|
||||
GROUP BY
|
||||
CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END,
|
||||
CASE WHEN max_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END
|
||||
ORDER BY big_decimal_status, max_decimal_status;
|
||||
|
||||
-- Three-column NULL status combination grouping
|
||||
SELECT
|
||||
CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as big_decimal_status,
|
||||
CASE WHEN huge_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as huge_decimal_status,
|
||||
CASE WHEN max_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as max_decimal_status,
|
||||
COUNT(*) as count
|
||||
FROM decimal_test
|
||||
GROUP BY
|
||||
CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END,
|
||||
CASE WHEN huge_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END,
|
||||
CASE WHEN max_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END
|
||||
ORDER BY big_decimal_status, huge_decimal_status, max_decimal_status;
|
||||
|
||||
-- HAVING with NULL conditions
|
||||
SELECT
|
||||
CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as big_decimal_status,
|
||||
COUNT(*) as count
|
||||
FROM decimal_test
|
||||
GROUP BY CASE WHEN big_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY big_decimal_status;
|
||||
|
||||
SELECT
|
||||
CASE WHEN huge_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END as huge_decimal_status,
|
||||
COUNT(*) as count
|
||||
FROM decimal_test
|
||||
GROUP BY CASE WHEN huge_decimal IS NULL THEN 'NULL' ELSE 'NOT NULL' END
|
||||
HAVING COUNT(*) > 2
|
||||
ORDER BY huge_decimal_status;
|
||||
|
||||
-- NULL behavior in sorting (NULL values usually sort first or last)
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal;
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal DESC;
|
||||
SELECT * FROM decimal_test ORDER BY huge_decimal;
|
||||
SELECT * FROM decimal_test ORDER BY huge_decimal DESC;
|
||||
SELECT * FROM decimal_test ORDER BY max_decimal;
|
||||
SELECT * FROM decimal_test ORDER BY max_decimal DESC;
|
||||
|
||||
-- Multi-column sorting with NULL handling
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal, huge_decimal;
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal DESC, huge_decimal DESC;
|
||||
SELECT * FROM decimal_test ORDER BY huge_decimal, max_decimal;
|
||||
SELECT * FROM decimal_test ORDER BY huge_decimal DESC, max_decimal DESC;
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal, huge_decimal, max_decimal;
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal DESC, huge_decimal DESC, max_decimal DESC;
|
||||
|
||||
-- Using NULLS FIRST/LAST
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal NULLS FIRST;
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal NULLS LAST;
|
||||
SELECT * FROM decimal_test ORDER BY huge_decimal NULLS FIRST;
|
||||
SELECT * FROM decimal_test ORDER BY huge_decimal NULLS LAST;
|
||||
SELECT * FROM decimal_test ORDER BY max_decimal NULLS FIRST;
|
||||
SELECT * FROM decimal_test ORDER BY max_decimal NULLS LAST;
|
||||
|
||||
-- Multi-column sorting with NULLS FIRST/LAST combinations
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal NULLS FIRST, huge_decimal NULLS LAST;
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal NULLS LAST, huge_decimal NULLS FIRST;
|
||||
SELECT * FROM decimal_test ORDER BY big_decimal DESC NULLS FIRST, huge_decimal ASC NULLS LAST;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue