PostgreSQL自定义运算符比较varchar和整数

时间:2017-05-13 16:37:35

标签: postgresql custom-operator

- 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。

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

我有很多疑问。

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

- 结果为真或假

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';

- 结果是"运算符不存在:字符变化=整数"

select '10'::character varying = 10; 

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

第1步:创建简单的功能

CREATE OR REPLACE FUNCTION public.is_equal_char_int(character varying, integer) RETURNS boolean AS 
$BODY$ 
BEGIN 
    IF $1 = $2::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;

返回真实值。

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

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

结果是:

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

select pg_typeof('foo bar');

返回未知数据类型。

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

第1步:

CREATE OR REPLACE FUNCTION public.is_equal_char_unknown(character varying, unknown)
RETURNS boolean AS
$BODY$
BEGIN
IF $1 = $2::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';

我给

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

所以我在一个洞里。

1 个答案:

答案 0 :(得分:1)

要了解PostgreSQL中运算符的类型解析方式,请阅读文档中的operator type resolution rules

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

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

  • character = character(从character varying隐式转换为character)。

  • name = name(从character varying隐式转换为name)。

  • text = text(从character varying隐式转换为text)。

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

您目前正在做的是发现为什么某些运算符在PostgreSQL中定义,即为新类型组合定义新的比较运算符会导致导致错误的歧义,因为PostgreSQL无法确定运营商使用。

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

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