PostgreSQL 自定义运算符比较 varchar 和 integer

PostgreSQL Custom operator compare varchar and integer

-- x86_64-pc-linux-gnu 上的 PostgreSQL 9.6.2,由 gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17) 编译,64 位。

-- 从官方存储库安装。

-- postgresql.conf 没有任何变化。

-- CentOS 6.8 版。

-- 用户: postgres.

-- BigSQL 使用 pgAdmin3 LTS。

-- 服务器没有任何异常登录。

我有很多疑问。

在这种情况下,我需要比较字符可变数据类型(可能是 table 字段)与整数值。

--结果为真或假

select '10' = 10; 
select '10' = '10'; 
select '10'::character varying = '10'::character varying; 
select '10'::character varying = 'foo bar'; 
select '10'::character varying = 'foo bar'::character varying; 
select 'foo bar' = 'foo bar'; 
select '10'::character varying = '10';

--结果为"operator does not exist: character varying = integer"

select '10'::character varying = 10; 

所以我创建一个自定义运算符用于比较字符变化和整数

第 1 步:创建简单函数

CREATE OR REPLACE FUNCTION public.is_equal_char_int(character varying, integer) RETURNS boolean AS 
$BODY$ 
BEGIN 
    IF  = ::character varying THEN
        RETURN TRUE;
    ELSE 
        RETURN FALSE; 
    END IF;
End;
$BODY$ 
LANGUAGE plpgsql VOLATILE COST 100;

第 2 步:创建新运算符

CREATE OPERATOR public.=( 
PROCEDURE = is_equal_char_int,
LEFTARG = character varying,
RIGHTARG = integer);

所以我解决了我的问题并且

select '10'::character varying = 10;

return真值。

新问题是: 当我 将字符变化值与未知数据类型 值进行比较时,postgresql 使用我的自定义运算符 .

select '10'::character varying = 'foo bar';

结果是:

整数的无效输入语法:"foo bar"

select pg_typeof('foo bar');

return 未知数据类型。

下一步我创建新的运算符来比较字符变化和未知数据类型。

第 1 步:

CREATE OR REPLACE FUNCTION public.is_equal_char_unknown(character varying, unknown)
RETURNS boolean AS
$BODY$
BEGIN
IF  = ::character varying THEN
    RETURN TRUE;
ELSE
    RETURN FALSE;
END IF;
End;
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;

第 2 步:

CREATE OPERATOR public.=( 
PROCEDURE = is_equal_char_unknown,
LEFTARG = character varying,
RIGHTARG = unknown);

当我运行

select '10'::character varying = 'foo bar';

我给

错误:运算符不唯一:字符变化 = 未知。

所以我进了一个洞。

要了解 PostgreSQL 中运算符的类型解析是如何完成的,请阅读文档中的 operator type resolution rules

在您的特殊情况下,以下运算符在步骤 3.a 之后保留:

  • 您的自定义运算符(character varying = integer)。

  • character = character(从character varyingcharacter的隐式转换)。

  • name = name(从character varyingname的隐式转换)。

  • text = text(从character varyingtext的隐式转换)。

规则 3.c 然后选择您的运算符,因为它是唯一具有完全类型匹配的运算符。如果没有您的运算符,步骤 3.d 会选择 text = text,因为 text 是字符串类别的唯一首选类型。

你现在正在做的是发现为什么某些运算符在 PostgreSQL 中 没有 定义,即为新类型组合定义新的比较运算符会导致歧义,从而导致错误因为 PostgreSQL 无法决定使用哪个运算符。

问题的核心是 PostgreSQL 能够重载 运算符,即具有多个具有相同名称的运算符。然而,这是一个很好的功能,演员和操作员系统经过精心平衡,使体验尽可能好。 unknown 类型也是该系统的一部分。

换句话说,PostgreSQL 试图猜测你的意思,但这并不总是可能的。如果你想比较一个(不是unknown)字符串和一个数字,你想要什么?它们应该作为数字还是作为字符串进行比较? '010' 是否应该与 10 相同? PostgreSQL 不懂你的意思,放弃了。