PostgreSQL SQL 语言:类型转换

本文档为PostgreSQL 9.6.0文档,本转载已得到原译者彭煜玮授权。1. 概述SQL是一种强类型语言。也就是说,每个数据项都有一个相关的数据类型,数据类型决定其行为和允许的用法。 PostgreSQL有一个可扩展的类型系统,该系统比其它SQL实现更具通用和灵活。因而,PostgreSQL中大多数类型转换行为是由通用规则来管理的,而不是ad h...
摘要由CSDN通过智能技术生成

本文档为PostgreSQL 9.6.0文档,本转载已得到原译者彭煜玮授权。

1. 概述

SQL是一种强类型语言。也就是说,每个数据项都有一个相关的数据类型,数据类型决定其行为和允许的用法。 PostgreSQL有一个可扩展的类型系统,该系统比其它SQL实现更具通用和灵活。因而,PostgreSQL中大多数类型转换行为是由通用规则来管理的,而不是ad hoc启发式规则。这种做法允许使用混合类型表达式,即便是其中包含用户定义的类型。

PostgreSQL扫描器/解析器只将词法元素分解成五个基本种类:整数、非整数数字、字符串、标识符、关键字。大多数非数字类型常量首先被分类为字符串。SQL语言定义允许将类型名指定为字符串, 这个机制被PostgreSQL用于保证解析器沿着正确的方向运行。例如,查询:

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

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

有两个文字常量,类型分别为text和point。如果一个串文字没有指定类型,初始将被分配一个占位符类型unknown,该类型将在下文描述的后续阶段被解析。

在SQL解析器里,有四种基本的SQL结构要求独立的类型转换规则:

函数调用

PostgreSQL类型系统的大部分建立在一套丰富的函数上。 函数可以有一个或多个参数。由于PostgreSQL允许函数重载, 所以函数名自身并不唯一地标识将要被调用的函数,解析器必须根据提供的参数类型选择正确的函数。

操作符

PostgreSQL允许带有前缀和后缀一元(单目)操作符的表达式,也允许二元(两个参数)操作符。像函数一样,操作符也可以被重载,因此操作符的选择也有同样的问题。

值存储

SQL INSERT和UPDATE语句将表达式的结果放 入表中。语句中的表达式类型必须和目标列的类型一致(或者可以被转换为一致)。

UNION、CASE和相关结构

因为来自一个联合的SELECT语句中的所有查询结果必须在一个列集中显示,所以每个 SELECT子句的结果类型必须能相互匹配并被转换成一个统一的集合。类似地,一个 CASE结构的结果表达式必须被转换成一种公共的类型,这样CASE表达式作为整体才 有一种已知的输出类型。同样的要求也存在于ARRAY结构以及GREATEST和LEAST函数中。

系统目录存储有关哪些数据类型之间存在哪种转换(或造型)以及如何执行这些转换的相关信息。额外的造型可以由用户通过CREATE CAST命令增加(这个通常和定义一种新的数据类型一起完成。 内建的类型转换集已经经过了仔细的雕琢,最好不要去更改它们)。

解析器提供了一种额外的启发式规则,它允许在具有隐式造型的类型组中恰当造型行为的改进决定。 数据类型被分为几个基本的类型分类,包括boolean、numeric、string、bitstring、datetime、timespan、geometric、network和用户自定义(可参阅Table 50-56中的列表;但需要注意的是 也可以创建自定义的类型分类)。在每个分类中,可以有一个或多个首选类型, 当存在类型选择时,这个是更好的选择。利用精心选择的首选类型和可用的隐式造型, 我们可以确保有歧义的表达式(那些有多个候选解析方案的表达式)可以用一种有用的方式来处理。

所有类型转换规则都是建立在下面几个基本原则上的:

  • 隐式转换决不能有意外的或不可预见的输出。
  • 如果一个查询不需要隐式类型转换,解析器或执行器不应该有额外的开销。也就是说,如果一个查询是结构良好的并且类型已经匹配,则查询不应该在解析器里耗费额外的时间执行,也不会在查询中引入不必要的隐式类型转换调用。
  • 另外,如果一个查询通常要求为某个函数进行隐式类型转换,而用户定义了一个有正确参数类型的新函数, 解析器应该使用新函数并不再做隐式转换来使用旧函数。

2. 操作符

被一个操作符表达式引用的特定操作符由下列过程决定。注意这个过程会被所涉及的操作符的优先级间接地影响,因为这将决定哪些子表达式被用作哪个操作符的输入。详见Section 4.1.6。

操作符类型决定

1.从系统目录pg_operator中选出要考虑的操作符。如果使用了一个不带模式限定的操作符 名(常见的情况),那么操作符被认为是那些在当前搜索路径中可见并有匹配的名字和参数个数的操作符。如果给出一个被限定的操作符名,那么只考虑指定模式中的操作符。

a.如果搜索路径找到了多个有相同参数类型的操作符,那么只考虑最早出现在路径中的那一个。 但是不同参数类型的操作符将被平等看待,而不管它们在路径中的位置如何。

2.查找一个正好接受输入参数类型的操作符。如果找到一个(在一组被考虑的操作符中,可能只存在一个正好匹配的),则使用之。

a.如果一个二元操作符调用中的一个参数是unknown类型,则在本次检查中假设它与另一个参数类型相同。 对于涉及两个unknown输入的调用或者带有一个unknown输入的一元操作符,在这一步将永远找不到一个匹配。

b.如果一个二元操作符调用的其中一个参

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值