在一次函數(shù)調(diào)用中使用的特定函數(shù)由以下幾個步驟決定。 函數(shù)類型解析
a. 拋棄那些輸入類型不匹配并且也不能隱式轉(zhuǎn)換成匹配的候選函數(shù)。unknown 文本在這種情況下可以轉(zhuǎn)換成任何東西。如果只剩下一個候選項(xiàng),則用之,否則繼續(xù)下一步。 b. 遍歷所有候選函數(shù),保留那些輸入類型匹配最準(zhǔn)確的。此時, 域被看作和他們的基本類型相同。如果沒有一個函數(shù)能準(zhǔn)確匹配,則保留所有候選。 如果只剩下一個候選項(xiàng),則用之,否則繼續(xù)下一步。 c. 遍歷所有候選函數(shù),保留那些需要類型轉(zhuǎn)換時接受(屬于輸入數(shù)據(jù)類型的類型范疇的) 首選類型位置最多的函數(shù)。如果沒有接受首選類型的函數(shù),則保留所有候選。 如果只剩下一個候選項(xiàng),則用之,否則繼續(xù)下一步。 d. 如果有任何輸入?yún)?shù)是unknown類型,檢查剩余的候選函數(shù)對應(yīng)參數(shù)位置的類型范疇。 在每一個能夠接受字符串類型范疇的位置使用string類型(這種對字符串的偏愛是合適的, 因?yàn)?unknown 文本確實(shí)像字符串)。另外,如果所有剩下的候選函數(shù)都接受相同的類型范疇, 則選擇該類型范疇,否則拋出一個錯誤(因?yàn)樵跊]有更多線索的條件下無法作出正確的選擇)。 現(xiàn)在拋棄不接受選定的類型范疇的候選函數(shù),然后,如果任意候選函數(shù)在那個范疇接受一個首選類型, 則拋棄那些在該參數(shù)位置接受非首選類型的候選函數(shù)。
請注意,”最佳匹配”規(guī)則對操作符和對函數(shù)的類型分析都是一樣的。下面是一些例子。 例.圓整函數(shù)參數(shù)類型解析 只有一個round函數(shù)有兩個參數(shù)(第一個是numeric, 第二個是integer)。所以下面的查詢自動把第一個類型為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ù)值常量初始時被賦予numeric類型, 因此下面的查詢將不需要類型轉(zhuǎn)換,并且可能會略微高效一些: SELECT round(4.0, 4); 例.子字符串函數(shù)類型解析 有好幾個substr函數(shù),其中一個接受text 和integer類型。如果用一個未聲明類型的字符串常量調(diào)用它, 系統(tǒng)將選擇接受string類型范疇的首選類型 (也就是text類型)的候選函數(shù)。 SELECT substr('1234', 3);substr--------34(1 row) 如果該字符串聲明為varchar類型,就像從表中取出來的數(shù)據(jù)一樣, 分析器將試著將其轉(zhuǎn)換成text類型: SELECT substr(varchar '1234', 3);substr--------34(1 row) Note 分析器從pg_cast表中了解到text和varchar 是二進(jìn)制兼容的,意思是說一個可以傳遞給接受另一個的函數(shù)而不需要做任何物理轉(zhuǎn)換。 因此,在這種情況下,實(shí)際上沒有做任何類型轉(zhuǎn)換。 而且,如果以integer為參數(shù)調(diào)用函數(shù),分析器將試圖將其轉(zhuǎn)換成text類型: SELECT substr(1234, 3);substr--------34(1 row) 事實(shí)上變成: SELECT substr(CAST (1234 AS text), 3); 這種自動轉(zhuǎn)換可行是因?yàn)橛幸粋€從integer 到text 的隱式轉(zhuǎn)換。 |
|