fix(athena): treat DECIMAL(p) as scale 0, not a default non-zero scale (#2403)

This commit is contained in:
Bartok
2026-06-29 10:52:28 +08:00
committed by GitHub
parent 89ea46c4fd
commit 22d3125ced
2 changed files with 23 additions and 1 deletions
+7 -1
View File
@@ -91,7 +91,13 @@ def _trino_data_type_to_arrow(node) -> pa.DataType:
return _TRINO_DATA_TYPE_TO_ARROW[kind]
if kind == T.DECIMAL:
precision, scale = 38, 9
# Trino/Athena DECIMAL semantics: DECIMAL(p) means scale 0 (an integer
# of p digits), NOT an unspecified scale. Bare DECIMAL defaults to
# (38, 0). Only DECIMAL(p, s) carries a non-zero scale. Defaulting the
# scale to a non-zero value here both mistyped DECIMAL(p) columns and,
# for small precisions (e.g. DECIMAL(5)), produced scale > precision,
# which PyArrow rejects with an ArrowInvalid.
precision, scale = 38, 0
params = node.expressions
if len(params) >= 1:
with contextlib.suppress(AttributeError, ValueError, TypeError):
@@ -78,6 +78,22 @@ def test_parse_athena_type_decimal():
assert _parse_athena_type("decimal(12,4)") == pa.decimal128(12, 4)
def test_parse_athena_type_decimal_precision_only_is_scale_zero():
# Trino/Athena: DECIMAL(p) means scale 0, not an unspecified/default scale.
assert _parse_athena_type("decimal(10)") == pa.decimal128(10, 0)
def test_parse_athena_type_decimal_bare_defaults():
# Bare DECIMAL is DECIMAL(38, 0) per the SQL standard / Trino.
assert _parse_athena_type("decimal") == pa.decimal128(38, 0)
def test_parse_athena_type_decimal_small_precision_only():
# Regression: DECIMAL(5) must not yield scale > precision. A non-zero
# default scale (e.g. 9) produced decimal128(5, 9), which PyArrow rejects.
assert _parse_athena_type("decimal(5)") == pa.decimal128(5, 0)
def test_parse_athena_type_array():
assert _parse_athena_type("array(varchar)") == pa.list_(pa.string())