Implementation:Apache Paimon DecimalType
| Knowledge Sources | |
|---|---|
| Domains | Type System, Numeric Types |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
DecimalType represents a fixed-precision and fixed-scale decimal number type in Apache Paimon's type system.
Description
DecimalType is a public class extending DataType that represents decimal numbers with configurable precision (total number of digits) and scale (number of digits after the decimal point). It enforces strict constraints: precision must be between 1 and 38 (inclusive), and scale must be between 0 and the precision value. These limits align with SQL standard decimal types and ensure compatibility with common database systems.
The class distinguishes between "compact" and non-compact decimals based on precision. Decimals with precision up to 18 (MAX_COMPACT_PRECISION) can be stored efficiently in a long (8 bytes), while larger precision decimals require 16 bytes for storage. This optimization is checked via the static isCompact() method and affects the defaultSize() return value.
DecimalType provides four constructors: the primary one accepting nullability, precision, and scale; convenience constructors with default nullability (true), default scale (0), or both default precision (10) and scale (0). The class supports standard DataType operations including copying with different nullability, SQL string generation in format "DECIMAL(precision, scale)", and visitor pattern acceptance for type system traversal. Available since version 0.4.0 as @Public API.
Usage
Use DecimalType for representing monetary values, scientific measurements, or any numeric data requiring exact precision without floating-point rounding errors. It is essential for financial applications where precision is critical.
Code Reference
Source Location
Signature
@Public
public class DecimalType extends DataType {
public static final int MAX_COMPACT_PRECISION = 18;
public static final int MIN_PRECISION = 1;
public static final int MAX_PRECISION = 38;
public static final int DEFAULT_PRECISION = 10;
public static final int MIN_SCALE = 0;
public static final int DEFAULT_SCALE = 0;
public DecimalType(boolean isNullable, int precision, int scale)
public DecimalType(int precision, int scale)
public DecimalType(int precision)
public DecimalType()
public int getPrecision()
public int getScale()
@Override
public int defaultSize()
@Override
public DataType copy(boolean isNullable)
@Override
public String asSQLString()
@Override
public <R> R accept(DataTypeVisitor<R> visitor)
public static boolean isCompact(int precision)
}
Import
import org.apache.paimon.types.DecimalType;
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| precision | int | No (default: 10) | Total number of digits (1-38) |
| scale | int | No (default: 0) | Number of digits after decimal point (0 to precision) |
| isNullable | boolean | No (default: true) | Whether the decimal can be null |
Outputs
| Name | Type | Description |
|---|---|---|
| DecimalType | DecimalType | Configured decimal type instance |
| Precision | int | The total number of digits |
| Scale | int | The number of decimal places |
| Default size | int | Storage size in bytes (8 or 16) |
| SQL string | String | Format "DECIMAL(precision, scale)" with optional "NOT NULL" |
Usage Examples
// Default decimal (10, 0)
DataType defaultDecimal = new DecimalType();
// Monetary values - two decimal places
DataType money = new DecimalType(10, 2); // e.g., 99999999.99
DataType price = DataTypes.DECIMAL(12, 2);
// High precision scientific values
DataType scientific = new DecimalType(38, 10);
// Percentage with 4 decimal places
DataType percentage = new DecimalType(6, 4); // e.g., 99.9999
// Non-nullable decimal
DataType requiredAmount = new DecimalType(false, 10, 2);
// Check properties
DecimalType decimal = new DecimalType(10, 2);
int precision = decimal.getPrecision(); // 10
int scale = decimal.getScale(); // 2
int size = decimal.defaultSize(); // 8 (compact)
// Check if compact storage
boolean compact = DecimalType.isCompact(18); // true
boolean notCompact = DecimalType.isCompact(19); // false
// SQL representation
String sql = decimal.asSQLString(); // "DECIMAL(10, 2)"
// Copy with different nullability
DataType nonNull = decimal.copy(false);
String nonNullSql = nonNull.asSQLString(); // "DECIMAL(10, 2) NOT NULL"
// Storage size comparison
DecimalType compact = new DecimalType(18, 5);
int compactSize = compact.defaultSize(); // 8 bytes
DecimalType large = new DecimalType(20, 5);
int largeSize = large.defaultSize(); // 16 bytes
// Use in schema
DataType row = DataTypes.ROW(
DataTypes.FIELD(0, "product_id", DataTypes.INT()),
DataTypes.FIELD(1, "price", DataTypes.DECIMAL(10, 2)),
DataTypes.FIELD(2, "tax_rate", DataTypes.DECIMAL(5, 4)),
DataTypes.FIELD(3, "total", DataTypes.DECIMAL(12, 2))
);