可以用同样的 SQL 名称定义多于一个函数,只要它们的参数不同即可。 换句话说,函数名可以被重载。当一个查询 被执行时,服务器将从数据类型和所提供的参数个数来决定要调用哪个 函数。重载也可用来模拟具有可变参数个数(最大个数有限)的函数。
在创建一个重载函数家族时,应该小心不要创建歧义。例如,给定函数:
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
)
另一种可能的冲突在于 variadic 和非 variadic 函数之间。例如,可以创建
foo(numeric)
和foo(VARIADIC numeric[])
。
在这种情况下,对于提供了一个数字参数的调用(例如foo(10.1)
)
就不清楚应该匹配哪一个函数。规则是使用在搜索路径中出现得较早的
函数,或者当两者都在同一个模式中时优先使用非 variadic 的那一个函数。
在重载 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 函数名称反映了很多种可能的习惯之一。