You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by jo...@apache.org on 2019/07/26 21:40:34 UTC

[impala] 04/08: IMPALA-8434: retain tables and functions in altering database

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

joemcdonnell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit c501b34fb2ea7378ae0b1b615d9610e93a2e5af0
Author: stiga-huang <hu...@gmail.com>
AuthorDate: Tue Jul 23 17:09:09 2019 -0700

    IMPALA-8434: retain tables and functions in altering database
    
    In the legacy catalog implementation (ImpaladCatalog), when altering a
    database, the tables and functions in it will disappear until we run
    INVALIDATE METADATA to reset the cache. The cause is that we just
    replace the old Db object with the new one deserialized from the
    TDatabase. We should migrate the existing tables and functions to the
    new Db object.
    
    Tests:
     - Add test_metadata_after_alter_database for the bug.
     - Run Core tests
    
    Change-Id: Ia3dc9857fd2733e20cf10fbe17bb1a4670d7d015
    Reviewed-on: http://gerrit.cloudera.org:8080/13904
    Reviewed-by: Vihang Karajgaonkar <vi...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 .../java/org/apache/impala/catalog/ImpaladCatalog.java   | 16 +++++++++++++++-
 tests/metadata/test_ddl.py                               | 14 ++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/fe/src/main/java/org/apache/impala/catalog/ImpaladCatalog.java b/fe/src/main/java/org/apache/impala/catalog/ImpaladCatalog.java
index 13cb620..05fb2b3 100644
--- a/fe/src/main/java/org/apache/impala/catalog/ImpaladCatalog.java
+++ b/fe/src/main/java/org/apache/impala/catalog/ImpaladCatalog.java
@@ -19,6 +19,7 @@ package org.apache.impala.catalog;
 
 import java.nio.ByteBuffer;
 import java.util.ArrayDeque;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
@@ -388,16 +389,29 @@ public class ImpaladCatalog extends Catalog implements FeCatalog {
         existingDb.getCatalogVersion() < catalogVersion) {
       Db newDb = Db.fromTDatabase(thriftDb);
       newDb.setCatalogVersion(catalogVersion);
-      addDb(newDb);
       if (existingDb != null) {
         CatalogObjectVersionSet.INSTANCE.updateVersions(
             existingDb.getCatalogVersion(), catalogVersion);
         CatalogObjectVersionSet.INSTANCE.removeAll(existingDb.getTables());
         CatalogObjectVersionSet.INSTANCE.removeAll(
             existingDb.getFunctions(null, new PatternMatcher()));
+        // IMPALA-8434: add back the existing tables/functions. Note that their version
+        // counters in CatalogObjectVersionSet have been decreased by the above removeAll
+        // statements, meaning their references from the old db are deleted since the old
+        // db object has been replaced by newDb. addTable and addFunction will add their
+        // versions back.
+        for (Table tbl: existingDb.getTables()) {
+          newDb.addTable(tbl);
+        }
+        for (List<Function> functionList: existingDb.getAllFunctions().values()) {
+          for (Function func: functionList) {
+            newDb.addFunction(func);
+          }
+        }
       } else {
         CatalogObjectVersionSet.INSTANCE.addVersion(catalogVersion);
       }
+      addDb(newDb);
     }
   }
 
diff --git a/tests/metadata/test_ddl.py b/tests/metadata/test_ddl.py
index e5dfc25..41502cc 100644
--- a/tests/metadata/test_ddl.py
+++ b/tests/metadata/test_ddl.py
@@ -237,6 +237,20 @@ class TestDdlStatements(TestDdlBase):
     assert len(properties) == 1
     assert {'foo_role': 'ROLE'} == properties
 
+  def test_metadata_after_alter_database(self, vector, unique_database):
+    self.client.execute("create table {0}.tbl (i int)".format(unique_database))
+    self.client.execute("create function {0}.f() returns int "
+                        "location '{1}/libTestUdfs.so' symbol='NoArgs'"
+                        .format(unique_database, WAREHOUSE))
+    self.client.execute("alter database {0} set owner user foo_user".format(
+      unique_database))
+    table_names = self.client.execute("show tables in {0}".format(
+      unique_database)).get_data()
+    assert "tbl" == table_names
+    func_names = self.client.execute("show functions in {0}".format(
+      unique_database)).get_data()
+    assert "INT\tf()\tNATIVE\ttrue" == func_names
+
   def test_alter_table_set_owner(self, vector, unique_database):
     table_name = "{0}.test_owner_tbl".format(unique_database)
     self.client.execute("create table {0}(i int)".format(table_name))