DECIMAL
DECIMAL(P[,S]) — это значение с фиксированной точкой высокой точности. P обозначает общее количество значащих цифр (precision). S обозначает максимальное количество десятичных знаков (scale).
Если P не указан, значение по умолчанию — 10. Если S не указан, значение по умолчанию — 0.
- Для версий до v2.0.0 Selena поддерживает DECIMAL128 на основе Fast DECIMAL.
- Для версий v2.0.0 и более поздних Selena поддерживает DECIMAL256.
Возможности
Fast DECIMAL
Управляется динамическим параметром FE enable_decimal_v3, Fast DECIMAL включен по умолчанию.
Для Fast DECIMAL диапазон P составляет [1,38], а диапазон S — [0, P]. Значение S по умолчанию — 0.
Fast DECIMAL использует целые числа переменной ширины для представления десятичных чисел.
-
Decimal(P ≤ 18, S)
- LogicalType: Decimal64
- Stored as: int64
- Delegate LogicalType: BIGINT
-
Decimal(P > 18 & P ≤ 38, S)
- LogicalType: Decimal128
- Stored as: int128
- Delegate LogicalType: LARGEINT
Начиная с версии v1.5.2, Selena поддерживает элементы Fast Decimal в ARRAY, MAP и STRUCT.
DECIMAL256
Selena вводит DECIMAL256 начиная с версии v2.0.0.
Для DECIMAL256 диапазон P составляет (38,76], а диапазон S — [0, P]. Значение S по умолчанию — 0.
DECIMAL256 расширяет верхний предел точности до 76 бит. Его числовая ёмкость в 10³⁸ раз больше, чем у DECIMAL128, что снижает вероятность переполнения до незначительного уровня.
DECIMAL256 использует ту же стратегию для представления десятичных чисел, что и Fast DECIMAL. В дополнение к двум упомянутым выше типам деся тичных чисел он поддерживает:
- Decimal(P > 38 & P ≤ 76, S)
- LogicalType: Decimal256
- Stored as: int256
- Delegate LogicalType: INT_256
Фактический представимый диапазон DECIMAL256 — от -57896044618658097711785492504343953926634992332820282019728792003956564819968 до 57896044618658097711785492504343953926634992332820282019728792003956564819967.
Операции приведения типов
DECIMAL256 поддерживает двунаправленное преобразование типов между всеми перечисленными ниже типами:
| Исходный тип | Целевые типы |
|---|---|
| TYPE_DECIMAL256 | BOOL |
| TYPE_DECIMAL256 | TYPE_TINYINT, TYPE_SMALLINT, TYPE_INT, TYPE_BIGINT, TYPE_LARGEINT |
| TYPE_DECIMAL256 | TYPE_FLOAT, TYPE_DOUBLE |
| TYPE_DECIMAL256 | TYPE_VARCHAR |
Агрегатные функции
В настоящее время DECIMAL256 поддерживает следующие агрегатные функции: COUNT, COUNT DISTINCT, SUM, SUM DISTINCT, AVG, AVG DISTINCT, MAX, MIN и ABS.
Ограничения
DECIMAL256 имеет следующие ограничения:
-
В настоящее время DECIMAL256 не поддерживает автоматическое увеличение точности для десятичных операций.
Например,
DECIMAL128 * DECIMAL128не будет автоматически увеличен до DECIMAL256. Функции DECIMAL256 применяются только тогда, когдаDECIMAL256явно указан в качестве операнда либо в операторе CREATE TABLE, либо с использованием CAST (SELECT CAST(p38s10 as DECIMAL(70, 30))). -
DECIMAL256 не поддерживает оконные функции.
-
Агрегатные таблицы не поддерживают тип DECIMAL256.
Примеры
Пример Fast DECIMAL
Определение столбцов DECIMAL при создании таблицы.
CREATE TABLE decimalDemo (
pk BIGINT(20) NOT NULL COMMENT "",
account DECIMAL(20,10) COMMENT ""
) ENGINE=OLAP
DUPLICATE KEY(pk)
COMMENT "OLAP"
DISTRIBUTED BY HASH(pk);
INSERT INTO decimalDemo VALUES
(1,3.141592656),
(2,21.638378),
(3,4873.6293048479);
SELECT * FROM decimalDemo;
+------+-----------------+
| pk | account |
+------+-----------------+
| 1 | 3.1415926560 |
| 3 | 4873.6293048479 |
| 2 | 21.6383780000 |
+------+-----------------+
Пример DECIMAL256
Создание таблицы со столбцом типа DECIMAL256.
CREATE TABLE test_decimal256(
p50s48 DECIMAL(50, 48) COMMENT ""
);
Вставка различных значений:
INSERT INTO test_decimal256(p50s48) SELECT 1.222222;
Этот оператор выполняется успешно, значения записываются корректно.
INSERT INTO test_decimal256(p50s48) SELECT 11111111111111111111111111111111111111111111.222222;
Этот оператор выполняется успешно, значения записываются как NULL. Поскольку целая часть и десятичная часть (которая имеет 44 цифры) с указанным scale (который равен 48) вместе превышают максимальное целое число, которое может быть представлено 256 битами, FE напрямую преобразует значение в NULL.
INSERT INTO test_decimal256(p50s48) SELECT 333;
Этот оператор вернёт ошибку ERROR 1064 (HY000): Insert has filtered data. Поскольку целая часть и десятичная часть с указанным scale (который равен 48) вместе превышают максимальное значение, представленное 50-разрядным целым числом, BE возвращает ошибку.
Примечания по использованию
Вы можете установить системную переменную sql_mode в ERROR_IF_OVERFLOW, чтобы система возвращала ошибку вместо NULL в случае арифметического переполнения.
Ключевые слова
decimal, decimalv3, fast decimal, decimal128, decimal256