{"record":{"id":"2e3b705f83b977fa","repo":"apache/iceberg","slug":"unsupported-decimal-precision","errorCode":null,"errorMessage":"Unsupported decimal precision: ","messagePattern":"Unsupported decimal precision: ","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/variants/Variants.java","lineNumber":202,"sourceCode":"    return new PrimitiveWrapper<>(PhysicalType.TIMESTAMPNTZ, value);\n  }\n\n  public static VariantPrimitive<Long> ofIsoTimestampntz(String value) {\n    return ofTimestampntz(DateTimeUtil.isoTimestampToMicros(value));\n  }\n\n  public static VariantPrimitive<BigDecimal> of(BigDecimal value) {\n    int precision = value.precision();\n\n    if (precision >= 1 && precision <= 9) {\n      return new PrimitiveWrapper<>(PhysicalType.DECIMAL4, value);\n    } else if (precision >= 10 && precision <= 18) {\n      return new PrimitiveWrapper<>(PhysicalType.DECIMAL8, value);\n    } else if (precision <= 38) {\n      return new PrimitiveWrapper<>(PhysicalType.DECIMAL16, value);\n    }\n\n    throw new UnsupportedOperationException(\"Unsupported decimal precision: \" + precision);\n  }\n\n  public static VariantPrimitive<ByteBuffer> of(ByteBuffer value) {\n    return new PrimitiveWrapper<>(PhysicalType.BINARY, value);\n  }\n\n  public static VariantPrimitive<String> of(String value) {\n    return new PrimitiveWrapper<>(PhysicalType.STRING, value);\n  }\n\n  public static VariantPrimitive<Long> ofTime(long value) {\n    return new PrimitiveWrapper<>(PhysicalType.TIME, value);\n  }\n\n  public static VariantPrimitive<Long> ofIsoTime(String value) {\n    return ofTime(DateTimeUtil.isoTimeToMicros(value));\n  }\n","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/variants/Variants.java#L184-L220","documentation":"Variants.of(BigDecimal) maps a decimal to a PhysicalType based on precision: DECIMAL4 (<=9), DECIMAL8 (10-18), DECIMAL16 (<=38). The variant spec caps decimal precision at 38, so any precision above 38 throws UnsupportedOperationException because no variant physical encoding exists for it.","triggerScenarios":"Calling Variants.of(BigDecimal) with a BigDecimal whose precision() > 38, e.g. new BigDecimal(\"12345678901234567890123456789012345678901234567890\") or computed division results with huge precision.","commonSituations":"High-precision financial computations or BigDecimal division producing expanded precision beyond 38 digits; schema columns declared decimal(39+) being converted to variants.","solutions":["Reduce the BigDecimal precision to <=38 via value.setScale(..., roundingMode) or value.round(mathContext)","Check precision before conversion and reject/alter oversized decimals","Use a non-variant storage path for decimals with precision > 38"],"exampleFix":"// before\nVariantPrimitive<BigDecimal> v = Variants.of(bigValue);\n// after\nBigDecimal capped = bigValue.round(new MathContext(38));\nVariantPrimitive<BigDecimal> v = Variants.of(capped);","handlingStrategy":"validation","validationCode":"if (value.precision() > 38) { throw new IllegalArgumentException(\"Decimal precision \" + value.precision() + \" exceeds variant max 38\"); }","typeGuard":"boolean isVariantCompatible(BigDecimal v) { return v.precision() <= 38; }","tryCatchPattern":"try { return Variants.of(value); } catch (UnsupportedOperationException e) { return null; /* or serialize as string */ }","preventionTips":["Set explicit scale/precision MathContext on computed BigDecimals","Validate decimal precision at schema boundaries (columns are max decimal(38))","Avoid raw BigDecimal division without rounding context"],"tags":["variants","decimal","precision"],"backgroundTag":"value-out-of-range","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}