CREATE OPERATOR — 定义一个新的运算符
CREATE OPERATORname( {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 语法保留,因此不能用作运算符名称。
运算符 != 在输入时映射到 <>,因此这两个名称始终等效。
对于二元运算符,必须定义 LEFTARG 和 RIGHTARG。对于前缀运算符,仅应定义 RIGHTARG。function_name 函数必须先前使用 CREATE FUNCTION 定义,并且必须定义为接受指定类型的正确数量的参数(一个或两个)。
在 CREATE OPERATOR 的语法中,关键字 FUNCTION 和 PROCEDURE 是等效的,但引用的函数在任何情况下都必须是一个函数,而不是一个过程。 此处使用关键字 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 节。
旧选项 SORT1、SORT2、LTCMP 和 GTCMP 以前用于指定与可合并连接的运算符关联的排序运算符的名称。 这不再是必要的,因为有关关联运算符的信息是通过查看 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 OPERATOR 是 PostgreSQL 的扩展。 SQL 标准中没有用户定义运算符的规定。
如果您在文档中发现任何不正确的内容,与您使用特定功能的经验不符或需要进一步澄清的内容,请使用此表格报告文档问题。