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

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

不受支持的版本: 7.0 / 6.4
历史版本PostgreSQL 6.4 已于 2003 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本手册首页。

11.2. 操作符

11.2.1. 转换过程

操作符求值

  1. 在 pg_operator 系统目录中检查精确匹配。

    1. 如果二元操作符的一个参数是 unknown, 就假定它与另一个参数的类型相同。

    2. 交换参数,寻找与一个指向自身为可交换的 操作符的精确匹配。 如果找到,就在解析树中交换参数并使用该操作符。

  2. 寻找最佳匹配。

    1. 列出所有同名的操作符。

    2. 如果列表中只有一个操作符,输入类型可强制转换时就使用它, 类型不能强制转换时就报错。

    3. 保留类型显式匹配最多的操作符。如果没有 显式匹配则全部保留并进入下一步。 如果只剩一个候选,类型可强制转换时就使用它。

    4. 如果有输入参数是"unknown",把输入候选归类为 boolean、numeric、string、geometric 或用户自定义。如果类别 混合,或者用户定义类型多于一个,就报错,因为 没有更多线索就无法推断出正确的选择。 如果只有一个类别,就把"首选类型"赋给 先前为"unknown"的输入列。

    5. 选择类型精确匹配最多且与上一步中每个列类别的 "首选类型"匹配的候选。 如果候选仍多于一个,或者一个也没有, 就报错。

11.2.2. 示例

11.2.2.1. 求幂操作符

目录中只定义了一个求幂 操作符,它接受 float8 参数。 扫描器为这个查询表达式的两个参数 都赋予初始类型 int4:

tgl=> select 2 ^ 3 AS "Exp";
Exp
---
  8
(1 row)

于是解析器对两个操作数都做类型转换,查询 等价于

tgl=> select float8(2) ^ float8(3) AS "Exp";
Exp
---
  8
(1 row)

或

tgl=> select 2.0 ^ 3.0 AS "Exp";
Exp
---
  8
(1 row)

注意

最后这种形式的开销最小,因为不需要调用任何函数来做 隐式类型转换。这对小查询不是问题,但可能 影响涉及大表的查询的性能。

11.2.2.2. 字符串连接

类字符串的语法既用于处理字符串类型,也用于 处理复杂的扩展类型。 未指定类型的字符串会与可能的操作符候选 匹配。

一个参数未指定类型:

tgl=> SELECT text 'abc' || 'def' AS "Text and Unknown";
Text and Unknown
----------------
abcdef
(1 row)

在这种情况下,解析器会查看是否存在一个两边参数都接受text的操作符。既然存在,它就会假定第二个参数应解释为text类型。

未指定类型上的串接:

tgl=> SELECT 'abc' || 'def' AS "Unspecified";
Unspecified
-----------
abcdef
(1 row)

这种情况下没有关于使用哪个类型的初始提示,因为查询中 没有指定类型。于是解析器查找所有候选操作符, 发现所有候选的所有参数都是 string 类型。它为这个查询 选择 string 的"首选类型" text。

注意

如果用户定义了一个新类型并为它定义了 “||” 操作符来配合它工作,这个查询就会 不再按原样成功。解析器此时会 有来自两个类别的候选类型,无法决定用哪一个。

11.2.2.3. 阶乘

这个例子展示了一个有趣的结果。传统上 阶乘操作符只对整数定义。Postgres 的操作符目录中只有一个阶乘条目,接受整型操作数。 如果给定一个非整数的数值参数,Postgres 会尝试把该参数转换成整数来求 阶乘。

tgl=> select (4.3 !);
?column?
--------
      24
(1 row)

注意

当然,这会得到数学上可疑的结果, 因为原则上非整数的阶乘是没有定义的。 不过,数据库的角色不是教数学,而是 做数据操作的工具。如果用户选择求浮点数的 阶乘,Postgres 会尽量照办。

提交更正

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