您的位置:寻梦网首页编程乐园数据库PostgreSQL 7.2 Documentation

5.4. 函数

函数调用的参数类型是用下面的步骤来解析的.

函数参数类型解析

  1. pg_proc 系统表里查找准确的匹配. (涉及到 unknown 类型的情况下在本步骤不会找到任何匹配.)

  2. 如果在系统表中没有准确的匹配,则看看函数调用是否明显需要 一个简单的类型转换.如果函数调用只有一个参数并且函数名与某些数据类型 的(内部)名称相同,那么就会出现这种情况.另外,该函数的参数必须是 一个未知类型的文本或者与命名数据类型二进制兼容.如果符合这些条件, 则该函数参数在不做任何明确函数调用的情况下转换成这个命名的数据类型.

  3. 查找最优的匹配

    1. 生成一个具有相同数量参数的同名函数的列表:它们的输入类型匹配 或者可以转换成匹配的类型. ( unknown 文本在这里假设可以转换成任何类型.) 如果只有一个,用之;否则继续下一步.

    2. 遍历所有候选函数,保留那些在输入类型上有最多准确匹配的. 如果没有一个有准确匹配,则保留全部. 如果只剩下一个,用之;否则继续下一步.

    3. 遍历所有候选函数,保留那些在输入类型上有最多准确匹配的 或者在输入类型上有二进制兼容匹配的. 如果没有一个有准确匹配,则保留全部. 如果只剩下一个,用之;否则继续下一步.

    4. 遍历所有候选函数,保留那些在最多需要类型转换的参数位置上 接受优选类型的函数. 如果没有哪个候选函数接受优选类型,则保留全部. 如果只剩下一个,用之;否则继续下一步.

    5. 如果任何输入参数是 unknown ,检查剩下的候选函数对应参数位置的 类型表.如果任何候选函数接受 string 类型,则在那些位置选 "string" 类型(这个假设认为 string 是合适的,因为 unknown 类型文本确实象 string). 否则,如果所有剩下的候选函数接受相同的类型,选择该类型; 否则抛出一个错误,因为在没有更多线索的条件下不能导出正确的选择. 还要注意是否有哪个候选函数在选出的类型表中有优选类型. 现在抛弃不接受选定的类型表的候选函数;然后, 如果任意候选函数在某个给定的参数位置接受一个优选类型, 则抛弃那些在该参数位置接受非优选类型的候选函数.

    6. 如果只剩下一个函数,用之. 如果还有超过一个的候选函数或是没有候选函数,则产生一个错误.

例子

Example 5-4. 阶乘函数参数类型解析

pg_proc 系统表里只定义了一个 int4fac 函数.所以下面的查询自动将 int2 参数转换成 int4

tgl=> SELECT int4fac(int2 '4');
 int4fac
---------
      24
(1 row)

实际上它被分析器转换成:

tgl=> SELECT int4fac(int4(int2 '4'));
 int4fac
---------
      24
(1 row)

Example 5-5. 子字串函数类型解析

pg_proc 里定义了两个 substr 函数. 但是,其中只有一个使用两个参数,参数类型分别是 text int4

如果调用时其中一个字符串常量的类型不明确,其类型直接与唯一的候选函数匹配:

tgl=> SELECT substr('1234', 3);
 substr
--------
     34
(1 row)

如果该字符串声明为类型 varchar , 就像大多数从表中取来的数据一样,分析器将试着将其转换成 text

tgl=> SELECT substr(varchar '1234', 3);
 substr
--------
     34
(1 row)

被分析器转换后变成:

tgl=> SELECT substr(text(varchar '1234'), 3);
 substr
--------
     34
(1 row)

Note: 实际上,分析器知道 text varchar 二进制兼容 的,意思是说其中一个可以传递给一个接受另外一个的函数 而不需要做任何物理转换.因此,在这种情况下,实际上没有做任何明确的 类型转换.

而且,如果以 int4 为参数调用函数,分析器将试图将其转换成 text

tgl=> SELECT substr(1234, 3);
 substr
--------
     34
(1 row)

实际上是这样执行的

tgl=> SELECT substr(text(1234), 3);
 substr
--------
     34
(1 row)

这样可以运行是因为在系统表里面有一个转换函数 text(int4).