[flink] Fix TableNotExistException when listing partitions on changelog / binlog virtual tables#3641
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes Flink optimizer failures when it calls partition-related catalog methods (listPartitions, createPartition, dropPartition) on $changelog / $binlog virtual tables by mapping those virtual table names back to their underlying physical table before calling the Fluss admin API.
Changes:
- Added
toPhysicalTablePath()inFlinkCatalogand switchedtableExists(),listPartitions(...),createPartition(), anddropPartition()to use it for virtual table names. - Added unit/integration test coverage to ensure partition listing and partition operations work through
$changelog/$binlognames. - Added an end-to-end
SHOW PARTITIONSregression test for$changelogvirtual tables.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/catalog/FlinkCatalog.java | Strips virtual-table suffixes for existence/partition operations so $changelog/$binlog map to the base physical table. |
| fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/source/ChangelogVirtualTableITCase.java | Adds IT coverage for SHOW PARTITIONS on $changelog virtual tables. |
| fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/catalog/FlinkCatalogTest.java | Adds unit test verifying tableExists + partition operations via $changelog/$binlog paths. |
| fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/catalog/FlinkCatalogITCase.java | Adds IT coverage for planner-driven listPartitions() behavior on $changelog tables. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| private TablePath toPhysicalTablePath(ObjectPath objectPath) { | ||
| String tableName = objectPath.getObjectName(); | ||
| // Strip virtual table suffixes to get the base physical table name | ||
| if (tableName.endsWith(CHANGELOG_TABLE_SUFFIX)) { | ||
| tableName = | ||
| tableName.substring(0, tableName.length() - CHANGELOG_TABLE_SUFFIX.length()); | ||
| } else if (tableName.endsWith(BINLOG_TABLE_SUFFIX)) { | ||
| tableName = tableName.substring(0, tableName.length() - BINLOG_TABLE_SUFFIX.length()); | ||
| } else if (tableName.contains(LAKE_TABLE_SPLITTER)) { | ||
| tableName = tableName.split("\\" + LAKE_TABLE_SPLITTER)[0]; | ||
| } | ||
| return TablePath.of(objectPath.getDatabaseName(), tableName); | ||
| } |
|
Thanks for tackling #3640. The root cause is correct, and the
Overall, the read path changes look good to me. I just think we should reject mutating DDL on virtual tables and keep the |
MehulBatra
left a comment
There was a problem hiding this comment.
Left one small comment
|
Thanks @MehulBatra for your review! I have pushed an update to address the comments:
PTAL, thanks! |
Purpose
Linked issue: close #3640
When the Flink optimizer calls
listPartitions()on a$changelogor$binlogvirtual table, it throwsTableNotExistExceptionbecause the virtual table suffix is not stripped before querying the Fluss server.getTable()correctly dispatches virtual table names togetVirtualChangelogTable()/getVirtualBinlogTable(), buttableExists(),listPartitions(),createPartition(), anddropPartition()all pass the unstripped virtual table name directly to the admin API, which fails because no physical table namedxxx$changelogexists.Brief change log
toPhysicalTablePath()private helper method toFlinkCatalogthat strips$changelog,$binlog, and$lakesuffixes from the table name, returning the base physical table pathtableExists()to usetoPhysicalTablePath()— virtual tables now correctly report existence based on the base tablelistPartitions(ObjectPath, CatalogPartitionSpec)to usetoPhysicalTablePath()— virtual tables now list partitions of the base tablecreatePartition()anddropPartition()to usetoPhysicalTablePath()— partition management through virtual table names delegates to the base tableTests
FlinkCatalogTest#testVirtualTablePartitionsAndExistencewhich verifies:tableExists()returnstruefor$changelogand$binlogvirtual table nameslistPartitions()returns the same partitions as the base table for both virtual table suffixeslistPartitions()with aCatalogPartitionSpecworks correctly on virtual table namescreatePartition()anddropPartition()work through virtual table namesFlinkCatalogTest#testOperatePartitionscontinues to pass (no regression)API and Format
No API or storage format changes. The fix only affects internal catalog method behavior for virtual table names.
Documentation
No documentation changes needed — this is a bug fix that makes virtual table behavior consistent with
getTable().