2015-12-16 100 views
1

我有PostgreSQL函數名爲test(integer)integer參數和一個重載函數的同名test(character varying)PostgreSQL函數調用

當使用空值調用此函數時,Postgres始終執行採用integer參數的函數。爲什麼會發生?爲什麼Postgres沒有選擇帶有varchar參數的函數?

函數調用例如:

select test(null); 
+1

什麼是你確切的Postgres版本和你使用的客戶端進行測試? –

回答

3

這是由Function Type Resolution規則決定。手冊中的詳細說明。相關閱讀:

NULL沒有顯式類型轉換開始作爲類型 「未知」:

SELECT pg_typeof(NULL) 

pg_typeof 
----------- 
unknown 

其實,我了疑惑,便跑了快速測試,只是在Postgres 9.3和9.4中找到不同的結果。 varchar是精挑細選integer(其中奇怪違揹你的發現):

SQL Fiddle.

我會認爲根據規則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;