apache/seatunnel · warning
DECIMAL scale {} is negative, setting to 0
Error message
DECIMAL scale {} is negative, setting to 0 What it means
Warning from DuckDBTypeConverter.handleDecimalType: the DECIMAL scale is negative, which the DuckDB dialect does not support, so it is clamped to 0. A negative scale (allowed by some engines, e.g. NUMBER(10,-2)) means rounding to tens/hundreds; clamping to 0 changes the represented value semantics.
Source
Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java:208
return builder.build();
}
private void handleDecimalType(
PhysicalColumn.PhysicalColumnBuilder builder, BasicTypeDefine typeDefine) {
long precision =
typeDefine.getPrecision() != null ? typeDefine.getPrecision() : DEFAULT_PRECISION;
int scale = typeDefine.getScale() != null ? typeDefine.getScale() : DEFAULT_SCALE;
if (precision > MAX_PRECISION) {
log.warn(
"DECIMAL precision {} exceeds maximum {}, truncating to {}",
precision,
MAX_PRECISION,
MAX_PRECISION);
precision = MAX_PRECISION;
}
if (scale < 0) {
log.warn("DECIMAL scale {} is negative, setting to 0", scale);
scale = 0;
} else if (scale > MAX_SCALE) {
log.warn(
"DECIMAL scale {} exceeds maximum {}, truncating to {}",
scale,
MAX_SCALE,
MAX_SCALE);
scale = MAX_SCALE;
}
if (scale <= 0) {
builder.dataType(new DecimalType((int) precision, 0));
} else {
builder.dataType(new DecimalType((int) precision, scale));
}
builder.columnLength(precision);
builder.scale(scale);
}View on GitHub (pinned to cf67b549a7)
Solutions
- Cast the source column to a non-negative scale: CAST(col AS DECIMAL(p,0)).
- Confirm whether rounding to integer is acceptable; otherwise keep the column as DOUBLE in the source projection.
- Handle the rounding explicitly upstream (e.g. ROUND(col, 0)) so behavior is deterministic.
- If exact negative-scale semantics are required, move the data as string/decimal text.
Example fix
// before SELECT amount FROM src; -- NUMBER(10,-2) // after SELECT ROUND(amount, 0) AS amount FROM src; -- or CAST to DECIMAL(10,0)
Defensive patterns
Strategy: validation
Validate before calling
if (scale < 0) {
// normalize before the pipeline runs
column = ROUND(col, 0); // or CAST to DECIMAL(p, 0)
} Type guard
boolean hasNonNegativeScale(DecimalType t) { return t.getScale() >= 0; } Prevention
- When migrating from Oracle/DB2, expand NUMBER(p,-s) columns to their effective integer scale.
- Document rounding semantics when negative scale is collapsed to 0.
- Prefer explicit CASTs in source SQL over implicit clamping.
When it happens
Trigger: convert invoked on a BasicTypeDefine whose getScale() < 0 (or null defaulting path yields negative scale from driver metadata).
Common situations: Oracle/DB2-style NUMBER(p,-s) columns read through a generic JDBC path into a DuckDB sink; driver metadata reporting negative scale for rounded numeric columns.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- DECIMAL scale {} exceeds maximum {}, truncating to {}
- The decimal column {} type decimal({},{}) is out of range, w
- The decimal column {} type decimal({},{}) is out of range, w
- The decimal column {} type decimal({},{}) is out of range, w
- DECIMAL precision {} exceeds maximum {}, truncating to {}
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/07f21e262976e38a.
Report an issue: GitHub.