Chapter 10. 类型转换

Table of Contents
10.1. 概述
10.2. 操作符
10.3. 函数
10.4. 值存储
10.5. UNIONCASE 和相关构造

SQL 语句可能(有意无意地)要求在同一表达式里混合不同的数据类型。 PostgreSQL 在计算混合类型表达式方面有许多扩展性很强的功能。

在大多数情况下,用户不需要明白类型转换机制的细节。 但是,由 PostgreSQL 所进行的隐含的类型转换会对查询的结果产生影响, 必要时这些影响又可以用明确的类型转换进行剪裁利用。

本章介绍 PostgreSQL类型转换的传统和机制。 关于特定的类型和函数及操作符的进一步信息, 请参考Chapter 8Chapter 9里的相关章节。

10.1. 概述

SQL 是强类型语言。 也就是说,每一数据都与一个决定其行为和可行用法的数据类型相联。 PostgreSQL 有一个可扩展的数据类型系统, 该系统比其他 SQL 实现实现更具通用性和灵活性。 因而,PostgreSQL中大多数类型转换的特性是由通用规则来管理的, 而不是由专门搜索方法来分析,以此令混合类型表达式有实际意义,即便是用户定义的类型也如此。

PostgreSQL 扫描/分析器只将词法元素分解成五个基本种类: 整数(integers),浮点数(floating-point numbers), 字符串(strings),名字(names)和关键字(keywords)。 大多数扩展的类型首先表征为字符串(strings)。 SQL 语言的定义允许将类型名声明为字符串,这个机制被 PostgreSQL 用于令分析器沿着正确的方向运行。例如,下面查询

SELECT text 'Origin' AS "label", point '(0,0)' AS "value";

 label  | value
--------+-------
 Origin | (0,0)
(1 row)

有两个文本常量,类型分别为 textpoint。 如果没有为字串文本声明类型, (该文本)先被初始化成一个拥有存储空间的 unknown(未知)类型, 该类型将在后面描述的晚期阶段分析。

PostgreSQL 分析器里, 有四种基本的 SQL 元素需要独立的类型转换规则:

函数调用

多数 PostgreSQL 类型系统是建筑在一套丰富的函数上的。 函数调用可以有一个或多个参数。 因为 PostgreSQL 允许函数重载, 所以函数名自身并不唯一地标识将要调用的函数 — 分析器必须以函数提供的参数的类型为基础选择正确的函数。

操作符

PostgreSQL 也允许使用左目或右目操作符(单目操作符,一个参数), 允许表达式里使用双目操作符(两个参数)。

值存储

SQL INSERTUPDATE 语句将表达式结果放入表中。 语句中的表达式类型必须和的目标列的类型一致或者是(可能需要)转换成一致的。

UNIONCASE 和相关的构造

因为联合SELECT语句中的所有查询结果必须在一列里显示出来, 所以每个SELECT 子句中的元素类型必须相互匹配并转换成一套统一类型。 类似,一个CASE构造的结果表达式必须转换成统一的类型, 这样CASE表达式自身作为整体有一种已知输出类型。 同样的要求也存在于 ARRAY 构造中, 以及 GREATESTLEAST 函数。

系统表存储有关哪种数据类型之间的转换(叫 casts )是合法的, 以及如何执行这些转换的信息。额外的转换可以由用户通过 CREATE CAST 命令增加。(通常和定义一种新的数据类型一起完成。 内置类型的类型转换集已经经过仔细的雕琢了,因此最好不要去更改它们。)

分析器中还有一个搜索器用于更好地猜测 SQL 标准类型的确切特性。 分析器里定义了几种类型范畴booleannumericstringbitstringdatetimetimespangeometricnetwork,和用户定义(user-defined)。 除用户定义类型外, 每种类型都有一种首选类型用于解决类型定义歧义的问题。 对于用户定义的类型,其自身就是自己的首选类型,所以那些含混不清的表达式(在分析结果中有多种可能的表达式) 如果有多个内置类型的时候大多可以正确分析,但如果有多个用户定义类型可选,则会抛出错。

所有类型转换规则都是建立在下面几个基本原则上的: