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";