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 就足够了。
In all three cases, you must own both operators in order to mark them as commutators.
取反操作符对可以使用与交换子对相同的方法来定义。
无法在 CREATE OPERATOR 中指定操作符的词法优先级,因为解析器的优先级行为是硬编码的。优先级详情请参阅 Section 4.1.6。
已废弃的选项 SORT1、SORT2、LTCMP 和 GTCMP 曾用于指定与可归并连接操作符相关联的排序操作符的名称。现在已经不再需要这样做,因为有关相关联操作符的信息改为通过查看 B-tree 操作符族来获得。如果给出了这些选项之一,它会被忽略,只是隐式地将 MERGES 设置为真。
使用 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 标准中没有对用户定义操作符的规定。