{"record":{"id":"5e52375337e78068","repo":"apache/iceberg","slug":"unsupported-base-type-for-decimal-primitive-g-5e5237","errorCode":null,"errorMessage":"Unsupported base type for decimal: \" + primitive.getPrimitiveTypeName()","messagePattern":"Unsupported base type for decimal: \" \\+ primitive\\.getPrimitiveTypeName\\(\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"arrow/src/main/java/org/apache/iceberg/arrow/vectorized/VectorizedArrowReader.java","lineNumber":525,"sourceCode":"      switch (primitive.getPrimitiveTypeName()) {\n        case BINARY:\n        case FIXED_LEN_BYTE_ARRAY:\n          ((FixedSizeBinaryVector) vector).allocateNew(batchSize);\n          return Optional.of(\n              new LogicalTypeVisitorResult(\n                  vector, ReadType.FIXED_LENGTH_DECIMAL, primitive.getTypeLength()));\n        case INT64:\n          ((BigIntVector) vector).allocateNew(batchSize);\n          return Optional.of(\n              new LogicalTypeVisitorResult(\n                  vector, ReadType.LONG_BACKED_DECIMAL, (int) BigIntVector.TYPE_WIDTH));\n        case INT32:\n          ((IntVector) vector).allocateNew(batchSize);\n          return Optional.of(\n              new LogicalTypeVisitorResult(\n                  vector, ReadType.INT_BACKED_DECIMAL, (int) IntVector.TYPE_WIDTH));\n        default:\n          throw new UnsupportedOperationException(\n              \"Unsupported base type for decimal: \" + primitive.getPrimitiveTypeName());\n      }\n    }\n\n    @Override\n    public Optional<LogicalTypeVisitorResult> visit(\n        LogicalTypeAnnotation.DateLogicalTypeAnnotation dateLogicalType) {\n      FieldVector vector = arrowField.createVector(rootAlloc);\n      ((DateDayVector) vector).allocateNew(batchSize);\n      return Optional.of(\n          new LogicalTypeVisitorResult(vector, ReadType.INT, (int) IntVector.TYPE_WIDTH));\n    }\n\n    @Override\n    public Optional<LogicalTypeVisitorResult> visit(\n        LogicalTypeAnnotation.TimeLogicalTypeAnnotation timeLogicalType) {\n      FieldVector vector = arrowField.createVector(rootAlloc);\n      ((TimeMicroVector) vector).allocateNew(batchSize);","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/arrow/src/main/java/org/apache/iceberg/arrow/vectorized/VectorizedArrowReader.java#L507-L543","documentation":"Inside VectorizedArrowReader's logical-type visitor, decimal columns are only supported over INT32, INT64, and fixed-size binary physical bases. When a decimal's backing physical type is anything else, visit() throws this UnsupportedOperationException because there is no decimal read path for that base type.","triggerScenarios":"Vectorized read of a Parquet decimal column whose primitive base type is not INT32/INT64/FixedSizeBinary (e.g. BINARY-backed or FLOAT-backed decimal), reaching the default branch of the decimal visit method.","commonSituations":"Parquet files produced by third-party writers storing decimals in nonstandard physical layouts; enabling vectorization for tables with legacy decimal encodings.","solutions":["Rewrite the data so decimals use INT32/INT64/FIXED_LEN_BYTE_ARRAY physical types (standard Iceberg writes do this)","Disable vectorized reads to use the generic decimal path","Upgrade Iceberg for newer supported decimal base types"],"exampleFix":"// before\n// BINARY-backed decimal + vectorized reads -> throws\n// after\ntable.updateProperties().set(TableProperties.PARQUET_VECTORIZATION_ENABLED, \"false\");","handlingStrategy":"fallback","validationCode":"if (decimalType.getLogicalTypeAnnotation() instanceof DecimalLogicalTypeAnnotation dec) {\n  PrimitiveTypeName base = primitive.getPrimitiveTypeName();\n  boolean ok = base == PrimitiveTypeName.INT32 || base == PrimitiveTypeName.INT64\n      || base == PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY;\n  if (!ok) { /* use generic reader */ }\n}","typeGuard":"boolean decimalBaseSupported(PrimitiveType p) {\n  return p.getPrimitiveTypeName() == PrimitiveTypeName.INT32\n      || p.getPrimitiveTypeName() == PrimitiveTypeName.INT64\n      || p.getPrimitiveTypeName() == PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY;\n}","tryCatchPattern":"try {\n  return vectorizedDecimalReader();\n} catch (UnsupportedOperationException e) {\n  return genericDecimalReader();\n}","preventionTips":["Write decimals with Iceberg's standard INT32/INT64/FixedLenByteArray mapping","Rewrite legacy third-party decimal files","Disable vectorization for tables with nonstandard decimal encodings"],"tags":["arrow","decimal","vectorized-reads"],"backgroundTag":"unsupported-operation","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"}