postgresql “CHECK”约束使用'IN'->为什么要双转换?

vwhgwdsa  于 2022-12-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(142)

当我指定“CHECK”条件约束时,例如:

CONSTRAINT ADR_CHECK_1 CHECK (ACTIVE IN('Y', 'N'))

然后PostgreSQL将其实现为:

CONSTRAINT adr_check_1 CHECK (active::text = ANY (ARRAY['Y'::character varying::text, 'N'::character varying::text]))

--或者,也可以看到--

CONSTRAINT adr_check_1 CHECK (active::text = ANY (ARRAY['Y'::character varying, 'N'::character varying]::text[]))


为什么要进行双重强制转换?(首先转换为字符变量,然后转换为文本)

vuktfyat

vuktfyat1#

这必须在解析过程中发生。
最初,字符串文字(如'Y')的类型为unknown,然后通过上下文解析该类型。由于字符串文字与character varying类型的列进行比较,因此'Y'被解析为character varying类型。这一定是第一次强制转换的原因。(注意:我没有阅读资料来证实这一点。)
IN被转换为= ANY,因此data type resolution rules for operators生效。由于类型character varying没有运算符=,因此双方都被转换为 *preferred字符类型 * text。这就是第二次转换的原因。
也许可以在PostgreSQL中改进一些东西来避免这种奇怪的情况,但是如果您像这样定义约束,就可以很容易地避免这种情况:

ALTER TABLE adr ADD CHECK (active = ANY (ARRAY['Y', 'N']));

或者,等价地,

ALTER TABLE adr ADD CHECK (active::text IN ('Y', 'N'));

相关问题