pysx0503
作者pysx0503联盟成员·2020-04-17 21:46
系统工程师·第十区。散人

GBase 8a MPP Cluster UDF&UDAF 使用手册

字数 25477阅读 1148评论 0赞 3

GBase 8a MPP Cluster) (集群)
UDF&UDAF 使用手册
GBase 8a MPP Cluster UDF&UDAF 使用手册,南大通用数据技术股份有限公司
GBase e 版权所有©2004-2018,保留所有权利。
版权声明
本文档所涉及的软件著作权、版权和知识产权已依法进行了相关注册、登
记,由南大通用数据技术股份有限公司合法拥有,受《中华人民共和国著作权
法》、《计算机软件保护条例》、《知识产权保护条例》和相关国际版权条约、法
律、法规以及其它知识产权法律和条约的保护。未经授权许可,不得非法使用。
免责声明
本文档包含的南大通用公司的版权信息由南大通用公司合法拥有,受法律
的保护,南大通用公司对本文档可能涉及到的非南大通用公司的信息不承担任
何责任。在法律允许的范围内,您可以查阅,并仅能够在《中华人民共和国著
作权法》规定的合法范围内复制和打印本文档。任何单位和个人未经南大通用
公司书面授权许可,不得使用、修改、再发布本文档的任何部分和内容,否则
将视为侵权,南大通用公司具有依法追究其责任的权利。
本文档中包含的信息如有更新,恕不另行通知。您对本文档的任何问题,
可直接向南大通用数据技术股份有限公司告知或查询。
未经本公司明确授予的任何权利均予保留。
通讯方式
南大通用数据技术股份有限公司
天津华苑产业区海泰发展六道 6 号海泰绿色产业基地 J 座(300384)
电话:400-013-9696 邮箱:info@gbase.cn
商标声明
是南大通用数据技术股份有限公司向中华人民共和国国家商标
局申请注册的注册商标,注册商标专用权由南大通用公司合法拥有,受法律保
护。未经南大通用公司书面许可,任何单位及个人不得以任何方式或理由对该
商标的任何部分进行使用、复制、修改、传播、抄录或与其它产品捆绑使用销
售。凡侵犯南大通用公司商标权的,南大通用公司将依法追究其法律责任。
GBase 8a MPP Cluster UDF&UDAF 使用手册
南大通用数据技术股份有限公司 I
目 录
前言 ......................................................... 1
手册简介 ................................................. 1
公约 ..................................................... 1
1 环境要求 ................................................. 2
2 UDF 函数接口 .............................................. 3
2.1 func()(必需) ...................................... 3
2.2 func_init()(必需) ................................. 3
2.3 func_deinit()(可选) ............................... 4
3 函数参数形式及结构........................................ 5
3.1 函数参数形式........................................ 5
3.2 参数结构 ........................................... 5
3.2.1 initid 参数 .................................... 5
3.2.2 args 参数 ...................................... 6
4 UDF 返回值和错误处理 ..................................... 10
4.1 错误处理 .......................................... 10
4.2 函数返回值 ........................................ 10
5 编译及创建 UDF ........................................... 12
6 UDF 函数串并行控制 ....................................... 14
7 UDAF 函数部署和使用 ...................................... 16
7.1 编译 .............................................. 16
7.2 部署 .............................................. 16
7.3 创建 .............................................. 16
7.4 删除 .............................................. 17
7.5 更新 .............................................. 17
7.6 权限 .............................................. 18
8 UDAF 函数功能描述 ........................................ 18
8.1 func_init():...................................... 18
8.2 func_max_buffer_length() ......................... 19
GBase 8a MPP Cluster UDF&UDAF 使用手册
II 南大通用数据技术股份有限公司
8.3 func_clear() .................................... 19
8.4 func_add() ...................................... 20
8.5 func() .......................................... 20
8.6 func_deinit() ..................................... 22
9 UDAF 接口参数描述........................................ 22
9.1 UDF_INIT 结构 ...................................... 22
9.2 UDF_ARGS 结构 ...................................... 25
10 UDAF 函数使用示例 .................................... 29
11 Python UDF .......................................... 30
11.1 匿名执行任意 python 脚本.......................... 30
11.2 Python 自定义函数支持 ............................ 31
11.3 约束和限制 ...................................... 35
12 附录 ................................................ 35
12.1 Mysql 的 UDF 错误处理机制 ......................... 35
12.2 gbase 中 UDF 和自定义函数使用 ..................... 36
12.3 UDAF 函数大小写不敏感 ............................ 37
GBase 8a MPP Cluster UDF&UDAF 使用手册
南大通用数据技术股份有限公司 - 1 -
前言
手册简介
GBase 8a MPP Cluster UDF&UDAF 使用手册主要用于说明 Gbase 8a MPP
Cluster 中 UDF、UDAF 的通用扩展机制,通过该机制,数据库用户可以自行定
义开发高效的 SQL 函数(使用 C/C++语言实现)。
风险:F UDF 以动态库的形式存在,其稳定性会影响到数据库服务的稳定性。
建议用户将需求发给数据库厂商,由专业人员进行编写。
公约
下面的文本约定用于本文档:
约 定 说 明
加粗字体 表示文档标题
大写英文(SELECT) 表示 GBase 8a 关键字
等宽字体 表示代码示例
… 省略号指明被省略的内容。
GBase 8a MPP Cluster UDF&UDAF 使用手册

  • 2 - 南大通用数据技术股份有限公司
  • 1 环境要求
  • 操作系统必须支持动态加载;
  • 函数实现必须使用 C 或 C++语言;
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 3 -
  • 2 F UDF 函数接口
    对每一个想在 SQL 语句中使用的函数(假设函数名为 func),应该定义对
    应的 C(或 C++ ,C++函数声明要加上 extern "C ")函数,该函数满足以下规
    则:
    2.1 func () (必 需 )
    主函数。这是计算函数结果的地方,每行调用一次。SQL 类型与 C/C++函
    数返回类型的对应关系如下:
    SQL 类型 C/C++ 类型
    STRING char *
    INTEGER long long
    REAL double
    2.2 func _init() ( 必需 )
    func()的初始化函数,只在开始调用一次,它可用于:
     检查传到 func()的参数个数
     检查参数类型是否正确或者当主函数被调用时将参数强制转换成需要
    的类型
     分配主函数所需的内存
     指定返回结果的最大长度
     指定返回 REAL 类型的函数的最大小数位
     指定结果是否允许为 NULL
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 4 - 南大通用数据技术股份有限公司
    2.3 func _deinit() (可选)
    func()的结束函数,只在所有行结束后调用一次,它可用于释放初始化函
    数分配的内存。
    总结:当一条 SQL语句调用 func()时,GBase 调用初始化函数 func_init(),
    执行所需的初始化工作,例如参数检查或内存分配。如果 func_init()返回一
    个错误,SQL 语句返回一条错误消息同时不会调用主函数和结束函数。否则,
    为每行调用主函数 func()一次。在所有行被处理完后,调用结束函数
    func_deinit(),执行必要的清理工作。
    注意:所有函数必须是线程安全的(不仅是主函数,还有初始化和结束函
    数)。不允许在函数中改变全局共享或静态的变量。如果需要内存,应该在
    func_init()中分配它并且在 func_deinit()中释放它。
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 5 -
  • 3 函数参数形式及结构
    3.1 函数参数形式
  • 主函数返回类型和参数的不同取决于 CREATE FUNCTION 语句中声明
    SQL 函数 func()返回类型
    对 SQL 中返回 STRING 的函数,形式如下:
    char func(UDF_INIT initid, UDF_ARGS *args,
    char result, unsigned long length,
    char is_null, char error);
    对 SQL 中返回 INTEGER 函数,形式如下:
    long long func(UDF_INIT initid, UDF_ARGS args,
    char is_null, char error);
    对 SQL 中返回 REAL 函数,形式如下:
    double func(UDF_INIT initid, UDF_ARGS args,
    char is_null, char error);
  • 初始化函数和结束函数的声明形式如下:
    my_bool func_init(UDF_INIT initid, UDF_ARGS args, char *message);
    void func_deinit(UDF_INIT *initid);
    3.2 参数结构
    3.2.1 d initid 参数
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 6 - 南大通用数据技术股份有限公司
    这个参数被传给所有 3 个函数,它指向一个 UDF_INIT 结构,被用来在函数
    之间传递信息。UDF_INIT 结构成员列在下面。初始化函数应该初始化它想要改
    变的任何成员。(对一个成员使用缺省值,不改变它。)
  • my_bool maybe_null
    如果 func()能返回 NULL,func_init()应该设置 maybe_null 为 1。如果任
    何一个参数被声明为 maybe_null,缺省值是 1。
  • unsigned int decimals
    小数位数目。缺省值是在被传给主函数的参数中小数位的最大数目。(例
    如,如果函数传递 1.11、1.111 和 1.1,缺省值将是 3,因为 1.111 有 3 个小数
    位。
  • unsigned int max_length
    返回结果的最大长度。缺省值不同,取决于函数的结果类型。对字符串函
    数,缺省是最长的参数的长度。对整数函数,缺省是 21 位。对实数函数,缺省
    是 13 加上由 initid->decimals 指出的小数位数。(对数字函数,长度包括任
    何符号位或小数点字符。)
  • char *ptr
    函数可以自己使用的一个指针。例如,函数能使用 initid->ptr 在函数之
    间传递分配的内存。在 func_init()中,分配内存并将它赋给这个指针:
    initid->ptr = allocated_memory;
    在 func()和 func_deinit()中,使用 initid->ptr 并释放内存。
    3.2.2 s args 参数
    这个参数指向一个 UDF_ARGS 成员,其结构如下:
  • unsigned int arg_count
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 7 -
    参数个数。如果函数有固定数量的参数,在初始化函数中检查这个值。例
    如:
    if (args->arg_count != 1)
    {
    strcpy(message," func() requires one arguments");
    return 1;
    }
  • enum Item_result *arg_type
    每个参数的类型。可能的类型值是 STRING_RESULT、INT_RESULT 和
    REAL_RESULT。确保参数是所需类型,如果不是,返回错误,在初始化函数中检
    查 arg_type 数组。例如:
    if (args->arg_type[0] != STRING_RESULT
    && args->arg_type[1] != INT_RESULT)
    {
    strcpy(message," func() requires a string and an integer");
    return 1;
    }
    另外也可以使用初始化函数把 arg_type 成员设置成所需类型。这样 GBase
    为每个 func()调用强制将参数转换成所需类型。例如,为了指定前两个参数是
    字符串和整数,可以在 func_init()中这样做:
    args->arg_type[0] = STRING_RESULT;
    args->arg_type[1] = INT_RESULT;
  • char **args
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 8 - 南大通用数据技术股份有限公司
    args 将函数的参数传递给初始化函数和主函数。函数引用第 i 个参数的方
    式如下:
    一个 STRING_RESULT 类型的参数由一个字符串指针加一个长度给出,允许
    处理任意的长度的数据。字符串内容可由 args->args[i]得到并且字符串长度
    是 args->lengths[i]。不用考虑字符串是否以空(null)结束
    对于一个 INT_RESULT 类型的参数,必须强制转换 args->args[i]为一个
    long long 值:
    long long int_val;
    int_val = ((long long) args->args[i]);
    对一个 REAL_RESULT 类型的参数,必须强制转换 args->args[i]为一个
    double 值:
    double real_val;
    real_val = ((double) args->args[i]);
    对一个 DECIMAL_RESULT 类型的参数,处理方式同 STRING_RESULT 一样。
  • unsigned long *lengths
    在初始化函数中,lengths 数组指出每个参数的最大字符串长度。对于主
    函数调用,lengths 为当前正在处理的行的任何字符串参数的实际长度。对
    INT_RESULT 或 REAL_RESULT 类型的参数,lengths 仍然包含参数的最大长度。
  • char *maybe_null
    在初始化函数中,maybe_null 指出每个参数是否允许为空(NULL)(1 表示
    允许,0 表示不允许);
  • char **attributes
    每个参数的别名,如果不存在别名,就是参数实际名称,如:
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 9 -
    select 1 from t1 group by udf_func(1+2);则 args->attributes[0]
    为”1+2”,select 1+2 as plus from t1 group by udf_func(plus);则
    args->attributes[0]为‚plus‛。
  • unsigned long *attribute_lengths
    每个 attributes 的长度
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 10 - 南大通用数据技术股份有限公司
  • 4 F UDF 返回值和错误处理
    4.1 错误处理
    如果没有出现错误,初始化函数应该返回 0,否则返回 1。如果发生一个错
    误,func_init()应该在 message 参数中存储错误信息返回给客户。错误信息缓
    冲区是 GBASE_ERRMSG_SIZE(目前在 GBase 中这个长度是 512 字符)个字符长,
    该缓冲区长度不宜设置过大,一般不要超过 80 字符。
    4.2 函数返回值
    对 long long 和 double 函数,主函数 func()的返回值即是函数返回值。
    对字符串函数,字符串可以在 result 和 length 参数中被返回。result 是 255
    个字节长的一个缓冲区,如果返回结果不超过 255,就可以把返回结果放到
    result 中,这样做的一个好处就是不用去管理 result 的内存。例如:
    memcpy(result, "result value", 12);
    *length = 12;
    return result;
    但是如果返回结果超过 255 个字节,就需要在 func_init()或 func()中申
    请空间并在 func_deinit()中释放了,注意不要产生内存泄露。例如:
    在 func_init 中:
    initid->ptr = (char *) malloc(MAX_LEN);
    在 func_deinit 中:
    free(initid->ptr);
    为了在主函数中表明一个 NULL 返回值,设定 is_null为 1:
    *is_null = 1;
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 11 -
    为了在函数中表明一个错误返回,设定 error 参数为 1:
    *error = 1;
    如果,某一行 func()设置*error 为 1,则当前行函数值是 NULL,但是并不
    影响后续行的结果,func ()将继续被调用。
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 12 - 南大通用数据技术股份有限公司
  • 5 编译及创建 UDF
  • 把 C 或 C++程序编译成共享库,使用如下的命令:
    shell> gcc -fPIC func.c -shared -o func.so -I head_file_path 或
    shell> gcc -fPIC func.cc -shared -o func.so -I head_file_path 或
    shell> g++ -fPIC func.cc -shared -o func.so -I head_file_path
    其中 head_file_path 是 func.c 中用到的 gbase 头文件存放路径,一般是
    GBase 安装目录的 include/gbase。
  • 把编译好的共享库(一般以.so 结尾,如上面的 func.so)拷贝到 GBase
    服务的 plugin 目录下。
    可以通过系统变量 plugin_dir 得到 plugin 目录,show variables like
    ‘plugin_dir’;
    注意:有些系统只会识别 lib 开头的.so 文件,这是需要把.so 改名,如
    func.so 改为 libfunc.so
  • 在共享库被拷贝以后,就可以创建想要的函数了:
    gbase> CREATE FUNCTION func RETURNS STRING SONAME 'func.so';
    可以使用 DROP FUNCTION 删除函数:
    gbase> DROP FUNCTION func;
    CREATE FUNCTION 和 DROP FUNCTION 语句在 gbase 数据库中更新系统表
    func。函数名、类型和共享库名被保存在该表中。当前用户必须有 insert 和
    delete 权限才能创建和删除函数。
    不能使用 CREATE FUNCTION 创建一个已经被创建的函数。如果需要重新创
    建函数,应该用 DROP FUNCTION 删除它,然后用 CREATE FUNCTION 重新创建它。
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 13 -
    例如,如果重新编译函数的一个新版本,以便 GBase 获得新版本,需要删除函
    数并重新创建,否则 GBase 将继续使用旧版本。
    新增函数在每次服务器启动时再次装载,除非使用--skip-grant-tables
    选项启动 GBase。在这种情况下,用户自定义函数的初始化被跳过,新增函数
    将失效。
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 14 - 南大通用数据技术股份有限公司
  • 6 F UDF 函数串并行控制
    扩展 UDF 支持多线程并行计算,但有如下限制:
  • UDF 函数的串/并行执行需要由用户自己做出判断,并传入控制参数,
    数据库无法对 UDF 函数进行串/并行执行的判断。
  • 不可并行的 UDF 函数:首先 UDF 函数是一个非确定性函数,即使 UDF
    传入相同的参数,此 UDF 函数也会获得不同的值,其次这个 UDF 函数
    对一组数据集合操作得到的结果集还和 UDF 函数对这组数据集合的调
    用次序有关。(例如 sequence,如果进行并行操作,则会得到如下结
    果)。
    thread1
    2
    3
    5
    4
    0
    1
    1
    4
    Sequence(0,1) =1 Sequence(1,4) =2 Sequence(2,5) =3 Sequence(3,4) =4
    thread1
    2
    3
    5
    4
    0
    1
    1
    4
    Sequence(0,1) =1 Sequence(1,4) =2
    Sequence(2,5) =1 Sequence(3,4) =2
    thread2
    Merge
    深度
    拷贝
    并行
    普通
    串行
    2
    3
    3
    4
    0
    1
    1
    2
    2
    3
    1
    2
    0
    1
    1
    2
  • gbased对所有UDF函数默认并行执行: 当gbase_parallel_execution
    这个并行开关开启后,gbased 对所有 UDF 函数的默认执行模式也是并
    行的。在此情况下,如果用户需要串行执行 UDF 函数,需要自行更改
    UDF 代码,在 UDF_INIT 时,传给 gbased 串行执行的配置参数。参照
    下面的例子。
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 15 -
    以下是控制 UDF 串行执行的模板示例:
    //用户必须提供 my_bool func_init(UDF_INIT initid, UDF_ARGS args,
    char *message);
    my_bool func_init (UDF_INIT initid ,UDF_ARGS args ,char *message )
    {
    initid->extension = malloc(sizeof("no_parallel"));
    memcpy(initid->extension,"no_parallel",sizeof("no_parallel"));
    //no_parallel 代表 UDF 函数串 串行执行
    }
    //用户需要提供 void func_deinit(UDF_INIT *initid)
    void fullToHalf_utf8_deinit(UDF_INIT *initid)
    {
    free(initid->extension);
    return;
    }
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 16 - 南大通用数据技术股份有限公司
  • 7 F UDAF 函数部署和使用
    7.1 编译
    把 C 或 C++文件编译成共享库,分别使用如下命令:
    gcc -fPIC -Wall func.c -shared -o func.so –I head_file_path
    g++ -fPIC -Wall func.cc -shared -o func.so –I head_file_path
    其中 head_file_path 是 func.c 中用到的 gbase 头文件存放路径,一般是
    GBase 安装目录的 include/gbase。
    7.2 部署
    把编译好的共享库(一般以.so 结尾,如上面的 func.so)拷贝到 GBase 服务
    的 plugin 目录下。
    可以通过系统变量 plugin_dir 得到 plugin 目录,show variables like
    'plugin_dir'。
    注意:有些系统只会识别 lib 开头的.so 文件,这时需要把.so 改名,如
    func.so 改为 libfunc.so。
    把共享库放到 plugin 目录下后,就可以创建 UDAF 函数了。
    集群 UDF 执行环境配置:同时拷贝动态库文件到所有集群节点的
    $GCLUSTER_HOME/server/lib/gbase/plugin 目录下和
    $GBASE_HOME/server/lib/gbase/plugin 目录下
    7.3 创建
    创建 UDAF 函数的语法如下:
    CREATE AGGREGATE FUNCTION func RETURNS STRING SONAME ' func .so';
     func 是创建的 UDAF 的函数名;
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 17 -
     STRING 是该 UDAF 的结果的返回类型, 目前支持返回 string、
    int、real、decimal 四种类型;
     func.so 是要加载的共享库的名字;
     注意创建函数时,函数名和.so 文件中的函数名大小写要保持一
    致,否则创建失败。
    SQL 类型与 C/C++函数返回类型的对应关系如下:
    SQL 类型 C/C++ 类型
    STRING char *
    INTEGER long long
    REAL double
    DECIMAL char *
    7.4 删除
    使用完 UDAF 后,可以删除 UDAF,删除 UDAF 函数的语法如下:
    DROP FUNCTION func ;
     func 是要删除的 UDAF 的名字
    7.5 更新
    如果需要更新一个 UDF/UDAF 函数,那么需要用户删除此 UDF/UDAF 后,同时
    删除引用的同一动态库(.so)的所有 UDF/UDAF 函数,然后再重新创建 UDF/UDAF
    函数。否则后面引用的时候可能产生宕机。
    我们建议一个 UDF/UDAF 函数编译时构建一个动态库(.so),以避免
    UDF/UDAF 更新产生的异常。
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 18 - 南大通用数据技术股份有限公司
    不能使用 CREATE AGGREGATE FUNCTION 创建一个已经被创建的函数。如果
    需要重新创建函数,应该用 DROP FUNCTION 删除它,然后用 CREATE AGGREGATE
    FUNCTION 重新创建它。例如,如果重新编译函数的一个新版本,以便 GBase 获
    得新版本,需要删除函数并重新创建,否则 GBase 将继续使用旧版本。
    7.6 权限
    CREATE AGGREGATE FUNCTION 和 DROP FUNCTION 语句在 gbase 数据库中更
    新系统表 func。函数名、类型和共享库名被保存在该表中。当前用户必须有
    insert 和 delete 权限才能创建和删除函数。
  • 8 F UDAF 函数功能描述
    8.1 func _init() :
    函数原型:
    my_bool func _init( UDF_INIT initid, UDF_ARGS args, char*
    message );
    函数说明:
    1) 检查传到 func()的参数个数 。
    2) 检查参数类型是否正确。
    3) 如果参数类型不正确的话,或者在 func_init 中检查然后报错,或者
    在 func_add 函数中自己转换。
    4) 指定返回结果的最大长度
    对于 string/decimal,这个值是返回值的最大字节数(decimal 时是显示
    数值,
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 19 -
    会包括正负号、小数点等)。返回类型为 int、real 类型时会忽略该值。
    5) 指定返回结果的最大小数位,主要针对 decimal和 real。
    6) 指定结果属性为不含 NULL,或者可以为 NULL(create table as select
    中列属性会参照此值)。
    参数说明:
    1) char *message 如果 func_init 发生错误,用户可以向 message 拷
    贝错误信息,同时函数返回 1。
    该函数是 UDAF 的初始化函数,只在开始调用一次,它可用于:参数校验,
    设置输出结果属性等功能 如果 func_init()返回一个错误,SQL 语句返回一条
    错误消息,同时不会调用 UDAF 后面的函数。
    8.2 func_ _ max_buffer_length ()
    函数原型:
    unsigned long long func _max_buffer_length(UDF_INIT* initid,
    UDF_ARGS args ,char is_null,char * error );
    函数说明:
    设置分组聚集运算过程中缓存中间结果所需 buf 的最大字节数, 也就是一
    个分组需要的最大内存。
    1) 参数 UDF_ARGS *args 中会得到每个参数的字段类型和最大宽度。
    用户可以根据参数特征评估出最大输出宽度。
    2) 程序会为每一个分组分配一个等长 buf,并用 initid->ptr 引用。
    8.3 func_ _ clear ()
    函数原型:
    void func_clear( UDF_INIT initid, char is_null , char* error) ) ;
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 20 - 南大通用数据技术股份有限公司
    函数说明:
    重置分组 buf(func_max_buffer_length 函数指定大小)。用户可以通过
    initid->ptr 对分组 buf 进行初始值设置或者清空。
    8.4 func _add ()
    函数原型:
    void func_ _ add (UDF_INIT initid, UDF_ARGS args ,char * is_null, char
  • error );
    函数说明:
    在同一分组内,读取当前行的数据聚集到聚集结果上,并存放到 buf 上,buf
    通过 initid->ptr 引用。该函数有以下功能:
    1) 调用此函数时,buf 存储当前的聚集结果
    2) 调用此函数时,args 里存储当前行需要聚集的列值
    3) 根据buf存储的聚集结果和args存储的需要聚集的数据进行相应
    的聚集操作,并将结果存放回 buf 上
    4) 如果参数类型不正确的话,或者在 func_init 中检查然后报错,
    或者在 func_add 函数中自己转换。
    8.5 func ()
    函数原型:
    分组的最终聚集结果输出,函数返回类型和参数的不同取决于 create
    aggregate function 语句中声明 SQL 函数 func()返回的类型。
    对 SQL 中返回 string/decimal 的函数,形式如下:
    char func (UDF_INIT initid, UDF_ARGS args, , char result, unsigned
    long length, uchar is_null ,uchar error );
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 21 -
    该 UDAF 返回结果类型为 string/decimal 类型时调用该函数,读取并返回
    每个分组的聚集结果。该函数有以下功能:
    1) 读取 func_add 函数最终存放在 initid->ptr 指向 buf 的聚集结果
    2) 将读取的聚集结果返回,每个分组会调用一次
    3) is_null 标识返回的 string 是否为 null
    4) error 表示函数是否发生错误。
    5) length 标识返回的 string 的 length(字节长度)
    6) 字段为 date 类型时,返回 string 类型。
    重要参数说明:
    1) is_null 表示返回是否为 NULL,如果函数的在 init 时设置为
    UDF_INIT::maybe_null 为 0,这里却返回 NULL,则 sql 会报错
    退出。
    2) error 是否返回错误,如果为非零,则 SQL 会直接返回错误。
    错误描述大致为为:UDAF funcname execute error, err_no:error。
    注意:
    对于 UDF 函数,如果用户设置 error 为非 0,则行结果为 NULL,不会报错。
    参见附录用例 Mysql 的 UDF 错误处理机制。
    is_null 和 error 虽然作为所有 UDAF 函数接口的输出参数,但是只在部分
    函数接口中有实际的意义。 如下表:
    输出
    参数
    func_max_buffer_le
    ngth
    func_c
    lear
    func_
    add
    func
    Is_nu
    ll
    不生效 不生效 不生

    生效
    error 不生效 生效 生效 生效
    对 SQL 中返回 integer 函数,形式如下:
    lon glong func ( UDF_INIT initid , , UDF_ARGS args ,uchar* is_null,
    uchar* error );
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 22 - 南大通用数据技术股份有限公司
    该 UDAF 返回结果类型为 lonlong 类型时调用该函数,读取并返回每个分组
    的聚集结果。
    对 SQL 中返回 real 函数,形式如下:
    double func (UDF_INIT initid, UDF_ARGS args ,uchar* is_null,
    uchar* error );
    8.6 func _deinit()
    该 UDAF 的结束函数,只在所有行结束后调用一次,它可用于释放初始化函
    数分配的内存。
    注意:所有函数必须是线程安全的。不允许在函数中改变全局共享或静态
    的变量。
  • 9 F UDAF 接口参数描述
    9.1 T UDF_INIT 结构
    这个参数被传给所有 UDAF 函数,它指向一个 UDF_INIT 结构,被用来在函
    数之间传递信息。UDF_INIT 结构成员列在下面。初始化函数应该初始化它想要
    改变的任何成员,未初始化的成员变量使用默认值。
    typedef struct st_udf_init
    {
    my_bool maybe_null;
    unsigned int decimals;
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 23 -
    unsigned long max_length;
    char *ptr;
    my_bool const_item;
    void *extension;
    unsigned long *arg_max_lengths;
    unsigned long max_buffer_length;
    } UDF_INIT;
     unsigned int decimals
    指定聚集结果小数点的最大位数,对于返回 real、decimal 类型的 func
    适用。
     unsigned int max_length
    指定返回结果最大长度,用于 creat table like/as select 等 DML,各种
    UDAF 返回类型对应的 max_length 配置规则参见 错误! !。 未找到引用源。。对于返
    回 string/decimal 类型的函数如果函数输出超过 max_length,程序行为如
    Table 5-3。此表分别列出了 mysql 和 express 引擎的默认行为。
    以上的 max_length、decimals 在 UDAF 返回不同的数据类型时的配置规则,
    具体参见下表:
    UDAF 返回值类型含义
    返回数据
    类型
    类型含义 数据结果表示
    max_length decimals
    string varchar ,
    date 类
    最大字节数(结
    果超过报错)
    不生效
    decimal decimal 最大字节数(结
    果溢出报错)
    最大小数位(结
    果超过截断)
    real double (使用缺省)不 最大小数位(结
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 24 - 南大通用数据技术股份有限公司
    生效 果超过截断)
    integer bigint (使用缺省)不
    生效
    不生效
    针对 udf、udaf,不管是 express 引擎还是 mysql 引擎,对 init 函数中的
    max_length、decimals 值在 init 之后进行合法性检查。具体规则如下:
    返回数据类型 UDF/UDAF
    String 最大值为 65535
    最小值为 0, 不合
    法时报错
    不生效
    Decimal 最大值为 67(包含
    小数部分时候,最大为
    67,不包含小数部分时,
    最大为 66),总之换算成
    precision 后,最大为 65
    不合法时报错
    最大值为 30
    不合法时报错
    Real
    不生效 最大值为 31
    不合法时报错
    Integer 不生效 不生效
    引擎类别 func函数返回长度超过max_length后的处理行
    为(select 为例)
    String Decimal
    Mysql 默认 超出后报错 超出后报错
    Express 引擎 超出后抛异常 超出后抛异常
     char *ptr
    指向程序为每个分组分配的中间结果 buf。
     unsigned long *arg_max_lengths
    参数占用的最大字节长度,是一个数组,每个参数占用一个。
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 25 -
     unsigned long max_buffer_length
    存放聚集中间结果的 buf 的最大字节宽度,用户在
    func_max_buffer_length 函数中更新并返回此值。
     my_bool maybe_null
    如果 func 不返回 null,则设置为 0,如果后续 func 返回了 Null 值,则 sql
    报错退出,默认为 1 。
     my_bool const_item
    func 始终返回同一个值 。则设置为 1。
     void * extention
    UDAF 函数不使用此字段 。
    9.2 S UDF_ARGS 结构
    用在 func_init、func_max_buffer_length 和 func_add 函数中,结构如下:
    typedef struct st_udf_args
    {
    unsigned int arg_count;
    enum Item_result *arg_type;
    char **args;
    unsigned long *lengths;
    char *maybe_null;
    char **attributes;
    unsigned long *attribute_lengths;
    void *extension;
    enum_field_types *field_type
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 26 - 南大通用数据技术股份有限公司
    } UDF_ARGS;
     unsigned int arg_count
    参数个数。如果函数有固定数量的参数,在 func_init 初始化函数中检查
    这个值。例如:
    if (args->arg_count != 1)
    {
    strcpy(message," func() requires one arguments");
    return 1;
    }
     enum Item_result *arg_type
    每个参数的返回类型。可能的类型值是 STRING_RESULT、INT_RESULT 和
    REAL_RESULT, DECIMAL_RESULT。确保参数是所需类型,如果不是,返回错误,
    在 func_init 初始化函数中检查 arg_type 数组来判断参数类型是否符合要求。
    例如:
    if (args->arg_type[0] != STRING_RESULT && args->arg_type[1] !=
    INT_RESULT)
    {
    strcpy(message," func() requires a string and an integer");
    return 1;
    }
     char **args
    args 将函数的参数值缓冲传递给 func_init()和 func_add()。
     enum enum_field_types *field_type
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 27 -
    参数中每个字段的类型。
    以上三个字段对参数进行了描述,对于不同的字段程序按照以下的默认行
    为返回给用户函数,推荐用户函数按照以下方式处理。
    field_type arg_type 用户函数处理方式(args
    中存储格式和用户处理方式)
    String(varchar,char
    )
    STRING_RE
    SULT
    返回类型: 字符串
    Char * tmp
    tmp = args->args[i]
    Decimal(低精度,高
    精度)
    DECIMAL_R
    ESULT
    返回类型:字符串
    Char * tmp
    tmp = args->args[i]
    Date
    (time,timestamp,date…

    STRING_RE
    SULT
    返回类型: ISO 标准的固
    定长度时间字符串,以下各种类
    型具体长度。
    date 10 字节
    如:'2017-03-12'
    Datatime,timestamp 两种
    类型返回的字符长度可能为 19
    或者 26,如下示
    例: :'2017-03-
  • 23:12:56' '2017-01-01
    01:02:03.456789'
    '2017-01-01
    01:02:03.010000'(规则是微秒
    为零不返回微秒,否则返回 6 位
    定长微秒)
    Time 数据类型返回的字符
    串长度可能为 10 或者 17,如下
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 28 - 南大通用数据技术股份有限公司
    示例: :'23:12:56'
    '01:02:03.456789'
    '01:02:03.010000'
    '-111:02:03.010000'(规则负
    号显示,正号省略,小时最多三
    位,)
    解析方式:
    char *tmp
    tmp = args->args[i]
    Int(short,long,tiny

    INT_RESUL
    T
    返回类型: 8 字节空间
    解析方式:
    Longlong int_val;
    Int_val = *(longlong
    *)args->args[i]
    Double(float,double
    )
    REAL_RESU
    LT
    返回类型: 8 字节空间.以
    double存储。
    double real_val
    real_val = ((double)
    args->args[i]);
    Table 9-4 UDAF 输入参数总结
     unsigned long *lengths
    对于 func_add()调用,lengths 为当前正在处理行的任何字符串参数
    (STRING_RESULT,DECIMAL_RESULT)的实际长度。对 INT_RESULT或 REAL_RESULT
    类型的参数,lengths 仍然包含参数的最大长度,一般为 8 个字节长度。
     char *maybe_null
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 29 -
    在初始化函数中,maybe_null 指出每个参数是否可能为空 NULL(1 表示可
    能,0 表示不可能)。此变量一般由传入参数的字段属性决定。用户不要指定。
     char **attributes
    每个参数的别名,如果不存在别名,就是参数实际名称,如:
    select 1 from t1 group by udf_func(1+2);
    则 args->attributes[0]为”1+2”。
    select 1+2 as plus from t1 group by udf_func(plus);
    则 args->attributes[0]为‚plus‛。
     unsigned long *attribute_lengths
    每个 attributes 的长度。
  • F UDAF 函数使用示例
    创建完 UDAF 后,跟使用普通的内置函数一样使用 UDAF 函数。
    如下示例,使用 UDAF 函数 newest 来查找字段 n1 最大值的所在行的字段
    quantity 值。
    drop function newest;
    CREATE AGGREGATE FUNCTION newest RETURNS STRING SONAME 'newest.so';
    drop table if exists t;
    create table t(n1 date,quantity varchar(10));
    insert into t values('2011-01-01','aa');
    insert into t values('2012-02-01','bb');
    insert into t values('2012-01-02','cc');
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 30 - 南大通用数据技术股份有限公司

    gbase> select newest(n1,quantity) from t;
    newest(n1,quantity)
    bb

  • row in set (Elapsed: 00:00:00.01)
  • Python UDF
    在 Postgres 中,使用 PL/Python 存储过程语言来支持使用 python 语言编
    写的 UDF 函数。PL/Python 以‘非信任’语言( ’untrusted’ language)的形式
    存在,这意味着它不限制用户如何使用 Python。所以这种语言被命名为
    plpythonu。如果 Python 将来提供了新的安全机制,会提供 plpython 语言。未
    信任的 PL/Python 的编写者必须谨慎编写这些函数,不要用来做非法操作,因
    为这个功能使得拥有 DBA 身份的用户可以执行任意脚本。只有超级用户才有权
    限创建这些函数。
    11.1 匿名执行任意 n python 脚本
    支持参数传入,输出参数返回字符串类型的执行结果。
    语法格式:
    python(code,[<parameter_1>[,…] [,parameter_n])
    code 为字符串类型的 python 代码
    parameter 可选,type 是 GBase 8a MPP Cluster 支持的数据类型
    示例:

    gbase> select python('return 1+1');
    python('return 1+1')

    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 31 -

    2

    gbase> select python('import datetime\nreturn

    datetime.datetime.now()');
    python('import datetime\nreturn datetime.datetime.now()')
    2017-01-03 17:38:47.138760

    gbase> select python('import platform\nreturn platform.platform()')

    as result;
    result
    Linux-2.6.32-431.el6.x86_64-x86_64-with-redhat-6.5-Santiago

    gbase> set @a=1,@b=2;

    gbase> select python('return a+b',@a,@b);
    python('return a+b',@a,@b)
    3

    11.2 n Python 自定义函数支持
    语法格式:
    CREATE FUNCTION <func_name>([<parameter_1>[,…] [,parameter_n]])
    RETURNS type

    $$
    &lt;Python 函数定义>
    $$ LANGUAGE plpythonu
    参数说明如下:
    GBase 8a MPP Cluster UDF&amp;UDAF 使用手册

  • 32 - 南大通用数据技术股份有限公司
    <func_name>要创建的函数的名称。在同一数据库内,函数的名称必须唯一。
    函数名称只允许 a~z、A~Z、0~9、下划线,且不能只包含数字。
    ([<parameter_1>[,...] [,parameter_n]])定义函数的参数,每一个参数
    的定义格式是:
    <参数名称><参数数据类型>
    这里新增了字符串包围符‚$$‛,和包围符‚’‛相比,这种包围符能避免
    在 Python 函数定义中使用转义。
    <参数名称>在同一个函数中必须唯一,只允许 a~z、A~Z、0~9、下划线,
    且不能只包含数字。
    <参数数据类型>指定参数的数据类型。
    <函数定义>是一系列的 Python 语句的组合,其中包含一些数据操作以完成
    一定的功能逻辑。
    定义函数时,函数名后面的括号是必需的,即使没有任何参数,也不能省
    略。
    type 是 GBase 8a MPP Cluster 支持的数据类型。
    示例 1:
    gbase> create function getUrlTitle(url varchar) returns varchar $$
    -> import lxml.html,urllib
    -> return
    lxml.html.parse(urllib.urlopen(url)).xpath("//title")[0].text
    -> $$ LANGUAGE plpythonu;

    gbase> select getUrlTitle('http://192.168.6.253/') as result;
    result
    Login to Phabricator

    gbase> drop function getUrlTitle;
    示例 2:tinyint 类型支持;
    gbase> create function type_tinyint(i tinyint) returns tinyint
    $$ return i $$ LANGUAGE plpythonu;
    gbase> select type_tinyint(127);
    GBase 8a MPP Cluster UDF&UDAF 使用手册

    南大通用数据技术股份有限公司 - 33 -
    type_tinyint(127)
    127

    示例 3:smallint 类型支持:
    gbase> create function type_smallint(i smallint) returns smallint
    $$ return i $$ LANGUAGE plpythonu;

    gbase> select type_smallint(32767);
    type_smallint(32767)
    32767

    示例 4:int 类型支持:
    gbase> create function type_int(i int) returns int $$ return i
    $$ LANGUAGE plpythonu;

    gbase> select type_int(2147483647);
    type_int(2147483647)
    2147483647

    示例 5:bigint 类型支持:
    gbase> create function type_bigint(i bigint) returns bigint
    $$ return i $$ LANGUAGE plpythonu;

    gbase> select type_bigint(9223372036854775806);
    type_bigint(9223372036854775806)
    9223372036854775806

    示例 6:float 类型支持:
    gbase> create function type_float(i float) returns float $$ return
    i $$ LANGUAGE plpythonu;
    GBase 8a MPP Cluster UDF&UDAF 使用手册

  • 34 - 南大通用数据技术股份有限公司

    gbase> select type_float(3.40E+38);
    type_float(3.40E+38)
    3.39999995214436e+38

    示例 7:double 类型支持:
    gbase> create function type_double(i double) returns double
    $$ return i $$ LANGUAGE plpythonu;

    gbase> select type_double(1.7976931348623157E+308);
    type_double(1.7976931348623157E+308)
    1.79769313486232e+308

    示例 8:varchar 类型支持:
    gbase> create function type_varchar(i varchar) returns varchar
    $$ return i $$ LANGUAGE plpythonu;

    gbase> select type_varchar('abc');
    type_varchar('abc')
    abc

    示例 9:SQL NULL 和 Python None 转换支持:

    gbase> select type_varchar(NULL);
    type_varchar(NULL)
    NULL

    gbase> create function type_none() returns varchar $$ return None
    $$ LANGUAGE plpythonu;

    gbase> select type_none();
    type_none()

    GBase 8a MPP Cluster UDF&UDAF 使用手册

    南大通用数据技术股份有限公司 - 35 -
    NULL

    11.3 约束和限制
    本次支持的数据入参数据类型映射关系:
    GBase Python2
    TINYINT/SMALLINT/INT/BIGINT long
    FLOAT/DOUBLE float
    VARCHAR str(数据库编码)
    NULL None
    本次支持的数据返回值数据类型映射关系:
    GBase Python2
    TINYINT/SMALLINT/INT/BIGINT long
    FLOAT/DOUBLE float
    VARCHAR str(数据库编码)
    NULL None
    不支持的功能包括:
    1.支持 Python2,不支持 Python3;
    2.不支持 python UDF 函数间共享变量;
    3.不支持 Python UDF 作为触发器使用;
    4.不支持 Python 语法检查,语法错误时,自定义函数可成功创建。若存在
    语法错误,在执行时可明确提示报错信息;
    5.数据类型只支持列表中的 GBase 数据类型,不支持 DECIMAL、CHAR、TEXT
    类型;
    6.参数列表不支持 OUT 类型定义,不支持从参数列表返回值。

  • 附录
    12.1 l Mysql 的 的 F UDF 错误处理机制
    GBase 8a MPP Cluster UDF&UDAF 使用手册
  • 36 - 南大通用数据技术股份有限公司
    以下是 mysql 错误处理机制,其中 myfunc_int 设置输出参数 error 为 0,
    gbase> create table t2_x (c1 int) engine='GsSYS';
    Query OK, 0 rows affected (Elapsed: 00:00:00.03)
    gbase> insert into t2_x values(1),(2);
    Query OK, 2 rows affected (Elapsed: 00:00:00.00)
    Records: 2 Duplicates: 0 Warnings: 0

    运行中如果 error 被置 1 后,UDAF 返回结果为 NULL,这里是人为在代码

    里 error 置 1

    gbase> select myfunc_int(c1) from t2_x;
    myfunc_int(c1)
    NULL
    NULL

  • rows in set (Elapsed: 00:00:09.51)
    12.2 e gbase 中 中 F UDF 和自定义函数使用
    表 12-1 Mysql 的 DF 和 UDF 相关性
    DF (自定义函数) UDF (用户自定义函数)
    创建( create
    function)
    校验:1是否存在 UDF
  • 是否存在 DF
    Yacc 中会去判断是否存在同名的内置函数
    创建 DF 的时候会去判断 UDF 是否存在名函
    数 gbase_execute_command
    校验:1 是否存在 UDF
    Yacc 中会去判断是否存在同名的内置函数
    删 除 (drop
    function)
    如果同时存在 DF 和 UDF,首先删除 DF。 如果同时存在 DF 和 UDF,首先删除 DF。
    调用(call) 如果同时存在 NAF(内置函数),DF 和 UDF,
    调用顺序 NAF>UDF>DF。
    如果同时存在 NAF(内置函数),DF 和 UDF,
    调用顺序 NAF>UDF>DF。
    GBase 8a MPP Cluster UDF&UDAF 使用手册
    南大通用数据技术股份有限公司 - 37 -
    12.3 F UDAF 函数大小写不敏感
    这是因为我们默认的系统字符集为 my_charset_ci,这种字符集是不区分
    大小写的,这就意味着所有的库、表、函数、字段名都是不区分大小写的。
    GBase 8a MPP Cluster UDF&UDAF 使用手册

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

3

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广