mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03:00
Avoid trying to lock OLD/NEW in a rule with FOR UPDATE.
transformLockingClause neglected to exclude the pseudo-RTEs for OLD/NEW when processing a rule's query. This led to odd errors or even crashes later on. This bug is very ancient, but it's not terribly surprising that nobody noticed, since the use-case for SELECT FOR UPDATE in a non-view rule is somewhere between thin and non-existent. Still, crashing is not OK. Per bug #17151 from Zhiyong Wu. Thanks to Masahiko Sawada for analysis of the problem. Discussion: https://postgr.es/m/17151-c03a3e6e4ec9aadb@postgresql.org
This commit is contained in:
@@ -3026,6 +3026,31 @@ select * from only t1_2;
|
||||
(10 rows)
|
||||
|
||||
reset constraint_exclusion;
|
||||
-- test FOR UPDATE in rules
|
||||
create table rules_base(f1 int, f2 int);
|
||||
insert into rules_base values(1,2), (11,12);
|
||||
create rule r1 as on update to rules_base do instead
|
||||
select * from rules_base where f1 = 1 for update;
|
||||
update rules_base set f2 = f2 + 1;
|
||||
f1 | f2
|
||||
----+----
|
||||
1 | 2
|
||||
(1 row)
|
||||
|
||||
create or replace rule r1 as on update to rules_base do instead
|
||||
select * from rules_base where f1 = 11 for update of rules_base;
|
||||
update rules_base set f2 = f2 + 1;
|
||||
f1 | f2
|
||||
----+----
|
||||
11 | 12
|
||||
(1 row)
|
||||
|
||||
create or replace rule r1 as on update to rules_base do instead
|
||||
select * from rules_base where f1 = 11 for update of old; -- error
|
||||
ERROR: relation "old" in FOR UPDATE clause not found in FROM clause
|
||||
LINE 2: select * from rules_base where f1 = 11 for update of old;
|
||||
^
|
||||
drop table rules_base;
|
||||
-- test various flavors of pg_get_viewdef()
|
||||
select pg_get_viewdef('shoe'::regclass) as unpretty;
|
||||
unpretty
|
||||
|
@@ -992,6 +992,20 @@ select * from only t1_2;
|
||||
|
||||
reset constraint_exclusion;
|
||||
|
||||
-- test FOR UPDATE in rules
|
||||
|
||||
create table rules_base(f1 int, f2 int);
|
||||
insert into rules_base values(1,2), (11,12);
|
||||
create rule r1 as on update to rules_base do instead
|
||||
select * from rules_base where f1 = 1 for update;
|
||||
update rules_base set f2 = f2 + 1;
|
||||
create or replace rule r1 as on update to rules_base do instead
|
||||
select * from rules_base where f1 = 11 for update of rules_base;
|
||||
update rules_base set f2 = f2 + 1;
|
||||
create or replace rule r1 as on update to rules_base do instead
|
||||
select * from rules_base where f1 = 11 for update of old; -- error
|
||||
drop table rules_base;
|
||||
|
||||
-- test various flavors of pg_get_viewdef()
|
||||
|
||||
select pg_get_viewdef('shoe'::regclass) as unpretty;
|
||||
|
Reference in New Issue
Block a user