This is an automated email from the ASF dual-hosted git repository.

jerryshao pushed a commit to branch branch-1.3
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/branch-1.3 by this push:
     new 9ea67df015 [Cherry-pick to branch-1.3] [#11538] fix(catalog-glue): 
Support RENAME TABLE for Iceberg tables (#11555) (#11563)
9ea67df015 is described below

commit 9ea67df0153ba80399eb5dba8356e71d0b8c060f
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Jun 10 18:13:59 2026 -0700

    [Cherry-pick to branch-1.3] [#11538] fix(catalog-glue): Support RENAME 
TABLE for Iceberg tables (#11555) (#11563)
    
    **Cherry-pick Information:**
    - Original commit: dda2c216239e84420e68601e966588800709fbca
    - Target branch: `branch-1.3`
    - Status: ✅ Clean cherry-pick (no conflicts)
    
    Co-authored-by: Yuhui <[email protected]>
---
 .../catalog/glue/GlueCatalogOperations.java        | 15 ++++++++++--
 .../catalog/glue/GlueIcebergTableHelper.java       | 24 ++++++++++++++++---
 .../glue/TestGlueCatalogOperationsForIceberg.java  | 27 ++++++++++++++++++----
 .../integration/test/glue/SparkGlueCatalogIT.java  | 23 ++++++++++++++++++
 4 files changed, 79 insertions(+), 10 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 66534c172e..0e8fa2dc12 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
@@ -67,6 +67,7 @@ import 
org.apache.gravitino.rel.expressions.transforms.Transforms;
 import org.apache.gravitino.rel.indexes.Index;
 import org.apache.gravitino.rel.types.Type;
 import org.apache.gravitino.utils.PrincipalUtils;
+import org.apache.iceberg.catalog.TableIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import software.amazon.awssdk.services.glue.GlueClient;
@@ -595,8 +596,18 @@ public class GlueCatalogOperations implements 
CatalogOperations, SupportsSchemas
     if (hasMetadataLocation && !isSdkManaged) {
       return alterRegisterModeIcebergTable(ident, dbName, rawGlueTable, 
changes);
     }
-    GlueIcebergTableHelper.alterTable(icebergGlueCatalog, dbName, 
ident.name(), changes);
-    return loadTable(ident);
+    TableIdentifier finalId =
+        GlueIcebergTableHelper.alterTable(icebergGlueCatalog, dbName, 
ident.name(), changes);
+    String newDbName = finalId.namespace().level(0);
+    NameIdentifier finalIdent;
+    if (newDbName.equals(dbName) && finalId.name().equals(ident.name())) {
+      finalIdent = ident;
+    } else {
+      String[] levels = ident.namespace().levels().clone();
+      levels[levels.length - 1] = newDbName;
+      finalIdent = NameIdentifier.of(Namespace.of(levels), finalId.name());
+    }
+    return loadTable(finalIdent);
   }
 
   private GlueTable alterRegisterModeIcebergTable(
diff --git 
a/catalogs/catalog-glue/src/main/java/org/apache/gravitino/catalog/glue/GlueIcebergTableHelper.java
 
b/catalogs/catalog-glue/src/main/java/org/apache/gravitino/catalog/glue/GlueIcebergTableHelper.java
index c69d23c992..d8bb3f6b05 100644
--- 
a/catalogs/catalog-glue/src/main/java/org/apache/gravitino/catalog/glue/GlueIcebergTableHelper.java
+++ 
b/catalogs/catalog-glue/src/main/java/org/apache/gravitino/catalog/glue/GlueIcebergTableHelper.java
@@ -380,8 +380,9 @@ final class GlueIcebergTableHelper {
   /**
    * Alters an Iceberg table via the Iceberg SDK.
    *
-   * <p>Delegates schema changes to {@link UpdateSchema} and property changes 
to {@link
-   * UpdateProperties}.
+   * <p>Supports {@link TableChange.RenameTable}, {@link 
TableChange.ColumnChange}, {@link
+   * TableChange.SetProperty}, and {@link TableChange.RemoveProperty}. A 
rename is an exclusive
+   * operation and cannot be combined with other changes.
    *
    * <p><b>Note:</b> Schema changes and property changes are committed in two 
separate transactions.
    * If the schema commit succeeds but the property commit fails, the table is 
left in a partially
@@ -391,9 +392,25 @@ final class GlueIcebergTableHelper {
    * @param dbName the Glue database name
    * @param tableName the table name
    * @param changes the table changes to apply
+   * @return the final {@link TableIdentifier} (differs from the input only 
when a rename is
+   *     applied, including cross-schema renames)
    */
-  static void alterTable(
+  static TableIdentifier alterTable(
       Catalog icebergCatalog, String dbName, String tableName, TableChange... 
changes) {
+    for (TableChange change : changes) {
+      if (change instanceof TableChange.RenameTable) {
+        Preconditions.checkArgument(
+            changes.length == 1, "RenameTable cannot be combined with other 
table changes");
+        TableChange.RenameTable rename = (TableChange.RenameTable) change;
+        String newDbName = rename.getNewSchemaName().orElse(dbName);
+        String newName = rename.getNewName();
+        TableIdentifier to = TableIdentifier.of(newDbName, newName);
+        icebergCatalog.renameTable(TableIdentifier.of(dbName, tableName), to);
+        LOG.info("Renamed Iceberg table {}.{} to {}.{}", dbName, tableName, 
newDbName, newName);
+        return to;
+      }
+    }
+
     Table table = icebergCatalog.loadTable(TableIdentifier.of(dbName, 
tableName));
 
     boolean hasSchemaChange = false;
@@ -484,6 +501,7 @@ final class GlueIcebergTableHelper {
       update.commit();
       LOG.info("Altered Iceberg table {}.{} properties via Iceberg SDK", 
dbName, tableName);
     }
+    return TableIdentifier.of(dbName, tableName);
   }
 
   // 
---------------------------------------------------------------------------
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 cfb5569ccc..8970b74a4a 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
@@ -236,21 +236,38 @@ class TestGlueCatalogOperationsForIceberg {
   }
 
   @Test
-  void testAlterTable_icebergRenameThrows() {
+  void testAlterIcebergTableRename() {
+    String newName = "ice1_renamed";
     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();
+    software.amazon.awssdk.services.glue.model.Table renamedTable =
+        software.amazon.awssdk.services.glue.model.Table.builder()
+            .name(newName)
+            .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());
+        .thenReturn(GetTableResponse.builder().table(rawTable).build())
+        .thenReturn(GetTableResponse.builder().table(renamedTable).build());
+    when(mockIcebergCatalog.loadTable(TableIdentifier.of(DB, newName)))
+        .thenThrow(new RuntimeException("no iceberg metadata"));
+    when(mockClient.getPartitions(any(GetPartitionsRequest.class)))
+        .thenReturn(GetPartitionsResponse.builder().build());
 
     NameIdentifier ident = NameIdentifier.of("cat", "ns", DB, TABLE);
-    assertThrows(
-        IllegalArgumentException.class,
-        () -> ops.alterTable(ident, TableChange.rename("new_table_name")));
+    GlueTable result = ops.alterTable(ident, TableChange.rename(newName));
+
+    ArgumentCaptor<TableIdentifier> fromCaptor = 
ArgumentCaptor.forClass(TableIdentifier.class);
+    ArgumentCaptor<TableIdentifier> toCaptor = 
ArgumentCaptor.forClass(TableIdentifier.class);
+    verify(mockIcebergCatalog).renameTable(fromCaptor.capture(), 
toCaptor.capture());
+    assertEquals(TableIdentifier.of(DB, TABLE), fromCaptor.getValue());
+    assertEquals(TableIdentifier.of(DB, newName), toCaptor.getValue());
+    assertEquals(newName, result.name());
   }
 
   @Test
diff --git 
a/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/integration/test/glue/SparkGlueCatalogIT.java
 
b/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/integration/test/glue/SparkGlueCatalogIT.java
index ddcf473710..da65d3541c 100644
--- 
a/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/integration/test/glue/SparkGlueCatalogIT.java
+++ 
b/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/integration/test/glue/SparkGlueCatalogIT.java
@@ -422,6 +422,29 @@ public abstract class SparkGlueCatalogIT extends 
SparkGlueEnvIT {
     Assertions.assertEquals("1,Alice,NULL", after.get(0));
   }
 
+  @Test
+  void testRenameIcebergTable() {
+    String oldName = "test_iceberg_rename_old";
+    String newName = "test_iceberg_rename_new";
+    dropTableIfExists(oldName);
+    dropTableIfExists(newName);
+
+    sql(getCreateSimpleTableString(oldName) + " USING iceberg");
+    sql(String.format("INSERT INTO %s VALUES (1, 'before_rename', 10)", 
oldName));
+
+    Assertions.assertTrue(tableExists(oldName));
+    Assertions.assertFalse(tableExists(newName));
+
+    sql(String.format("ALTER TABLE %s RENAME TO %s", oldName, newName));
+
+    Assertions.assertFalse(tableExists(oldName));
+    Assertions.assertTrue(tableExists(newName));
+
+    List<String> tableData = getTableData(newName);
+    Assertions.assertFalse(tableData.isEmpty());
+    Assertions.assertEquals("1,before_rename,10", tableData.get(0));
+  }
+
   @Test
   void testCreateTableWithComment() {
     String tableName = "test_table_with_comment";

Reply via email to