2017-04-26 45 views
1

我找下面的解釋,如果我運行像這樣的東西,我得到一個unknown類型,「未知」和類型推斷的規則是什麼?

SELECT pg_typeof(a) 
FROM (SELECT null) AS t(a); 
pg_typeof 
----------- 
unknown 
(1 row) 

然而,隨着更多的複雜性就變得text神奇,

SELECT pg_typeof(a) 
FROM (
    SELECT null 
    UNION SELECT null 
) AS t(a); 
pg_typeof 
----------- 
text 
(1 row) 

明確鑄造沒有改變,這也返回text,

SELECT pg_typeof(a) 
FROM (
    SELECT null::unknown 
    UNION SELECT null::unknown    
) AS t(a); 

它是如下usingly這個工作,

SELECT pg_typeof(a) 
FROM (
    SELECT null 
    UNION SELECT 42     
) AS t(a); 

但是,這不,

SELECT pg_typeof(a) 
FROM (
    SELECT null 
    UNION SELECT null 
    UNION SELECT 42 
) AS t(a); 

什麼用途的unknown類型有過一次,如果它認爲是在上述情況下的文字?

+0

我投票決定關閉自己的問題,因爲我認爲這是對[dba.se]更好的匹配 –

+0

我投遷移過,但我不知道它是值得的:這些案件[完美描述在文檔](https://www.postgresql.org/docs/current/static/typeconv-union-case.html)(第3點) - 除了最後一個。這只是一個[優先問題](http://rextester.com/TNG47898)。 – pozs

回答

2

其中有三個問題我會盡量回答。

  1. unknown是什麼目的?

    這是最初分配給SQL語句中的NULL和字符串文字的數據類型。如果立即將這些文字分配到text類型,則很難推斷出正確的類型。

    例如,你想myfunc('hello')調用myfunc(character varying),但是從text沒有隱式類型轉換爲character varying(它會引起歧義,如果你創建了一個)。

  2. 爲什麼SELECT null返回一個類型爲unknown的列?

    傳統的答案是:因爲用戶沒有指定類型。

    但是,這種行爲一直存在問題。例如,如果您創建一個表是這樣的:

    CREATE TABLE test 
        AS SELECT 'hello'; 
    

    你最終會與unknown類型的列,這是不理想的,將進一步對造成問題。 unknown類型確實不應該是用戶可見的,而應該是實現細節。

    因此,this commit已經從PostgreSQL的V10改變的行爲:現在留在SELECTRETURNING列表中的任何unknown s的被迫text,並表不能與unknown類型的列上創建。

  3. 爲什麼SELECT NULL UNION SELECT 42有效,但不是SELECT NULL UNION SELECT NULL UNION SELECT 42

    這是欠type conversion rulesUNION是左結合的,因此後者查詢被解釋爲

    (SELECT NULL UNION SELECT NULL) UNION SELECT 42; 
    

    現在第一UNION解析爲text因爲規則3的數據類型:

    如果所有輸入都是類型unknown,解析爲鍵入文本(字符串類別的首選類型)。

    這將導致試圖解決型第二UNION因爲規則4時的錯誤:

    如果非unknown輸入不是全部屬於同一類型類別,失敗。

    在另一方面,在查詢

    SELECT NULL UNION SELECT 42; 
    

    「 」 NULL已鍵入unknown,和「 」 42具有類型integer(選擇用於數字文字不帶小數點的類型)。

    規則5

    選擇第一非未知輸入類型,是在該類別中的優選類型,如果有的話。

    在這裏並不適用,因爲integer不在其類別中的首選類型(這將是oiddouble precision),所以第6條用於:

    否則,選擇最後的非未知輸入類型,允許所有前面的未知輸入隱式轉換爲它。

    這產生integer的一種類型。

+0

假設字符串文本是文本是合理的,但這似乎是一種笨拙的方式。無論如何,好的答案。理想情況下,在結果集完成而不是第一次結合之前,將類型推遲爲未知類型會更有意義。 –

相關問題