2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

CREATE OPERATOR

CREATE OPERATOR — 定义新的运算符

概要

CREATE OPERATOR name (
    {FUNCTION|PROCEDURE} = function_name
    [, LEFTARG = left_type ] [, RIGHTARG = right_type ]
    [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
    [, RESTRICT = res_proc ] [, JOIN = join_proc ]
    [, HASHES ] [, MERGES ]
)

描述

CREATE OPERATOR 定义一个新的运算符,name。定义运算符的用户成为其所有者。如果给定模式名称,则运算符将在指定的模式中创建。否则,它将在当前模式中创建。

运算符名称最多为 NAMEDATALEN-1(默认为 63)个字符,这些字符来自以下列表


+ - * / < > = ~ ! @ # % ^ & | ` ?

对您选择的名称有一些限制

  • --/* 不能出现在运算符名称的任何位置,因为它们将被视为注释的开始。

  • 多字符运算符名称不能以 +- 结尾,除非名称还包含至少一个这些字符


    ~ ! @ # % ^ & | ` ?

    例如,@- 是允许的运算符名称,但 *- 不是。此限制允许 PostgreSQL 解析符合 SQL 的命令,而无需在标记之间添加空格。

  • 符号 => 由 SQL 语法保留,因此不能用作运算符名称。

运算符 != 在输入时映射到 <>,因此这两个名称始终等效。

对于二元运算符,必须定义 LEFTARGRIGHTARG。对于前缀运算符,仅应定义 RIGHTARGfunction_name 函数必须先前已使用 CREATE FUNCTION 定义,并且必须定义为接受指定类型的正确数量的参数(一个或两个)。

CREATE OPERATOR 的语法中,关键字 FUNCTIONPROCEDURE 等效,但引用的函数在任何情况下都必须是函数,而不是过程。此处使用关键字 PROCEDURE 是历史性的,并且已弃用。

其他子句指定可选的运算符优化属性。它们的含义在第 36.15 节 中详细说明。

要能够创建运算符,您必须对参数类型和返回类型具有 USAGE 权限,以及对底层函数具有 EXECUTE 权限。如果指定了交换运算符或否定运算符,则您必须拥有这些运算符。

参数

name

要定义的运算符的名称。有关允许的字符,请参见上文。名称可以是模式限定的,例如 CREATE OPERATOR myschema.+ (...)。如果不是,则运算符将在当前模式中创建。如果同一模式中的两个运算符对不同的数据类型进行操作,则它们可以具有相同的名称。这称为重载

function_name

用于实现此运算符的函数。

left_type

运算符左操作数的数据类型(如果有)。此选项将为前缀运算符省略。

right_type

运算符右操作数的数据类型。

com_op

此运算符的交换运算符。

neg_op

此运算符的否定运算符。

res_proc

此运算符的限制选择性估计器函数。

join_proc

此运算符的连接选择性估计器函数。

HASHES

指示此运算符可以支持散列连接。

MERGES

指示此运算符可以支持合并连接。

要在 com_op 或其他可选参数中提供模式限定的运算符名称,请使用 OPERATOR() 语法,例如

COMMUTATOR = OPERATOR(myschema.===) ,

注释

有关更多信息,请参阅第 36.14 节第 36.15 节

当您定义自交换运算符时,您只需执行此操作。当您定义一对交换运算符时,事情会稍微复杂一些:第一个定义的运算符如何引用您尚未定义的另一个运算符?这个问题有三种解决方案

  • 一种方法是在您定义的第一个运算符中省略 COMMUTATOR 子句,然后在第二个运算符的定义中提供一个。由于 PostgreSQL 知道交换运算符成对出现,因此当它看到第二个定义时,它将自动返回并填充第一个定义中缺少的 COMMUTATOR 子句。

  • 另一种更直接的方法是在两个定义中都包含 COMMUTATOR 子句。当 PostgreSQL 处理第一个定义并意识到 COMMUTATOR 引用了一个不存在的运算符时,系统将在系统目录中为该运算符创建一个虚拟条目。此虚拟条目仅对运算符名称、左右操作数类型和所有者具有有效数据,因为这是 PostgreSQL 在此时可以推断出的所有内容。第一个运算符的目录条目将链接到此虚拟条目。稍后,当您定义第二个运算符时,系统将使用第二个定义中的其他信息更新虚拟条目。如果您在填充虚拟运算符之前尝试使用它,您只会收到错误消息。

  • 或者,两个运算符都可以在没有 COMMUTATOR 子句的情况下定义,然后可以使用 ALTER OPERATOR 设置它们的交换运算符链接。只需 ALTER 对中的任意一个即可。

在这三种情况下,您都必须拥有两个运算符才能将它们标记为交换运算符。

否定运算符对可以使用与交换运算符对相同的方法定义。

无法在 CREATE OPERATOR 中指定运算符的词法优先级,因为解析器的优先级行为是硬编码的。有关优先级的详细信息,请参见第 4.1.6 节

已弃用的选项 SORT1SORT2LTCMPGTCMP 以前用于指定与可合并连接运算符关联的排序运算符的名称。这不再必要,因为有关关联运算符的信息是通过查看 B 树运算符族而不是通过这些选项找到的。如果给定其中一个选项,则会忽略它,除非隐式设置 MERGES 为 true。

使用DROP OPERATOR 从数据库中删除用户定义的运算符。使用ALTER OPERATOR 修改数据库中的运算符。

示例

以下命令为数据类型 box 定义一个新的运算符 area-equality。

CREATE OPERATOR === (
    LEFTARG = box,
    RIGHTARG = box,
    FUNCTION = area_equal_function,
    COMMUTATOR = ===,
    NEGATOR = !==,
    RESTRICT = area_restriction_function,
    JOIN = area_join_function,
    HASHES, MERGES
);

兼容性

CREATE OPERATORPostgreSQL 的扩展。SQL 标准中没有用户定义运算符的规定。

提交更正

如果您在文档中看到任何不正确的内容、与您对特定功能的体验不符的内容或需要进一步澄清的内容,请使用此表单 报告文档问题。