当前位置: 首页 > news >正文

postgreSQL 中的自定义操作符

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

操作符

看下面这条语句:

SELECT 3 OPERATOR(pg_catalog.+) 4 sum;  -- 1️⃣

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

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

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;

image

不知道你有没有疑惑:这不还是用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 aggMERGES                   -- 支持 merge join
);-- 创建取反操作符 !==
CREATE OPERATOR !== (LEFTARG = anyelement,RIGHTARG = anyelement,PROCEDURE = geometry_strict_equal,NEGATOR = ===            -- 互相指向对方
);

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

4. 查询操作符

SELECTn.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); -- 先删除操作符,必须传左右两个参数,没有的写NONEDROP 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;
http://www.jsqmd.com/news/77002/

相关文章:

  • 如何在5分钟内快速部署SendPortal邮件营销平台
  • 2025年Q4一物一码服务商Top10榜单解析 - 速递信息
  • 2025年包钢无缝管直销厂家权威推荐榜单:碳钢无缝管/厚壁无缝钢管/A53GR.B无缝钢管源头供应商精选 - 品牌推荐官
  • 2025年包钢无缝管直销厂家权威推荐榜单:碳钢无缝管/厚壁无缝钢管/A53GR.B无缝钢管源头供应商精选 - 品牌推荐官
  • 前端已死?React Server Components 惊现远程代码执行,塞讯攻击库已实时更新
  • 2025年南京公考培训机构推荐:中政公考等五家机构教学方法与 - 工业品牌热点
  • 手把手教你用DLT Viewer:从零开始掌握汽车日志分析神器
  • C语言实战2
  • 成都AI大模型代运营公司哪家好?测评成都5大代运营公司 - 百誉集团
  • 真空烘箱哪个品牌好/工业烘箱哪家好?哪家性价比高?国内品牌哪个好? - 品牌推荐大师1
  • 计算机毕业设计springboot大连科技学院运动会管理系统 SpringBoot高校田径运动会综合管理平台基于 SpringBoot的校园体育赛事智能编排与成绩发布系统
  • 2025售后完善的原木家具制造厂TOP5权威推荐:甄选企业助 - mypinpai
  • 济宁远潮影像品牌实力解析 - charlieruizvin
  • 优思学院|JIT准时制生产的核心思想
  • 2025年红外热像仪行业五大实力厂商推荐,上海热像科技专业测 - myqiye
  • 2025年12月亚克力展柜,亚克力雕刻,亚克力制品厂家推荐:异形定制案例透视 - 品牌鉴赏师
  • 破局出海新时代:石家庄企业借力外贸GEO优化,抢占全球市场先机! - 博客万
  • 2025年12月社区商户经济,社区团购经济,社区智慧化经济服务品牌推荐榜,彰显服务实力 - 品牌鉴赏师
  • 2025年德国ELBE联轴器及驱动轴供应商年度排名:ELBE - mypinpai
  • 2025年上海五大靠谱移民机构排行榜,新测评精选知名的移民品 - mypinpai
  • 泰迪智能科技案例库 | 信息技术行业项目案例合集
  • 2025年深圳电梯噪音治理公司排行榜,靠谱的电梯噪音治理公司 - myqiye
  • Java 中 new 一个对象的过程是怎么样的?
  • 2025冷却塔降噪治理厂商TOP5权威推荐:甄选专业企业破解 - myqiye
  • 2025年十大饲料分析检测单位排行榜,专业测评精选推荐 - 工业品牌热点
  • 2025年雪茄柜设计哪家口碑好?十大专业雪茄柜设计公司排名推 - 工业品牌热点
  • Spring中的注解@Scope
  • 2025年北京助听器验配机构联系电话完整汇总: 重点机构官方联系方式与专业验配服务指南 - 品牌推荐
  • TileLang实战指南:零基础避坑,3步实现GPU算子性能翻倍
  • 钛管厂家五大推荐:2025年高可靠钛材供应商选型指南(含钛板、钛棒、钛法兰、钛锻件全品类) - 深度智识库