Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0bdf1ef

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 ea90879 commit 0bdf1ef

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, Oid use
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
@@ -217,12 +218,12 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
217218
strcmp(rte->eref->aliasname, "new") == 0))
218219
continue;
219220

220-
/* Check infinite recursion in the view definition. */
221+
/*
222+
* We might be dealing with a self-referential view. If so, we
223+
* can just stop recursing, since we already locked it.
224+
*/
221225
if (list_member_oid(context->ancestor_views, relid))
222-
ereport(ERROR,
223-
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
224-
errmsg("infinite recursion detected in rules for relation \"%s\"",
225-
get_rel_name(relid))));
226+
continue;
226227

227228
/* Check permissions with the view owner's privilege. */
228229
aclresult = LockTableAclCheck(relid, context->lockmode, context->viewowner);
@@ -240,7 +241,8 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
240241
get_rel_name(relid))));
241242

242243
if (rte->relkind == RELKIND_VIEW)
243-
LockViewRecurse(relid, context->lockmode, context->nowait, context->ancestor_views);
244+
LockViewRecurse(relid, context->lockmode, context->nowait,
245+
context->ancestor_views);
244246
else if (rte->inh)
245247
LockTableRecurse(relid, context->lockmode, context->nowait, context->viewowner);
246248
}
@@ -257,13 +259,14 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
257259
}
258260

259261
static void
260-
LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views)
262+
LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait,
263+
List *ancestor_views)
261264
{
262265
LockViewRecurse_context context;
263-
264266
Relation view;
265267
Query *viewquery;
266268

269+
/* caller has already locked the view */
267270
view = table_open(reloid, NoLock);
268271
viewquery = get_view_query(view);
269272

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)