9.6. 函数重载

如果函数的参数不同,可以定义为同名的 SQL 函数。换句话说,函数名可以 重载 。函数也可以与一个字段/属性同名。 这时,一个 复合类型的函数和一个复合类型的字段/属性会有冲突, 这种情况下总是使用字段/属性。

9.6.1. 名字空间冲突

对于 PostgreSQL 7.0, SQL CREATE FUNCTION 命令的 AS 子句的可选形式把 SQL 函数名 和 C 源代码的函数名脱钩。目前这是实现函 数重载的比较好的技巧。

9.6.1.1. v7.0以前

对于用 C 写的函数,在 CREATE FUNCTION 里定义的 SQL 名称必须和 C 代码里的实际函数名称完全一样(因此它必须是 一个合法的 C 函数名)。

这样的限制有个小小的暗示:尽管大多数的操作系统的动态链接过程允许 你装载任意数目的包含冲突(同名的)的函数名的 共享库,实际上它们可能用某种有趣的方式修补这样的装载。 例如,如果你定义了一个与内建于 PostgreSQL 的函数同名的动态 装载的函数,DEC OSF/1 的动态装载器会令 PostgreSQL 调用它自己内部的函数 而不是令 PostgreSQL 调用你的函数。因此,如果你 希望你的函数用于不同的体系,我们建议你不要重载 C 函数名。

我们可以用一个很聪明的技巧绕开上面提到的问题。 因为重载 SQL 函数没有问题, 所以你可以定义一套不同名的 C 函数, 然后定义一套同名的 SQL 函数封装, 这些 SQL 函数封装接收合适的参数类型并且调用对应的 C 函数。

另一个解决方法是避免使用动态装载,而是把你的函数和后端进行静态链接, 并且把他们定义为 INTERNAL 函数。这样, 函数必须有不同的 C 名称,但是可以定义为相同的 SQL 名称 (当然它们的参数类型不同)。 这个方法避免了 SQL 封装函数 的过荷,付出的代价是制作一个客户化的后端可执行文件。 (这个选项只有在 v6.5 和以后的版本中有,因为以前的版本要求 内部函数与 SQL 函数有与 C 代码里的一样的名称。)