This is an automated email from the ASF dual-hosted git repository. github-actions[bot] pushed a commit to branch cherry-pick-1637d27f-to-branch-1.3 in repository https://gitbox.apache.org/repos/asf/gravitino.git
commit f1f7041f776f52d11c6a08ed020a3ba93a35bdfc Author: Xu Bai <[email protected]> AuthorDate: Thu Jun 4 10:11:38 2026 +0800 [#11352] fix(glue): improve error logging for Iceberg metadata loading (#11359) ### What changes were proposed in this pull request? This PR updates the Glue catalog warning when loading Iceberg metadata fails. The warning no longer says that partitioning and sort order information may be incomplete. Instead, it reports the Iceberg metadata load failure directly and keeps the original exception in the stacktrace, so missing `metadata.json` files are easier to diagnose. This PR also adds a regression test to ensure that a table returned after Iceberg metadata loading fails still keeps its Glue operation context. ### Why are the changes needed? The previous warning was misleading when the real root cause was a missing Iceberg metadata file, for example an S3 `NoSuchKeyException` for `metadata/*.metadata.json`. It made the issue look like a partition or sort-order compatibility problem. Fix: #11352 ### Does this PR introduce _any_ user-facing change? Yes. The Glue catalog warning message for Iceberg metadata loading failures is changed. No API or configuration changes are introduced. ### How was this patch tested? - `./gradlew :catalogs:catalog-glue:test --tests org.apache.gravitino.catalog.glue.TestGlueCatalogOperationsForIceberg -PskipITs` - `./gradlew :catalogs:catalog-glue:test -PskipITs` --- .../catalog/glue/GlueCatalogOperations.java | 7 +---- .../glue/TestGlueCatalogOperationsForIceberg.java | 32 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/catalogs/catalog-glue/src/main/java/org/apache/gravitino/catalog/glue/GlueCatalogOperations.java b/catalogs/catalog-glue/src/main/java/org/apache/gravitino/catalog/glue/GlueCatalogOperations.java index 8023895196..72f995ef9e 100644 --- a/catalogs/catalog-glue/src/main/java/org/apache/gravitino/catalog/glue/GlueCatalogOperations.java +++ b/catalogs/catalog-glue/src/main/java/org/apache/gravitino/catalog/glue/GlueCatalogOperations.java @@ -377,12 +377,7 @@ public class GlueCatalogOperations implements CatalogOperations, SupportsSchemas try { GlueIcebergTableHelper.loadTable(icebergGlueCatalog, dbName, ident.name(), table); } catch (Exception e) { - LOG.warn( - "Failed to load Iceberg metadata for table {}.{}. " - + "Partitioning and sort order information may be incomplete.", - dbName, - ident.name(), - e); + LOG.warn("Failed to load Iceberg metadata for table {}.{}", dbName, ident.name(), e); } } diff --git a/catalogs/catalog-glue/src/test/java/org/apache/gravitino/catalog/glue/TestGlueCatalogOperationsForIceberg.java b/catalogs/catalog-glue/src/test/java/org/apache/gravitino/catalog/glue/TestGlueCatalogOperationsForIceberg.java index f901d38958..cfb5569ccc 100644 --- a/catalogs/catalog-glue/src/test/java/org/apache/gravitino/catalog/glue/TestGlueCatalogOperationsForIceberg.java +++ b/catalogs/catalog-glue/src/test/java/org/apache/gravitino/catalog/glue/TestGlueCatalogOperationsForIceberg.java @@ -20,6 +20,7 @@ package org.apache.gravitino.catalog.glue; import static org.apache.gravitino.catalog.glue.GlueConstants.ICEBERG_TABLE_TYPE_VALUE; import static org.apache.gravitino.catalog.glue.GlueConstants.TABLE_TYPE_PARAM; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -31,6 +32,7 @@ import static org.mockito.Mockito.when; import java.util.Map; import java.util.Set; import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.rel.SupportsPartitions; import org.apache.gravitino.rel.TableChange; import org.apache.gravitino.rel.expressions.distributions.Distributions; import org.apache.gravitino.rel.expressions.transforms.Transform; @@ -42,8 +44,11 @@ import org.apache.iceberg.catalog.Catalog; import org.apache.iceberg.catalog.TableIdentifier; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import software.amazon.awssdk.services.glue.GlueClient; +import software.amazon.awssdk.services.glue.model.GetPartitionsRequest; +import software.amazon.awssdk.services.glue.model.GetPartitionsResponse; import software.amazon.awssdk.services.glue.model.GetTableRequest; import software.amazon.awssdk.services.glue.model.GetTableResponse; import software.amazon.awssdk.services.glue.model.StorageDescriptor; @@ -203,6 +208,33 @@ class TestGlueCatalogOperationsForIceberg { Indexes.EMPTY_INDEXES)); } + @Test + void testLoadTableWithIcebergMetadataLoadFailure() { + software.amazon.awssdk.services.glue.model.Table rawTable = + software.amazon.awssdk.services.glue.model.Table.builder() + .name(TABLE) + .parameters(Map.of(TABLE_TYPE_PARAM, ICEBERG_TABLE_TYPE_VALUE)) + .storageDescriptor(StorageDescriptor.builder().build()) + .build(); + + when(mockClient.getTable(any(GetTableRequest.class))) + .thenReturn(GetTableResponse.builder().table(rawTable).build()); + when(mockIcebergCatalog.loadTable(any(TableIdentifier.class))) + .thenThrow(new RuntimeException("metadata file is missing")); + when(mockClient.getPartitions(any(GetPartitionsRequest.class))) + .thenReturn(GetPartitionsResponse.builder().build()); + + GlueTable result = ops.loadTable(NameIdentifier.of("cat", "ns", DB, TABLE)); + SupportsPartitions partitions = result.supportPartitions(); + + assertEquals(0, partitions.listPartitionNames().length); + ArgumentCaptor<GetPartitionsRequest> captor = + ArgumentCaptor.forClass(GetPartitionsRequest.class); + verify(mockClient).getPartitions(captor.capture()); + assertEquals(DB, captor.getValue().databaseName()); + assertEquals(TABLE, captor.getValue().tableName()); + } + @Test void testAlterTable_icebergRenameThrows() { software.amazon.awssdk.services.glue.model.Table rawTable =
