💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 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) ``` 有两个文本常量,类型分别为`text`和`point`。 如果没有为字符串文本声明类型,该文本先被初始化成一个拥有存储空间的 `unknown`类型,该类型将在后面描述的晚期阶段分析。 在PostgreSQL分析器里, 有四种基本的SQL元素需要独立的类型转换规则: 函数调用 多数PostgreSQL类型系统是建筑在一套丰富的函数上的。 函数调用可以有一个或多个参数。因为PostgreSQL允许函数重载, 所以函数名自身并不唯一地标识将要调用的函数, 分析器必须根据函数提供的参数类型选择正确的函数。 操作符 PostgreSQL允许在表达式上使用前缀或后缀(单目)操作符, 也允许表达式内部使用双目操作符(两个参数)。像函数一样,操作符也可以被重载, 因此操作符的选择也和函数一样取决于参数类型。 值存储 `INSERT`和`UPDATE`语句将表达式结果放入表中。 语句中的表达式类型必须和目标字段的类型一致或者可以转换为一致。 `UNION`, `CASE`和相关构造 因为联合`SELECT`语句中的所有查询结果必须在一列里显示出来, 所以每个`SELECT`子句中的元素类型必须相互匹配并转换成一套统一类型。 类似地,一个`CASE`构造的结果表达式必须转换成统一的类型, 这样`CASE`表达式自身作为整体有一种已知输出类型。 同样的要求也存在于`ARRAY`构造以及`GREATEST`和`LEAST`函数中。 系统表_casts_存储有关哪种数据类型之间存在哪种转换以及如何执行这些转换的信息。 额外的转换可以由用户通过[CREATE CAST](#calibre_link-556)命令增加。 这个通常和定义一种新的数据类型一起完成。内置的类型转换集已经经过仔细的雕琢了, 因此最好不要去更改它们。 分析器中还提供了一个额外的搜索器,允许提高对有隐含转换的类型组之间的适当的转换行为的决断。 数据类型分成了几个基本_类型分类_,包括:`boolean`, `numeric`, `string`, `bitstring`, `datetime`, `timespan`, `geometric`, `network`, user-defined(用户定义)。 (参阅列表[Table 47-52](#calibre_link-1465); 但是要注意的是创建自定义的类型分类也是可能的。) 每种类型都有一种或多种_首选类型_用于解决类型选择的问题。 小心的选择首选类型和可用的隐含转换,就有可能保证有歧义的表达式(那些有多个候选解析方案的) 可以用有效的方式解决。 所有类型转换规则都是建立在下面几个基本原则上的: * 隐含转换决不能有奇怪的或不可预见的输出。 * 如果一个查询不需要隐含的类型转换,分析器或执行器不应该进行更多的额外操作。 这就是说,任何一个类型匹配、格式清晰的查询不应该在分析器里耗费更多的时间, 也不应该向查询中引入任何不必要的隐含类型转换调用。 另外,如果一个查询通常使用某个函数进行隐含类型转换,而用户定义了一个有正确参数的函数, 解释器应该使用新函数取代原先旧函数的隐含操作。