This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 409640ac46 [Bug](decimal) Prevent invalid decimal value (#23677)
409640ac46 is described below
commit 409640ac4616ed4aad70ed7ae92c3f4c44010d23
Author: Gabriel <[email protected]>
AuthorDate: Thu Aug 31 14:43:10 2023 +0800
[Bug](decimal) Prevent invalid decimal value (#23677)
---
be/src/vec/data_types/data_type_decimal.h | 13 ++++++++++++
be/src/vec/sink/vtablet_block_convertor.cpp | 31 +++++++++++++++++++++++++++--
be/src/vec/sink/vtablet_block_convertor.h | 3 +++
3 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/be/src/vec/data_types/data_type_decimal.h
b/be/src/vec/data_types/data_type_decimal.h
index 275f356ff7..bdd9598836 100644
--- a/be/src/vec/data_types/data_type_decimal.h
+++ b/be/src/vec/data_types/data_type_decimal.h
@@ -572,4 +572,17 @@ ToDataType::FieldType convert_to_decimal(const typename
FromDataType::FieldType&
}
}
+template <typename T>
+ requires IsDecimalNumber<T>
+typename T::NativeType max_decimal_value(UInt32 precision) {
+ return type_limit<T>::max() / DataTypeDecimal<T>::get_scale_multiplier(
+ (UInt32)(max_decimal_precision<T>()
- precision));
+}
+
+template <typename T>
+ requires IsDecimalNumber<T>
+typename T::NativeType min_decimal_value(UInt32 precision) {
+ return type_limit<T>::min() / DataTypeDecimal<T>::get_scale_multiplier(
+ (UInt32)(max_decimal_precision<T>()
- precision));
+}
} // namespace doris::vectorized
diff --git a/be/src/vec/sink/vtablet_block_convertor.cpp
b/be/src/vec/sink/vtablet_block_convertor.cpp
index 7c7300b9b3..45105e0cff 100644
--- a/be/src/vec/sink/vtablet_block_convertor.cpp
+++ b/be/src/vec/sink/vtablet_block_convertor.cpp
@@ -131,6 +131,33 @@ DecimalV2Value
OlapTableBlockConvertor::_get_decimalv2_min_or_max(const TypeDesc
return value;
}
+template <typename DecimalType, bool IsMin>
+DecimalType OlapTableBlockConvertor::_get_decimalv3_min_or_max(const
TypeDescriptor& type) {
+ std::map<int, typename DecimalType::NativeType>* pmap;
+ if constexpr (std::is_same_v<DecimalType, vectorized::Decimal32>) {
+ pmap = IsMin ? &_min_decimal32_val : &_max_decimal32_val;
+ } else if constexpr (std::is_same_v<DecimalType, vectorized::Decimal64>) {
+ pmap = IsMin ? &_min_decimal64_val : &_max_decimal64_val;
+ } else {
+ pmap = IsMin ? &_min_decimal128_val : &_max_decimal128_val;
+ }
+
+ // found
+ auto iter = pmap->find(type.precision);
+ if (iter != pmap->end()) {
+ return iter->second;
+ }
+
+ typename DecimalType::NativeType value;
+ if constexpr (IsMin) {
+ value = vectorized::min_decimal_value<DecimalType>(type.precision);
+ } else {
+ value = vectorized::max_decimal_value<DecimalType>(type.precision);
+ }
+ pmap->emplace(type.precision, value);
+ return value;
+}
+
Status OlapTableBlockConvertor::_validate_column(RuntimeState* state, const
TypeDescriptor& type,
bool is_nullable,
vectorized::ColumnPtr column,
size_t slot_index, bool*
stop_processing,
@@ -269,8 +296,8 @@ Status
OlapTableBlockConvertor::_validate_column(RuntimeState* state, const Type
#define CHECK_VALIDATION_FOR_DECIMALV3(DecimalType)
\
auto column_decimal = const_cast<vectorized::ColumnDecimal<DecimalType>*>(
\
assert_cast<const
vectorized::ColumnDecimal<DecimalType>*>(real_column_ptr.get())); \
- const auto& max_decimal = type_limit<DecimalType>::max();
\
- const auto& min_decimal = type_limit<DecimalType>::min();
\
+ const auto& max_decimal = _get_decimalv3_min_or_max<DecimalType,
false>(type); \
+ const auto& min_decimal = _get_decimalv3_min_or_max<DecimalType,
true>(type); \
for (size_t j = 0; j < column->size(); ++j) {
\
auto row = rows ? (*rows)[j] : j;
\
if (row == last_invalid_row) {
\
diff --git a/be/src/vec/sink/vtablet_block_convertor.h
b/be/src/vec/sink/vtablet_block_convertor.h
index 335e876284..bfc7b3b5d9 100644
--- a/be/src/vec/sink/vtablet_block_convertor.h
+++ b/be/src/vec/sink/vtablet_block_convertor.h
@@ -62,6 +62,9 @@ private:
template <bool is_min>
DecimalV2Value _get_decimalv2_min_or_max(const TypeDescriptor& type);
+ template <typename DecimalType, bool IsMin>
+ DecimalType _get_decimalv3_min_or_max(const TypeDescriptor& type);
+
Status _validate_column(RuntimeState* state, const TypeDescriptor& type,
bool is_nullable,
vectorized::ColumnPtr column, size_t slot_index,
bool* stop_processing,
fmt::memory_buffer& error_prefix,
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]