云數(shù)據(jù)庫(kù)GaussDB函數(shù)
函數(shù)類(lèi)型解析
從系統(tǒng)表pg_proc中選擇所有可能被選到的函數(shù)。如果使用了一個(gè)不帶模式修飾的函數(shù)名稱,那么認(rèn)為該函數(shù)是那些在當(dāng)前搜索路徑中的函數(shù)。如果給出一個(gè)帶修飾的函數(shù)名,那么只考慮指定模式中的函數(shù)。
如果搜索路徑中找到了多個(gè)不同參數(shù)類(lèi)型的函數(shù)。將從中選擇一個(gè)合適的函數(shù)。
早在去年,華為云便發(fā)布了《云原生2.0白皮書(shū)》,闡述了云原生2.0定義、價(jià)值及參考架構(gòu),解讀了“資源高效、應(yīng)用敏捷、業(yè)務(wù)智能、安全可信”四大價(jià)值以及預(yù)測(cè)未來(lái)發(fā)展趨勢(shì)。而今年的《云原生2.0架構(gòu)白皮書(shū)》,圍繞架構(gòu)升級(jí),重點(diǎn)詮釋了云原生2.0技術(shù)特征與架構(gòu)設(shè)計(jì)模式,以云原生技術(shù)力量推動(dòng)企業(yè)數(shù)字化轉(zhuǎn)型升級(jí)。
查找和輸入?yún)?shù)類(lèi)型完全匹配的函數(shù)。如果找到一個(gè),則用之。如果輸入的實(shí)參類(lèi)型都是unknown類(lèi)型,則不會(huì)找到匹配的函數(shù)。
如果未找到完全匹配,請(qǐng)查看該函數(shù)是否為一個(gè)特殊的類(lèi)型轉(zhuǎn)換函數(shù)。
尋找最優(yōu)匹配。
- 拋棄那些輸入類(lèi)型不匹配并且也不能隱式轉(zhuǎn)換成匹配的候選函數(shù)。unknown文本在這種情況下可以轉(zhuǎn)換成任何東西。如果只剩下一個(gè)候選項(xiàng),則用之,否則繼續(xù)下一步。
- 遍歷所有候選函數(shù),保留那些輸入類(lèi)型匹配最準(zhǔn)確的。此時(shí),域被看作和它們的基本類(lèi)型相同。如果沒(méi)有一個(gè)函數(shù)能準(zhǔn)確匹配,則保留所有候選。如果只剩下一個(gè)候選項(xiàng),則用之,否則繼續(xù)下一步。
- 遍歷所有候選函數(shù),保留那些需要類(lèi)型轉(zhuǎn)換時(shí)接受首選類(lèi)型位置最多的函數(shù)。如果沒(méi)有接受首選類(lèi)型的函數(shù),則保留所有候選。如果只剩下一個(gè)候選項(xiàng),則用之,否則繼續(xù)下一步。
- 如果有任何輸入?yún)?shù)是unknown類(lèi)型,檢查剩余的候選函數(shù)對(duì)應(yīng)參數(shù)位置的類(lèi)型范疇。在每一個(gè)能夠接受字符串類(lèi)型范疇的位置使用string類(lèi)型(這種對(duì)字符串的偏愛(ài)是合適的,因?yàn)閡nknown文本確實(shí)像字符串)。另外,如果所有剩下的候選函數(shù)都接受相同的類(lèi)型范疇,則選擇該類(lèi)型范疇,否則拋出一個(gè)錯(cuò)誤(因?yàn)樵跊](méi)有更多線索的條件下無(wú)法作出正確的選擇)?,F(xiàn)在拋棄不接受選定的類(lèi)型范疇的候選函數(shù),然后,如果任意候選函數(shù)在那個(gè)范疇接受一個(gè)首選類(lèi)型,則拋棄那些在該參數(shù)位置接受非首選類(lèi)型的候選函數(shù)。如果沒(méi)有一個(gè)候選符合這些測(cè)試則保留所有候選。如果只有一個(gè)候選函數(shù)符合,則使用它;否則,繼續(xù)下一步。
- 如果同時(shí)有unknown和已知類(lèi)型的參數(shù),并且所有已知類(lèi)型的參數(shù)有相同的類(lèi)型,假設(shè)unknown參數(shù)也是這種類(lèi)型,檢查哪個(gè)候選函數(shù)可以在unknown參數(shù)位置接受這種類(lèi)型。如果正好一個(gè)候選符合,那么使用它。否則,產(chǎn)生一個(gè)錯(cuò)誤。
GaussDB 函數(shù)示例
示例1:圓整函數(shù)參數(shù)類(lèi)型解析。只有一個(gè)round函數(shù)有兩個(gè)參數(shù)(第一個(gè)是numeric,第二個(gè)是integer)。所以下面的查詢自動(dòng)把第一個(gè)類(lèi)型為integer的參數(shù)轉(zhuǎn)換成numeric類(lèi)型。
實(shí)際上它被分析器轉(zhuǎn)換成:
因?yàn)閹?shù)點(diǎn)的數(shù)值常量初始時(shí)被賦予numeric類(lèi)型,因此下面的查詢將不需要類(lèi)型轉(zhuǎn)換,并且可能會(huì)略微高效一些:
示例2:子字符串函數(shù)類(lèi)型解析。有好幾個(gè)substr函數(shù),其中一個(gè)接受text和integer類(lèi)型。如果用一個(gè)未聲明類(lèi)型的字符串常量調(diào)用它,系統(tǒng)將選擇接受string類(lèi)型范疇的首選類(lèi)型(也就是text類(lèi)型)的候選函數(shù)。
如果該字符串聲明為varchar類(lèi)型,就像從表中取出來(lái)的數(shù)據(jù)一樣,分析器將試著將其轉(zhuǎn)換成text類(lèi)型:
被分析器轉(zhuǎn)換后實(shí)際上變成:
說(shuō)明:分析器從pg_cast表中了解到text和varchar是二進(jìn)制兼容的,意思是說(shuō)一個(gè)可以傳遞給接受另一個(gè)的函數(shù)而不需要做任何物理轉(zhuǎn)換。因此,在這種情況下,實(shí)際上沒(méi)有做任何類(lèi)型轉(zhuǎn)換。
而且,如果以integer為參數(shù)調(diào)用函數(shù),分析器將試圖將其轉(zhuǎn)換成text類(lèi)型:
被分析器轉(zhuǎn)換后實(shí)際上變成: