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

zabetak 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 a732ae0f071 HIVE-29443: NPE in FunctionRegistry#getFunctionInfo when 
session not available (#6301)
a732ae0f071 is described below

commit a732ae0f071b0e9a3e9e030db8fc0acb441c6f68
Author: Stamatis Zampetakis <[email protected]>
AuthorDate: Mon Feb 9 09:39:28 2026 +0100

    HIVE-29443: NPE in FunctionRegistry#getFunctionInfo when session not 
available (#6301)
---
 .../hadoop/hive/ql/exec/FunctionRegistry.java      |  3 +-
 .../apache/hadoop/hive/ql/exec/FunctionUtils.java  | 15 +++++++++
 .../org/apache/hadoop/hive/ql/exec/Registry.java   |  9 ++----
 .../hadoop/hive/ql/exec/TestFunctionRegistry.java  | 36 ++++++++++++++++++++--
 4 files changed, 52 insertions(+), 11 deletions(-)

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 eda1360293f..46ee2ad7bc7 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
@@ -817,8 +817,7 @@ public static String getNormalizedFunctionName(String fn) 
throws SemanticExcepti
     // Does the same thing as getFunctionInfo, except for getting the function 
info.
     fn = fn.toLowerCase();
     return (FunctionUtils.isQualifiedFunctionName(fn) || getFunctionInfo(fn) 
!= null) ? fn
-        : FunctionUtils.qualifyFunctionName(
-        fn, SessionState.get().getCurrentDatabase().toLowerCase());
+        : FunctionUtils.qualifyFunctionName(fn);
   }
 
   public static FunctionInfo getFunctionInfo(String functionName) throws 
SemanticException {
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionUtils.java 
b/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionUtils.java
index 9a916397c9c..78adb6c2937 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionUtils.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionUtils.java
@@ -20,6 +20,7 @@
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
+import org.apache.hadoop.hive.metastore.Warehouse;
 import org.apache.hadoop.hive.metastore.api.ResourceType;
 import org.apache.hadoop.hive.metastore.api.ResourceUri;
 import org.apache.hadoop.hive.ql.exec.FunctionInfo.FunctionResource;
@@ -104,6 +105,20 @@ public static boolean isQualifiedFunctionName(String 
functionName) {
     return functionName.indexOf('.') >= 0;
   }
 
+  /**
+   * Qualifies the provided function name with the current database if it is 
not already qualified.
+   * If a session is not available, the default database name will be used for 
qualification.
+   * @return a qualified function name with the current database
+   */
+  public static String qualifyFunctionName(String functionName) {
+    if (isQualifiedFunctionName(functionName)) {
+      return functionName;
+    }
+    SessionState ss = SessionState.get();
+    String dbName = ss != null ? ss.getCurrentDatabase().toLowerCase() : 
Warehouse.DEFAULT_DATABASE_NAME;
+    return dbName + "." + functionName;
+  }
+
   public static String qualifyFunctionName(String functionName, String dbName) 
{
     if (isQualifiedFunctionName(functionName)) {
       return functionName;
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 8c8d90f2537..6fb92776862 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
@@ -312,8 +312,7 @@ public FunctionInfo registerPermanentFunction(String 
functionName,
     FunctionInfo function = new FunctionInfo(functionName, className, 
resources);
     // register to session first for backward compatibility
     if (registerToSession) {
-      String qualifiedName = FunctionUtils.qualifyFunctionName(
-          functionName, SessionState.get().getCurrentDatabase().toLowerCase());
+      String qualifiedName = FunctionUtils.qualifyFunctionName(functionName);
       FunctionInfo newFunction = registerToSessionRegistry(qualifiedName, 
function);
       if (newFunction != null) {
         addFunction(functionName, function);
@@ -367,8 +366,7 @@ public FunctionInfo getFunctionInfo(String functionName) 
throws SemanticExceptio
         throw new SemanticException ("UDF " + functionName + " is not 
allowed");
       }
       if (functionInfo == null) {
-        functionName = FunctionUtils.qualifyFunctionName(
-            functionName, 
SessionState.get().getCurrentDatabase().toLowerCase());
+        functionName = FunctionUtils.qualifyFunctionName(functionName);
         functionInfo = getQualifiedFunctionInfo(functionName);
       }
       addToCurrentFunctions(functionName, functionInfo);
@@ -386,8 +384,7 @@ public WindowFunctionInfo getWindowFunctionInfo(String 
functionName) throws Sema
     FunctionInfo info = getFunctionInfo(WINDOW_FUNC_PREFIX + functionName);
     // Try qualifying with current db name for permanent functions and try 
register function to session
     if (info == null && FunctionRegistry.getFunctionInfo(functionName) != 
null) {
-      String qualifiedName = FunctionUtils.qualifyFunctionName(
-              functionName, 
SessionState.get().getCurrentDatabase().toLowerCase());
+      String qualifiedName = FunctionUtils.qualifyFunctionName(functionName);
       info = getFunctionInfo(WINDOW_FUNC_PREFIX + qualifiedName);
     }
     if (info instanceof WindowFunctionInfo) {
diff --git 
a/ql/src/test/org/apache/hadoop/hive/ql/exec/TestFunctionRegistry.java 
b/ql/src/test/org/apache/hadoop/hive/ql/exec/TestFunctionRegistry.java
index 15bf768895a..e183449b904 100644
--- a/ql/src/test/org/apache/hadoop/hive/ql/exec/TestFunctionRegistry.java
+++ b/ql/src/test/org/apache/hadoop/hive/ql/exec/TestFunctionRegistry.java
@@ -26,7 +26,6 @@
 
 
 import org.apache.hadoop.hive.common.type.HiveVarchar;
-import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConfForTest;
 import org.apache.hadoop.hive.ql.exec.FunctionInfo.FunctionResource;
 import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
@@ -53,6 +52,8 @@
 import org.junit.Assert;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import org.junit.Before;
 import org.junit.After;
@@ -97,8 +98,6 @@ public void setUp() {
     varchar5 = TypeInfoFactory.getPrimitiveTypeInfo("varchar(5)");
     char10 = TypeInfoFactory.getPrimitiveTypeInfo("char(10)");
     char5 = TypeInfoFactory.getPrimitiveTypeInfo("char(5)");
-    HiveConf conf = new HiveConfForTest(getClass());
-    SessionState.start(conf);
   }
 
   private void implicit(TypeInfo a, TypeInfo b, boolean convertible) {
@@ -440,6 +439,7 @@ public void testImpliesOrder() throws Exception {
 
   @Test
   public void testRegisterTemporaryFunctions() throws Exception {
+    SessionState state = SessionState.start(new 
HiveConfForTest(TestFunctionRegistry.class));
     FunctionResource[] emptyResources = new FunctionResource[] {};
 
     // UDF
@@ -463,10 +463,12 @@ public void testRegisterTemporaryFunctions() throws 
Exception {
     FunctionRegistry.registerTemporaryUDF("tmp_explode", 
GenericUDTFExplode.class, emptyResources);
     functionInfo = FunctionRegistry.getFunctionInfo("tmp_explode");
     assertFalse(functionInfo.isNative());
+    state.close();
   }
 
   @Test
   public void testRegisterPermanentFunction() throws Exception {
+    SessionState state = SessionState.start(new 
HiveConfForTest(TestFunctionRegistry.class));
     FunctionResource[] emptyResources = new FunctionResource[] {};
 
     // UDF
@@ -505,6 +507,7 @@ public void testRegisterPermanentFunction() throws 
Exception {
     assertTrue(functionInfo.isPersistent());
     assertTrue(functionInfo.isNative());
     assertFalse(functionInfo.isBuiltIn());
+    state.close();
   }
 
   @Test
@@ -516,6 +519,7 @@ public void testBuiltInFunction() throws Exception {
 
   @Test
   public void testIsPermanentFunction() throws Exception {
+    SessionState state = SessionState.start(new 
HiveConfForTest(TestFunctionRegistry.class));
     // Setup exprNode
     GenericUDF udf = new GenericUDFCurrentTimestamp();
     List<ExprNodeDesc> children = new ArrayList<ExprNodeDesc>();
@@ -530,6 +534,32 @@ public void testIsPermanentFunction() throws Exception {
         GenericUDFCurrentTimestamp.class.getName(), true, emptyResources);
 
     assertTrue("Function should now be recognized as permanent function", 
FunctionRegistry.isPermanentFunction(fnExpr));
+    state.close();
+  }
+
+  @Test
+  public void testGetFunctionInfoNoSessionValidName() throws Exception {
+    assertNotNull(FunctionRegistry.getFunctionInfo("concat"));
+  }
+
+  @Test
+  public void testGetFunctionInfoNoSessionMissingName() throws Exception {
+    assertNull(FunctionRegistry.getFunctionInfo("nofn"));
+  }
+
+  @Test
+  public void testGetWindowFunctionInfoNoSessionValidName() throws Exception {
+    assertNotNull(FunctionRegistry.getWindowFunctionInfo("max"));
+  }
+
+  @Test
+  public void testGetWindowFunctionInfoNoSessionMissingName() throws Exception 
{
+    assertNull(FunctionRegistry.getWindowFunctionInfo("nofn"));
+  }
+
+  @Test
+  public void testGetWindowFunctionInfoNoSessionInvalidName() throws Exception 
{
+    assertNull(FunctionRegistry.getWindowFunctionInfo("concat"));
   }
 
   private GenericUDF getUDF(String udfName) throws Exception {

Reply via email to