?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
被一個(gè)函數(shù)調(diào)用引用的特定函數(shù)使用下面步驟來決定。
函數(shù)類型解析
從pg_proc
系統(tǒng)目錄中選擇考慮的函數(shù)。
如果使用一個(gè)不合格的模式的函數(shù)名稱,那么考慮到的函數(shù)是那些可以在當(dāng)前搜索路
徑(查閱Section 5.7.3)中匹配名稱和現(xiàn)有的參數(shù)數(shù)量的函數(shù)。
如果給定的是一個(gè)合格的函數(shù)名稱,那么只考慮在指定的模式中的函數(shù)。
如果搜索路徑里發(fā)現(xiàn)多個(gè)參數(shù)類型相同的函數(shù),那么只考慮最早在搜索路徑中出現(xiàn)的那個(gè)。 不同參數(shù)類型的函數(shù)被平等對(duì)待,不受搜索路徑位置的影響。
如果使用一個(gè)VARIADIC數(shù)組參數(shù)聲明一個(gè)函數(shù),并且調(diào)用不使用關(guān)鍵字VARIADIC, 那么該函數(shù)被作為是否數(shù)組參數(shù)被一個(gè)或更多它元素類型的事件,需要去匹配調(diào)用。 這樣的擴(kuò)展函數(shù)之后或許會(huì)有對(duì)于一些非可變參數(shù)函數(shù)有效的相同的參數(shù)類型。 在這種情況下,使用在搜索路徑中出現(xiàn)比較早的函數(shù),或者如果兩個(gè)函數(shù)在相同的模式中,那么首選非可變的一個(gè)。
考慮使用有默認(rèn)參數(shù)值的函數(shù)來匹配任何省略了零或者多個(gè)默認(rèn)表參數(shù)位置的調(diào)用。 如果有更多的超出一個(gè)的函數(shù)匹配一個(gè)調(diào)用,那么使用最早出現(xiàn)在搜索路徑中的那個(gè)。 如果在同一個(gè)相同的在非默認(rèn)位置的參數(shù)類型的模式中有兩個(gè)或者更多的這樣的函數(shù)(他們有 不同的默認(rèn)參數(shù)設(shè)置或許是可能的),系統(tǒng)將不能確定去選擇哪個(gè),并且如此一個(gè)"模糊的函數(shù)調(diào)用" 錯(cuò)誤導(dǎo)致是否可以發(fā)現(xiàn)更匹配的調(diào)用。
檢查函數(shù)正確地接受了輸入?yún)?shù)類型。如果存在一個(gè)(在所考慮的函數(shù)的設(shè)置中可以僅有一個(gè)精確匹配),那么使用它。 (在該步驟中該情況涉及的未知將永不匹配)
如果沒有發(fā)現(xiàn)精確匹配,那么查看調(diào)用函數(shù)是否作為一個(gè)特定的轉(zhuǎn)換訪問類型出現(xiàn)。 如果函數(shù)調(diào)用僅有一個(gè)參數(shù)并且函數(shù)名和一些數(shù)據(jù)類型名相同,那么該情況將會(huì)發(fā)生。 并且,函數(shù)參數(shù)不能是一個(gè)未知類型的文字,或者是一個(gè)以數(shù)據(jù)類型命名的可強(qiáng)迫的二進(jìn)制類型, 或者是一個(gè)可以被轉(zhuǎn)換為以類型的I/O命名的數(shù)據(jù)類型(也就是,轉(zhuǎn)換要么是那樣要么是來在標(biāo)準(zhǔn)字符類型中的一個(gè))。 當(dāng)遇到這些條件的時(shí)候,函數(shù)調(diào)用被當(dāng)做CAST規(guī)格的一個(gè)格式來看。 [1]
查找最佳匹配。
丟棄候選函數(shù) 輸入類型不匹配且不能轉(zhuǎn)換(使用一個(gè)隱式變換轉(zhuǎn)換)匹配。 為了這個(gè)目的,unknown文字是假定的轉(zhuǎn)換為任何形式。 如果僅有一個(gè)候選項(xiàng),那么使用它;或者繼續(xù)下一步。
通過所有候選項(xiàng)并保持在輸入類型中的最佳匹配。 (為達(dá)到該目的,域被認(rèn)為和它們的基礎(chǔ)類型一樣。) 如果沒有精確匹配那么保持所有候選項(xiàng)。 如果僅有一個(gè)候選項(xiàng),那么使用它;或者繼續(xù)下一步。
通過所有候選項(xiàng)并保持那些接受優(yōu)先類型(輸入數(shù)據(jù)類型的類型分類)在大多數(shù)類型轉(zhuǎn)換被訪問位置。 如果沒有可以接受的首選類型那么保持所有的候選項(xiàng)。 如果僅有一個(gè)候選項(xiàng),那么使用它;或者繼續(xù)下一步。
如果輸入?yún)?shù)是未知,那么通過剩下的候選項(xiàng)檢查在那些參數(shù)位置上接受的類型類別。 在每一個(gè)位置上,如果任何候選項(xiàng)接受類別那么選擇string類。 (這個(gè)偏向于字符串是恰當(dāng)?shù)?,因?yàn)橐粋€(gè)未知類型文字看起來像字符。) 否則,如果所有剩余的候選項(xiàng)接受相同的類型類別,那么選擇那個(gè)類別; 否則將失敗因?yàn)樵谌狈Ω嗟奶崾緯r(shí)不能推斷出正確的選擇。 現(xiàn)在,丟棄的候選項(xiàng)不接受選擇類型分類。 此外,如果在那樣的分類中任何一個(gè)候選項(xiàng)接受一個(gè)首選的類型,那么丟棄的候選項(xiàng)為那個(gè)參數(shù)接受非首選類型。
如果僅有一個(gè)候選項(xiàng),那么使用它。 如果沒有候選項(xiàng)或多于一個(gè)的首選項(xiàng),那么將會(huì)失敗。
注意,對(duì)于操作符和函數(shù)類型解析來說"最佳匹配"規(guī)則是完全相同的。 下面是一些例子。
Example 10-4. 取整函數(shù)參數(shù)類型解析
只有一個(gè)帶有兩個(gè)參數(shù)的取整
函數(shù);
它攜帶一個(gè)參數(shù)numeric類型和一個(gè)integer類型。
所以下面的語句將自動(dòng)地將第一個(gè)integer類型參數(shù)轉(zhuǎn)換為numeric類型:
SELECT round(4, 4); round -------- 4.0000 (1 row)
該查詢實(shí)際上是由解析器轉(zhuǎn)換為:
SELECT round(CAST (4 AS numeric), 4);
因?yàn)榘?shù)點(diǎn)的數(shù)字常數(shù)首選指定為numeric格式, 所以下面的查詢語句將不需要格式轉(zhuǎn)換,因此這樣會(huì)稍微更有效:
SELECT round(4.0, 4);
Example 10-5. 子字符串函數(shù)類型解析
有幾個(gè)substr
函數(shù),其中一個(gè)為text和
integer類型。如果為未指定類型的字符常量調(diào)用,那么系統(tǒng)選擇
接受一個(gè)首選類型為string(也就是text類型)的參數(shù)的候選函數(shù)。
SELECT substr('1234', 3); substr -------- 34 (1 row)
如果字符串聲明為varchar,那么如果它來自于一個(gè)表或許會(huì)是這樣的,解析器將試圖轉(zhuǎn)換它為text:
SELECT substr(varchar '1234', 3); substr -------- 34 (1 row)
有效地轉(zhuǎn)變是通過解析器轉(zhuǎn)換:
SELECT substr(CAST (varchar '1234' AS text), 3);
Note: 解析器從系統(tǒng)表pg_cast中解析到text和varchar類型是兼容二進(jìn)制的, 意思是它可以被轉(zhuǎn)化成一個(gè)接受其它不做屋里轉(zhuǎn)換的函數(shù)。 因此,在這種情況下調(diào)用的類型轉(zhuǎn)換沒有真正地插入。
并且,如果該函數(shù)被一個(gè)integer類型的參數(shù)調(diào)用,那么解析器將試圖轉(zhuǎn)換其為text:
SELECT substr(1234, 3); ERROR: 函數(shù)substr(integer, integer)不存在 HINT: 沒有函數(shù)匹配所給的名稱和參數(shù)類型。你或許需要添加明確的類型。
由于integer類型不會(huì)隱含地轉(zhuǎn)換為text所以它不能正常工作。 在一個(gè)明確的情況下它才會(huì)工作,然而:
SELECT substr(CAST (1234 AS text), 3); substr -------- 34 (1 row)
[1] | 該步的原因是在那些沒有一個(gè)實(shí)際的類型轉(zhuǎn)換函數(shù)的情況下支持函數(shù)風(fēng)格澆鑄規(guī)格。 如果有一個(gè)類型轉(zhuǎn)換函數(shù),那么在它的輸出類型之后按慣例命名,并且不需要有一個(gè)特殊情況。 查閱CREATE CAST獲取更多的說明。 |