是否可以重载PostgreSQL中现有的相等运算符,以给出类型为intreal的两个值之间相等的新定义?我认为这违反了超载规则,但我想知道是否有办法做到这一点.我试过这个:

CREATE OPERATOR = ( LEFTARG = real ,
                    RIGHTARG = real,
                    PROCEDURE = new_equality,
                    COMMUTATOR = = ,
                    NEGATOR = !=
                  );

CREATE OR REPLACE FUNCTION new_equality (real, real) RETURNS BOOLEAN AS 
$$
SELECT abs ($1 - $2) < 0,2 ;
$$ LANGUAGE PL/PGSQL

But when I use the equality operator in a query I don't get any result.
I also tried to define the new_equality() function parameters as the type of my attributes like this:

CREATE OR REPLACE FUNCTION new_equality (Student.age%TYPE, Student.age%TYPE) RETURNS BOOLEAN 
AS
$$
SELECT abs ($1 - $2) < 0,2;
$$ lANGUAGE PL/PGSQL

但我收到通知说Postgres将它们转换为real,当我在查询中使用相等运算符时,仍然没有得到任何结果.

推荐答案

劳伦兹指出了眼前的问题.还有更多.

假设是Postgres 14,这就行了:

CREATE OR REPLACE FUNCTION public.new_equality (real, real)  -- be explicit about the schema!
  RETURNS bool
  LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE COST 10
BEGIN ATOMIC
SELECT abs($1 - $2) < 0.2;
END;

CREATE OR REPLACE FUNCTION public.new_inequality (real, real)  -- be explicit about the schema!
  RETURNS bool
  LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE COST 10
BEGIN ATOMIC
SELECT abs($1 - $2) >= 0.2;
END;

CREATE OPERATOR public.= (             -- be explicit about the schema!
  LEFTARG    = real
, RIGHTARG   = real
, FUNCTION   = public.new_equality
, COMMUTATOR = OPERATOR(public.=)      -- be explicit about the schema!
, NEGATOR    = OPERATOR(public.!=)     -- must also exist
);

CREATE OPERATOR public.!= (
  LEFTARG    = real
, RIGHTARG   = real
, FUNCTION   = public.new_inequality
, COMMUTATOR = OPERATOR(public.!=)
, NEGATOR    = OPERATOR(public.=)
);

使用OPERATOR()构造将其命名为:

SELECT id, real '0.1' OPERATOR(public.=) real '0.2';
SELECT id, real '0.1' OPERATOR(public.!=) real '0.2';
SELECT id, real '0.1' OPERATOR(public.<>) real '0.2';

db<>fiddle 100-有更多的例子

请注意higher operator precedence,可能是普通运算符无法使用的强制括号!

你还必须遵守你在声明中提到的NEGATOR条.使用内置的!=将是自相矛盾的胡说八道.创建一个匹配运算符,必须使用符合模式的语法引用该运算符.The manual:

要在100或其他可选参数中提供模式限定运算符名称,请使用OPERATOR()语法[…]

相关的:

请注意,<>!=的自动别名,<>是SQL中的默认不等式运算符.

一个不合格的=将是标准的相等运算符(OPERATOR(pg_catalog.=)),而你不需要与search_path打交道来降级pg_catalog——这是你不应该做的!降级pg_catalog为各种严重问题打开了大门,因为系统对象现在隐藏在一个或多个其他模式后面.除非你确切知道自己在做什么,否则就这么做.关于search_path:

这假设至少有14个研究生.大约BEGIN ATOMIC人:

使用关键字FUNCTION而不是误导性的PROCEDURE,这对于向后兼容性仍然有效.见:

a_horse_with_no_name suggested一样,使用与现有符号不同的运算符符号可能更方便,以避免冲突.仍将具有比默认比较运算符更高的标准(=更高)运算符优先级,并且不容易更改.

Sql相关问答推荐

基于模式或其他行集的数据复制

Select /过滤postgr中的树 struct

如何更改函数返回的列名?

SQL将 Select 查询作为新列添加到另一个 Select 查询

我希望以正确的升序获取SQL结果.怎样才能得到它们?

BigQuery-当子查询不返回任何结果时,所有结果为零

无法将发票与产品价格相关联

SQL数据库规范化与数据插入

我需要在 ASP.NET C# 中获取 2 个 SQL 查询结果的平均值

从输出中删除 jsonb_build_object

SQL SUM Filter逻辑解释

如何在第二个 INSERT 中使用第一个 INSERT 自动生成的 ID

如何在TSQL中编写此窗口查询

COBOL\DB2作业(job)需要帮助?快来获取专业指导!

在 BigQuery 数据集中查找表大小和占总数据集大小的百分比

T-SQL 查询计算日期在其他列中定义的日期之间绑定的行数

PostgreSQL 如何在一组项目及其数量上找到完全相同的订单?

有没有一种方法可以将始终遵循序列的单个字段的值组合起来,以创建每个 ID 的所有移动?

使用同一表中的数据或任何其他虚拟数据在 SQL 表中插入数据的最快方法

使用分隔符拆分字符串并将它们放在 sql 中的多行中不起作用