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

Open Beginner friendly
#39,749 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
java
Domain
backend

Research direction

Start in SchemaUtils.java at toPrettyFieldValueString and trace the call from Row#toString through SchemaUtils.toPrettyString. Run the reproducer from the issue and add regression coverage for an ITERABLE backed by a plain Iterable; done means Row#toString completes without throwing for that value.

Written by the indexing model from the issue text.

Description

java P3
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
Dominant language
Java
Stars
8.7k
Forks
4.7k
Avg merge
2d 6h
Merged PRs (30d)
194

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/beam

All issues in apache/beam

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.