summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane2021-08-19 16:12:35 +0000
committerTom Lane2021-08-19 16:12:35 +0000
commit8d2d6ec7708b475787fd92a9f828e554805e3df6 (patch)
treeb8dd5475b30e83538485d6686232471adfa2a609 /src/test
parentbed5eac2d50eb86a254861dcdea7b064d10c72cf (diff)
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
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/rules.out25
-rw-r--r--src/test/regress/sql/rules.sql14
2 files changed, 39 insertions, 0 deletions
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e5ab11275d9..2fa00a3c29a 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -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
diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql
index 6ec37c43811..b732833e63c 100644
--- a/src/test/regress/sql/rules.sql
+++ b/src/test/regress/sql/rules.sql
@@ -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;