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 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 不懂你的意思,放弃了。
-- 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 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 不懂你的意思,放弃了。