{"record":{"id":"00bfce630bc90f5d","repo":"apache/iceberg","slug":"not-supported-yet-00bfce","errorCode":null,"errorMessage":"Not supported yet.","messagePattern":"Not supported yet\\.","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java","lineNumber":215,"sourceCode":"        LocalDateTime ldt = (LocalDateTime) timeVal;\n        return TimestampData.fromEpochMillis(\n            ldt.toInstant(ZoneOffset.UTC).toEpochMilli(), ldt.getNano() % 1_000_000);\n      } else if (timeVal instanceof Long) {\n        long timeLong = (Long) timeVal;\n        return TimestampData.fromEpochMillis(\n            Math.floorDiv(timeLong, 1_000_000L), (int) Math.floorMod(timeLong, 1_000_000L));\n      } else {\n        throw new IllegalStateException(\"Unknown type for timestamp_ns: \" + timeVal.getClass());\n      }\n    }\n    long timeLong = getLong(pos);\n    return TimestampData.fromEpochMillis(\n        Math.floorDiv(timeLong, 1000L), (int) Math.floorMod(timeLong, 1000L) * 1000);\n  }\n\n  @Override\n  public <T> RawValueData<T> getRawValue(int pos) {\n    throw new UnsupportedOperationException(\"Not supported yet.\");\n  }\n\n  @Override\n  public byte[] getBinary(int pos) {\n    return isNullAt(pos) ? null : getBinaryInternal(pos);\n  }\n\n  private byte[] getBinaryInternal(int pos) {\n    Object bytes = struct.get(pos, 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 if (bytes instanceof UUID) {\n      UUID uuid = (UUID) bytes;\n      ByteBuffer bb = ByteBuffer.allocate(16);","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java#L197-L233","documentation":"StructRowData.getRawValue(pos) is part of Flink's RowData contract for RawValueData access, but Iceberg's implementation does not support raw value access and throws UnsupportedOperationException unconditionally. Raw value semantics (pass-through binary) are not applicable to projected Iceberg struct rows.","triggerScenarios":"Calling getRawValue(...) on a StructRowData, e.g. from a Flink sink or operator that uses RawValueData APIs (such as some serialization paths or async sinks).","commonSituations":"Connecting Iceberg scan output directly to operators that call getRawValue on all RowData; generic RowData-processing utilities that touch every accessor.","solutions":["Materialize the field via typed accessors (getInt/getLong/getString/getBinary) and construct RawValueData yourself if needed","Ensure downstream operators don't call getRawValue on Iceberg-projected rows (e.g. wrap rows in GenericRowData)","Reorder the pipeline so RawValueData usage happens before Iceberg projection wrapping"],"exampleFix":"// before\nRawValueData<String> raw = structRowData.getRawValue(pos); // throws\n// after\nString s = structRowData.getString(pos);\nRawValueData<String> raw = StringData.fromString(s);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { RawValueData<T> raw = row.getRawValue(pos); } catch (UnsupportedOperationException e) { T value = typedAccessor(row, pos); raw = RawValueData.fromObject(value); }","preventionTips":["Never rely on getRawValue for Iceberg StructRowData","Use typed accessors to build RawValueData when needed","Wrap projected rows before passing to raw-value-aware operators"],"tags":["flink","rowdata","unsupported-operation"],"backgroundTag":"method-not-implemented","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"}