PostgreSQL 18 中文参考文档(未翻译部分保留英文)🌐 切换到英文原版 →

10.1. 概述 #

SQL 是一种强类型语言。这意味着每一个独立的数据项都有一个与之关联的数据类型,该类型严格决定了它的计算行为与允许的操作。PostgreSQL 拥有比其他许多商业 SQL 实现更为通用、灵活的可扩展类型系统。因此,PostgreSQL 中的绝大多数类型转换行为均由系统级通用规则统一驱动,而非依赖临时的特例规则。这使得系统即便面对用户自定义的全新数据类型,也能平滑支持混合类型表达式的计算。

PostgreSQL 的词法分析器/解析器将输入的词法单元划分为五大基本类别:整数、非整数数值、字符串、标识符以及关键字。绝大多数非数值类型的字面常量在词法阶段首先被分类为字符串。SQL 语言规范允许在字面量前附加类型名称,这一机制可以被用来引导解析器沿着正确的类型推断路径推进。例如查询:

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

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

该语句包含两个字面常量,分别被显式赋予了 text 与 point 类型。如果未给字符串字面量显式指定类型,系统会初始赋予其占位符类型 unknown,并在后续阶段根据上下文做进一步推断。

在 PostgreSQL 解析器中,有四类基础 SQL 语法结构需要应用各自独立的类型转换规则:

函数调用

PostgreSQL 类型系统的核心建立在丰富的函数集合之上。函数可以拥有一个或多个参数。由于系统支持函数重载,单纯依据函数名称无法唯一确定待执行的目标函数;解析器必须根据调用方传入的实参数据类型来挑选最恰当的函数候选。

运算符

系统支持一元前缀运算符与二元中缀运算符。类似于函数,运算符同样支持重载,因而面临着同样的操作符重载决议挑战。

值存储

INSERT 与 UPDATE 语句需要将表达式的计算结果写入数据表。语句中产出的表达式类型必须与目标表中相应字段列的物理类型精准匹配,必要时执行自动类型转换。

UNION、CASE 及相关结构

由于参与联合操作的 SELECT 语句的所有结果行最终必须汇聚在统一的列集合中输出,各分支子句的返回类型必须相互匹配并转换为公共统一类型。同理,CASE 各分支的返回表达式也必须统一收敛为同一种输出类型。ARRAY[] 数组构造器以及 GREATEST、LEAST 等函数同样依赖相同的多分支公共类型推断规则。

系统目录持久化记录了各数据类型之间存在哪些合法的转换路径(casts)以及如何执行具体转换。用户可以通过 CREATE CAST 命令注册新的转换规则。

解析器引入了一项关键机制:将所有数据类型划分为若干类型类别(type categories),包括 boolean、numeric、string、bitstring、datetime、timespan、geometric、network 以及用户自定义类别(详见 Table 52.65)。在每一个类型类别内部,可以指定一个或多个首选类型(preferred types)。在面对存在多种候选转换路径的歧义表达式时,解析器会优先倒向该类别内的首选类型,从而确保复杂表达式能够稳定地按照最符合人类直觉的方式得到确定解析。

全套类型转换规则遵循以下核心设计哲学: