Skip to content

Commit

Permalink
refine decimal exception message (#3375)
Browse files Browse the repository at this point in the history
  • Loading branch information
dragonly authored Nov 4, 2021
1 parent 5d487be commit 89c472f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
12 changes: 8 additions & 4 deletions dbms/src/DataTypes/DataTypeDecimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace DB
{

template <typename T>
std::string DataTypeDecimal<T>::getName() const
{
Expand Down Expand Up @@ -183,15 +182,20 @@ static DataTypePtr create(const ASTPtr & arguments)
const ASTLiteral * arg0 = typeid_cast<const ASTLiteral *>(arguments->children[0].get());
if (!arg0 || arg0->value.getType() != Field::Types::UInt64 || arg0->value.get<UInt64>() == 0)
throw Exception(
"Decimal data type family must have a number (positive integer) as its argument", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
"Decimal data type family must have a number (positive integer) as its argument",
ErrorCodes::ARGUMENT_OUT_OF_BOUND);
const ASTLiteral * arg1 = typeid_cast<const ASTLiteral *>(arguments->children[1].get());
if (!arg1 || arg1->value.getType() != Field::Types::UInt64)
throw Exception(
"Decimal data type family must have a number (positive integer) as its argument", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
"Decimal data type family must have a number (positive integer) as its argument",
ErrorCodes::ARGUMENT_OUT_OF_BOUND);
return createDecimal(arg0->value.get<UInt64>(), arg1->value.get<UInt64>());
}

void registerDataTypeDecimal(DataTypeFactory & factory) { factory.registerDataType("Decimal", create, DataTypeFactory::CaseInsensitive); }
void registerDataTypeDecimal(DataTypeFactory & factory)
{
factory.registerDataType("Decimal", create, DataTypeFactory::CaseInsensitive);
}

template class DataTypeDecimal<Decimal32>;
template class DataTypeDecimal<Decimal64>;
Expand Down
36 changes: 25 additions & 11 deletions dbms/src/DataTypes/DataTypeDecimal.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <DataTypes/DataTypeFactory.h>
#include <DataTypes/IDataType.h>
#include <IO/WriteHelpers.h>
#include <fmt/core.h>


namespace DB
Expand All @@ -22,7 +23,7 @@ extern const int ARGUMENT_OUT_OF_BOUND;
// Int256 65

template <typename T>
class DataTypeDecimal : public IDataType
class DataTypeDecimal final : public IDataType
{
static_assert(IsDecimal<T>);

Expand Down Expand Up @@ -52,7 +53,20 @@ class DataTypeDecimal : public IDataType
{
if (precision > decimal_max_prec || scale > precision || scale > decimal_max_scale)
{
throw Exception(getName() + "is out of bound", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
std::string msg = getName() + "is out of bound";
if (precision > decimal_max_prec)
{
msg = fmt::format("{}, precision {} is greater than maximum value {}", msg, precision, decimal_max_prec);
}
else if (scale > precision)
{
msg = fmt::format("{}, scale {} is greater than precision {}", msg, scale, precision);
}
else
{
msg = fmt::format("{}, scale {} is greater than maximum value {}", msg, scale, decimal_max_scale);
}
throw Exception(msg, ErrorCodes::ARGUMENT_OUT_OF_BOUND);
}
}

Expand Down Expand Up @@ -119,7 +133,7 @@ class DataTypeDecimal : public IDataType
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettingsJSON &) const override;

void serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextCSV(IColumn & column, ReadBuffer & istr, const char delimiter) const override;
void deserializeTextCSV(IColumn & column, ReadBuffer & istr, char delimiter) const override;

void readText(T & x, ReadBuffer & istr) const;

Expand Down Expand Up @@ -216,26 +230,26 @@ typename std::enable_if_t<(sizeof(T) < sizeof(U)), const DataTypeDecimal<U>> dec

inline PrecType getDecimalPrecision(const IDataType & data_type, PrecType default_value)
{
if (auto * decimal_type = checkDecimal<Decimal32>(data_type))
if (const auto * decimal_type = checkDecimal<Decimal32>(data_type))
return decimal_type->getPrec();
if (auto * decimal_type = checkDecimal<Decimal64>(data_type))
if (const auto * decimal_type = checkDecimal<Decimal64>(data_type))
return decimal_type->getPrec();
if (auto * decimal_type = checkDecimal<Decimal128>(data_type))
if (const auto * decimal_type = checkDecimal<Decimal128>(data_type))
return decimal_type->getPrec();
if (auto * decimal_type = checkDecimal<Decimal256>(data_type))
if (const auto * decimal_type = checkDecimal<Decimal256>(data_type))
return decimal_type->getPrec();
return default_value;
}

inline ScaleType getDecimalScale(const IDataType & data_type, ScaleType default_value)
{
if (auto * decimal_type = checkDecimal<Decimal32>(data_type))
if (const auto * decimal_type = checkDecimal<Decimal32>(data_type))
return decimal_type->getScale();
if (auto * decimal_type = checkDecimal<Decimal64>(data_type))
if (const auto * decimal_type = checkDecimal<Decimal64>(data_type))
return decimal_type->getScale();
if (auto * decimal_type = checkDecimal<Decimal128>(data_type))
if (const auto * decimal_type = checkDecimal<Decimal128>(data_type))
return decimal_type->getScale();
if (auto * decimal_type = checkDecimal<Decimal256>(data_type))
if (const auto * decimal_type = checkDecimal<Decimal256>(data_type))
return decimal_type->getScale();
return default_value;
}
Expand Down

0 comments on commit 89c472f

Please sign in to comment.