扩展 MySQL 8.0  / 第 6 章 向 MySQL 添加函数  /  6.1 添加原生函数

6.1 添加原生函数

要添加本机 MySQL 函数,请使用此处描述的过程,这需要您使用源代码分发。您不能将本机函数添加到二进制分发版中,因为有必要修改 MySQL 源代码并从修改后的源代码编译 MySQL。如果迁移到另一个版本的 MySQL(例如,发布新版本时),则必须对新版本重复该过程。

如果将在将复制到副本的语句中引用本机函数,则必须确保每个副本也具有可用的函数。否则,当副本尝试调用该函数时,复制将在副本上失败。

要添加本机功能,请按照以下步骤修改目录中的源文件sql

  1. 为中的函数创建一个子类 item_create.cc

    • 如果函数采用固定数量的参数,则分别创建 、 、 或 的子类 Create_func_arg0Create_func_arg1具体 Create_func_arg2取决于 Create_func_arg3函数采用零、一个、两个还是三个参数。有关示例,请参阅 Create_func_uuidCreate_func_absCreate_func_powCreate_func_lpad类。

    • 如果该函数采用可变数量的参数,请创建 Create_native_func. 有关示例,请参阅Create_func_concat

  2. 要提供可以在 SQL 语句中引用该函数的名称,请 item_create.cc通过向该数组添加一行来注册该名称:

    static Native_func_registry func_array[]

    您可以为同一功能注册多个名称。例如,查看 和 的行"LCASE""LOWER"它们是 的别名 Create_func_lcase

  3. item_func.h中,声明一个继承自Item_num_func或 的类Item_str_func,具体取决于您的函数返回的是数字还是字符串。

  4. 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()

  5. 如果函数是不确定的,请在项目构造函数中包含以下语句以指示不应缓存函数结果:

    current_thd->lex->safe_to_cache_query=0;

    如果给定参数的固定值,则函数是不确定的,它可以为不同的调用返回不同的结果。

  6. 您可能还应该定义以下对象函数:

    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.

  • 除非绝对必要,否则所有当前的字符串函数都尽量避免分配任何内存!