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.===) ,
更多信息请参见Section 36.14和 Section 36.15。
当你定义一个自交换操作符时,直接定义即可。定义一对互为交换子的操作 符时则稍微复杂一些:先定义的那个操作符如何引用另一个尚未定义的操作 符呢?这个问题有三种解决办法:
一种方法是在先定义的第一个操作符中省略 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 标准中没有用户定义操作符的规定。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。