Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
15 changes: 15 additions & 0 deletions ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 3 additions & 6 deletions ql/src/java/org/apache/hadoop/hive/ql/exec/Registry.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -505,6 +507,7 @@ public void testRegisterPermanentFunction() throws Exception {
assertTrue(functionInfo.isPersistent());
assertTrue(functionInfo.isNative());
assertFalse(functionInfo.isBuiltIn());
state.close();
}

@Test
Expand All @@ -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>();
Expand All @@ -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 {
Expand Down