Repository navigation
Fix Beam SQL UNNEST of array elements with a nested row through JDBC #40841
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
dd8e97d
7a2a631
390bfad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -351,6 +351,62 @@ public void testSelectsFromExistingComplexTable() throws Exception { | |
| assertThat(resultRows, containsInAnyOrder(row(1L, "aaa"), row(2L, "bbb"))); | ||
| } | ||
|
|
||
| @Test | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new JDBC test only exercises the non-null nested row path. The null-nested-row fix in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added in 7a2a631. The JDBC test now has a third element whose |
||
| public void testUnnestArrayOfRowsWithNestedRow() throws Exception { | ||
| TestTableProvider tableProvider = new TestTableProvider(); | ||
| Connection connection = JdbcDriver.connect(tableProvider, PipelineOptionsFactory.create()); | ||
|
|
||
| connection | ||
| .createStatement() | ||
| .executeUpdate( | ||
| "CREATE EXTERNAL TABLE person ( \n" | ||
| + "name VARCHAR, \n" | ||
| + "items ARRAY<ROW< \n" | ||
| + " description VARCHAR, \n" | ||
| + " nestedRow ROW<id BIGINT, name VARCHAR>>> \n" | ||
| + ") \n" | ||
| + "TYPE 'test'"); | ||
|
|
||
| Schema tableSchema = | ||
| Schema.builder() | ||
| .addNullableField("name", Schema.FieldType.STRING) | ||
| .addNullableField("items", Schema.FieldType.array(Schema.FieldType.row(COMPLEX_SCHEMA))) | ||
| .build(); | ||
| tableProvider.addRows( | ||
| "person", | ||
| row( | ||
| tableSchema, | ||
| "person1", | ||
| Arrays.asList( | ||
| row(COMPLEX_SCHEMA, "description1", row(1L, "aaa")), | ||
| row(COMPLEX_SCHEMA, "description2", row(2L, "bbb")), | ||
| row(COMPLEX_SCHEMA, "description3", null)))); | ||
|
|
||
| ResultSet selectResult = | ||
| connection | ||
| .createStatement() | ||
| .executeQuery( | ||
| "SELECT item.description, item.nestedRow.name " | ||
| + "FROM person CROSS JOIN UNNEST(person.items) AS item"); | ||
|
|
||
| Schema resultSchema = | ||
| Schema.builder() | ||
| .addNullableField("description", Schema.FieldType.STRING) | ||
| .addNullableField("name", Schema.FieldType.STRING) | ||
| .build(); | ||
| List<Row> resultRows = | ||
| readResultSet(selectResult).stream() | ||
| .map(values -> values.stream().collect(toRow(resultSchema))) | ||
| .collect(Collectors.toList()); | ||
|
|
||
| assertThat( | ||
| resultRows, | ||
| containsInAnyOrder( | ||
| row(resultSchema, "description1", "aaa"), | ||
| row(resultSchema, "description2", "bbb"), | ||
| row(resultSchema, "description3", null))); | ||
| } | ||
|
|
||
| @Test | ||
| public void testInsertIntoCreatedTable() throws Exception { | ||
| TestTableProvider tableProvider = new TestTableProvider(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isRowColumnwill throwIndexOutOfBoundsExceptionifindex >= outputSchema.getFieldCount(). This can only happen when the element schema and the output schema disagree on field count, which indicates a planning bug rather than user error. A bounds guard with a clear message would make that failure much easier to diagnose than a raw IOOBE:Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a guard in 7a2a631. Instead of throwing,
isRowColumnreturns false past the last output column. The extra values then reachRow.Builder#build(), which fails with the sameRow expected N fields ... initialized with M fieldserror as in #26911. That message lists the output schema fields, so a planner mismatch is easier to trace. Happy to switch to anIllegalStateExceptionif you would rather have that.