Postgresql 中文操作指南

38.6. Function Overloading #

使用相同 SQL 名称可以定义多个函数,只要它们采用的参数不同。换句话说,函数名称可以_overloaded_。无论你是否使用它,在一些用户不信任其他用户的数据库中调用函数时,此功能需要进行安全预防;请参见 Section 10.3。当执行查询时,服务器将根据提供参数的数据类型和数量确定要调用的函数。也可使用重载模拟具有有限的最大数量的可变数量参数的函数。

在创建重载函数族时,应小心不要创建歧义。例如,给定如下函数:

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

使用一些琐碎输入(比如 test(1, 1.5))时,尚不确定会调用哪个函数。当前实施的解决方案规则在 Chapter 10中进行描述,但设计高度依赖此行为的系统不明智。

通常,接受复合类型单个参数的函数不应该与该类型中的任何属性(字段)同名。请回忆一下 attribute(table)_ is considered equivalent to _ table_. attribute. In the case that there is an ambiguity between a function on a composite type and an attribute of the composite type, the attribute will always be used. It is possible to override that choice by schema-qualifying the function name (that is, 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 函数的名称反映了许多可能的约定之一。