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

dweeks pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/main by this push:
     new a3dcfd19fd Hive: Optimize tableExists API in hive catalog (#11597)
a3dcfd19fd is described below

commit a3dcfd19fd1b2a709f7bdf013b83836953d49c6f
Author: Hongyue/Steve Zhang <[email protected]>
AuthorDate: Thu Dec 12 11:01:44 2024 -0700

    Hive: Optimize tableExists API in hive catalog (#11597)
    
    * Hive: Optimize tableExists API in hive catalog
    
    Skip creation of hive table operation when check existence of iceberg table 
in hive catalog
    
    * Add a newline after if/else
    
    * Add current thread interrupt
    
    * Handle metadata tables and separate the tests
    
    * Add comment back
    
    * Address feedback
    
    * Add extra  comment for EcsCatalog override method
    
    * Move javadoc  around
    
    * Added note if hive table with same name exists
    
    * Added note if hive table with same name exists
    
    * Add test with invalid identifier
---
 .../org/apache/iceberg/BaseMetastoreCatalog.java   |  2 +-
 .../java/org/apache/iceberg/hive/HiveCatalog.java  | 37 ++++++++++++++++
 .../org/apache/iceberg/hive/HiveTableTest.java     | 49 ++++++++++++++++++++++
 3 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java 
b/core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java
index e960fe2b63..29068df380 100644
--- a/core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java
+++ b/core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java
@@ -113,7 +113,7 @@ public abstract class BaseMetastoreCatalog implements 
Catalog, Closeable {
     }
   }
 
-  private boolean isValidMetadataIdentifier(TableIdentifier identifier) {
+  protected boolean isValidMetadataIdentifier(TableIdentifier identifier) {
     return MetadataTableType.from(identifier.name()) != null
         && 
isValidIdentifier(TableIdentifier.of(identifier.namespace().levels()));
   }
diff --git 
a/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java 
b/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java
index 1cf738d736..9fd7c6f2ee 100644
--- a/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java
+++ b/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java
@@ -412,6 +412,43 @@ public class HiveCatalog extends BaseMetastoreViewCatalog
     }
   }
 
+  /**
+   * Check whether table or metadata table exists.
+   *
+   * <p>Note: If a hive table with the same identifier exists in catalog, this 
method will return
+   * {@code false}.
+   *
+   * @param identifier a table identifier
+   * @return true if the table exists, false otherwise
+   */
+  @Override
+  public boolean tableExists(TableIdentifier identifier) {
+    TableIdentifier baseTableIdentifier = identifier;
+    if (!isValidIdentifier(identifier)) {
+      if (!isValidMetadataIdentifier(identifier)) {
+        return false;
+      } else {
+        baseTableIdentifier = 
TableIdentifier.of(identifier.namespace().levels());
+      }
+    }
+
+    String database = baseTableIdentifier.namespace().level(0);
+    String tableName = baseTableIdentifier.name();
+    try {
+      Table table = clients.run(client -> client.getTable(database, 
tableName));
+      HiveOperationsBase.validateTableIsIceberg(table, fullTableName(name, 
baseTableIdentifier));
+      return true;
+    } catch (NoSuchTableException | NoSuchObjectException e) {
+      return false;
+    } catch (TException e) {
+      throw new RuntimeException("Failed to check table existence of " + 
baseTableIdentifier, e);
+    } catch (InterruptedException e) {
+      Thread.currentThread().interrupt();
+      throw new RuntimeException(
+          "Interrupted in call to check table existence of " + 
baseTableIdentifier, e);
+    }
+  }
+
   @Override
   public void createNamespace(Namespace namespace, Map<String, String> meta) {
     Preconditions.checkArgument(
diff --git 
a/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableTest.java 
b/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableTest.java
index 5650c4e824..7f7a56c9a1 100644
--- a/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableTest.java
+++ b/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableTest.java
@@ -388,6 +388,55 @@ public class HiveTableTest extends HiveTableBaseTest {
     HIVE_METASTORE_EXTENSION.metastoreClient().dropTable(DB_NAME, 
hiveTableName);
   }
 
+  @Test
+  public void testTableExists() throws TException, IOException {
+    String testTableName = "test_table_exists";
+    TableIdentifier identifier = TableIdentifier.of(DB_NAME, testTableName);
+    TableIdentifier metadataIdentifier = TableIdentifier.of(DB_NAME, 
testTableName, "partitions");
+    TableIdentifier invalidIdentifier = TableIdentifier.of(DB_NAME, "invalid", 
testTableName);
+
+    assertThat(catalog.tableExists(invalidIdentifier))
+        .as("Should return false on invalid identifier")
+        .isFalse();
+    assertThat(catalog.tableExists(identifier))
+        .as("Table should not exist before create")
+        .isFalse();
+    catalog.buildTable(identifier, SCHEMA).create();
+
+    assertThat(catalog.tableExists(identifier)).as("Table should exist after 
create").isTrue();
+    assertThat(catalog.tableExists(metadataIdentifier))
+        .as("Metadata table should also exist")
+        .isTrue();
+
+    assertThat(catalog.dropTable(identifier)).as("Should drop a table that 
does exist").isTrue();
+    assertThat(catalog.tableExists(identifier)).as("Table should not exist 
after drop").isFalse();
+    assertThat(catalog.tableExists(metadataIdentifier))
+        .as("Metadata table should not exist after drop")
+        .isFalse();
+
+    HIVE_METASTORE_EXTENSION
+        .metastoreClient()
+        .createTable(createHiveTable(testTableName, TableType.EXTERNAL_TABLE));
+    assertThat(catalog.tableExists(identifier))
+        .as("Should return false when a hive table with the same name exists")
+        .isFalse();
+    assertThat(catalog.tableExists(metadataIdentifier))
+        .as("Metadata table should not exist")
+        .isFalse();
+    HIVE_METASTORE_EXTENSION.metastoreClient().dropTable(DB_NAME, 
testTableName);
+
+    catalog
+        .buildView(identifier)
+        .withSchema(SCHEMA)
+        .withDefaultNamespace(identifier.namespace())
+        .withQuery("spark", "select * from ns.tbl")
+        .create();
+    assertThat(catalog.tableExists(identifier))
+        .as("Should return false if identifier refers to a view")
+        .isFalse();
+    catalog.dropView(identifier);
+  }
+
   private org.apache.hadoop.hive.metastore.api.Table createHiveTable(
       String hiveTableName, TableType type) throws IOException {
     Map<String, String> parameters = Maps.newHashMap();

Reply via email to