Skip to content

38.6. 函数重载#

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

在创建重载函数系列时,应注意不要产生歧义。例如,给定函数

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

并不清楚使用test(1, 1.5)等一些简单输入时会调用哪个函数。当前实现的解析规则在第 10 章中进行了描述,但设计一个巧妙依赖此行为的系统是不明智的。

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

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

在重载 C 语言函数时,存在一个附加约束:重载函数系列中每个函数的 C 名称必须不同于所有其他函数(无论是内部函数还是动态加载函数)的 C 名称。如果违反此规则,则行为不可移植。您可能会收到运行时链接器错误,或者其中一个函数将被调用(通常是内部函数)。SQLCREATE 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 函数的名称反映了许多可能的约定之一。