This is an automated email from the ASF dual-hosted git repository.
ayushtkn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new 96c325d598d HIVE-30161: Iceberg: Fix Create table failures leaving
orphan table entry in HMS (#6872)
96c325d598d is described below
commit 96c325d598dc24a324d62f35d5f5a15542c5a78b
Author: Ayush Saxena <[email protected]>
AuthorDate: Mon Oct 19 17:40:30 2026 +0530
HIVE-30161: Iceberg: Fix Create table failures leaving orphan table entry
in HMS (#6872)
---
.../iceberg/mr/hive/HiveIcebergMetaHook.java | 14 +++++++
.../hive/TestHiveIcebergStorageHandlerNoScan.java | 45 ++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git
a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java
b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java
index 1c522cfd026..1f25959ba46 100644
---
a/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java
+++
b/iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java
@@ -171,13 +171,27 @@ public class HiveIcebergMetaHook extends
BaseHiveIcebergMetaHook {
private AlterTableType currentAlterTableOp;
private HiveLock commitLock;
private List<SQLDefaultConstraint> sqlDefaultConstraints;
+ private boolean createTableCommitted;
public HiveIcebergMetaHook(Configuration conf) {
super(conf);
}
+ @Override
+ public void rollbackCreateTable(org.apache.hadoop.hive.metastore.api.Table
hmsTable) {
+ if (createTableCommitted && tableProperties != null &&
Catalogs.hiveCatalog(conf, tableProperties)) {
+ try {
+ Catalogs.dropTable(conf, tableProperties);
+ } catch (Exception e) {
+ LOG.warn("Failed to clean up table during rollback of CREATE TABLE for
{}.{}",
+ hmsTable.getDbName(), hmsTable.getTableName(), e);
+ }
+ }
+ }
+
@Override
public void commitCreateTable(org.apache.hadoop.hive.metastore.api.Table
hmsTable) {
+ createTableCommitted = true;
if (HiveTableUtil.isIcebergView(hmsTable)) {
tableProperties = IcebergTableProperties.getTableProperties(hmsTable,
conf);
Map<String, String> tblProps =
diff --git
a/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergStorageHandlerNoScan.java
b/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergStorageHandlerNoScan.java
index 4284ce7a26e..81d9c9e9f31 100644
---
a/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergStorageHandlerNoScan.java
+++
b/iceberg/iceberg-handler/src/test/java/org/apache/iceberg/mr/hive/TestHiveIcebergStorageHandlerNoScan.java
@@ -720,6 +720,51 @@ public void testCreateTableError() {
}
}
+ @Test
+ public void testCreateTableRollbackCleansUpHMSEntry() {
+ Assume.assumeTrue("Rollback cleanup is only relevant for HiveCatalog",
+ testTableType == TestTableType.HIVE_CATALOG);
+
+ // Creating with format-version=2 should fail, and the HMS entry should be
cleaned up.
+ Assertions.assertThatThrownBy(
+ () -> shell.executeStatement(
+ "CREATE TABLE rollback_test (id INT, ts TIMESTAMP(9)) " +
+ "STORED BY ICEBERG STORED AS PARQUET " +
+ "TBLPROPERTIES ('format-version'='2')"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("timestamp_ns is not supported until v3");
+
+ // Without the rollback fix, this would fail with AlreadyExistsException
+ // because the HMS entry from the failed create would still exist.
+ shell.executeStatement(
+ "CREATE TABLE rollback_test (id INT, ts TIMESTAMP(9)) " +
+ "STORED BY ICEBERG STORED AS PARQUET " +
+ "TBLPROPERTIES ('format-version'='3')");
+
+ shell.executeStatement("DROP TABLE rollback_test");
+ }
+
+ @Test
+ public void testCreateTableRollbackDoesNotDropExistingTable() {
+ Assume.assumeTrue("Rollback cleanup is only relevant for HiveCatalog",
+ testTableType == TestTableType.HIVE_CATALOG);
+
+ shell.executeStatement(
+ "CREATE TABLE existing_tbl (id INT) STORED BY ICEBERG STORED AS
PARQUET");
+
+ // Attempting to create a table with the same name should fail with
AlreadyExistsException.
+ // The rollback must NOT drop the existing table.
+ Assertions.assertThatThrownBy(
+ () -> shell.executeStatement(
+ "CREATE TABLE existing_tbl (id INT) STORED BY ICEBERG STORED AS
PARQUET"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("already exists");
+
+ // The original table should still be intact.
+ shell.executeStatement("DESCRIBE existing_tbl");
+ shell.executeStatement("DROP TABLE existing_tbl");
+ }
+
@Test
public void testCreateTableAboveExistingTable() throws IOException {
// Create the Iceberg table