Kyl*_*yle 5 postgresql view upsert
我有一个可更新的视图,指向具有部分索引的基础表。它看起来像这样
CREATE TABLE if not exists foo (
a INT,
b INT,
x INT,
y INT,
z BOOLEAN,
CONSTRAINT x_or_y CHECK (
(z and x is not null and y is null)
or
(not z and x is null and y is not null)
)
);
CREATE UNIQUE INDEX ux ON foo (x, a) WHERE z=TRUE;
CREATE UNIQUE INDEX uy ON foo (y, a) WHERE z=FALSE;
CREATE OR REPLACE VIEW foo_view AS
SELECT * FROM foo;
Run Code Online (Sandbox Code Playgroud)
也就是说,对于每一行,如果为 true,y
则必须为 null ;如果为 false,则必须为 null ;并且,和中只有一个可能不为空。并且必须是唯一的。(抱歉,如果这太复杂了。我正在根据我的真实表格进行翻译,该表格还有很多其他内容。)z
x
z
x
y
(x, a)
(y, a)
当我想更新时我的问题就来了ON CONFLICT
。我相信我应该能够做到这一点。
INSERT INTO foo_view(x, y, a, b, z)
VALUES
(5, null, 1, 2, true),
(null, 5, 1, 2, false);
select * from foo_view;
INSERT INTO foo_view(x, y, a, b, z)
VALUES
(5, null, 1, 2, true)
ON CONFLICT (x, a) where z=true
DO UPDATE
set b = EXCLUDED.b;
Run Code Online (Sandbox Code Playgroud)
但是,我得到了例外:
ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
Run Code Online (Sandbox Code Playgroud)
我可以插入foo
而不是foo_view
使用相同的内容ON CONFLICT
而不会出现错误。
这是一个小提琴:https://www.db-fiddle.com/f/cX2HXg91Q7yKoPeMBYzVLg/0
infer_arbiter_indexes
通过 PostgreSQL 代码调试后,我会说src/backend/optimizer/util/plancat.c
. 它将索引谓词与WHERE
中的条件进行比较ON CONFLICT
,但似乎忽略了它们位于不同的对象上。
我不确定 PostgreSQL 是否愿意将其视为错误,但您可以报告它。