{"record":{"id":"22aff1fbd2b9e45d","repo":"apache/iceberg","slug":"unsupported-structuredtype","errorCode":null,"errorMessage":"Unsupported StructuredType.","messagePattern":"Unsupported StructuredType\\.","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/FlinkTypeVisitor.java","lineNumber":58,"sourceCode":"\n  @Override\n  public T visit(YearMonthIntervalType yearMonthIntervalType) {\n    throw new UnsupportedOperationException(\"Unsupported YearMonthIntervalType.\");\n  }\n\n  @Override\n  public T visit(DayTimeIntervalType dayTimeIntervalType) {\n    throw new UnsupportedOperationException(\"Unsupported DayTimeIntervalType.\");\n  }\n\n  @Override\n  public T visit(DistinctType distinctType) {\n    throw new UnsupportedOperationException(\"Unsupported DistinctType.\");\n  }\n\n  @Override\n  public T visit(StructuredType structuredType) {\n    throw new UnsupportedOperationException(\"Unsupported StructuredType.\");\n  }\n\n  @Override\n  public T visit(NullType nullType) {\n    throw new UnsupportedOperationException(\"Unsupported NullType.\");\n  }\n\n  @Override\n  public T visit(RawType<?> rawType) {\n    throw new UnsupportedOperationException(\"Unsupported RawType.\");\n  }\n\n  @Override\n  public T visit(SymbolType<?> symbolType) {\n    throw new UnsupportedOperationException(\"Unsupported SymbolType.\");\n  }\n\n  @Override","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/FlinkTypeVisitor.java#L40-L76","documentation":"Flink StructuredType is an anonymous structured/record logical type (e.g. from class-based UDTs) with no direct Iceberg mapping, so FlinkTypeVisitor throws UnsupportedOperationException when it is visited. Iceberg conversion expects concrete row types it can map to Iceberg StructType.","triggerScenarios":"Converting a row type containing a StructuredType column, typically produced by Java/Scala class UDTs or connectors emitting structured logical types, when running FlinkTypeVisitor-based schema conversion.","commonSituations":"Sink queries that include UDT columns feeding Iceberg; Flink version differences where inference yields StructuredType where an older version inferred RowType; object constructors in SELECT lists producing structured types.","solutions":["Convert the UDT column to an explicit ROW(...) type, e.g. CAST(obj AS ROW<a INT, b STRING>), so Iceberg maps it to StructType.","Flatten the structured column into individual scalar columns before the Iceberg sink.","Remove the structured column from the Iceberg table schema if it is not needed.","Override visit(StructuredType) in a custom FlinkTypeVisitor subclass to map fields to an Iceberg StructType."],"exampleFix":"// before\nINSERT INTO iceberg_t SELECT my_udt_col FROM src; // StructuredType\n// after\nINSERT INTO iceberg_t SELECT CAST(my_udt_col AS ROW<x INT, y STRING>) AS r FROM src;","handlingStrategy":"validation","validationCode":"import org.apache.flink.table.types.logical.LogicalType;\nimport org.apache.flink.table.types.logical.StructuredType;\n\nstatic boolean containsStructuredType(org.apache.flink.table.api.Schema schema) {\n  return schema.getColumns().stream()\n      .anyMatch(c -> c.getType().getLogicalType() instanceof StructuredType);\n}","typeGuard":"static boolean isStructuredType(LogicalType t) {\n  return t instanceof StructuredType;\n}","tryCatchPattern":null,"preventionTips":["Prefer explicit ROW(...) types over class-based UDTs in Iceberg sink pipelines.","Cast UDT columns to ROW types with explicit fields before the sink.","Flatten structured columns into scalar columns where possible.","Pin consistent Flink versions so type inference is stable across upgrades."],"tags":["flink","iceberg","unsupported-type","type-conversion"],"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"}