为hive permanent function添加默认database特性

前言

hive 0.13开始增加了permanent function;允许用户自定义的function无需往.hiverc文件中添加create temporary function,提高hive的启动时间(无需预先执行创建临时函数命令);并且可以将udf jar包放置于hdfs上,方便管理,无需向hive client端推送udf;但是permanent function有一个问题,就是,需要在function名前添加database名称,即[database].[function];如果不填写database,这会取当前database自动补全function。

参照传统的关系型数据库,一般存在默认的schema,在搜索function时,优先搜索默认的schema;如iopostgresql的pg_catalog等。因此想着为Hive添加default database这个特性。

设计

添加两个参数

hive.function.default.function.enabled  默认为:false,表示禁用此特性;设置为true,表示启动该特性;搜索函数时,优先查找默认database。

hive.function.default.function 默认为: default;当hive.function.default.function.enabled=true时生效;默认函数搜索路径。

实现

需要添加这个功能,需要了解permanent function在什么时候会用当前database,补全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) &amp;&amp; (e.getCause() instanceof MetaException)) &amp;&amp;
         (e.getCause().getCause() != null) &amp;&amp; (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 static <T extends CommonFunctionInfo> T getFunctionInfo(
      Map<String, T> 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 &amp;&amp; !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 };
  }

在这些代码上添加一个判断hive.function.default.function.enabled是否为true,如果为true,则将默认dbName调整为hive.function.default.function。

时间: 2024-10-25 14:34:00

为hive permanent function添加默认database特性的相关文章

[Hive - LanguageManual] Create/Drop/Alter Database Create/Drop/Truncate Table

Hive Data Definition Language Hive Data Definition Language Overview Create/Drop/Alter Database Create/Drop/Truncate Table Alter Table/Partition/Column Create/Drop/Alter View Create/Drop/Alter Index Create/Drop Function Create/Drop/Grant/Revoke Roles

自定义控件如何给特殊类型的属性添加默认值 z(转)

自定义控件如何给特殊类型的属性添加默认值 z 定义控件如何给特殊类型的属性添加默认值了,附自定义GroupBox一枚 标题有点那啥,但确实能表达我掌握此法后的心情. 写自定义控件时往往会有一个需求,就是给属性指定一个默认值(就是可以在VS中右键该属性→重置),如果该属性的类型是内置值类型还好,直接使用DefaultValue特性就好,例如: [DefaultValue(false)] public bool CanSelect { get; set; } 对于能够根据字符串常量转换得到的类型也还

自定义控件如何给特殊类型的属性添加默认值 z

定义控件如何给特殊类型的属性添加默认值了,附自定义GroupBox一枚 标题有点那啥,但确实能表达我掌握此法后的心情. 写自定义控件时往往会有一个需求,就是给属性指定一个默认值(就是可以在VS中右键该属性→重置),如果该属性的类型是内置值类型还好,直接使用DefaultValue特性就好,例如: [DefaultValue(false)] public bool CanSelect { get; set; } 对于能够根据字符串常量转换得到的类型也还好,可以这样: [DefaultValue(t

asp.net WebPages 网页添加默认命名空间

asp.net 网页框架常用的三种: WebForm,Mvc,WebPages 1.WebForm 直接在 system.web/pages 下添加 2.Mvc 新建个Mvc项目,直接复制 3.WebPage 大致上与Mvc相同,区别在于 host factoryType,pages pageBaseType <host factoryType="System.Web.WebPages.Razor.WebRazorHostFactory, System.Web.WebPages.Razor

【Windows 10 IoT】为Win10 IoT镜像添加默认应用(树莓派)

[Windows 10 IoT]为Win10 IoT镜像添加默认应用(树莓派) 在Windows 10 IoT应用程序开发好之后,一般通过IoT WebManagement或者直接用vs将应用部署上去.并且执行命令iotstartup.exe add headed/headless AppxID,将应用设置为开机启动.但是,如果想基于一个开发板,量产某种硬件设备,这种方式肯定是不可行的. 我们会想到,是否可以将我们的应用直接打包到镜像中,并设置成为开机自启的默认应用呢?当然可以. 基本原理是这样

为Python添加默认模块搜索路径

为Python添加默认模块搜索路径 方法一:函数添加 1) import sys 2) 查看sys.path 3) 添加sys.path.append("c:\\") 方法二:修改环境变量 windows用户可以修改系统环境变量PYTHONPATH 方法三:增加.pth文件,推荐! 在site-packages添加一个路径文件,如mypkpath.pth,必须以.pth为后缀,写上你要加入的模块文件所在的目录名称就是了. 1) windows c:\python27\site-pack

关于yii2框架活动记录activeRecord添加默认字段的问题

平时使用sql的时候可以如下添加默认字段flag: "select a.*,0 as flag from user_info a", 对于yii2框架则需要这样: $query =(new \yii\db\Query()) ->select([ 'r.real_name', new Expression("'身份证' id_no_type") ]) ->from(['r' => $this->tableName()])

IIS7.5网站添加默认文档时提示“由于权限不足而无法写入配置文件”。

在对网站添加默认文档时提示“由于权限不足而无法写入配置文件”. 其实这不是权限不足造成的,而是网站的配置文件属性是“只读”造成的. 右击网站配置文件--属性--属性项里去掉只读--确定.

[小问题笔记(八)] 常用SQL(读字段名,改字段名,打印影响行数,添加默认值,查找存储过程等)

读取所有字段,自然排序 declare @fields varchar(max) Select @fields=ISNULL(@fields,'')++name+',' from syscolumns Where ID=OBJECT_ID('contact') order by colorder print @fields 读取所有字段,名称排序 declare @fields varchar(max) Select @fields=ISNULL(@fields,'')++name+',' fr