CREATE OPERATOR

Name

CREATE OPERATOR  --  定义一个新的操作符

Synopsis

CREATE OPERATOR name ( 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

要定义的操作符。可用的字符见下文。 其名字可以用大纲修饰, 比如 CREATE OPERATOR myschema.+ (...)

func_name

用于实现该操作符的函数。

lefttype

如果存在的话,操作符左手边的参数类型. 如果是左目操作符,这个参数可以省略。

righttype

如果存在的话,操作符右手边的参数类型. 如果是右目操作符,这个参数可以省略。

com_op

该操作符对应的交换(commutator)操作符。

neg_op

对应的负操作符。

res_proc

此操作符约束选择性计算函数。

join_proc

此操作符连接选择性计算函数。

HASHES

表明此操作符支持哈希(散列)连接。

left_sort_op

如果此操作符支持融合连接(join),此操作符的左手边数据的排序操作符。

right_sort_op

如果此操作符支持融合连接(join),此操作符的右手边数据的排序操作符。

输出

CREATE

成功创建操作符后的返回信息.

描述

CREATE OPERATOR 定义一个新的操作符, name. 定义该操作符的用户成为其所有者.

如果给出了一个大纲名,那么该操作符将在指定的大纲中创建. 否则它会在当前大纲中创建(在搜索路径前面的那个; 参阅 CURRENT_SCHEMA()).

在同一个大纲里的两个操作伏可以有相同的名字,只要它们有 不一样的数据类型.这就叫重载.协同将以实际 输入的数据类型为基础,在出险歧义的时候尽力选取所需要的操作符.

操作符 name 是一个最多NAMEDATALEN-1 长的(缺省为 63 个)下列字符组成的字串:

+ - * / < > = ~ ! @ # % ^ & | ` ? $
   

你选择名字的时候有几个限制:

注意: 当使用非 SQL-标准操作符名时, 你通常将需要用空白把联接的操作符分离开以避免含混. 例如,如果你定义了一个左目操作符,名为 "@",你不能写 X*@Y;你必须写成 X* @Y 以保证 PostgreSQL 把它读做两个操作符而不是一个.

操作符 "!=" 在输入时映射成 "<>", 因此这两个名称总是相等的.

至少需要定义一个LEFTARGRIGHTARG. 对于双目操作符来说,两者都需要定义. 对右目操作符来说,只需要定义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 将在表中查找它.如果找到, 而且其本身没有一个交换符,那么交换符表将被更新,以当前(最 新)创建的操作符作为它的交换符.这一点一样适用于负号操作符. 这就允许定义两个互为交换符或负号符的操作符. 第一个操作符应该定义为没有交换符 或负号符(as appropriate). 当定义第二个操作符时,将第一个符号作为交换符或负号符. 第一个将因上述的副作用一样被更新(而获得交换符 或负号符).(对于PostgreSQL 6.5, 把两个操作符指向对方同样也行。)

HASHESSORT1SORT2LTCMP, 和GTCMP 选项将为查询优化器进行连接查询时提供支持. PostgreSQL 能够总是用迭代替换法来计算一个连接( 也就是说,处理这样的子句,该子句有两个元组变量, 这两个变量被一个操作符分开,这个操作符返回一个boolean量) . 另外, PostgreSQL 可以延着 实现一个散列-连接算法(hash-join algorithm); 但是,我们必须知道这个策略是否可行.目前的散列-连接算法只是对代表相等 测试的操作符有效;而且,数据类型的相等必须意味着类型的表现是按位相等的。 (例如,一个包含未用的位的数据类型,这些位对相等测试没有 影响,但却不能用于哈希连接。)HASHES标记告诉优化器, 对这个操作符可以安全地使用哈希连接。

类似的,MERGES标记告诉查询优化器一个融合-排序 (merge-sort)对这种操作符而言是否是一个可用的连接策略。 融合连接要求两种输入数据类型有一致的顺序,并且融合连接操作符 在排序是的行为类似等于。比如,我们可以在一个整数和一个浮点数 之间按照等于来融合连接,方法是把两个输入按照一般的数字顺序排序。 执行一个融合连接要求系统能够标识和融合连接相等操作符:用于左输入 数据类型的小于比较,用于右输入数据类型的小于比较,在两种数据类型 之间的小于比较和两种数据类型之间的大于比较。我们可以用名字来声明 这些东西,分别就像 SORT1SORT2LTCMP,和 GTCMP 选项一样。 如果在声明 MERGES 的时候省略了任意这些选项,那么 系统将分别填充缺省的 <<<>。 同样,如果任何这四个操作符选项出现,也将假设 MERGES 是隐含的。

如果发现有其他联合策略可用, PostgreSQL 将更改优化器和运行时系统以利用这些策略, 并且在定义一个操作符时将需要更多的声明.幸运的是,研究 团队不经常发明新的联合策略, 而且增加用户定义联合策略的方法看来与其实现的复杂性相比是不值得的。

RESTRICTJOIN选项帮助优化器计算结果的尺寸大小.如果像下面的语句:

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 从数据库中删除用户定义操作符.

要在 com_op 或者 其它可选的参数种给出一个模式修饰的操作符名, 使用 OPERATOR() 语法,比如

   COMMUTATOR = OPERATOR(myschema.===) ,

用法

下面命令定义一个新操作符,面积相等,用于 BOX 数据类型.

CREATE OPERATOR === (
   LEFTARG = box,
   RIGHTARG = box,
   PROCEDURE = area_equal_procedure,
   COMMUTATOR = ===,
   NEGATOR = !==,
   RESTRICT = area_restriction_procedure,
   JOIN = area_join_procedure,
   HASHES,
   SORT1 = <<<,
   SORT2 = <<<
);
  

兼容性

SQL92

CREATE OPERATORPostgreSQL 扩展. 在SQL92中没有 CREATE OPERATOR 语句.