PostgreSQL
上一页 第六章. 类型转换 下一页

操作符

转换过程

操作符评估

  1. 在 pg_operator 系统表里找出准确的匹配.
    1. 如果一个双目操作符的一个参数是 unknown.则假设其与另一个参数类型相同.
    2. 掉转参数,寻找一个在参数掉转后仍然匹配的操作符.如果找到,则掉转分析树上的参数并使用该操作符.
  2. 寻找最优匹配
    1. 生成一个同名的操作符的列表.
    2. 如果表中只有一个操作符:如果输入类型可以匹配或转换,则使用该操作符,否则输出一个错误.
    3. 挑出具有最多显式的类型匹配的操作符.挑出所有没有显式的类型匹配的操作符并进行下一步. 如果结果只有一个候选操作符,而且类型匹配或可转换.则使用之.
    4. 如果输入参数是 "unknown", 将输入按布尔(boolean),数字(numeric),字符串(string),几何(geometric)或用户定义(user-defined)分类.如果分类结果有多种类型,或超过一种用户定义类型,则产生一个错误,因为在没有更多线索的条件下不能导出正确的选择.如果分类结果只有一类,则将先前"unknown"的类型转为"优选类型".
    5. 挑出类型匹配最准确的和从前一步中挑出的匹配各类的"优选类型"的操作符.如果还有超过一个的候选操作符或是没有候选操作符,则产生一个错误.

例子

指数操作符

在分类里只有一个指数操作符,它以 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)

注意 最后的形式最高效,因为不用调用函数做隐含类型转换.这对小查询没有什么影响,但可能对那些操作大表的查询的性能产生较大影响.

字符串连接

一种类字符串的语法既可以用于字符串也可以用于复杂的扩展类型.包含不明类型的字串使用可能的候选操作符匹配.

有一个未声明的参数:

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)

本例中对类型的初始值没有任何暗示,因为查询中没有声明任何类型.因此,分析器查找所有参数都是字符串类的候选操作符.并且它选择"优选类型"text作为本查询字符串类的类型.

注意: 如果用户定义了一个新的数据类型,并且定义了用于该类型的操作符 “||” ,那么本查询将不会象上面写的那样成功完成.这时分析器会因为现在有两类候选操作符而无法决定使用哪个.

阶乘

本例演示了一个有趣的结果.一般来说,阶乘只用于整数,Postgres 操作符类别中用于阶乘的只有一个,其以整数为操作数.如果输入一个非整数数字参数.Postgres 将试图把该参数转换成整数进行阶乘运算.

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

注意: 这样做当然会导致一个数学上有疑问的结果,因为非整数的阶乘原则没有定义.但是,数据库的角色不是数学教学,而是数据操作.如果用户一定要进行浮点数的阶乘,Postgres 将尽可能服从.


上一页 首页 下一页
类型转换 开头 函数