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
This commit is contained in:
parent
48e1291342
commit
5b7bfc3972
@ -32,7 +32,8 @@ static void LockTableRecurse(Oid reloid, LOCKMODE lockmode, bool nowait);
|
||||
static AclResult LockTableAclCheck(Oid relid, LOCKMODE lockmode, Oid userid);
|
||||
static void RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid,
|
||||
Oid oldrelid, void *arg);
|
||||
static void LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views);
|
||||
static void LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait,
|
||||
List *ancestor_views);
|
||||
|
||||
/*
|
||||
* LOCK TABLE
|
||||
@ -195,12 +196,12 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
|
||||
strcmp(rte->eref->aliasname, "new") == 0))
|
||||
continue;
|
||||
|
||||
/* Check infinite recursion in the view definition. */
|
||||
/*
|
||||
* We might be dealing with a self-referential view. If so, we
|
||||
* can just stop recursing, since we already locked it.
|
||||
*/
|
||||
if (list_member_oid(context->ancestor_views, relid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||
errmsg("infinite recursion detected in rules for relation \"%s\"",
|
||||
get_rel_name(relid))));
|
||||
continue;
|
||||
|
||||
/* Check permissions with the view owner's privilege. */
|
||||
aclresult = LockTableAclCheck(relid, context->lockmode, context->viewowner);
|
||||
@ -218,7 +219,8 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
|
||||
get_rel_name(relid))));
|
||||
|
||||
if (rte->relkind == RELKIND_VIEW)
|
||||
LockViewRecurse(relid, context->lockmode, context->nowait, context->ancestor_views);
|
||||
LockViewRecurse(relid, context->lockmode, context->nowait,
|
||||
context->ancestor_views);
|
||||
else if (rte->inh)
|
||||
LockTableRecurse(relid, context->lockmode, context->nowait);
|
||||
}
|
||||
@ -235,13 +237,14 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
|
||||
}
|
||||
|
||||
static void
|
||||
LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views)
|
||||
LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait,
|
||||
List *ancestor_views)
|
||||
{
|
||||
LockViewRecurse_context context;
|
||||
|
||||
Relation view;
|
||||
Query *viewquery;
|
||||
|
||||
/* caller has already locked the view */
|
||||
view = table_open(reloid, NoLock);
|
||||
viewquery = get_view_query(view);
|
||||
|
||||
|
@ -124,16 +124,14 @@ select relname from pg_locks l, pg_class c
|
||||
(2 rows)
|
||||
|
||||
ROLLBACK;
|
||||
-- detecting infinite recursions in view definitions
|
||||
-- Verify that we cope with infinite recursion in view definitions.
|
||||
CREATE OR REPLACE VIEW lock_view2 AS SELECT * from lock_view3;
|
||||
BEGIN TRANSACTION;
|
||||
LOCK TABLE lock_view2 IN EXCLUSIVE MODE;
|
||||
ERROR: infinite recursion detected in rules for relation "lock_view2"
|
||||
ROLLBACK;
|
||||
CREATE VIEW lock_view7 AS SELECT * from lock_view2;
|
||||
BEGIN TRANSACTION;
|
||||
LOCK TABLE lock_view7 IN EXCLUSIVE MODE;
|
||||
ERROR: infinite recursion detected in rules for relation "lock_view2"
|
||||
ROLLBACK;
|
||||
-- Verify that we can lock a table with inheritance children.
|
||||
CREATE TABLE lock_tbl2 (b BIGINT) INHERITS (lock_tbl1);
|
||||
|
@ -87,7 +87,7 @@ select relname from pg_locks l, pg_class c
|
||||
where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock'
|
||||
order by relname;
|
||||
ROLLBACK;
|
||||
-- detecting infinite recursions in view definitions
|
||||
-- Verify that we cope with infinite recursion in view definitions.
|
||||
CREATE OR REPLACE VIEW lock_view2 AS SELECT * from lock_view3;
|
||||
BEGIN TRANSACTION;
|
||||
LOCK TABLE lock_view2 IN EXCLUSIVE MODE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user