Merge pull request #53328 from valbok/decimal

Introduce default parameters to DECIMAL family types
This commit is contained in:
Robert Schulze 2023-09-05 23:30:11 +02:00 committed by GitHub
commit b314b8d4ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 14 deletions

View File

@ -4,15 +4,17 @@ sidebar_position: 42
sidebar_label: Decimal sidebar_label: Decimal
--- ---
# Decimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S), Decimal256(S) # Decimal, Decimal(P), Decimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S), Decimal256(S)
Signed fixed-point numbers that keep precision during add, subtract and multiply operations. For division least significant digits are discarded (not rounded). Signed fixed-point numbers that keep precision during add, subtract and multiply operations. For division least significant digits are discarded (not rounded).
## Parameters ## Parameters
- P - precision. Valid range: \[ 1 : 76 \]. Determines how many decimal digits number can have (including fraction). - P - precision. Valid range: \[ 1 : 76 \]. Determines how many decimal digits number can have (including fraction). By default the precision is 10.
- S - scale. Valid range: \[ 0 : P \]. Determines how many decimal digits fraction can have. - S - scale. Valid range: \[ 0 : P \]. Determines how many decimal digits fraction can have.
Decimal(P) is equivalent to Decimal(P, 0). Similarly, the syntax Decimal is equivalent to Decimal(10, 0).
Depending on P parameter value Decimal(P, S) is a synonym for: Depending on P parameter value Decimal(P, S) is a synonym for:
- P from \[ 1 : 9 \] - for Decimal32(S) - P from \[ 1 : 9 \] - for Decimal32(S)
- P from \[ 10 : 18 \] - for Decimal64(S) - P from \[ 10 : 18 \] - for Decimal64(S)

View File

@ -74,21 +74,30 @@ SerializationPtr DataTypeDecimal<T>::doGetDefaultSerialization() const
static DataTypePtr create(const ASTPtr & arguments) static DataTypePtr create(const ASTPtr & arguments)
{ {
if (!arguments || arguments->children.size() != 2) UInt64 precision = 10;
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, UInt64 scale = 0;
"Decimal data type family must have exactly two arguments: precision and scale"); if (arguments)
{
if (arguments->children.empty() || arguments->children.size() > 2)
throw Exception(
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
"Decimal data type family must have precision and optional scale arguments");
const auto * precision = arguments->children[0]->as<ASTLiteral>(); const auto * precision_arg = arguments->children[0]->as<ASTLiteral>();
const auto * scale = arguments->children[1]->as<ASTLiteral>(); if (!precision_arg || precision_arg->value.getType() != Field::Types::UInt64)
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Decimal argument precision is invalid");
precision = precision_arg->value.get<UInt64>();
if (!precision || precision->value.getType() != Field::Types::UInt64 || if (arguments->children.size() == 2)
!scale || !(scale->value.getType() == Field::Types::Int64 || scale->value.getType() == Field::Types::UInt64)) {
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Decimal data type family must have two numbers as its arguments"); const auto * scale_arg = arguments->children[1]->as<ASTLiteral>();
if (!scale_arg || !isInt64OrUInt64FieldType(scale_arg->value.getType()))
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Decimal argument scale is invalid");
scale = scale_arg->value.get<UInt64>();
}
}
UInt64 precision_value = precision->value.get<UInt64>(); return createDecimal<DataTypeDecimal>(precision, scale);
UInt64 scale_value = scale->value.get<UInt64>();
return createDecimal<DataTypeDecimal>(precision_value, scale_value);
} }
template <typename T> template <typename T>

View File

@ -0,0 +1,4 @@
Decimal(9, 8)
Decimal(18, 0)
Decimal(10, 0)
Decimal(18, 0) Decimal(10, 0)

View File

@ -0,0 +1,19 @@
DROP TABLE IF EXISTS decimal;
CREATE TABLE IF NOT EXISTS decimal
(
d1 DECIMAL(9, 8),
d2 DECIMAL(18),
d3 DECIMAL
)
ENGINE = MergeTree
PARTITION BY toInt32(d1)
ORDER BY (d2, d3);
INSERT INTO decimal (d1, d2, d3) VALUES (4.2, 4.2, 4.2);
SELECT type FROM system.columns WHERE table = 'decimal' AND database = currentDatabase();
SELECT toTypeName(d2), toTypeName(d3) FROM decimal LIMIT 1;
DROP TABLE decimal;