CREATE FUNCTION
描述
CREATE FUNCTION
语句用于创建临时或永久函数。临时函数的作用域是会话级别,而永久函数的作用域是持久目录。
函数是在持久化目录中创建的,所有会话都可以使用。在 USING
子句中指定的资源会在首次执行时提供给所有执行器。
除了 SQL 接口外,rainlake 还允许用户使用 Scala、Java、Python语言创建自定义的标量和聚合函数。
请参考 标量 UDFs 和 UDAFs 获取更多信息。
语法
CREATE [ OR REPLACE ] [ TEMPORARY ] FUNCTION [ IF NOT EXISTS ] function_name
[ COMMENT function_comment ]
[ LANGUAGE language_type ]
AS [ class_name | $$ function_code $$ ]
[ USING resource1, resource2, ... ]
参数
OR REPLACE
如果指定,函数的资源将被重新加载。这主要用于获取对函数实现所做的任何更改。
该参数与IF NOT EXISTS
相互排斥,不能同时指定。TEMPORARY
表示创建函数的作用域。指定
TEMPORARY
时,创建的函数在当前会话中有效并可见。目录中不会为此类函数创建持久条目。IF NOT EXISTS
如果指定,则仅在函数不存在时创建该函数。如果系统中已存在指定函数,则函数创建成功(不出错)。
此参数与OR REPLACE
相互排斥,不能同时指定。function_name
指定要创建的函数名称。函数名称可选择使用数据库名称限定。
语法:
[ database_name. ] function_name
function_comment
为函数指定注释。
LANGUAGE language_type
使用其他语言来创建函数。目前支持的语言有
JAVA
、SCALA
和PYTHON
。class_name
指定为要创建的函数提供实现的类的名称。
实现类应扩展以下基类之一:- 应扩展
org.apache.hadoop.hive.ql.exec
包中的UDF
或UDAF
。 - 应扩展
org.apache.hadoop.hive.ql.udf.generic
包中的AbstractGenericUDAFResolver
,GenericUDF
, 或GenericUDTF
。 - 应扩展
org.apache.spark.sql.expressions
包中的UserDefinedAggregateFunction
。
- 应扩展
function_code
指定要创建的函数的代码。该代码应是一个有效的
Java
、Scala
或Python
函数。该函数应返回一个标量值或一个数组。
如果指定了其他语言,则应该在AS
之后使用function_code
而不是class_name
。
如果是Java
函数,函数名应为fun
。
如果是Scala
,则应当使用lambda
函数而非普通函数(使用def
定义的函数)。
如果是Python
,支持lambda
函数和def
定义函数。由于Python
语言的缩进特点,多行代码请参考下面的示例。resource_locations
指定包含函数实现及其依赖关系的资源列表。在使用
class_name
时需要指定资源。语法:
USING { { (JAR | FILE | ARCHIVE) resource_uri } , ... }
示例
Jar包示例
-- 1. Create a simple UDF `SimpleUdf` that increments the supplied integral value by 10.
-- import org.apache.hadoop.hive.ql.exec.UDF;
-- public class SimpleUdf extends UDF {
-- public int evaluate(int value) {
-- return value + 10;
-- }
-- }
-- 2. Compile and place it in a JAR file called `SimpleUdf.jar` in /tmp.
-- Create a table called `test` and insert two rows.
CREATE TABLE test(c1 INT);
INSERT INTO test VALUES (1), (2);
-- Create a permanent function called `simple_udf`.
CREATE FUNCTION simple_udf AS 'SimpleUdf'
USING JAR '/tmp/SimpleUdf.jar';
-- Verify that the function is in the registry.
SHOW USER FUNCTIONS;
+------------------+
| function|
+------------------+
|default.simple_udf|
+------------------+
-- Invoke the function. Every selected value should be incremented by 10.
SELECT simple_udf(c1) AS function_return_value FROM test;
+---------------------+
|function_return_value|
+---------------------+
| 11|
| 12|
+---------------------+
-- Created a temporary function.
CREATE TEMPORARY FUNCTION simple_temp_udf AS 'SimpleUdf'
USING JAR '/tmp/SimpleUdf.jar';
-- Verify that the newly created temporary function is in the registry.
-- Please note that the temporary function does not have a qualified
-- database associated with it.
SHOW USER FUNCTIONS;
+------------------+
| function|
+------------------+
|default.simple_udf|
| simple_temp_udf|
+------------------+
-- 1. Modify `SimpleUdf`'s implementation to add supplied integral value by 20.
-- import org.apache.hadoop.hive.ql.exec.UDF;
-- public class SimpleUdfR extends UDF {
-- public int evaluate(int value) {
-- return value + 20;
-- }
-- }
-- 2. Compile and place it in a jar file called `SimpleUdfR.jar` in /tmp.
-- Replace the implementation of `simple_udf`
CREATE OR REPLACE FUNCTION simple_udf AS 'SimpleUdfR'
USING JAR '/tmp/SimpleUdfR.jar';
-- Invoke the function. Every selected value should be incremented by 20.
SELECT simple_udf(c1) AS function_return_value FROM test;
+---------------------+
|function_return_value|
+---------------------+
| 21|
| 22|
+---------------------+
Scala示例
-- 使用 `SCALA` 语法编写函数,使传入的参数加 10 之后返回,之后将函数嵌入 `CREATE FUNCTION` 语句中。
CREATE FUNCTION scala_udf LANGUAGE SCALA
AS $$(x: Int) => { x + 10 }$$;
-- 调用函数,每个被选中的值都被加了 10。
SELECT scala_udf(c1) AS function_return_value FROM test;
+---------------------+
|function_return_value|
+---------------------+
| 11|
| 12|
+---------------------+
-- 修改 `scala_udf` ,使传入的参数加 20 之后返回,之后将函数嵌入 `CREATE FUNCTION` 语句中。
CREATE FUNCTION scala_udf LANGUAGE SCALA
AS $$(x: Int) => { x + 20 }$$;
-- 调用函数,每个被选中的值都被加了 20。
SELECT scala_udf(c1) AS function_return_value FROM test;
+---------------------+
|function_return_value|
+---------------------+
| 21|
| 22|
+---------------------+
Java示例
-- 使用 `JAVA` 语法编写函数,使传入的参数加 10 之后返回,之后将函数嵌入 `CREATE FUNCTION` 语句中。
-- 目前跑不了
CREATE FUNCTION java_udf LANGUAGE JAVA AS $$
public Integer fun(Integer x) {
return x + 10;
} $$;
-- 调用函数,每个被选中的值都被加了 10。
SELECT java_udf(c1) AS function_return_value FROM test;
+---------------------+
|function_return_value|
+---------------------+
| 11|
| 12|
+---------------------+
Python示例
-- 1. 普通函数定义的Python UDF:返回两个字符串中较长的字符串(长度相同时返回第一个字符串)
-- 多行的python代码需要正确缩进,建议def写在行开头的位置
CREATE DATABASE py_udf;
USE DATABASE py_udf;
CREATE FUNCTION longer_def LANGUAGE PYTHON AS $$
def longer_of_two(str1, str2):
if len(str1) >= len(str2):
return str1
else:
return str2
$$
SELECT longer_def("333", "4444");
+----------------------------+
|py_udf.longer_def(333, 4444)|
+----------------------------+
| 4444|
+----------------------------+
-- 2. lambda形式的Python UDF
CREATE FUNCTION longer_lambda LANGUAGE PYTHON AS $$ lambda str1, str2 : str1 if len(str1) >= len(str2) else str2 $$
SELECT longer_lambda("333", "4444")
+-------------------------------+
|py_udf.longer_lambda(333, 4444)|
+-------------------------------+
| 4444|
+-------------------------------+
相关语句
TODO
- 需要支持一下jar包导入函数,RAINLAKE-332
- select func(a) as col1 from table,查询之后列名不是col1
- 集群上create java function 会报错 parseException