Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

36.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 名称。如果违反此规则,则行为无法移植。您可能会遇到运行时链接器错误,或者其中一个函数会被调用(通常是内部函数)。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 函数名称反映了许多可能的约定之一。