{"record":{"id":"c132f473b61332ae","repo":"apache/iceberg","slug":"unsupported-type-interval","errorCode":null,"errorMessage":"Unsupported type: interval","messagePattern":"Unsupported type: interval","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java","lineNumber":202,"sourceCode":"  }\n\n  private byte[] getBinaryInternal(int ordinal) {\n    Object bytes = struct.get(ordinal, Object.class);\n\n    // should only be either ByteBuffer or byte[]\n    if (bytes instanceof ByteBuffer) {\n      return ByteBuffers.toByteArray((ByteBuffer) bytes);\n    } else if (bytes instanceof byte[]) {\n      return (byte[]) bytes;\n    } else {\n      throw new IllegalStateException(\n          \"Unknown type for binary field. Type name: \" + bytes.getClass().getName());\n    }\n  }\n\n  @Override\n  public CalendarInterval getInterval(int ordinal) {\n    throw new UnsupportedOperationException(\"Unsupported type: interval\");\n  }\n\n  @Override\n  public InternalRow getStruct(int ordinal, int numFields) {\n    return isNullAt(ordinal) ? null : getStructInternal(ordinal);\n  }\n\n  private InternalRow getStructInternal(int ordinal) {\n    return new StructInternalRow(\n        type.fields().get(ordinal).type().asStructType(), struct.get(ordinal, StructLike.class));\n  }\n\n  @Override\n  public ArrayData getArray(int ordinal) {\n    return isNullAt(ordinal) ? null : getArrayInternal(ordinal);\n  }\n\n  private ArrayData getArrayInternal(int ordinal) {","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java#L184-L220","documentation":"Spark's CalendarInterval type has no corresponding Iceberg type, so StructInternalRow.getInterval always throws UnsupportedOperationException. This method exists only to satisfy Spark's InternalRow interface.","triggerScenarios":"A Spark plan attempts to read an interval column from an Iceberg scan — e.g. a query projecting an interval-typed expression whose input is this row, or code incorrectly assuming interval support.","commonSituations":"Queries mixing interval literals/expressions with Iceberg scan output; custom code treating this row as a general-purpose interval container; accidental interval inference in a projection.","solutions":["Do not attempt to read interval values from Iceberg rows — Iceberg has no interval type","Rewrite the query to avoid projecting interval-typed values through the scan (compute intervals after materialization)","If hit inside an expression, restructure so intervals are constructed in Spark, not read from the row"],"exampleFix":"// before\nCalendarInterval iv = row.getInterval(ordinal);\n// after\n// construct in Spark instead of reading from Iceberg row\nCalendarInterval iv = CalendarInterval.fromString(\"1 months 2 days\");","handlingStrategy":"validation","validationCode":"// Iceberg has no interval type; never request it from scan rows\nif (sparkType instanceof CalendarIntervalType) {\n  throw new IllegalArgumentException(\"Iceberg rows cannot supply CalendarInterval values\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return row.getInterval(ordinal);\n} catch (UnsupportedOperationException e) {\n  throw new UnsupportedOperationException(\"Build intervals in Spark, not from Iceberg rows\", e);\n}","preventionTips":["Never project interval-typed columns through Iceberg scans","Construct intervals from literals/functions in Spark","Keep interval logic outside the scan reading path"],"tags":["spark","interval","unsupported-type","internalrow"],"backgroundTag":"unsupported-dtype","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"}