↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本PostgreSQL 7.1 已于 2006 年 4 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

5.3. 函数 #

函数调用类型解析

  1. 在 pg_proc 系统目录中检查精确匹配。 (涉及 unknown 的情况在这一步 永远找不到匹配。)

  2. 寻找最佳匹配。

    1. 列出所有同名、参数个数相同且输入类型 匹配或可以强制转换成匹配的 函数。(为此目的,假定 unknown 字面量 可以转换成任何类型。)如果只有一个, 就使用它;否则继续下一步。

    2. 遍历所有候选,保留输入类型精确匹配 最多的。如果没有任何精确匹配,则保留全部 候选。如果只剩一个候选,就使用它;否则继续下一步。

    3. 遍历所有候选,保留输入类型精确匹配或二进制 兼容匹配最多的。如果没有任何精确或二进制 兼容匹配,则保留全部候选。 如果只剩一个候选,就使用它;否则继续下一步。

    4. 遍历所有候选,保留在需要类型强制转换的最多个 位置上接受首选类型的。 如果没有任何候选接受首选类型,则保留全部候选。 如果只剩一个候选,就使用它;否则继续下一步。

    5. 如果有输入参数是"unknown",检查其余候选在这些参数 位置上接受的类型类别。在每个位置上,如果有候选接受 "string" 类别就选择该类别(这种偏向字符串的做法 是恰当的,因为未知类型的字面量看起来确实像字符串)。 否则,如果所有剩余候选接受相同的类型类别, 就选择该类别;否则失败,因为没有更多线索 就无法推断出正确的选择。还要注意 是否有候选接受所选类别中的首选数据类型。 现在丢弃不接受所选类型类别的操作符候选; 此外,如果某个候选在给定的参数 位置上接受首选类型,就丢弃在该参数上 接受非首选类型的候选。

    6. 如果只剩一个候选操作符,就使用它。如果没有候选操作符或者不止一个候选操作符剩余,则失败。

  3. 如果找不到最佳匹配,看看这个函数调用是否 是一个平凡的类型强制转换请求。当函数调用 只有一个参数且函数名与某个数据类型的(内部) 名相同时就是这种情况。此外,函数参数必须是 未知类型的字面量或与该数据类型二进制 兼容的类型。满足这些条件时,函数参数被强制 转换为该数据类型。

5.3.1. 示例

5.3.1.1. 阶乘函数

pg_proc 目录中只定义了一个阶乘函数。 因此下面的查询自动把 int2 参数 转换为 int4:

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

并且实际上被解析器变换为

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

5.3.1.2. 子串函数

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)

注意

实际上,解析器知道 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)。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。