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 代碼裡的一樣的名稱。)