PostgreSQL 10.1 手册_部分 II. SQL 语言_第 10 章 类型转换_10.2. 操作符

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
简介: 10.2. 操作符 被一个操作符表达式引用的特定操作符由下列过程决定。注意这个过程会被所涉及的操作符的优先级间接地影响,因为这将决定哪些子表达式被用作哪个操作符的输入。详见第 4.1.6 节。 操作符类型决定 从系统目录pg_operator中选出要考虑的操作符。

10.2. 操作符

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

操作符类型决定

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

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

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

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

    2. 如果一个二元操作符调用的其中一个参数是unknown类型 而另一个是一种域类型,下一次检查会看看是否有一个操作符正好在两边都 接受该域的基类型,如果有就使用它。

  3. 寻找最优匹配。

    1. 抛弃那些输入类型不匹配并且也不能被转换成匹配的候选操作符。 unknown文字被假定为可以为这个目的被转换为 任何东西。如果只剩下一个候选操作符,则使用之,否则继续下一 步。

    2. 如果任何输入参数是一种域类型,对所有后续步骤都把它当做是该 域的基类型。这确保在做有歧义的操作符解析时,域的举止像它们 的基类型。

    3. 遍历所有候选操作符,保留那些在输入类型上的匹配最准确的。如果没有一个操作符能准确匹配,则保留所有候选。如果只剩下一个候选操作符,则使用之,否则继续下一步。

    4. 遍历所有候选操作符,保留那些在最多个需要类型转换的位置上接受首选类型(属于输入数据类型的类型分类)的操作符。如果没有接受首选类型的操作符,则保留所有候选。如果只剩下一个候选操作符,则使用之, 否则继续下一步。

    5. 如果有任何输入参数是unknown类型,检查被剩余候选操作符在那些参数位置上接受的类型分类。 在每一个位置,如果任何候选接受该分类,则选择string分类(这种对字符串的偏爱是合适的, 因为未知类型的文本确实像字符串)。否则,如果所有剩下的候选操作符都接受相同的类型 分类,则选择该分类;否则抛出一个错误(因为在没有更多线索的条件下无法作出正确 的推断)。现在抛弃不接受选定的类型分类的候选操作符。然后,如果任意候选操作符接受那个分类中的首选类型, 则抛弃那些在该参数位置接受非首选类型的候选操作符。如果没有候选操作符能通过这些测试则保留全部候选者。如果只剩下一个候选者,则使用之;否则继续下一步。

    6. 如果既有unknown参数也有已知类型的参数,并且所有已知类型参数具有相同的类型,则假定该unknown参数也是那种类型的,并且检查哪些候选操作符可以在该unknown参数的位置上接受那个类型。如果正好有一个候选者通过了这个测试,则使用之;否则失败。

下面是一些例子。

例 10.1. 阶乘操作符类型决定

在标准目录中只有一个被定义的阶乘操作符(后缀!),它接受一个类型为bigint的参数。在下面这个查询表达式中,扫描器会为该参数分配一个初始类型integer

SELECT 40 ! AS "40 factorial";

                   40 factorial
--------------------------------------------------
 815915283247897734345611269596115894272000000000
(1 row)

因此,解析器在操作数上做了一个类型转换,该查询等价于:

SELECT CAST(40 AS bigint) ! AS "40 factorial";

例 10.2. 字符串连接操作符类型决定

一个类字符串的语法被用来处理字符串类型和处理复杂的扩展类型。未指定类型的字符串与可能的候选操作符匹配。

一个未指定参数的例子:

SELECT text 'abc' || 'def' AS "text and unknown";

 text and unknown
------------------
 abcdef
(1 row)

在这种情况下,解析器查看是否有一个操作符的两个参数都使用text。既然有,那么它假设第二个参数应被解释为text类型。

下面是两个未指定类型的值的连接:

SELECT 'abc' || 'def' AS "unspecified";

 unspecified
-------------
 abcdef
(1 row)

在这种情况下,没有对于使用哪种类型的初始提示,因为在查询中没有指定类型。 因此,解析器查找所有的候选操作符并找到候选者同时接受字符串分类和位串分类的输入。 因为字符串分类在可用时是首选的,该分类会被选中,并且接下来字符串的首选类型(text)会被用作解决未知类型文字的指定类型。


例 10.3. 绝对值与否定操作符类型决定

PostgreSQL操作符目录中有几个对于前缀操作符@的条目, 这些都现实了针对各种数字数据类型的绝对值操作。其中之一用于float8类型,它是在数字分类中的首选类型。 因此,PostgreSQL将在遇到一个unknown输入时使用它:

SELECT @ '-4.5' AS "abs";
 abs
-----
 4.5
(1 row)

在这里,系统在应用所选操作符之前已经隐式地解决了将未知类型文字作为float8类型。 我们可以验证我们使用的是float8而不是别的类型:

SELECT @ '-4.5e500' AS "abs";

ERROR:  "-4.5e500" is out of range for type double precision

另一方面,前缀符~(按位取反)只为整数数据类型定义,而没有为float8定义。因此,如果我们尝试一个与使用~类似的情况,我们会得到:

SELECT ~ '20' AS "negation";

ERROR:  operator is not unique: ~ "unknown"
HINT:  Could not choose a best candidate operator. You might need to add
explicit type casts.

这是因为系统不能决定在几个可能的~符号中应该选择哪一个。我们可以用一个显式造型来帮助它:

SELECT ~ CAST('20' AS int8) AS "negation";

 negation
----------
      -21
(1 row)

例 10.4. 数组包含操作符类型决定

这里是另一个决定带有一个已知和一个未知输入的操作符的例子:

