在一次函数调用中使用的特定函数由以下几个步骤决定。 函数类型解析
a. 抛弃那些输入类型不匹配并且也不能隐式转换成匹配的候选函数。unknown 文本在这种情况下可以转换成任何东西。如果只剩下一个候选项,则用之,否则继续下一步。 b. 遍历所有候选函数,保留那些输入类型匹配最准确的。此时, 域被看作和他们的基本类型相同。如果没有一个函数能准确匹配,则保留所有候选。 如果只剩下一个候选项,则用之,否则继续下一步。 c. 遍历所有候选函数,保留那些需要类型转换时接受(属于输入数据类型的类型范畴的) 首选类型位置最多的函数。如果没有接受首选类型的函数,则保留所有候选。 如果只剩下一个候选项,则用之,否则继续下一步。 d. 如果有任何输入参数是unknown类型,检查剩余的候选函数对应参数位置的类型范畴。 在每一个能够接受字符串类型范畴的位置使用string类型(这种对字符串的偏爱是合适的, 因为 unknown 文本确实像字符串)。另外,如果所有剩下的候选函数都接受相同的类型范畴, 则选择该类型范畴,否则抛出一个错误(因为在没有更多线索的条件下无法作出正确的选择)。 现在抛弃不接受选定的类型范畴的候选函数,然后,如果任意候选函数在那个范畴接受一个首选类型, 则抛弃那些在该参数位置接受非首选类型的候选函数。
请注意,”最佳匹配”规则对操作符和对函数的类型分析都是一样的。下面是一些例子。 例.圆整函数参数类型解析 只有一个round函数有两个参数(第一个是numeric, 第二个是integer)。所以下面的查询自动把第一个类型为integer 的参数转换成numeric类型: SELECT round(4, 4);round--------4.0000(1 row) 实际上它被分析器转换成: SELECT round(CAST (4 AS numeric), 4); 因为带小数点的数值常量初始时被赋予numeric类型, 因此下面的查询将不需要类型转换,并且可能会略微高效一些: SELECT round(4.0, 4); 例.子字符串函数类型解析 有好几个substr函数,其中一个接受text 和integer类型。如果用一个未声明类型的字符串常量调用它, 系统将选择接受string类型范畴的首选类型 (也就是text类型)的候选函数。 SELECT substr('1234', 3);substr--------34(1 row) 如果该字符串声明为varchar类型,就像从表中取出来的数据一样, 分析器将试着将其转换成text类型: SELECT substr(varchar '1234', 3);substr--------34(1 row) Note 分析器从pg_cast表中了解到text和varchar 是二进制兼容的,意思是说一个可以传递给接受另一个的函数而不需要做任何物理转换。 因此,在这种情况下,实际上没有做任何类型转换。 而且,如果以integer为参数调用函数,分析器将试图将其转换成text类型: SELECT substr(1234, 3);substr--------34(1 row) 事实上变成: SELECT substr(CAST (1234 AS text), 3); 这种自动转换可行是因为有一个从integer 到text 的隐式转换。 |
|