37.5. 函数重载

可以使用相同的 SQL 名称定义多个函数,只要它们采用的参数不同即可。换句话说,函数名称可以* overloaded *。无论您是否使用它,在某些用户不信任其他用户的数据库中调用函数时,此功能都需要采取安全预防措施。参见Section 10.3。执行查询时,服务器将根据数据类型和所提供参数的数量确定要调用的函数。重载还可用于模拟具有可变数量的参数(最大数量有限)的函数。

创建一系列重载函数时,应注意不要造成歧义。例如,给定功能:

CREATE FUNCTION test(int, real) RETURNS ...
CREATE FUNCTION test(smallint, double precision) RETURNS ...

目前尚不清楚使用一些琐碎的 Importing(例如test(1, 1.5))将调用哪个函数。当前实现的解决规则在Chapter 10中进行了描述,但是设计一个巧妙地依赖此行为的系统是不明智的。

带有复合类型的单个参数的函数通常不应与该类型的任何属性(字段)具有相同的名称。回想一下attribute(table)被认为等效于table.attribute。在复合类型上的函数与复合类型的属性之间存在歧义的情况下,将始终使用该属性。可以通过模式限定函数名(即schema.func(table))来覆盖该选择,但最好不要选择冲突的名称来避免该问题。

可变函数函数和非可变函数之间的另一个可能冲突。例如,可以同时创建foo(numeric)foo(VARIADIC numeric[])。在这种情况下,不清楚应该将哪一个与提供单个数值参数(例如foo(10.1))的调用匹配。规则是使用在搜索路径中较早出现的功能,或者如果两个功能在同一模式中,则首选非可变功能。

重载 C 语言函数时,还有一个附加约束:重载函数族中每个函数的 C 名称必须与内部或动态加载的所有其他函数的 C 名称不同。如果违反此规则,则该行为不可移植。您可能会遇到运行时链接程序错误,或者将调用其中一个函数(通常是内部函数)。 SQL CREATE FUNCTION命令的AS子句的替代形式是将 SQL 函数名与 C 源代码中的函数名解耦。例如:

CREATE FUNCTION test(int) RETURNS int
    AS 'filename', 'test_1arg'
    LANGUAGE C;
CREATE FUNCTION test(int, int) RETURNS int
    AS 'filename', 'test_2arg'
    LANGUAGE C;

C 函数的名称在这里反映了许多可能的约定之一。