第27章:扩展MySQL / 27.2. 为MySQL添加新函数 / 27.2.4. 添加新的固有函数

下面介绍添加新固有函数的步骤。要注意你不能添加固有函数到二进制分发版里,因为这个步骤包含修改MySQL源代码。你必须从源码分发版自己编译MySQL。另外要注意,如果你把MySQL移植到另一个版本(比如新版本放出来的时候),你需要用新版本重复这个添加 步骤。

采取下列步骤来添加MySQL新的固有函数:

  1. 在定义函数名的lex.h文件中的sql_functions[]数列里添加一行。

  2. 如果函数原型是简单的(只有零个,一个,二个或三个参量),你应该在lex.h中指定 SYM(FUNC_ARGN) (其中N 是参量的个数)作为sql_functions[]数列中的第二个 参量,并添加一个在item_create.cc中创建函数目标的函数。可以看看 "ABS" 和 create_funcs_abs() 作为举例说明。

    如果函数原型是复杂的(举例,如果函数有多种参量),你应该给sql_yacc.yy添加两行。一行表示yacc应该定义的预处理程序记号,(这应该在文件的开始添加)。然后定义函数 参数,并添加一个带这些参数的项到simple_expr分析规则中。举一个例子,你可以检查 sql_yacc.yy 中所有出现的ATAN 看看这个定义是什么样子的。

  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() 函数,它这个函数对::str()返回的值进行 atof()操作。

  5. 你或许也定义了下列目标函数:

    void Item_func_newname::fix_length_and_dec()
    

    这个函数至少应该计算基于给定参量的max_length。 max_length 是函数可能返回字符的最大个数。如果主函数不能返回 NULL值,这个函数也应该设置 maybe_null = 0。函数可以通过检查函数的maybe_null值来检查是否有函数 参量能返回NULL值。你可以看一下Item_func_mod::fix_length_and_dec 作为典型的例子来说明这个问题。

所有函数都必须是线程安全的,换句话说就是,如果没有互斥体保护,不要在函数中使用任何全局或静态变量。

如果你想要从函数::val(), ::val_int()或::str()返回NULL,你应该设null_value为1,并返回0。

对于目标函数 ::str() 有一些需要而外考虑之处::

  • 字符串参量*str 提供一个字符串缓冲可以用来保持结果(更多关于字符串类型的信息请参阅 sql_string.h文件)。 

  • 如果结果为NULL,::str() 函数应该返回保持这个结果的字符串或(char*) 0。

  • 除非有绝对地需要,所有当前的字符串函数要避免分配内存!