You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hudi.apache.org by "wombatu-kun (via GitHub)" <gi...@apache.org> on 2026/07/11 12:42:03 UTC
[I] [BUG] BasicStagedTable.newWriteBuilder matches LogicalWriteInfo instead of the staged Table, rejecting every write [hudi]
wombatu-kun opened a new issue, #19250:
URL: https://github.com/apache/hudi/issues/19250
### Bug Description
`BasicStagedTable.newWriteBuilder` pattern-matches its `LogicalWriteInfo` argument against `SupportsWrite`, instead of matching the staged `Table`:
```scala
override def newWriteBuilder(info: LogicalWriteInfo): WriteBuilder = {
info match {
case supportsWrite: SupportsWrite => supportsWrite.newWriteBuilder(info)
case _ => throw new HoodieException(s"Table `${ident.name}` does not support writes.")
}
}
```
`SupportsWrite` is a `Table` mixin (`SupportsWrite extends Table`, in `org.apache.spark.sql.connector.catalog`), while `LogicalWriteInfo` is an unrelated interface in `org.apache.spark.sql.connector.write` whose only Spark implementation, `LogicalWriteInfoImpl`, implements `LogicalWriteInfo, Product, Serializable`. No `LogicalWriteInfo` can ever satisfy the first case, so the delegating branch is dead and the method throws for every input, including one whose underlying table is perfectly writable.
**What happened:** every write staged through `BasicStagedTable` is rejected with ``Table `x` does not support writes.``
**What was expected:** the write is delegated to the underlying table when that table is `SupportsWrite`; the exception is raised only when it is not.
`BasicStagedTable` is what `HoodieCatalog` returns from `stageCreate`, `stageReplace` and `stageCreateOrReplace` for non-Hudi tables, so an atomic CTAS or RTAS against a writable V2 table reaches this method.
**Steps to reproduce:** a unit test is enough:
```scala
val table = mock(classOf[SupportsWrite])
val info = mock(classOf[LogicalWriteInfo])
when(table.newWriteBuilder(info)).thenReturn(mock(classOf[WriteBuilder]))
BasicStagedTable(Identifier.of(Array("db"), "tbl"), table, mock(classOf[TableCatalog])).newWriteBuilder(info)
// throws HoodieException: Table `tbl` does not support writes.
```
**Why it survived:** Scala compiles a match between two unrelated interfaces without a warning, since a class could in principle implement both, and `BasicStagedTable` had no test coverage at all. Present since #4611 (2022). Spark's own `BasicStagedTable` delegates via `table.asWritable`.
**Fix:** match on `table` instead of `info`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] [BUG] BasicStagedTable.newWriteBuilder matches LogicalWriteInfo instead of the staged Table, rejecting every write [hudi]
Posted by "wombatu-kun (via GitHub)" <gi...@apache.org>.
wombatu-kun closed issue #19250: [BUG] BasicStagedTable.newWriteBuilder matches LogicalWriteInfo instead of the staged Table, rejecting every write
URL: https://github.com/apache/hudi/issues/19250
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@hudi.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org