无法将“ON CONFLICT”与 postgres 可更新视图和部分索引一起使用

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 ;并且,和中只有一个可能不为空。并且必须是唯一的。(抱歉,如果这太复杂了。我正在根据我的真实表格进行翻译,该表格还有很多其他内容。)zxzxy(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

Lau*_*lbe 5

infer_arbiter_indexes通过 PostgreSQL 代码调试后,我会说src/backend/optimizer/util/plancat.c. 它将索引谓词与WHERE中的条件进行比较ON CONFLICT,但似乎忽略了它们位于不同的对象上。

我不确定 PostgreSQL 是否愿意将其视为错误,但您可以报告它。