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