SQL COMMAND · 类型与运算符
CREATE OPERATOR
定义一个新的操作符
CREATE类型与运算符引入 10(基线)现存至 20 devel2 次语法变更
- 动词
CREATE- 对象
OPERATOR- 分组
- 类型与运算符
- 引入版本
- 10(基线)
- 状态
- 现存
- 语法变更次数
- 2
- 手册小节数
- 6
版本轨迹
相对 PostgreSQL 17 无变化。
语法铁道图 PostgreSQL 18
沿轨道从左向右阅读,分岔表示选择,绕行表示可选,回环表示重复。方框为参数,点击带下划线的参数可展开子规则。
语法概要
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 标准中没有用户定义操作符的规定。
另见
语法演化
相邻大版本之间的差异,新的在前。版本号链接到对应快照。
PostgreSQL 19← 18语法变化
+ [, LEFTARG = left_type ] , RIGHTARG = right_type− [, LEFTARG = left_type ] [, RIGHTARG = right_type ]正文更新PostgreSQL 14← 13正文更新
正文更新PostgreSQL 12← 11正文更新
正文更新PostgreSQL 11← 10语法变化
+ {FUNCTION|PROCEDURE} = function_name− PROCEDURE = function_name正文更新
同组命令
| 命令 | 动词 | 对象 | 版本变动 | 最近变更 |
|---|---|---|---|---|
CREATE CAST | CREATE | CAST | — | |
| 定义一种新的类型转换 | 现存 | |||
DROP CAST | DROP | CAST | — | |
| 移除一个类型转换 | 现存 | |||
CREATE COLLATION | CREATE | COLLATION | 142 次 | |
| 定义一种新排序规则 | 现存 | |||
ALTER COLLATION | ALTER | COLLATION | 141 次 | |
| 更改排序规则的定义 | 现存 | |||
DROP COLLATION | DROP | COLLATION | — | |
| 删除一个排序规则 | 现存 | |||
CREATE CONVERSION | CREATE | CONVERSION | — | |
| 定义一个新的编码转换 | 现存 | |||
ALTER CONVERSION | ALTER | CONVERSION | 141 次 | |
| 更改一个转换的定义 | 现存 | |||
DROP CONVERSION | DROP | CONVERSION | — | |
| 移除一个转换 | 现存 | |||
CREATE DOMAIN | CREATE | DOMAIN | 142 次 | |
| 定义一个新域 | 现存 | |||
ALTER DOMAIN | ALTER | DOMAIN | 142 次 | |
| 更改一个域的定义 | 现存 | |||
DROP DOMAIN | DROP | DOMAIN | — | |
| 移除一个域 | 现存 | |||
CREATE OPERATOR | CREATE | OPERATOR | 192 次 | |
| 定义一个新的操作符 | 现存 | |||
ALTER OPERATOR | ALTER | OPERATOR | 141 次 | |
| 更改一个操作符的定义 | 现存 | |||
DROP OPERATOR | DROP | OPERATOR | 141 次 | |
| 移除一个操作符 | 现存 | |||
CREATE OPERATOR CLASS | CREATE | OPERATOR CLASS | — | |
| 定义一个新的操作符类 | 现存 | |||
ALTER OPERATOR CLASS | ALTER | OPERATOR CLASS | 141 次 | |
| 更改一个操作符类的定义 | 现存 | |||
DROP OPERATOR CLASS | DROP | OPERATOR CLASS | — | |
| 移除一个操作符类 | 现存 | |||
CREATE OPERATOR FAMILY | CREATE | OPERATOR FAMILY | — | |
| 定义一个新的操作符族 | 现存 | |||
ALTER OPERATOR FAMILY | ALTER | OPERATOR FAMILY | 141 次 | |
| 更改一个操作符族的定义 | 现存 | |||
DROP OPERATOR FAMILY | DROP | OPERATOR FAMILY | — | |
| 移除一个操作符族 | 现存 | |||
CREATE TYPE | CREATE | TYPE | 141 次 | |
| 定义一种新的数据类型 | 现存 | |||
ALTER TYPE | ALTER | TYPE | 142 次 | |
| 更改类型的定义 | 现存 | |||
DROP TYPE | DROP | TYPE | — | |
| 移除一个数据类型 | 现存 | |||