Skip to content

[Bug]: Row.toString throws for an ITERABLE field that is not backed by a List #39749

Description

@PDGGK

What happened?

Row#toString throws for an ITERABLE field whose value is a plain Iterable:

Schema schema =
    Schema.builder().addStringField("k").addIterableField("vals", FieldType.STRING).build();
Iterable<String> bare = () -> Arrays.asList("p", "q").iterator();
Row.withSchema(schema).attachValues("k1", bare).toString();
java.lang.IllegalArgumentException: value type is 'class ...' for field type 'ITERABLE'
	at org.apache.beam.sdk.schemas.SchemaUtils.toPrettyFieldValueString(SchemaUtils.java:273)

toPrettyFieldValueString requires a List before iterating:

if (!(value instanceof List)) {
  throw new IllegalArgumentException(...);
}

An ITERABLE field declares an Iterable, so the guard is stricter than the type it is guarding. The branch below it only iterates and counts — both available from an Iterable once materialised.

Row#toString is SchemaUtils.toPrettyString(this), so one unusual field takes out logging and debugger output for every field beside it, which is a poor trade for a stricter check in a renderer.

Note on where the fix belongs

There is a reasonable position that a materialised Row should always hold a List for ARRAY/ITERABLE, and that a non-List arriving here means a producer is at fault. That may well be true and worth fixing separately — but the reproducer above uses only Schema.builder, Row.withSchema(...).attachValues(...) and toString(), so a value that is merely Iterable does reach the renderer through the public API, and a toString() that throws is hard to defend regardless of who produced the value.

Issue Priority

Priority: 3 (minor)

Issue Components

  • Component: Java SDK

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions