HIVE-12304 "drop database cascade" needs to unregister functions

Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/dff25380
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/dff25380
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/dff25380

Branch: refs/heads/master-fixed
Commit: dff25380012be0782f78548f049ce645e3969076
Parents: 0f716f1
Author: aihuaxu <aihu...@apache.org>
Authored: Fri Oct 30 13:31:08 2015 -0400
Committer: aihuaxu <aihu...@apache.org>
Committed: Thu Nov 5 11:34:40 2015 -0500

----------------------------------------------------------------------
 .../org/apache/hadoop/hive/ql/exec/DDLTask.java |  7 +-
 .../hadoop/hive/ql/exec/FunctionRegistry.java   |  9 +++
 .../apache/hadoop/hive/ql/exec/Registry.java    | 12 +++
 .../clientnegative/drop_database_cascade.q      | 26 ++++++
 .../clientnegative/drop_database_cascade.q.out  | 85 ++++++++++++++++++++
 5 files changed, 138 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/dff25380/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java 
b/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
index caf98b5..9ab3e98 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
@@ -3731,7 +3731,12 @@ public class DDLTask extends Task<DDLWork> implements 
Serializable {
   private int dropDatabase(Hive db, DropDatabaseDesc dropDb)
       throws HiveException {
     try {
-      db.dropDatabase(dropDb.getDatabaseName(), true, dropDb.getIfExists(), 
dropDb.isCasdade());
+      String dbName = dropDb.getDatabaseName();
+      db.dropDatabase(dbName, true, dropDb.getIfExists(), dropDb.isCasdade());
+      // Unregister the functions as well
+      if (dropDb.isCasdade()) {
+        FunctionRegistry.unregisterPermanentFunctions(dbName);
+      }
     }
     catch (NoSuchObjectException ex) {
       throw new HiveException(ex, ErrorMsg.DATABASE_NOT_EXISTS, 
dropDb.getDatabaseName());

http://git-wip-us.apache.org/repos/asf/hive/blob/dff25380/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java 
b/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java
index de8e98c..2196ca9 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java
@@ -1571,6 +1571,15 @@ public final class FunctionRegistry {
     unregisterTemporaryUDF(functionName);
   }
 
+  /**
+   * Unregisters all the functions under the database dbName
+   * @param dbName specified database name
+   * @throws HiveException
+   */
+  public static void unregisterPermanentFunctions(String dbName) throws 
HiveException {
+    system.unregisterFunctions(dbName);
+  }
+
   private FunctionRegistry() {
     // prevent instantiation
   }

http://git-wip-us.apache.org/repos/asf/hive/blob/dff25380/ql/src/java/org/apache/hadoop/hive/ql/exec/Registry.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/Registry.java 
b/ql/src/java/org/apache/hadoop/hive/ql/exec/Registry.java
index 1121819..ea9813c 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/Registry.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/Registry.java
@@ -419,6 +419,18 @@ public class Registry {
     }
   }
 
+  /**
+   * Unregisters all the functions belonging to the specified database
+   * @param dbName database name
+   * @throws HiveException
+   */
+  public synchronized void unregisterFunctions(String dbName) throws 
HiveException {
+    Set<String> funcNames = getFunctionNames(dbName.toLowerCase() + "\\..*");
+    for (String funcName : funcNames) {
+      unregisterFunction(funcName);
+    }
+  }
+
   public GenericUDAFResolver getGenericUDAFResolver(String functionName) 
throws SemanticException {
     FunctionInfo info = getFunctionInfo(functionName);
     if (info != null) {

http://git-wip-us.apache.org/repos/asf/hive/blob/dff25380/ql/src/test/queries/clientnegative/drop_database_cascade.q
----------------------------------------------------------------------
diff --git a/ql/src/test/queries/clientnegative/drop_database_cascade.q 
b/ql/src/test/queries/clientnegative/drop_database_cascade.q
new file mode 100644
index 0000000..d544692
--- /dev/null
+++ b/ql/src/test/queries/clientnegative/drop_database_cascade.q
@@ -0,0 +1,26 @@
+-- This test verifies that if the functions and tables unregistered when the 
database is dropped
+-- and other databases are not affected
+
+CREATE DATABASE TEST_database;
+
+USE TEST_database;
+
+CREATE TABLE test_table (key STRING, value STRING);
+
+CREATE FUNCTION test_func as 'org.apache.hadoop.hive.ql.udf.UDFAscii';
+
+USE default;
+
+CREATE TABLE test_table (key STRING, value STRING);
+
+CREATE FUNCTION test_func as 'org.apache.hadoop.hive.ql.udf.UDFAscii';
+
+DROP DATABASE TEST_database CASCADE;
+
+describe test_table;
+
+describe function test_func;
+
+describe function TEST_database.test_func;
+
+describe TEST_database.test_table;

http://git-wip-us.apache.org/repos/asf/hive/blob/dff25380/ql/src/test/results/clientnegative/drop_database_cascade.q.out
----------------------------------------------------------------------
diff --git a/ql/src/test/results/clientnegative/drop_database_cascade.q.out 
b/ql/src/test/results/clientnegative/drop_database_cascade.q.out
new file mode 100644
index 0000000..304b967
--- /dev/null
+++ b/ql/src/test/results/clientnegative/drop_database_cascade.q.out
@@ -0,0 +1,85 @@
+PREHOOK: query: -- This test verifies that if the functions and tables 
unregistered when the database is dropped
+-- and other databases are not affected
+
+CREATE DATABASE TEST_database
+PREHOOK: type: CREATEDATABASE
+PREHOOK: Output: database:TEST_database
+POSTHOOK: query: -- This test verifies that if the functions and tables 
unregistered when the database is dropped
+-- and other databases are not affected
+
+CREATE DATABASE TEST_database
+POSTHOOK: type: CREATEDATABASE
+POSTHOOK: Output: database:TEST_database
+PREHOOK: query: USE TEST_database
+PREHOOK: type: SWITCHDATABASE
+PREHOOK: Input: database:test_database
+POSTHOOK: query: USE TEST_database
+POSTHOOK: type: SWITCHDATABASE
+POSTHOOK: Input: database:test_database
+PREHOOK: query: CREATE TABLE test_table (key STRING, value STRING)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: TEST_database@test_table
+PREHOOK: Output: database:test_database
+POSTHOOK: query: CREATE TABLE test_table (key STRING, value STRING)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: TEST_database@test_table
+POSTHOOK: Output: database:test_database
+PREHOOK: query: CREATE FUNCTION test_func as 
'org.apache.hadoop.hive.ql.udf.UDFAscii'
+PREHOOK: type: CREATEFUNCTION
+PREHOOK: Output: database:test_database
+PREHOOK: Output: test_database.test_func
+POSTHOOK: query: CREATE FUNCTION test_func as 
'org.apache.hadoop.hive.ql.udf.UDFAscii'
+POSTHOOK: type: CREATEFUNCTION
+POSTHOOK: Output: database:test_database
+POSTHOOK: Output: test_database.test_func
+PREHOOK: query: USE default
+PREHOOK: type: SWITCHDATABASE
+PREHOOK: Input: database:default
+POSTHOOK: query: USE default
+POSTHOOK: type: SWITCHDATABASE
+POSTHOOK: Input: database:default
+PREHOOK: query: CREATE TABLE test_table (key STRING, value STRING)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@test_table
+POSTHOOK: query: CREATE TABLE test_table (key STRING, value STRING)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@test_table
+PREHOOK: query: CREATE FUNCTION test_func as 
'org.apache.hadoop.hive.ql.udf.UDFAscii'
+PREHOOK: type: CREATEFUNCTION
+PREHOOK: Output: database:default
+PREHOOK: Output: default.test_func
+POSTHOOK: query: CREATE FUNCTION test_func as 
'org.apache.hadoop.hive.ql.udf.UDFAscii'
+POSTHOOK: type: CREATEFUNCTION
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default.test_func
+PREHOOK: query: DROP DATABASE TEST_database CASCADE
+PREHOOK: type: DROPDATABASE
+PREHOOK: Input: database:test_database
+PREHOOK: Output: database:test_database
+PREHOOK: Output: test_database@test_table
+POSTHOOK: query: DROP DATABASE TEST_database CASCADE
+POSTHOOK: type: DROPDATABASE
+POSTHOOK: Input: database:test_database
+POSTHOOK: Output: database:test_database
+POSTHOOK: Output: test_database@test_table
+PREHOOK: query: describe test_table
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: default@test_table
+POSTHOOK: query: describe test_table
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: default@test_table
+key                    string                                      
+value                  string                                      
+PREHOOK: query: describe function test_func
+PREHOOK: type: DESCFUNCTION
+POSTHOOK: query: describe function test_func
+POSTHOOK: type: DESCFUNCTION
+test_func(str) - returns the numeric value of the first character of str
+PREHOOK: query: describe function TEST_database.test_func
+PREHOOK: type: DESCFUNCTION
+POSTHOOK: query: describe function TEST_database.test_func
+POSTHOOK: type: DESCFUNCTION
+Function 'TEST_database.test_func' does not exist.
+FAILED: SemanticException [Error 10001]: Table not found 
TEST_database.test_table

Reply via email to