SQL是一种强类型语言。也就是说,每个数据项都有一个关联的数据类型,该数据类型决定了其行为和允许的使用方式。PostgreSQL 拥有一个可扩展的类型系统,该系统比其他SQL实现更为通用和灵活。因此,PostgreSQL 中的大多数类型转换行为都遵循通用规则,而不是临时的特殊处理。这使得即使使用用户定义的类型,也可以在混合类型表达式中使用。
PostgreSQL 的词法分析器/解析器将词法元素分为五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数字类型的常量首先被归类为字符串。PostgreSQL 的SQL语言定义允许使用字符串指定类型名称,并且可以在 PostgreSQL 中使用此机制来引导解析器进入正确的路径。例如,查询
SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; label | value --------+------- Origin | (0,0) (1 row)
有两个字面量常量,类型分别为 text
和 point
。如果字符串字面量未指定类型,则最初会分配占位符类型 unknown
,然后在后续阶段进行解析,如下所述。
有四个基本SQLPostgreSQL 解析器中需要不同类型转换规则的构造:
PostgreSQL 的类型系统很大程度上围绕着一套丰富的函数构建。函数可以有一个或多个参数。由于 PostgreSQL 允许函数重载,仅函数名称不能唯一标识要调用的函数;解析器必须根据所提供参数的数据类型来选择正确的函数。
PostgreSQL 允许使用前缀(单参数)运算符以及中缀(双参数)运算符的表达式。与函数一样,运算符也可以重载,因此存在选择正确运算符的相同问题。
SQL INSERT
和 UPDATE
语句将表达式的结果存入表中。语句中的表达式必须与目标列的类型匹配,并可能转换为目标列的类型。
UNION
、CASE
及相关构造由于联合 SELECT
语句的所有查询结果都必须出现在同一组列中,因此每个 SELECT
子句的结果类型必须匹配并转换为统一的集合。类似地,CASE
构造的结果表达式必须转换为公共类型,以便 CASE
表达式整体具有已知的输出类型。其他一些构造,如 ARRAY[]
以及 GREATEST
和 LEAST
函数,同样需要确定多个子表达式的公共类型。
系统目录存储有关哪些转换(或称 cast)存在于哪些数据类型之间以及如何执行这些转换的信息。用户可以使用 CREATE CAST 命令添加额外的 cast。(这通常与定义新数据类型结合进行。内置类型之间的 cast 集经过精心设计,最好不要更改。)
解析器提供了一个额外的启发式方法,可以改进对具有隐式 cast 的类型组之间正确 cast 行为的确定。数据类型被划分为几个基本 类型类别,包括 boolean
、numeric
、string
、bitstring
、datetime
、timespan
、geometric
、network
和用户定义的。(有关列表,请参阅 Table 52.65;但请注意,也可以创建自定义类型类别。)在每个类别中,可以有一个或多个 首选类型,在有多种可能类型可供选择时会偏向使用这些首选类型。通过仔细选择首选类型和可用的隐式 cast,可以确保歧义表达式(具有多个候选解析解决方案的表达式)能够以有用的方式得到解决。
所有类型转换规则的设计都考虑了几个原则:
隐式转换绝不应产生令人惊讶或不可预测的结果。
如果查询不需要隐式类型转换,则解析器或执行器不应有任何额外的开销。也就是说,如果查询格式正确且类型已经匹配,则查询应执行,而不会在解析器中花费额外时间,也不会在查询中引入不必要的隐式转换调用。
此外,如果一个查询通常需要为函数进行隐式转换,然后用户定义了一个具有正确参数类型的新函数,则解析器应使用这个新函数,而不再进行隐式转换来使用旧函数。
如果您在文档中发现任何不正确之处,与您对特定功能的实际体验不符,或需要进一步的说明,请使用 此表单 报告文档问题。