33.8. 函數重載

如果函數的參數不同,可以定義為同名的 SQL 函數。換句話說,函數名可以重載。 函數也可以與一個字段/屬性同名。這時,一個復合類型的函數和一個復合類型的字段/屬性會有衝突, 這種情況下總是使用字段/屬性。

一個函數也可以和一個屬性同名。(還記得attribute(table) 等效于 table.attribute。)這種情況下,定義在復合類型上的函數和復合類型的屬性之間有歧義,這個時候,將總是使用屬性。

在創建一個重載函數族的時候,我們應該仔細不要產生歧義。 比如,給出函數

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

如果我們輸入一些簡單的輸入,比如 test(1, 1.5), 是不會立即得出應該調用哪個函數的。目前實現的分析規則在 Chapter 10 裡描述,但是設計一套有意無意地依賴這個行為地系統顯然是不明智的。

在重載一個 C 語言函數的時候,還有另外一個約束:重載函數族的每個函數的 C 名字必須和所有其他函數的 C 名字不同, 不管是內部的還是動態裝載進來的。你可能會收到一個運行時鏈接錯,或者調用了其中的某個函數(通常是內部的)。 SQL 命令 CREATE FUNCTIONAS 子句的另外一種形式把 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 函數名字反映許多種轉換中的一種。