{"record":{"id":"89c4f2bf93271e50","repo":"apache/iceberg","slug":"unsupported-type-interval-89c4f2","errorCode":null,"errorMessage":"Unsupported type: interval","messagePattern":"Unsupported type: interval","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java","lineNumber":208,"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":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java#L190-L226","documentation":"StructInternalRow wraps Iceberg InternalRow data into a Spark InternalRow. CalendarInterval (Spark's INTERVAL type) is not supported by Iceberg's type system, so getInterval unconditionally throws UnsupportedOperationException. Iceberg has no interval type, so no value can ever be provided here.","triggerScenarios":"A Spark job reads an Iceberg table where the projected schema causes Spark to call getInterval on the wrapped row — e.g. schema evolution/type inference paths or a query referencing an interval-typed expression backed by this row adapter.","commonSituations":"Queries combining Iceberg scans with Spark INTERVAL columns, or custom code casting StructInternalRow rows to a schema containing CalendarInterval fields.","solutions":["Remove interval-typed fields from the query projection over the Iceberg table","Compute intervals in Spark after reading, from supported Iceberg types (long/int), rather than expecting an interval column","Upgrade Iceberg: newer versions may add support for interval via Spark compatibility layers","If this is your own wrapping code, use Spark's GenericInternalRow for rows containing intervals instead of StructInternalRow"],"exampleFix":"// before\nrow.getInterval(0); // throws\n// after\nlong months = row.getLong(0); // store interval components in supported numeric columns\njava.time.Period p = java.time.Period.ofMonths((int) months);","handlingStrategy":"validation","validationCode":"if (schema.fields().stream().anyMatch(f -> f.dataType() instanceof CalendarIntervalType)) {\n  throw new IllegalArgumentException(\"Iceberg StructInternalRow does not support interval columns; project them out\");\n}","typeGuard":"static boolean hasIntervalField(StructType schema) {\n  return java.util.Arrays.stream(schema.fields())\n      .anyMatch(f -> f.dataType() instanceof CalendarIntervalType);\n}","tryCatchPattern":null,"preventionTips":["Keep interval math in Spark post-read, not in the Iceberg-backed schema","Validate projected schemas exclude CalendarInterval before scanning Iceberg tables"],"tags":["spark","unsupported-type","interval"],"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"}