{"record":{"id":"94316c23403c86ce","repo":"apache/iceberg","slug":"struct-type-is-not-supported","errorCode":null,"errorMessage":"Struct type is not supported","messagePattern":"Struct type is not supported","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"arrow/src/main/java/org/apache/iceberg/arrow/vectorized/ArrowVectorAccessors.java","lineNumber":44,"sourceCode":"import org.apache.iceberg.arrow.vectorized.GenericArrowVectorAccessorFactory.DecimalFactory;\nimport org.apache.iceberg.arrow.vectorized.GenericArrowVectorAccessorFactory.StringFactory;\n\nfinal class ArrowVectorAccessors {\n\n  private static final GenericArrowVectorAccessorFactory<?, String, ?, ?> FACTORY;\n\n  static {\n    FACTORY =\n        new GenericArrowVectorAccessorFactory<>(\n            JavaDecimalFactory::new,\n            JavaStringFactory::new,\n            throwingSupplier(\"Struct type is not supported\"),\n            throwingSupplier(\"List type is not supported\"));\n  }\n\n  private static <T> Supplier<T> throwingSupplier(String message) {\n    return () -> {\n      throw new UnsupportedOperationException(message);\n    };\n  }\n\n  private ArrowVectorAccessors() {\n    throw new UnsupportedOperationException(\n        ArrowVectorAccessors.class.getName() + \" cannot be instantiated.\");\n  }\n\n  static ArrowVectorAccessor<?, String, ?, ?> getVectorAccessor(VectorHolder holder) {\n    return FACTORY.getVectorAccessor(holder);\n  }\n\n  private static final class JavaStringFactory implements StringFactory<String> {\n    @Override\n    public Class<String> getGenericClass() {\n      return String.class;\n    }\n","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/arrow/src/main/java/org/apache/iceberg/arrow/vectorized/ArrowVectorAccessors.java#L26-L62","documentation":"GenericArrowVectorAccessorFactory registers throwing Suppliers for struct and list logical types, so requesting an accessor for a STRUCT column yields a Supplier that throws this UnsupportedOperationException when invoked. The arrow accessor factory simply does not support struct columns in vectorized reads.","triggerScenarios":"Reading a table whose schema contains a STRUCT column through the vectorized (Arrow) read path and invoking the accessor factory's struct supplier; passing a VectorHolder backed by a struct type into getVectorAccessor's factory map.","commonSituations":"Enabling vectorized reads on tables with nested struct fields; listing/reading a nested column set where a struct column sneaks into the batch projection.","solutions":["Exclude struct columns from the vectorized read projection, or read those columns via the non-vectorized path","Flatten the struct fields into top-level columns in the query/schema","Check the Iceberg type of each column before requesting an Arrow accessor and route unsupported types elsewhere"],"exampleFix":"// before\nArrowVectorAccessor a = getVectorAccessor(structHolder); // supplier throws\n// after\nif (structHolder.type().typeId() == TypeID.STRUCT) {\n  // use row-based reader for this column\n} else {\n  ArrowVectorAccessor a = getVectorAccessor(structHolder);\n}","handlingStrategy":"fallback","validationCode":"if (holder Iceberg type is STRUCT) { routeColumnToRowReader(holder); }","typeGuard":"boolean isStruct(Type t) { return t.typeId() == TypeID.STRUCT; }","tryCatchPattern":"Supplier<Accessor> s = factory.get(structHolder); try { a = s.get(); } catch (UnsupportedOperationException e) { a = rowReaderAccessor(holder); }","preventionTips":["Pre-scan the projection schema for structs and split the read into vectorized (primitives) + row (structs) parts","Flatten structs at query level when vectorized performance is needed","Document struct limitations of the vectorized path for downstream users"],"tags":["arrow","vectorized-read","nested-types","struct"],"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"}