{"record":{"id":"b9ba9e8fce587212","repo":"apache/iceberg","slug":"row-based-reads-are-not-supported-b9ba9e","errorCode":null,"errorMessage":"Row-based reads are not supported","messagePattern":"Row-based reads are not supported","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkColumnarReaderFactory.java","lineNumber":47,"sourceCode":"import org.apache.spark.sql.vectorized.ColumnarBatch;\n\nclass SparkColumnarReaderFactory implements PartitionReaderFactory {\n  private final ParquetBatchReadConf parquetConf;\n  private final OrcBatchReadConf orcConf;\n\n  SparkColumnarReaderFactory(ParquetBatchReadConf conf) {\n    this.parquetConf = conf;\n    this.orcConf = null;\n  }\n\n  SparkColumnarReaderFactory(OrcBatchReadConf conf) {\n    this.orcConf = conf;\n    this.parquetConf = null;\n  }\n\n  @Override\n  public PartitionReader<InternalRow> createReader(InputPartition inputPartition) {\n    throw new UnsupportedOperationException(\"Row-based reads are not supported\");\n  }\n\n  @Override\n  public PartitionReader<ColumnarBatch> createColumnarReader(InputPartition inputPartition) {\n    Preconditions.checkArgument(\n        inputPartition instanceof SparkInputPartition,\n        \"Unknown input partition type: %s\",\n        inputPartition.getClass().getName());\n\n    SparkInputPartition partition = (SparkInputPartition) inputPartition;\n\n    if (partition.allTasksOfType(FileScanTask.class)) {\n      return new BatchDataReader(partition, parquetConf, orcConf);\n    } else {\n      throw new UnsupportedOperationException(\n          \"Unsupported task group for columnar reads: \" + partition.taskGroup());\n    }\n  }","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkColumnarReaderFactory.java#L29-L65","documentation":"SparkInputPartitionReaderFactory.createReader is the row-based read entry point for batch scans. The Iceberg Spark columnar reader factory only supports columnar (ColumnarBatch) reads, so calling the row-based entry point is explicitly rejected with UnsupportedOperationException. Iceberg batch reads through this factory must use createColumnarReader instead.","triggerScenarios":"Calling createReader(InputPartition) directly on SparkColumnarReaderFactory, or a Spark plan that falls back to row-based batch reads (e.g. a subclass/experimental listener that requests non-columnar reads through this factory).","commonSituations":"Custom Spark 3.x data source integration code invoking the wrong factory method; tooling or tests assuming row-oriented batch reads from the columnar factory; copying code from SparkBatchQueryScan row-based variants into a columnar context.","solutions":["Use createColumnarReader(inputPartition) instead of createReader, ensuring supportColumnarReads returned true for the partition","Route row-based reads through a row-oriented reader factory (e.g. the row-based Spark input partition reader factory) rather than the columnar one","If using Spark APIs, make sure the query is planned for columnar execution and the partition tasks are all FileScanTask"],"exampleFix":"// before\nPartitionReader<InternalRow> reader = factory.createReader(partition);\n// after\nPartitionReader<ColumnarBatch> reader = factory.createColumnarReader(partition);","handlingStrategy":"type-guard","validationCode":"if (partition.allTasksOfType(FileScanTask.class)) {\n  factory.createColumnarReader(partition);\n}","typeGuard":"boolean isColumnar = partition.allTasksOfType(FileScanTask.class);","tryCatchPattern":"try {\n  return factory.createColumnarReader(inputPartition);\n} catch (UnsupportedOperationException e) {\n  return rowFactory.createReader(inputPartition);\n}","preventionTips":["Always call supportColumnarReads before choosing the columnar factory","Never call createReader on a columnar-only factory","Keep row-based fallback factories available for non-columnar partitions"],"tags":["spark","unsupported-operation","columnar-read"],"backgroundTag":"unsupported-operation","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"}