SELECT array[1,2] <@ '{1,2,3}' as "is subset";

 is subset
-----------
 t
(1 row)

PostgreSQL操作符目录有一些条目用于中缀操作符<@,但是仅有的两个可以在左手边接受一个整数数组的是数组包含(anyarray <@ anyarray)和范围包含(anyelement <@anyrange)。因为这些多态伪类型(见第 8.20 节)中没有一个被认为是首选的,解析器不能以此为基础来解决歧义。不过,步骤 3.f告诉它假定位置类型的文字和其他输入的类型相同,即整数数组。现在这两个操作符中只有一个可以匹配,因此数组包含被选择(如果选择范围包含,我们将得到一个错误,因为该字符串没有成为一个范围文字的正确格式)。


例 10.5. 域类型上的自定义操作符

用户有时会尝试声明只适用于一种域类型的操作符。这是可能的, 但是远非它看起来那么有用,因为操作符解析规则被设计为选择 适用于域的基类型的操作符。考虑这个例子:

CREATE DOMAIN mytext AS text CHECK(...);
CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...;
CREATE OPERATOR = (procedure=mytext_eq_text, leftarg=mytext, rightarg=text);
CREATE TABLE mytable (val mytext);

SELECT * FROM mytable WHERE val = 'foo';

这个查询将不会使用自定义操作符。解析器将首先看看是否有一个 mytext = mytext操作符( 步骤 2.a),当然这里没有; 然后它将会考虑该域的基类型text,并且看看是否有一 个text = text操作符( 步骤 2.b),这里也没有;因 此它会把unknown-类型文字解析为text 并使用text = text操作符。 让自定义操作符能被使用的唯一方法是显式地转换改文字:

SELECT * FROM mytable WHERE val = text 'foo';

这样根据准确匹配规则会立即找到 mytext = text操作符。如果 到达最佳匹配规则,它们会积极地排斥域类型上的操作符。如果它 们没有,这样一个操作符将创建太多歧义操作符失败,因为转换规 则总是认为一个域可以和它的基类型相互转换,并且因此该域操作 符在所有与该基类型上的一个类似命名的操作符相同的情况中都被 认为可用。

本文转自PostgreSQL中文社区,原文链接: 10.2. 操作符
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
2月前
|
关系型数据库 Go 网络安全
go语言中PostgreSQL驱动安装
【11月更文挑战第2天】
131 5
|
3月前
|
SQL Oracle 关系型数据库
SQL语言的主要标准及其应用技巧
SQL(Structured Query Language)是数据库领域的标准语言,广泛应用于各种数据库管理系统(DBMS)中,如MySQL、Oracle、SQL Server等
109 9
|
3月前
|
SQL 关系型数据库 MySQL
Go语言项目高效对接SQL数据库:实践技巧与方法
在Go语言项目中,与SQL数据库进行对接是一项基础且重要的任务
115 11
|
4月前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
5月前
|
SQL 存储 关系型数据库
PostgreSQL核心之SQL基础学习
PostgreSQL核心之SQL基础学习
69 3
|
5月前
|
SQL 关系型数据库 MySQL
|
5月前
|
SQL 存储 大数据
SQL 语言发展史简直太震撼啦!从诞生到现代数据处理,见证一场奇妙的演变之旅,快来感受!
【8月更文挑战第31天】SQL(结构化查询语言)自20世纪70年代由IBM研究员E.F. Codd提出以来,已成为现代数据处理不可或缺的一部分。它最初简化了层次和网状模型中复杂的存储与检索问题,通过基本的SELECT、FROM和WHERE关键字实现了数据查询。80年代,SQL在商业数据库中广泛应用,引入了GROUP BY、HAVING和ORDER BY等功能,增强了数据分析能力。90年代,互联网和企业信息化推动了SQL的进一步优化与扩展,支持分布式数据库和数据仓库等技术。
101 0
|
5月前
|
SQL 存储 NoSQL
从SQL到NoSQL:理解不同数据库类型的选择与应用——深入比较数据模型、扩展性、查询语言、一致性和适用场景,为数据存储提供全面决策指南
【8月更文挑战第31天】在信息技术飞速发展的今天,数据库的选择至关重要。传统的SQL数据库因其稳定的事务性和强大的查询能力被广泛应用,而NoSQL数据库则凭借其灵活性和水平扩展性受到关注。本文对比了两种数据库类型的特点,帮助开发者根据应用场景做出合理选择。SQL数据库遵循关系模型,适合处理结构化数据和复杂查询;NoSQL数据库支持多种数据模型,适用于非结构化或半结构化数据。SQL数据库在一致性方面表现优异,但扩展性较差;NoSQL数据库则设计之初便考虑了水平扩展性。SQL使用成熟的SQL语言,NoSQL的查询语言更为灵活。
118 0
|
5月前
|
SQL 数据可视化 数据挖掘
SQL 在数据分析中简直太牛啦!从数据提取到可视化,带你领略强大数据库语言的神奇魅力!
【8月更文挑战第31天】在数据驱动时代,SQL(Structured Query Language)作为强大的数据库查询语言,在数据分析中扮演着关键角色。它不仅能够高效准确地提取所需数据,还能通过丰富的函数和操作符对数据进行清洗与转换,确保其适用于进一步分析。借助 SQL 的聚合、分组及排序功能,用户可以从多角度深入分析数据,为企业决策提供有力支持。尽管 SQL 本身不支持数据可视化,但其查询结果可轻松导出至 Excel、Python、R 等工具中进行可视化处理,帮助用户更直观地理解数据。掌握 SQL 可显著提升数据分析效率,助力挖掘数据价值。
195 0
|
5月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
628 0