我有PostgreSQL函數名爲test(integer)
取integer
參數和一個重載函數的同名test(character varying)
。PostgreSQL函數調用
當使用空值調用此函數時,Postgres始終執行採用integer
參數的函數。爲什麼會發生?爲什麼Postgres沒有選擇帶有varchar
參數的函數?
函數調用例如:
select test(null);
我有PostgreSQL函數名爲test(integer)
取integer
參數和一個重載函數的同名test(character varying)
。PostgreSQL函數調用
當使用空值調用此函數時,Postgres始終執行採用integer
參數的函數。爲什麼會發生?爲什麼Postgres沒有選擇帶有varchar
參數的函數?
函數調用例如:
select test(null);
這是由Function Type Resolution規則決定。手冊中的詳細說明。相關閱讀:
NULL沒有顯式類型轉換開始作爲類型 「未知」:
SELECT pg_typeof(NULL)
pg_typeof
-----------
unknown
其實,我了疑惑,便跑了快速測試,只是在Postgres 9.3和9.4中找到不同的結果。 varchar
是精挑細選integer
(其中奇怪違揹你的發現):
我會認爲根據規則point 4e in the list(沒有更早點決定了比賽):
在每個位置,如果有候選人接受該類別 ,請選擇字符串類別。 (對字符串這種偏差是因爲一個 未知類型文本看起來像串爲宜。)
如果添加了輸入型text
另一個函數重載組合,text
將超過varchar
採摘。
個人我幾乎總是使用text
而不是varchar
。雖然二進制兼容(差不多但不完全相同),但text
在各方面更接近Postgres的核心。
我在小提琴上添加了這個,以及另一個Postgres無法決定並引發發脾氣的例子。
如果你想選擇一個特定的功能,添加一個顯式類型轉換(這是去這裏的路!):
select test(null::int) AS func_int
, test(null::varchar) AS func_vc;
什麼是你確切的Postgres版本和你使用的客戶端進行測試? –