用户自定义函数(UDF)¶
本文介绍如何在悦数图数据库开发版中使用 GQL 创建和使用用户自定义函数(基于 GQL 的 UDF)。
概述¶
您可以使用 GQL 表达式定义自定义函数,扩展悦数图数据库开发版的内置函数库。UDF 在查询中的调用方式与内置函数一致,便于复用复杂的计算逻辑。
使用限制¶
- 仅支持定义类型为
scalar和aggregate的函数。关于函数的类型,请参见 SHOW FUNCTIONS。 - 不支持子查询表达式。
- 不支持可变参数。
- 不支持在函数定义中调用任何 UDF。
- 不允许使用全局聚合值变量(如
@nodeAgg)。
Note
对非默认 Schema 或其中的对象执行操作时,用户既要通过隐式访问规则或显式USAGE授权获得该 Schema 的访问权,也要具备目标操作所需的权限。Schema 访问校验和目标操作所需的权限校验相互独立,满足其中一项不能替代另一项。Schema 访问控制不适用于临时图、内置 Procedure 和内置 Function。更多信息,请参见 Schema 访问控制。
前提条件¶
- 若要创建 UDF,必须具备在当前 Schema 执行
CREATE FUNCTION权限。更多信息,请参见角色与权限。 - 若要删除 UDF,必须是 UDF 的所有者,或具备在 UDF 上执行
DROP权限;或具备在当前 Schema 执行DROP ANY FUNCTION操作权限。更多信息,请参见角色与权限。
语法¶
创建 UDF¶
- create_function_statement
- parameter_declaration
create_function_statement ::=
'CREATE' 'FUNCTION' ('IF NOT EXISTS')? function_name '(' (parameter_declaration (',' parameter_declaration)* )? ')' 'RETURNS' return_type 'AS' '{' expression '}' ('COMMENT' string_literal)?
parameter_declaration ::=
parameter_name parameter_type
IF NOT EXISTS¶
该子句用于检查是否已存在同名的 UDF。如果已存在,则不创建且不抛出异常。
如果不指定该子句,当同名 UDF 已存在时会抛出异常。
function_name¶
要创建的 UDF 名称。名称必须是合法的标识符,且不能与任何内置函数或已有的自定义函数名称冲突。有关标识符的命名规则,请参见标识符命名规则。
与 UDP 不同,UDF 不支持函数重载。不能创建多个同名但参数不同的 UDF。
parameter_declaration¶
UDF 的输入参数声明。每个参数由名称和数据类型组成。
parameter_name¶
UDF 接受的输入参数名称。参数名在同一个 UDF 内必须唯一。
parameter_type¶
UDF 接受的输入参数的数据类型,可以是任意数据类型。有关数据类型的信息,请参见数据类型。
return_type¶
UDF 返回值的数据类型。
COMMENT¶
UDF 的可选描述信息。使用字符串字面量说明函数用途。
expression¶
定义 UDF 逻辑的表达式。
删除 UDF¶
- drop_function_statement
drop_function_statement ::=
'DROP' 'FUNCTION' 'IF EXISTS'? function_name
IF EXISTS¶
该子句用于检查要删除的 UDF 是否存在。如果不存在,则不执行删除且不抛出异常。
如果不指定该子句,当 UDF 不存在时会抛出异常。
function_name¶
要删除的函数名称。
查看 UDF 信息¶
- show_functions_statement
- show_specific_function_statement
show_functions_statement ::=
'SHOW' 'GQL'? 'USER DEFINED' 'FUNCTIONS'
show_specific_function_statement ::=
'SHOW' 'GQL'? 'USER DEFINED' 'FUNCTION' function_name
更多信息,请参见 SHOW USER DEFINED FUNCTIONS。
示例¶
创建无参数的 UDF¶
'''
-- 创建一个返回圆周率的函数
CREATE FUNCTION IF NOT EXISTS _pi() RETURNS FLOAT AS {3.1415926}
'''
'''
-- 调用该函数
RETURN _pi() AS pi_value
'''
返回:
+-----------+
| pi_value |
+-----------+
| 3.1415926 |
+-----------+
创建带参数的 UDF¶
'''
-- 创建一个计算两数之和的函数
CREATE FUNCTION IF NOT EXISTS foo(a INT, b FLOAT) RETURNS FLOAT AS {a + b}
'''
'''
-- 调用该函数
RETURN foo(10, 5.5) AS result
'''
返回:
+--------+
| result |
+--------+
| 15.5 |
+--------+
创建带注释的 UDF¶
'''
-- 创建带注释的函数
CREATE FUNCTION IF NOT EXISTS add_tax(price FLOAT) RETURNS FLOAT AS {price * 1.06} COMMENT '计算含税价格'
'''
'''
-- 查看函数注释
SHOW USER DEFINED FUNCTION add_tax
'''
返回:
+---------+------------------------------------------------+--------------+
| name | signature | comment |
+---------+------------------------------------------------+--------------+
| add_tax | add_tax(price FLOAT) -> FLOAT { price * 1.06 } | 计算含税价格 |
+---------+------------------------------------------------+--------------+
创建使用聚合函数的 UDF¶
'''
-- 在 UDF 中使用内置聚合函数
CREATE FUNCTION IF NOT EXISTS avg_sum(b FLOAT) RETURNS FLOAT AS {avg(b) + sum(abs(b))}
'''
'''
-- 调用该函数
FOR pair IN [[1,2], [1,3], [2,3], [4,2]]
RETURN pair[0] AS a, pair[1] AS b
NEXT
RETURN a, avg_sum(b) AS result GROUP BY a
'''
返回:
+---+--------+
| a | result |
+---+--------+
| 1 | 7.5 |
| 2 | 6.0 |
| 4 | 4.0 |
+---+--------+
创建使用会话变量的 UDF¶
UDF 可以引用会话变量:
'''
-- 设置会话变量
SESSION SET VALUE $offset = 10
'''
'''
-- 创建使用会话变量的函数
CREATE FUNCTION IF NOT EXISTS add_offset(x FLOAT) RETURNS FLOAT AS {x + $offset}
'''
'''
-- 调用该函数
RETURN add_offset(5) AS result
'''
返回:
+--------+
| result |
+--------+
| 15 |
+--------+
在复杂查询中使用 UDF¶
在查询中调用前面示例中创建的foo()和_pi()函数:
示例 1:
'''
FOR i IN [1, 2, 3, 4]
RETURN i, foo(-i, _pi()) AS calculated_value
ORDER BY foo(-i, _pi()) DESC
'''
返回:
+---+------------------+
| i | calculated_value |
+---+------------------+
| 1 | 2.1415926 |
| 2 | 1.1415926 |
| 3 | 0.1415926 |
| 4 | -0.8584074 |
+---+------------------+
示例 2:
'''
USE movie
MATCH (v:Person WHERE v.id = foo(5, 10.0))-[e]->(n)
RETURN v.id AS vid, n.id AS nid, n.name AS nname
ORDER BY nname
'''
返回:
+-----+-----+-------------------------------+
| vid | nid | nname |
+-----+-----+-------------------------------+
| 15 | 644 | A.I. Artificial Intelligence |
| 15 | 497 | Green Mile |
| 15 | 377 | Nightmare on Elm Street |
| 15 | 473 | Pi |
| 15 | 129 | Sen To Chihiro No Kamikakushi |
| 15 | 10 | Star Wars |
| 15 | 11 | Star Wars: A New Hope |
+-----+-----+-------------------------------+
查看 UDF 信息¶
有关查看 UDF 信息的方法,请参见 SHOW USER DEFINED FUNCTIONS。
删除 UDF¶
'''
-- 删除前面示例中创建的 foo() 函数
DROP FUNCTION foo
-- 若存在则删除
DROP FUNCTION IF EXISTS foo
'''