Skip to content

Commit

Permalink
Core: Fix loading a table in CachingCatalog with metadata table name
Browse files Browse the repository at this point in the history
If a regular table had a metadata table name then CachingCatalog throws a
NoSuchTableException when loading that table.

Co-authored-by: Manu Zhang <[email protected]>
  • Loading branch information
gaborkaszab and manuzhang committed Dec 10, 2024
1 parent 11d21b2 commit efe4626
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
12 changes: 7 additions & 5 deletions core/src/main/java/org/apache/iceberg/CachingCatalog.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,16 @@ public Table loadTable(TableIdentifier ident) {
return cached;
}

if (MetadataTableUtils.hasMetadataTableName(canonicalized)) {
Table table = tableCache.get(canonicalized, catalog::loadTable);

if (table instanceof BaseMetadataTable) {
// Cache underlying table
TableIdentifier originTableIdentifier =
TableIdentifier.of(canonicalized.namespace().levels());
Table originTable = tableCache.get(originTableIdentifier, catalog::loadTable);

// share TableOperations instance of origin table for all metadata tables, so that metadata
// table instances are
// also refreshed as well when origin table instance is refreshed.
// Share TableOperations instance of origin table for all metadata tables, so that metadata
// table instances are also refreshed as well when origin table instance is refreshed.
if (originTable instanceof HasTableOperations) {
TableOperations ops = ((HasTableOperations) originTable).operations();
MetadataTableType type = MetadataTableType.from(canonicalized.name());
Expand All @@ -164,7 +166,7 @@ public Table loadTable(TableIdentifier ident) {
}
}

return tableCache.get(canonicalized, catalog::loadTable);
return table;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.iceberg.BaseMetadataTable;
import org.apache.iceberg.CachingCatalog;
import org.apache.iceberg.CatalogProperties;
import org.apache.iceberg.MetadataTableType;
Expand All @@ -41,6 +42,7 @@
import org.apache.iceberg.catalog.Catalog;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.exceptions.NoSuchTableException;
import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap;
import org.apache.iceberg.relocated.com.google.common.collect.Lists;
import org.apache.iceberg.util.FakeTicker;
Expand Down Expand Up @@ -166,6 +168,42 @@ public void testTableName() throws Exception {
.isEqualTo("hadoop.db.ns1.ns2.tbl.snapshots");
}

@Test
public void testNonExistingTable() throws Exception {
Catalog catalog = CachingCatalog.wrap(hadoopCatalog());

TableIdentifier tableIdent = TableIdentifier.of("otherDB", "otherTbl");

assertThatThrownBy(() -> catalog.loadTable(tableIdent))
.isInstanceOf(NoSuchTableException.class);
}

@Test
public void testTableWithMetadataTableName() throws Exception {
TestableCachingCatalog catalog =
TestableCachingCatalog.wrap(hadoopCatalog(), EXPIRATION_TTL, ticker);
TableIdentifier tableIdent = TableIdentifier.of("db", "ns1", "ns2", "partitions");
TableIdentifier metaTableIdent =
TableIdentifier.of("db", "ns1", "ns2", "partitions", "partitions");

catalog.createTable(tableIdent, SCHEMA, SPEC, ImmutableMap.of("key2", "value2"));
catalog.cache().invalidateAll();

Table table = catalog.loadTable(tableIdent);
assertThat(table.name()).isEqualTo("hadoop.db.ns1.ns2.partitions");
assertThat(catalog.cache().asMap()).containsKey(tableIdent);
assertThat(catalog.cache().asMap()).doesNotContainKey(metaTableIdent);

catalog.cache().invalidateAll();
assertThat(catalog.cache().asMap()).doesNotContainKey(tableIdent);

Table metaTable = catalog.loadTable(metaTableIdent);
assertThat(metaTable).isInstanceOf(BaseMetadataTable.class);
assertThat(metaTable.name()).isEqualTo("hadoop.db.ns1.ns2.partitions.partitions");
assertThat(catalog.cache().asMap()).containsKey(tableIdent);
assertThat(catalog.cache().asMap()).containsKey(metaTableIdent);
}

@Test
public void testTableExpiresAfterInterval() throws IOException {
TestableCachingCatalog catalog =
Expand Down

0 comments on commit efe4626

Please sign in to comment.