hive 0.13開(kāi)始增加了permanent function;允許用戶自定義的function無(wú)需往.hiverc文件中添加create temporary function,提高h(yuǎn)ive的啟動(dòng)時(shí)間(無(wú)需預(yù)先執(zhí)行創(chuàng)建臨時(shí)函數(shù)命令);并且可以將udf jar包放置于hdfs上,方便管理,無(wú)需向hive client端推送udf;但是permanent function有一個(gè)問(wèn)題,就是,需要在function名前添加database名稱,即[database].[function];如果不填寫database,這會(huì)取當(dāng)前database自動(dòng)補(bǔ)全function。
十多年的常熟網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整常熟建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“常熟網(wǎng)站設(shè)計(jì)”,“常熟網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
參照傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù),一般存在默認(rèn)的schema,在搜索function時(shí),優(yōu)先搜索默認(rèn)的schema;如iopostgresql的pg_catalog等。因此想著為Hive添加default database這個(gè)特性。
添加兩個(gè)參數(shù)
hive.function.default.function.enabled 默認(rèn)為:false,表示禁用此特性;設(shè)置為true,表示啟動(dòng)該特性;搜索函數(shù)時(shí),優(yōu)先查找默認(rèn)database。
hive.function.default.function 默認(rèn)為: default;當(dāng)hive.function.default.function.enabled=true時(shí)生效;默認(rèn)函數(shù)搜索路徑。
需要添加這個(gè)功能,需要了解permanent function在什么時(shí)候會(huì)用當(dāng)前database,補(bǔ)全function。
FunctionRegistry.java
private static FunctionInfo getFunctionInfoFromMetastore(String functionName) { FunctionInfo ret = null; try { String dbName; String fName; if (FunctionUtils.isQualifiedFunctionName(functionName)) { String[] parts = FunctionUtils.splitQualifiedFunctionName(functionName); dbName = parts[0]; fName = parts[1]; } else { // otherwise, qualify using current db dbName = SessionState.get().getCurrentDatabase().toLowerCase(); fName = functionName; } // Try looking up function in the metastore HiveConf conf = SessionState.get().getConf(); Function func = Hive.get(conf).getFunction(dbName, fName); if (func != null) { // Found UDF in metastore - now add it to the function registry // At this point we should add any relevant jars that would be needed for the UDf. try { FunctionTask.addFunctionResources(func.getResourceUris()); } catch (Exception e) { LOG.error("Unable to load resources for " + dbName + "." + fName + ":" + e.getMessage(), e); return null; } Class> udfClass = Class.forName(func.getClassName(), true, Utilities.getSessionSpecifiedClassLoader()); if (registerTemporaryFunction(functionName, udfClass)) { ret = mFunctions.get(functionName); } else { LOG.error(func.getClassName() + " is not a valid UDF class and was not registered."); } } } catch (HiveException e) { if (!((e.getCause() != null) && (e.getCause() instanceof MetaException)) && (e.getCause().getCause() != null) && (e.getCause().getCause() instanceof NoSuchObjectException)) { LOG.info("Unable to lookup UDF in metastore: " + e); } } catch (ClassNotFoundException e) { // Lookup of UDf class failed LOG.error("Unable to load UDF class: " + e); } return ret; }
public static String getNormalizedFunctionName(String fn) { // Does the same thing as getFunctionInfo, except for getting the function info. fn = fn.toLowerCase(); return (FunctionUtils.isQualifiedFunctionName(fn) || mFunctions.get(fn) != null) ? fn : FunctionUtils.qualifyFunctionName( fn, SessionState.get().getCurrentDatabase().toLowerCase()); } private staticT getFunctionInfo( Map mFunctions, String functionName) { functionName = functionName.toLowerCase(); T functionInfo = null; if (FunctionUtils.isQualifiedFunctionName(functionName)) { functionInfo = getQualifiedFunctionInfo(mFunctions, functionName); } else { // First try without qualifiers - would resolve builtin/temp functions. // Otherwise try qualifying with current db name. functionInfo = mFunctions.get(functionName); if (functionInfo == null && !FunctionUtils.isQualifiedFunctionName(functionName)) { String qualifiedName = FunctionUtils.qualifyFunctionName(functionName, SessionState.get().getCurrentDatabase().toLowerCase()); functionInfo = getQualifiedFunctionInfo(mFunctions, qualifiedName); } } return functionInfo; }
FunctionUtils.java
public static String[] getQualifiedFunctionNameParts(String name) throws HiveException { if (isQualifiedFunctionName(name)) { return splitQualifiedFunctionName(name); } String dbName = SessionState.get().getCurrentDatabase(); return new String[] { dbName, name }; }
在這些代碼上添加一個(gè)判斷hive.function.default.function.enabled是否為true,如果為true,則將默認(rèn)dbName調(diào)整為hive.function.default.function。