I hit an error when updating a view with conditional INSTEAD OF rules, the reproduce steps are list below:
CREATE TABLE t1(a int, b int);
CREATE TABLE t2(a int, b int);
CREATE VIEW v1 AS SELECT * FROM t1 where b > 100;
INSERT INTO v1 values(1, 110);
SELECT * FROM t1;
CREATE OR REPLACE rule r1 AS
ON UPDATE TO v1
WHERE old.a > new.b
DO INSTEAD (
INSERT INTO t2 values(old.a, old.b);
);
UPDATE v1 SET b = 2 WHERE a = 1;
ERROR: no relation entry for relid 2
With some hacks, It is because, for conditional INSTEAD OF rules conditional, the original UPDATE operation also need to perform on the view, however, we didn't rewrite the target view for any view with INSTEAD rules.
There should be only two cases that you can skip the rewrite of target view:
1) the view has INSTEAD OF triggers on the operations, the operations will be replaced by trigger-defined
2) the view has INSTEAD OF rules and it is non conditional rules, the operations will be replaced by actions.
It should be a typo in commit a99c42f291421572aef2, there is a description in documents:
"There is a catch if you try to use conditional rules
for complex view updates: there must be an unconditional
INSTEAD rule for each action you wish to allow on the view."
Commit a99c42f291421572aef2 explicitly change the description that the restriction only applies to complex view, conditional INSTEAD rule should work for a simple view.