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 标准中没有用户定义运算符的规定。
如果您在文档中发现任何不正确的内容,与您使用特定功能的经验不符或需要进一步澄清的内容,请使用此表格报告文档问题。