news 2026/4/3 6:42:30

postgreSQL 中的自定义操作符

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
postgreSQL 中的自定义操作符

postgre是想对标Oracle的。所以在定义操作符上也对标了

操作符

看下面这条语句:

/* by yours.tools - online tools website : yours.tools/zh/imagetopng.html */ SELECT 3 OPERATOR(pg_catalog.+) 4 sum; -- 1️⃣

这条 SQL 看起来很怪,但它在 PostgreSQL 里是完全合法的,并且会正常返回 7。

实际上,它就是我们熟悉的

/* by yours.tools - online tools website : yours.tools/zh/imagetopng.html */ SELECT 3 + 4; -- 2️⃣

1️⃣ 那行代码其实就是在玩 PostgreSQL 的一个“冷门但正式支持”的语法:显式使用 OPERATOR() 语法来调用操作符。
2️⃣这条语句执行时,PostgreSQL 内部会把+解析成一个真正的操作符对象,它的全名是pg_catalog.+(在系统目录 pg_operator 里能查到)。而1️⃣就是把平时隐藏的内部机制直接写出来了,只不过是用最“啰嗦、最底层”的方式调用加法操作符,你可以把 OPERATOR(schema.操作符名) 理解成“强制指定用哪个操作符来操作左右两边”。

实际上,1️⃣还能写得更短:

SELECT 3 OPERATOR(+) 4; -- 可以省略 schema,默认 pg_catalog

自定义操作符

PostgreSQL 目前具有主流数据库里最强的自定义操作符:

  • 完全自定义新操作符

  • 重载已有操作符(如重定义 +)

  • 操作符可绑定索引(B-Tree, GiST, GIN…)

  • 操作符可以有 commutator / negator

  • 操作符直接影响优化器、索引选择

在这一方面,连Oracle也难以匹敌。

1. 语法

CREATE OPERATOR operator_name ( { LEFTARG = left_type -- 左操作数类型(单目操作符可省略) | RIGHTARG = right_type -- 右操作数类型(单目操作符可省略) | BOTHARG = both_type } -- 左右类型相同时代替上面两个 [, PROCEDURE = function_name ] -- 必须:真正执行的函数 [, COMMUTATOR = com_op ] -- 可选:交换律操作符(如 + 和 + 本身) [, NEGATOR = neg_op ] -- 可选:取反操作符(如 = 的取反是 <>) [, RESTRICT = res_proc ] -- 可选:用于优化器选择性估计 [, JOIN = join_proc ] -- 可选:用于优化器连接估计 [, HASHES ] -- 可选:支持 HASH JOIN 和 hash 聚合 [, MERGES ] -- 可选:支持 MERGE JOIN );

2. 最简单的例子:创建 !!(双感叹号)前缀操作符,表示“转成大写”

-- 第1步:先创建一个底层函数 CREATE OR REPLACE FUNCTION immutable_upper(text) RETURNS text AS $$ SELECT upper($1); $$ LANGUAGE sql IMMUTABLE STRICT; -- 第2步:创建前缀操作符(右操作数,没有左操作数) CREATE OPERATOR !! ( RIGHTARG = text, -- 只有右操作数,在右边 → 前缀操作符 PROCEDURE = immutable_upper -- 调用上面那个函数 ); -- 第3步:试用 SELECT !! 'hello'; -- 返回 HELLO SELECT !! column_name FROM users;

不知道你有没有疑惑:这不还是用PG定义的函数吗?不还是PG本来就支持的东西吗?
没错。操作符只是一种“糖”,让你更方便、简洁的使用本来就有的能力。

3. 中级例子:创建自定义的 === 操作符,表示“可空相等”(带索引支持)

先创建函数

CREATE OR REPLACE FUNCTION geometry_strict_equal(anyelement, anyelement) RETURNS boolean AS $$ SELECT $1 IS NOT DISTINCT FROM $2; $$ LANGUAGE sql IMMUTABLE;

IS NOT DISTINCT FROM是什么?这是 PostgreSQL 特有的“空值安全的相等比较”

  • 当 a = b → true
  • 当 a 和 b 都是 NULL → true (普通的=,NULL = NULL → null (不为 true))
  • 其他情况 → false
  • 普通的=,NULL = NULL时 → null (不为 true)。

mysql中这个操作叫<=>“太空船运算符”,但是PG已经存在这个操作符了,主要在pg_trgm扩展中计算相似度,所以这里我们定义成===

IMMUTABLE 表示同样输入,永远返回同样的输出;可以用于索引;可以内联与优化。

anyelement 表示任意类型的参数,但是两个参数类型要一样。

接下来创建操作符

