2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:开发版
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 7.2

10.1. 概述 #

SQL是一种强类型语言。也就是说,每个数据项都具有一个关联的数据类型,该类型决定其行为和允许的用法。PostgreSQL 拥有一个可扩展的类型系统,它比其他SQL实现更通用、更灵活。因此,PostgreSQL 中的大多数类型转换行为受一般规则而不是特定启发式方法的约束。这允许即使在使用用户定义类型的情况下也使用混合类型表达式。

PostgreSQL 的扫描器/解析器将词法元素划分为五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数字类型的常量首先被分类为字符串。SQL语言定义允许使用字符串指定类型名称,并且此机制可用于 PostgreSQL 以使解析器走上正确的路径。例如,查询

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

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

有两个文字常量,类型分别为 textpoint。如果未为字符串文字指定类型,则初始分配占位符类型 unknown,并在后面阶段根据以下描述进行解析。

有四个基本的SQLPostgreSQL 解析器中需要不同的类型转换规则的结构

函数调用

大部分 PostgreSQL 类型系统都建立在一组丰富的函数基础上。函数可以有一个或多个参数。由于 PostgreSQL 允许函数重载,因此仅凭函数名称无法唯一标识要调用的函数;解析器必须根据提供的参数的数据类型选择正确的函数。

运算符

PostgreSQL 允许使用前缀(单参数)运算符以及中缀(双参数)运算符的表达式。与函数一样,运算符也可以重载,因此存在选择正确运算符的相同问题。

值存储

SQL INSERTUPDATE 语句将表达式的结果放入表中。语句中的表达式必须与目标列的类型匹配,并且可能需要转换为目标列的类型。

UNIONCASE 和相关结构

由于来自联合 SELECT 语句的所有查询结果都必须出现在一组列中,因此每个 SELECT 子句的结果类型必须匹配并转换为统一的集合。类似地,CASE 结构的结果表达式必须转换为通用类型,以便整个 CASE 表达式具有已知的输出类型。其他一些结构,例如 ARRAY[] 以及 GREATESTLEAST 函数,同样需要确定几个子表达式的通用类型。

系统目录存储有关哪些转换或强制转换存在于哪些数据类型之间以及如何执行这些转换的信息。用户可以使用 CREATE CAST 命令添加其他强制转换。(这通常是在定义新数据类型时完成的。内置类型之间的强制转换集经过精心设计,最好不要更改。)

解析器提供的额外启发式方法允许改进具有隐式强制转换的类型组之间正确强制转换行为的确定。数据类型被划分为几个基本类型类别,包括 booleannumericstringbitstringdatetimetimespangeometricnetwork 和用户定义。(有关列表,请参见 表 51.65;但请注意,还可以创建自定义类型类别。)在每个类别中,可以有一个或多个首选类型,当有多种可能的类型时,这些类型将被优先选择。通过仔细选择首选类型和可用的隐式强制转换,可以确保以有用的方式解决不明确的表达式(具有多个候选解析解决方案的表达式)。

所有类型转换规则的设计都考虑了以下几个原则

  • 隐式转换永远不应该产生令人惊讶或不可预测的结果。

  • 如果查询不需要隐式类型转换,则解析器或执行器中不应该有额外的开销。也就是说,如果查询格式正确并且类型已经匹配,则查询应该在不花费解析器额外时间的情况下执行,并且在查询中不引入不必要的隐式转换调用。

  • 此外,如果查询通常需要对函数进行隐式转换,并且如果用户随后使用正确的参数类型定义了一个新函数,则解析器应该使用此新函数,并且不再进行隐式转换以使用旧函数。

提交更正

如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步说明,请使用 此表单 报告文档问题。