Skip to content

Commit 5b7bfc3

Browse files
committed
Don't throw an error for LOCK TABLE on a self-referential view.
LOCK TABLE has complained about "infinite recursion" when applied to a self-referential view, ever since we made it recurse into views in v11. However, that breaks pg_dump's new assumption that it's okay to lock every relation. There doesn't seem to be any good reason to throw an error: if we just abandon the recursion, we've still satisfied the requirement of locking every referenced relation. Per bug #16703 from Andrew Bille (via Alexander Lakhin). Discussion: https://postgr.es/m/16703-e348f58aab3cf6cc@postgresql.org
1 parent 48e1291 commit 5b7bfc3

File tree

3 files changed

+14
-13
lines changed

3 files changed

+14
-13
lines changed

src/backend/commands/lockcmds.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ static void LockTableRecurse(Oid reloid, LOCKMODE lockmode, bool nowait);
3232
static AclResult LockTableAclCheck(Oid relid, LOCKMODE lockmode, Oid userid);
3333
static void RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid,
3434
Oid oldrelid, void *arg);
35-
static void LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views);
35+
static void LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait,
36+
List *ancestor_views);
3637

3738
/*
3839
* LOCK TABLE
@@ -195,12 +196,12 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
195196
strcmp(rte->eref->aliasname, "new") == 0))
196197
continue;
197198

198-
/* Check infinite recursion in the view definition. */
199+
/*
200+
* We might be dealing with a self-referential view. If so, we
201+
* can just stop recursing, since we already locked it.
202+
*/
199203
if (list_member_oid(context->ancestor_views, relid))
200-
ereport(ERROR,
201-
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
202-
errmsg("infinite recursion detected in rules for relation \"%s\"",
203-
get_rel_name(relid))));
204+
continue;
204205

205206
/* Check permissions with the view owner's privilege. */
206207
aclresult = LockTableAclCheck(relid, context->lockmode, context->viewowner);
@@ -218,7 +219,8 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
218219
get_rel_name(relid))));
219220

220221
if (rte->relkind == RELKIND_VIEW)
221-
LockViewRecurse(relid, context->lockmode, context->nowait, context->ancestor_views);
222+
LockViewRecurse(relid, context->lockmode, context->nowait,
223+
context->ancestor_views);
222224
else if (rte->inh)
223225
LockTableRecurse(relid, context->lockmode, context->nowait);
224226
}
@@ -235,13 +237,14 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
235237
}
236238

237239
static void
238-
LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views)
240+
LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait,
241+
List *ancestor_views)
239242
{
240243
LockViewRecurse_context context;
241-
242244
Relation view;
243245
Query *viewquery;
244246

247+
/* caller has already locked the view */
245248
view = table_open(reloid, NoLock);
246249
viewquery = get_view_query(view);
247250

src/test/regress/expected/lock.out

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,14 @@ select relname from pg_locks l, pg_class c
124124
(2 rows)
125125

126126
ROLLBACK;
127-
-- detecting infinite recursions in view definitions
127+
-- Verify that we cope with infinite recursion in view definitions.
128128
CREATE OR REPLACE VIEW lock_view2 AS SELECT * from lock_view3;
129129
BEGIN TRANSACTION;
130130
LOCK TABLE lock_view2 IN EXCLUSIVE MODE;
131-
ERROR: infinite recursion detected in rules for relation "lock_view2"
132131
ROLLBACK;
133132
CREATE VIEW lock_view7 AS SELECT * from lock_view2;
134133
BEGIN TRANSACTION;
135134
LOCK TABLE lock_view7 IN EXCLUSIVE MODE;
136-
ERROR: infinite recursion detected in rules for relation "lock_view2"
137135
ROLLBACK;
138136
-- Verify that we can lock a table with inheritance children.
139137
CREATE TABLE lock_tbl2 (b BIGINT) INHERITS (lock_tbl1);

src/test/regress/sql/lock.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ select relname from pg_locks l, pg_class c
8787
where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock'
8888
order by relname;
8989
ROLLBACK;
90-
-- detecting infinite recursions in view definitions
90+
-- Verify that we cope with infinite recursion in view definitions.
9191
CREATE OR REPLACE VIEW lock_view2 AS SELECT * from lock_view3;
9292
BEGIN TRANSACTION;
9393
LOCK TABLE lock_view2 IN EXCLUSIVE MODE;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy