10.1. Overview

SQL 是一种强类型语言。即,每个数据项都有一个关联的数据类型,该数据类型确定其行为和允许的使用情况。 PostgreSQL 有一个可扩展的类型系统,它比其他 SQL 实现更通用,更灵活。因此,PostgreSQL 中的大多数类型转换行为都是由通用规则而不是临时启发式规则控制的。这样即使在用户定义类型的情况下,也可以使用混合类型表达式。

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

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

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

有两个 Literals 常量,类型为textpoint。如果未为字符串 Literals 指定类型,则将首先分配占位符类型unknown,以在稍后的步骤中进行解析,如下所述。

PostgreSQL 解析器中有四种基本的 SQL 构造需要不同的类型转换规则:

  • Function calls

    • PostgreSQL 类型系统的大部分都是围绕一组丰富的功能构建的。函数可以具有一个或多个参数。由于 PostgreSQL 允许函数重载,因此仅函数名并不能唯一地标识要调用的函数。解析器必须根据提供的参数的数据类型选择正确的函数。
  • Operators

    • PostgreSQL 允许使用带有前缀和后缀的一元(一个参数)运算符以及二进制(两个参数)运算符的表达式。像函数一样,运算符可能会过载,因此存在选择正确运算符的相同问题。
  • Value Storage

    • SQL INSERTUPDATE语句将表达式的结果放入表中。语句中的表达式必须与目标列的类型匹配,或者可能转换为目标列的类型。
  • UNIONCASE和相关构造

    • 由于来自联合的SELECT语句的所有查询结果必须出现在一组列中,因此每个SELECT子句的结果类型必须匹配并转换为统一的集合。类似地,CASE构造的结果表达式必须转换为通用类型,以便CASE表达式作为一个整体具有已知的输出类型。 ARRAY构造以及GREATESTLEAST函数也是如此。

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

解析器提供的其他试探法可以改进对具有隐式强制类型转换的类型组之间正确强制转换行为的确定。数据类型分为几种基本的类型类别,包括booleannumericstringbitstringdatetimetimespangeometricnetwork和用户定义的。 (有关列表,请参见Table 52.63;但是请注意,也可以创建自定义类型类别。)在每个类别中可以有一个或多个* preferred types *,当可以选择可能的类型时,它们是首选的。通过仔细选择首选类型和可用的隐式强制转换,可以确保可以用一种有用的方法来解决歧义表达式(具有多个候选解析解的表达式)。

所有类型转换规则在设计时都牢记以下几个原则:

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

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

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