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
的是用是有历史原因的,现在已经被废弃。
其他条款指定了可选的操作符优化属性。它们的含义详见 Section 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.===) ,
Refer to Section 36.14 and Section 36.15 for further information.
当你定义一个自反交换算子时,你只需直接定义它。 当你定义一对交换算子时,情况会稍微复杂一些: 第一个被定义的算子如何引用另一个尚未定义的算子呢?对此问题有三种解决方案:
一种方法是在第一个定义的算子中省略COMMUTATOR
子句,
然后在第二个算子的定义中提供该子句。由于PostgreSQL
知道交换算子是成对出现的,当它看到第二个定义时,会自动回过头去补全
第一个定义中缺失的COMMUTATOR
子句。
另一种更直接的方法是,在两个定义中都包含COMMUTATOR
子句。
当PostgreSQL处理第一个定义并发现COMMUTATOR
指向一个不存在的算子时,系统会在系统目录中为该算子创建一个虚拟条目。
该虚拟条目仅包含算子名称、左右操作数类型和所有者的有效数据,
因为这就是PostgreSQL此时能推断出的全部信息。
第一个算子的目录条目将链接到这个虚拟条目。稍后,当你定义第二个算子时,
系统会用第二个定义中的附加信息更新该虚拟条目。如果你在虚拟条目被填充之前
尝试使用它,就会收到错误信息。
另外,也可以在两个算子定义时都不包含COMMUTATOR
子句,
然后使用ALTER OPERATOR
命令来设置它们的交换子链接。
只需ALTER
其中一个算子即可。
在这三种情况下,你必须拥有这两个算子的所有权,才能将它们标记为交换子。
否定算子对可以使用与换位算子对相同的方法来定义。
无法在CREATE OPERATOR
中指定一个操作符的
词法优先级,因为解析器的优先级行为是硬写在代码中的。详见
Section 4.1.6。
废弃的选项SORT1
、SORT2
、
LTCMP
以及GTCMP
以前被用来指定与支持
归并连接的操作符相关的排序操作符的名称。现在不再需要它们了,因为
相关操作符的信息可以在 B-树的操作符族中找到。如果给出了这些选项
之一,它会被忽略(除非是为了隐式设置MERGES
为真)。
使用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
标准中没有用户定义操作符的规定。