?
This document uses PHP Chinese website manual Release
下面講解的過程解釋了如何在一次操作符調(diào)用中確定所使用的究竟是哪個操作符。 請注意這個過程受被調(diào)用操作符的優(yōu)先級影響。參閱Section 4.1.6獲取更多信息
操作符類型解析
從系統(tǒng)表pg_operator
中選出要考慮的操作符。如果使用了一個不帶修飾的操作符
名(常見的狀況),那么認為該操作符是那些在當(dāng)前搜索路徑中名字和參數(shù)個數(shù)都正確的
操作符(參閱 Section 5.7.3)。
如果給出一個帶修飾的操作符名,那么只考慮指定模式中的操作符。
如果搜索路徑中找到了多個相同參數(shù)類型的操作符,那么只考慮最早出現(xiàn)在路徑中的那一個。 但是不同參數(shù)類型的操作符將被平等看待,而不管它們在路徑中的位置如何。
查找精確接受輸入?yún)?shù)類型的操作符。如果找到一個(在一組被考慮的操作符中,可能只存在一個精確匹配的), 則用之。
如果一個雙目操作符調(diào)用中的一個參數(shù)是unknown類型,則在本次檢查中假設(shè)其與另一個參數(shù)類型相同。 其它涉及unknown的情況絕不會在此處找到匹配。
尋找最優(yōu)匹配。
拋棄那些輸入類型不匹配并且也不能隱式轉(zhuǎn)換成匹配的候選操作符。unknown文本在這種情況下 可以轉(zhuǎn)換成任何東西。如果只剩下一個候選項,則用之,否則繼續(xù)下一步。
遍歷所有候選操作符,保留那些輸入類型匹配最準確的。此時,域被看作和他們的基本類型相同。如果沒有一個操作符能被保留,則保留所有候選。 如果只剩下一個候選項,則用之,否則繼續(xù)下一步。
遍歷所有候選操作符,保留那些需要類型轉(zhuǎn)換時接受(屬于輸入數(shù)據(jù)類型的類型范疇的)首選類型位置 最多的操作符。如果沒有接受首選類型的操作符,則保留所有候選。如果只剩下一個候選項,則用之, 否則繼續(xù)下一步。
如果有任何輸入?yún)?shù)是 unknown類型,檢查剩余的候選操作符對應(yīng)參數(shù)位置的類型范疇。 在每一個能夠接受字符串類型范疇的位置使用string類型(這種對字符串的偏愛是合適的, 因為unknown文本確實像字符串)。另外,如果所有剩下的候選操作符都接受相同的類型 范疇,則選擇該類型范疇,否則拋出一個錯誤(因為在沒有更多線索的條件下無法作出正確 的選擇)。現(xiàn)在拋棄不接受選定的類型范疇的候選操作符,然后,如果任意候選操作符在 某個給定的參數(shù)位置接受一個首選類型, 則拋棄那些在該參數(shù)位置接受非首選類型的候選操作符。
如果只剩下一個操作符,則用之。如果還有多個候選操作符或者沒有候選操作符,則產(chǎn)生一個錯誤。
下面是一些例子。
Example 10-1. 指數(shù)操作符類型解析
只有一個在標準目錄里被指定階乘的操作符,它接受一個參數(shù)類型bigint。 掃描器為在查詢表達式中的參數(shù)指定一個初始類型integer:
SELECT 40 ! AS "40 factorial"; 40 factorial -------------------------------------------------- 815915283247897734345611269596115894272000000000 (1 row)
因此,解析器在操作數(shù)上做了一個類型轉(zhuǎn)換,該查詢相當(dāng)于:
SELECT CAST(40 AS bigint) ! AS "40 factorial";
Example 10-2. 字符串連接操作符類型解析
一個類字符串性的語法用來處理字符串類型和處理復(fù)雜的擴展類型。 為指定類型的字符串與候選操作符進行匹配。
一個未指定參數(shù)的例子:
SELECT text 'abc' || 'def' AS "text and unknown"; text and unknown ------------------ abcdef (1 row)
在這種情況下,掃描器查看是否有一個對兩個參數(shù)使用了text的操作符。 既然有,那么它假設(shè)第二個參數(shù)應(yīng)被解釋為text類型。
下面是一個未指定類型的連接:
SELECT 'abc' || 'def' AS "unspecified"; unspecified ------------- abcdef (1 row)
在這種情況下,沒有對于所使用的類型的初始提示,因為沒有在查詢中指定類型。 因此,解析器查找所有的候選操作符并找到同時接受字符串類別和比特串類別的輸入。 因為當(dāng)可用時字符串類型是首選的,該類型被選中,并且對于字符串的首選類型, text作為解決未知文字的指定類型。
Example 10-3. 絕對值與否定操作符類型解析
PostgreSQL操作符目錄中有幾個對于前綴操作符@的條目, 這些都現(xiàn)實了針對各種數(shù)字數(shù)據(jù)類型的絕對值操作符。 其中有一條為float8類型,它是在數(shù)字類型中首選的類型。 因此,PostgreSQL將在遇到一個未知類型的輸入時使用它:
SELECT @ '-4.5' AS "abs"; abs ----- 4.5 (1 row)
在這里,系統(tǒng)在接受選取操作符之前已經(jīng)隱含地解決了將未知類型文字作為float8類型。 我們可以確認我們使用的是float8而不是別的類型:
SELECT @ '-4.5e500' AS "abs"; ERROR: "-4.5e500" 超出了雙精度類型范圍
另一方面,前綴符~只在整數(shù)數(shù)據(jù)類型的時候被指定,并不是為float8。 因此,如果我們嘗試一個使用~的類似操作,我們可以這樣:
SELECT ~ '20' AS "negation"; ERROR: 操作符不唯一: ~ "未知" HINT: 不能選擇一個最佳的候選操作符。你或許需要添加顯式類型。
此情況的發(fā)生是由于系統(tǒng)不能決定在幾個可能的~符號中哪個是指定的。 我們可以幫助它做出一個明確的選擇:
SELECT ~ CAST('20' AS int8) AS "negation"; negation ---------- -21 (1 row)