{"record":{"id":"07f21e262976e38a","repo":"apache/seatunnel","slug":"decimal-scale-is-negative-setting-to-0","errorCode":null,"errorMessage":"DECIMAL scale {} is negative, setting to 0","messagePattern":"DECIMAL scale (.+?) is negative, setting to 0","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java","lineNumber":208,"sourceCode":"        return builder.build();\n    }\n\n    private void handleDecimalType(\n            PhysicalColumn.PhysicalColumnBuilder builder, BasicTypeDefine typeDefine) {\n        long precision =\n                typeDefine.getPrecision() != null ? typeDefine.getPrecision() : DEFAULT_PRECISION;\n        int scale = typeDefine.getScale() != null ? typeDefine.getScale() : DEFAULT_SCALE;\n\n        if (precision > MAX_PRECISION) {\n            log.warn(\n                    \"DECIMAL precision {} exceeds maximum {}, truncating to {}\",\n                    precision,\n                    MAX_PRECISION,\n                    MAX_PRECISION);\n            precision = MAX_PRECISION;\n        }\n        if (scale < 0) {\n            log.warn(\"DECIMAL scale {} is negative, setting to 0\", scale);\n            scale = 0;\n        } else if (scale > MAX_SCALE) {\n            log.warn(\n                    \"DECIMAL scale {} exceeds maximum {}, truncating to {}\",\n                    scale,\n                    MAX_SCALE,\n                    MAX_SCALE);\n            scale = MAX_SCALE;\n        }\n\n        if (scale <= 0) {\n            builder.dataType(new DecimalType((int) precision, 0));\n        } else {\n            builder.dataType(new DecimalType((int) precision, scale));\n        }\n        builder.columnLength(precision);\n        builder.scale(scale);\n    }","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java#L190-L226","documentation":"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.","triggerScenarios":"convert invoked on a BasicTypeDefine whose getScale() < 0 (or null defaulting path yields negative scale from driver metadata).","commonSituations":"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.","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."],"exampleFix":"// before\nSELECT amount FROM src; -- NUMBER(10,-2)\n// after\nSELECT ROUND(amount, 0) AS amount FROM src; -- or CAST to DECIMAL(10,0)","handlingStrategy":"validation","validationCode":"if (scale < 0) {\n  // normalize before the pipeline runs\n  column = ROUND(col, 0); // or CAST to DECIMAL(p, 0)\n}","typeGuard":"boolean hasNonNegativeScale(DecimalType t) { return t.getScale() >= 0; }","tryCatchPattern":null,"preventionTips":["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."],"tags":["jdbc","duckdb","decimal","scale"],"backgroundTag":"value-out-of-range","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}