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
。必须使用 CREATE FUNCTION
提前定义 function_name
函数,并且必须定义为接受指定类型(一个或两个)的正确数量的参数。
在 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
定义了一个新的操作符面积相等
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 标准没有关于用户定义操作符的规定。