pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
CREATE OPERATOR — 定义一个新的操作符
CREATE OPERATORname( PROCEDURE =func_name[, LEFTARG =lefttype] [, RIGHTARG =righttype] [, COMMUTATOR =com_op] [, NEGATOR =neg_op] [, RESTRICT =res_proc] [, JOIN =join_proc] [, HASHES ] [, SORT1 =left_sort_op] [, SORT2 =right_sort_op] )
name要定义的操作符。允许的字符见下文。
func_name用于实现该操作符的函数。
lefttype操作符左参数的类型(如果有的话)。对于左一元操作符,这个选项要省略。
righttype操作符右参数的类型(如果有的话)。对于右一元操作符,这个选项要省略。
com_op该操作符的交换子。
neg_op该操作符的求反器。
res_proc该操作符的限制选择度估计函数。
join_proc该操作符的连接选择度估算函数。
表示该操作符可以支持哈希连接。
left_sort_op如果此操作符可以支持归并连接,则为对该操作符左侧数据类型排序的操作符。
right_sort_op如果此操作符可以支持归并连接,则为对该操作符右侧数据类型排序的操作符。
CREATE操作符创建成功时返回的消息。
CREATE OPERATOR 定义一个新的操作符 name。 定义操作符的用户将成为其所有者。
操作符的 name 是一个最多由 NAMEDATALEN-1(默认 31)个字符组成的序列,这些字符取自下面的列表:
+ - * / < > = ~ ! @ # % ^ & | ` ? $
对名称的选择有若干限制:
$ 不能定义为单字符操作符,尽管它可以是多字符操作符名称的一部分。
--和/*不能出现在操作符名称的 任何位置,因为它们会被视为注释的开始。
多字符操作符名称不能以+或- 结尾,除非该名称中还至少包含下列字符之一:
~ ! @ # % ^ & | ` ? $
例如,@- 是允许的操作符名称,而 *- 不是。这一限制使 PostgreSQL 能够解析符合 SQL 的查询而无需在记号之间加空格。
使用非 SQL 标准的操作符名称时,你通常需要用空格分隔相邻的操作符以避免歧义。例如,如果你定义了一个名为 @ 的左一元操作符,你就不能写 X*@Y;你必须写 X* @Y,以确保 PostgreSQL 把它读成两个操作符名而不是一个。
输入!=时会被映射为<>, 因此这两个名称始终等效。
LEFTARG 和 RIGHTARG 至少必须定义一个。对于二元操作符,两者都应定义。对于右一元操作符,只应定义 LEFTARG;对于左一元操作符,只应定义 RIGHTARG。
过程 func_name 必须此前已用 CREATE FUNCTION 定义,并且必须定义为接受正确数量的参数(一个或两个),类型为所指明的类型。
如果存在交换子操作符,就应当把它指出来,这样 PostgreSQL 就可以在需要时反转操作数的顺序。例如,面积小于操作符 <<< 大概会有一个交换子操作符——面积大于 >>>。于是,查询优化器就可以自由地把:
box '((0,0), (1,1))' >>> MYBOXES.description
转换为
MYBOXES.description <<< box '((0,0), (1,1))'
这使执行代码总能使用后一种表示,并在一定程度上简化了查询优化器。
类似地,如果存在求反器操作符,也应当把它指出来。假设存在一个操作符——面积等于 ===,同时也存在面积不等于 !==。求反器链接使查询优化器可以把
NOT MYBOXES.description === box '((0,0), (1,1))'
化简为
MYBOXES.description !== box '((0,0), (1,1))'
如果给出了交换子操作符的名称, PostgreSQL 会在目录中搜索它。如果找到了,而它自己还没有交换子,那么该交换子的条目就会被更新,把新创建的操作符作为其交换子。这对求反器同样适用。这样做的目的是允许定义两个互为交换子或互为求反器的操作符:第一个操作符应当不带交换子或求反器(视情况而定)先定义;定义第二个操作符时,把第一个指名为交换子或求反器,第一个就会作为副作用被更新。(从 PostgreSQL 6.5 起,让两个操作符互相引用也可以。)
HASHES、SORT1 和 SORT2 选项的存在是为了支持查询优化器执行连接。 PostgreSQL 总是能通过迭代替换 [WONG76] 求一个连接的值(即处理一个由返回 boolean 的操作符分隔两个元组变量的子句)。此外, PostgreSQL 还可以使用类似 [SHAP86] 的哈希连接算法;但它必须知道这一策略是否适用。当前的哈希连接算法只对表示相等测试的操作符是正确的;而且,数据类型的相等必须意味着类型表示的按位相等。(例如,一个包含对相等测试无关紧要的未用位的数据类型就不能做哈希连接。) HASHES 标志向查询优化器指明,此操作符可以安全地用于哈希连接。
类似地,两个排序操作符向查询优化器指明归并排序是否是可用的连接策略,以及应该用哪些操作符来排序两个操作数类。只应为相等操作符提供排序操作符,而且它们应分别指向左右两侧数据类型的小于操作符。
如果将来发现其他连接策略切实可行, PostgreSQL 会修改优化器和运行时系统来使用它们,并在定义操作符时要求额外的说明。幸运的是,研究界并不经常发明新的连接策略,而用户自定义连接策略带来的额外通用性被认为不值得为之增加复杂度。
RESTRICT 和 JOIN 选项帮助查询优化器估算结果大小。如果限定条件中出现了形如:
MYBOXES.description <<< box '((0,0), (1,1))'
的子句,那么 PostgreSQL 可能必须估算 MYBOXES 中满足该子句的实例比例。函数 res_proc 必须是一个已注册的函数(即已用 CREATE FUNCTION 定义),它接受正确数据类型的参数并返回一个浮点数。查询优化器只需调用该函数,传入参数 ((0,0), (1,1)),再把结果乘以关系的大小,就得到预期的实例数。
类似地,当操作符的两个操作数都含有实例变量时,查询优化器必须估算所得连接的大小。函数 join_proc 会返回另一个浮点数,把它乘以所涉及两个表的基数,就得到预期的结果大小。
函数
my_procedure_1 (MYBOXES.description, box '((0,0), (1,1))')
与操作符
MYBOXES.description === box '((0,0), (1,1))'
的区别在于:PostgreSQL 会尝试优化操作符,并可在涉及操作符时决定使用索引来限制搜索空间。但系统不会尝试优化函数,函数是靠蛮力执行的。此外,函数可以有任意数量的参数,而操作符只能有一个或两个。
更多信息参见 PostgreSQL 用户指南 中关于操作符的章节。参见 DROP OPERATOR 以从数据库中删除用户定义的操作符。
下面的命令为 BOX 数据类型定义一个新的操作符——面积相等:
CREATE OPERATOR === ( LEFTARG = box, RIGHTARG = box, PROCEDURE = area_equal_procedure, COMMUTATOR = ===, NEGATOR = !==, RESTRICT = area_restriction_procedure, JOIN = area_join_procedure, HASHES, SORT1 = <<<, SORT2 = <<< );
CREATE OPERATOR 是 PostgreSQL 的扩展。在 SQL92 中没有 CREATE OPERATOR 语句。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。