要添加本机 MySQL 函数,请使用此处描述的过程,这需要您使用源代码分发。您不能将本机函数添加到二进制分发版中,因为有必要修改 MySQL 源代码并从修改后的源代码编译 MySQL。如果迁移到另一个版本的 MySQL(例如,发布新版本时),则必须对新版本重复该过程。
如果将在将复制到副本的语句中引用本机函数,则必须确保每个副本也具有可用的函数。否则,当副本尝试调用该函数时,复制将在副本上失败。
要添加本机功能,请按照以下步骤修改目录中的源文件sql
:
-
为中的函数创建一个子类
item_create.cc
:如果函数采用固定数量的参数,则分别创建 、 、 或 的子类
Create_func_arg0
,Create_func_arg1
具体Create_func_arg2
取决于Create_func_arg3
函数采用零、一个、两个还是三个参数。有关示例,请参阅Create_func_uuid
、Create_func_abs
、Create_func_pow
和Create_func_lpad
类。如果该函数采用可变数量的参数,请创建
Create_native_func
. 有关示例,请参阅Create_func_concat
。
-
要提供可以在 SQL 语句中引用该函数的名称,请
item_create.cc
通过向该数组添加一行来注册该名称:static Native_func_registry func_array[]
您可以为同一功能注册多个名称。例如,查看 和 的行
"LCASE"
,"LOWER"
它们是 的别名Create_func_lcase
。 在
item_func.h
中,声明一个继承自Item_num_func
或 的类Item_str_func
,具体取决于您的函数返回的是数字还是字符串。-
在
item_func.cc
中,添加以下声明之一,具体取决于您定义的是数字函数还是字符串函数:double Item_func_newname::val() longlong Item_func_newname::val_int() String *Item_func_newname::Str(String *str)
如果您从任何标准项(如
Item_num_func
)继承您的对象,您可能只需要定义其中一个函数并让父对象处理其他函数。例如,Item_str_func
该类定义了一个val()
函数, 该函数atof()
对 返回的值 执行::str()
。 -
如果函数是不确定的,请在项目构造函数中包含以下语句以指示不应缓存函数结果:
current_thd->lex->safe_to_cache_query=0;
如果给定参数的固定值,则函数是不确定的,它可以为不同的调用返回不同的结果。
-
您可能还应该定义以下对象函数:
void Item_func_newname::fix_length_and_dec()
这个函数至少应该
max_length
根据给定的参数进行计算。max_length
是函数可以返回的最大字符数。maybe_null = 0
如果主函数不能返回NULL
值,也应该设置这个函数。NULL
该函数可以通过检查参数的 变量来检查是否有任何函数参数可以返回maybe_null
。查看Item_func_mod::fix_length_and_dec
如何执行此操作的典型示例。
所有函数都必须是线程安全的。换句话说,不要在函数中使用任何全局或静态变量,而不要使用互斥锁保护它们。
如果NULL
要从
::val()
、::val_int()
或
返回::str()
,则应设置
null_value
为 1 并返回 0。
对于::str()
对象函数,这些附加注意事项适用:
该
String *str
参数提供了一个可用于保存结果的字符串缓冲区。(有关String
类型的更多信息,请查看sql_string.h
文件。)该
::str()
函数应该返回保存结果的字符串,或者(char*) 0
如果结果是NULL
.除非绝对必要,否则所有当前的字符串函数都尽量避免分配任何内存!