CREATE OPERATOR === ( LEFTARG = anyelement, RIGHTARG = anyelement, PROCEDURE = geometry_strict_equal, COMMUTATOR = ===, -- 自己和自己交换律 NEGATOR = !==, -- 稍后会创建它的取反 HASHES, -- 支持 hash join / hash agg MERGES -- 支持 merge join ); -- 创建取反操作符 !== CREATE OPERATOR !== ( LEFTARG = anyelement, RIGHTARG = anyelement, PROCEDURE = geometry_strict_equal, NEGATOR = === -- 互相指向对方 );

看一下例子:

比较的两个对象必须是同类型的,不然会报错,所以要明确指出null是什么类型。
如果是用在表查询语句中,因为表结构和字段类型是确定的,所以不用指出来。

4. 查询操作符

SELECT n.nspname AS schema, o.oprname AS operator, -- 操作符名称 format_type(o.oprleft, NULL) AS left_type, format_type(o.oprright, NULL) AS right_type, p.proname AS function_name -- 函数名称 FROM pg_operator o JOIN pg_namespace n ON n.oid = o.oprnamespace JOIN pg_proc p ON p.oid = o.oprcode WHERE n.nspname NOT IN ('pg_catalog') and o.oprname = '!!'; -- 可以去掉过滤看看

5. 删除操作符

DROP OPERATOR IF EXISTS !! (NONE, text); -- 先删除操作符,必须传左右两个参数,没有的写NONE DROP FUNCTION public.immutable_upper(text); -- 函数如果还要用可以不删

小练习

ilike写一个操作符。我定义好函数了:

CREATE OR REPLACE FUNCTION chinese_ilike(text, text) RETURNS boolean AS $$ SELECT $1 ILIKE $2; $$ LANGUAGE sql IMMUTABLE STRICT;
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/1 15:39:43

codeforces Round 1070(Div. 2)

D https://codeforces.com/contest/2176/problem/D 哎哎&#xff0c;经典的赛后过题。分享D的另一种不同的思路。 Hint1 首先可以观察到除了单独一条边成斐波那契数列的情况&#xff0c;其它更长的数列情况中&#xff0c;除了作为开头的两个点&#xff0c;其它的点都是严格单调…

作者头像 李华
网站建设 2026/4/2 2:33:07

利用Apipost AI自动生成接口测试用例并批量执行

不少测试人员想了解&#xff0c;有没有不需要通过写代码&#xff0c;让AI快速生成接口测试用例和测试数据&#xff0c;并能够快速执行的方式&#xff1f;当下几个比较常用的接口测试工具&#xff0c;Apipost即具有这个能力&#xff0c;而且操作起来还很方便&#xff0c;完全是预…

作者头像 李华
网站建设 2026/4/1 14:06:11

团队文档协作首选:10款支持实时协同的共享网盘深度对比

在团队规模不断扩大的时代&#xff0c;文件共享不再只是“上传与下载”那么简单。项目进度需要实时同步、文档需要多人同时编辑、历史版本要随时可追溯——这些都让支持实时协作与版本管理的云端网盘成为企业协作效率的关键工具。 本文精选 10 款多人协作表现优秀的云盘服务&a…

作者头像 李华
网站建设 2026/4/2 15:05:16

wl-explorer:Vue开发者必备的终极文件管理解决方案

在当今快速发展的Web应用开发领域&#xff0c;文件管理功能已成为众多项目的核心需求。wl-explorer作为一款专为Vue框架设计的文件管理器插件&#xff0c;彻底解决了开发者在实现云盘级文件管理功能时面临的技术挑战。无论您是构建企业文档系统、个人云存储应用还是在线教育平台…

作者头像 李华
网站建设 2026/4/1 8:55:01

MaterialSearch:3分钟掌握本地素材AI语义搜索的终极方案

MaterialSearch是一个革命性的本地素材搜索工具&#xff0c;通过AI语义搜索技术&#xff0c;让你能够用自然语言快速查找本地照片和视频。无论是文字描述还是图片内容&#xff0c;都能在瞬间找到匹配的素材。 【免费下载链接】MaterialSearch AI语义搜索本地素材。以图搜图、查…

作者头像 李华
网站建设 2026/4/1 18:08:52

yadm点文件管理:5分钟解决90%常见问题的终极指南

yadm点文件管理&#xff1a;5分钟解决90%常见问题的终极指南 【免费下载链接】yadm Yet Another Dotfiles Manager 项目地址: https://gitcode.com/gh_mirrors/ya/yadm yadm点文件管理器是基于Git的强大配置管理工具&#xff0c;它让您的系统配置文件管理变得简单高效。…

作者头像 李华