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