{"record":{"id":"052bea07839a956e","repo":"apache/iceberg","slug":"invalid-precision-precision-052bea","errorCode":null,"errorMessage":"Invalid precision: ${precision}","messagePattern":"Invalid precision: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/data/SparkOrcValueReaders.java","lineNumber":69,"sourceCode":"  public static OrcValueReader<UTF8String> utf8String() {\n    return StringReader.INSTANCE;\n  }\n\n  public static OrcValueReader<UTF8String> uuids() {\n    return UUIDReader.INSTANCE;\n  }\n\n  public static OrcValueReader<Long> timestampTzs() {\n    return TimestampTzReader.INSTANCE;\n  }\n\n  public static OrcValueReader<Decimal> decimals(int precision, int scale) {\n    if (precision <= Decimal.MAX_LONG_DIGITS()) {\n      return new SparkOrcValueReaders.Decimal18Reader(precision, scale);\n    } else if (precision <= 38) {\n      return new SparkOrcValueReaders.Decimal38Reader(precision, scale);\n    } else {\n      throw new IllegalArgumentException(\"Invalid precision: \" + precision);\n    }\n  }\n\n  static OrcValueReader<?> struct(\n      TypeDescription record,\n      List<OrcValueReader<?>> readers,\n      Types.StructType struct,\n      Map<Integer, ?> idToConstant) {\n    return new StructReader(record, readers, struct, idToConstant);\n  }\n\n  static OrcValueReader<?> array(OrcValueReader<?> elementReader) {\n    return new ArrayReader(elementReader);\n  }\n\n  static OrcValueReader<?> map(OrcValueReader<?> keyReader, OrcValueReader<?> valueReader) {\n    return new MapReader(keyReader, valueReader);\n  }","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/data/SparkOrcValueReaders.java#L51-L87","documentation":"SparkOrcValueReaders.decimals selects a decimal reader based on precision: Decimal18Reader for precision <= MAX_LONG_DIGITS (18), Decimal38Reader for precision <= 38, otherwise IllegalArgumentException. It enforces the 38-digit maximum of the Iceberg/decimal spec.","triggerScenarios":"Reading ORC decimal columns whose declared precision exceeds 38, typically from schemas created outside Iceberg's constraints.","commonSituations":"ORC files with precision >38 decimals written by other engines; schema misconfiguration assigning oversized precision during table creation.","solutions":["Rescale the column to precision <= 38 before reading/writing with Iceberg.","Fix the schema to use a valid precision (e.g. decimal(38, scale) maximum).","If the data truly needs >38 digits, store it as string/binary instead of decimal."],"exampleFix":"// before\ncolumn decimal(40, 5)  // throws\n// after\ncolumn decimal(38, 5)","handlingStrategy":"validation","validationCode":"if (precision > 38) throw new IllegalArgumentException(\"precision must be <= 38\");","typeGuard":"boolean validDecimal(int precision, int scale) { return precision > 0 && precision <= 38 && scale >= 0 && scale <= precision; }","tryCatchPattern":"try { read } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Invalid precision\")) { /* rescale column to <=38 */ } else throw e; }","preventionTips":["Enforce decimal precision <= 38 at table creation","Rescale oversized decimals during ingestion from external engines","Validate ORC schemas before registering external tables"],"tags":["spark","orc","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-14T16:17:12.679Z"}