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

  1. Cast the source column to a non-negative scale: CAST(col AS DECIMAL(p,0)).
  2. Confirm whether rounding to integer is acceptable; otherwise keep the column as DOUBLE in the source projection.
  3. Handle the rounding explicitly upstream (e.g. ROUND(col, 0)) so behavior is deterministic.
  4. 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 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


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/07f21e262976e38a. Report an issue: GitHub.