v8-0002-Add-skip_locked-argument-to-find_all_inheritors.patch
application/octet-stream
Filename: v8-0002-Add-skip_locked-argument-to-find_all_inheritors.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch v8-0002
Subject: Add skip_locked argument to find_all_inheritors().
| File | + | − |
|---|---|---|
| contrib/sepgsql/dml.c | 1 | 1 |
| src/backend/catalog/pg_inherits.c | 27 | 3 |
| src/backend/commands/analyze.c | 1 | 1 |
| src/backend/commands/publicationcmds.c | 1 | 1 |
| src/backend/commands/tablecmds.c | 8 | 8 |
| src/backend/commands/trigger.c | 1 | 1 |
| src/backend/commands/vacuum.c | 1 | 1 |
| src/backend/executor/execPartition.c | 1 | 1 |
| src/backend/optimizer/prep/prepunion.c | 1 | 1 |
| src/backend/partitioning/partbounds.c | 1 | 1 |
| src/backend/tcop/utility.c | 2 | 1 |
| src/include/catalog/pg_inherits.h | 1 | 1 |
From 2c29d3cfa15cc231430fd6ddffe52bfc082d3a35 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Thu, 5 Apr 2018 16:52:56 +0000
Subject: [PATCH v8 02/12] Add skip_locked argument to find_all_inheritors().
---
contrib/sepgsql/dml.c | 2 +-
src/backend/catalog/pg_inherits.c | 30 +++++++++++++++++++++++++++---
src/backend/commands/analyze.c | 2 +-
src/backend/commands/publicationcmds.c | 2 +-
src/backend/commands/tablecmds.c | 16 ++++++++--------
src/backend/commands/trigger.c | 2 +-
src/backend/commands/vacuum.c | 2 +-
src/backend/executor/execPartition.c | 2 +-
src/backend/optimizer/prep/prepunion.c | 2 +-
src/backend/partitioning/partbounds.c | 2 +-
src/backend/tcop/utility.c | 3 ++-
src/include/catalog/pg_inherits.h | 2 +-
12 files changed, 46 insertions(+), 21 deletions(-)
diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c
index 9bdbd7b60f..bb7713380a 100644
--- a/contrib/sepgsql/dml.c
+++ b/contrib/sepgsql/dml.c
@@ -330,7 +330,7 @@ sepgsql_dml_privileges(List *rangeTabls, bool abort_on_violation)
if (!rte->inh)
tableIds = list_make1_oid(rte->relid);
else
- tableIds = find_all_inheritors(rte->relid, NoLock, NULL);
+ tableIds = find_all_inheritors(rte->relid, NoLock, NULL, false);
foreach(li, tableIds)
{
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 1b936123c5..a64037a958 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -180,10 +180,12 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode, bool skip_locked,
* The specified lock type is acquired on all child relations (but not on the
* given rel; caller should already have locked it). If lockmode is NoLock
* then no locks are acquired, but caller must beware of race conditions
- * against possible DROPs of child relations.
+ * against possible DROPs of child relations. If skip_locked is true and a
+ * child relation can not be locked immediately without waiting, both the
+ * returned OID list and *numparents will be set to NIL.
*/
List *
-find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
+find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents, bool skip_locked)
{
/* hash table for O(1) rel_oid -> rel_numparents cell lookup */
HTAB *seen_rels;
@@ -191,6 +193,7 @@ find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
List *rels_list,
*rel_numparents;
ListCell *l;
+ bool skipped = false;
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(Oid);
@@ -219,7 +222,7 @@ find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
ListCell *lc;
/* Get the direct children of this rel */
- currentchildren = find_inheritance_children(currentrel, lockmode, false, NULL);
+ currentchildren = find_inheritance_children(currentrel, lockmode, skip_locked, &skipped);
/*
* Add to the queue only those children not already seen. This avoids
@@ -248,6 +251,27 @@ find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
hash_entry->numparents_cell = rel_numparents->tail;
}
}
+
+ if (skipped)
+ break;
+ }
+
+ /* if a child relation was skipped, set the return lists to NIL */
+ if (skipped)
+ {
+ /* release all locks */
+ foreach(l, rels_list)
+ {
+ Oid currentrel = lfirst_oid(l);
+
+ if (currentrel != parentrelId)
+ UnlockRelationOid(currentrel, lockmode);
+ }
+
+ list_free(rel_numparents);
+ list_free(rels_list);
+ rel_numparents = NIL;
+ rels_list = NIL;
}
if (numparents)
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 25194e871c..651cf1f78e 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -1335,7 +1335,7 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
* the children.
*/
tableOIDs =
- find_all_inheritors(RelationGetRelid(onerel), AccessShareLock, NULL);
+ find_all_inheritors(RelationGetRelid(onerel), AccessShareLock, NULL, false);
/*
* Check that there's at least one descendant, else fail. This could
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 6f7762a906..a5e01ea61e 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -530,7 +530,7 @@ OpenTableList(List *tables)
List *children;
children = find_all_inheritors(myrelid, ShareUpdateExclusiveLock,
- NULL);
+ NULL, false);
foreach(child, children)
{
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 4f0640e9ba..a46aa8806e 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1356,7 +1356,7 @@ ExecuteTruncate(TruncateStmt *stmt)
ListCell *child;
List *children;
- children = find_all_inheritors(myrelid, AccessExclusiveLock, NULL);
+ children = find_all_inheritors(myrelid, AccessExclusiveLock, NULL, false);
foreach(child, children)
{
@@ -2754,7 +2754,7 @@ renameatt_internal(Oid myrelid,
* outside the inheritance hierarchy being processed.
*/
child_oids = find_all_inheritors(myrelid, AccessExclusiveLock,
- &child_numparents);
+ &child_numparents, false);
/*
* find_all_inheritors does the recursive search of the inheritance
@@ -2964,7 +2964,7 @@ rename_constraint_internal(Oid myrelid,
*li;
child_oids = find_all_inheritors(myrelid, AccessExclusiveLock,
- &child_numparents);
+ &child_numparents, false);
forboth(lo, child_oids, li, child_numparents)
{
@@ -5030,7 +5030,7 @@ ATSimpleRecursion(List **wqueue, Relation rel,
ListCell *child;
List *children;
- children = find_all_inheritors(relid, lockmode, NULL);
+ children = find_all_inheritors(relid, lockmode, NULL, false);
/*
* find_all_inheritors does the recursive search of the inheritance
@@ -8006,7 +8006,7 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse,
*/
if (!recursing && !con->connoinherit)
children = find_all_inheritors(RelationGetRelid(rel),
- lockmode, NULL);
+ lockmode, NULL, false);
/*
* For CHECK constraints, we must ensure that we only mark the
@@ -9210,7 +9210,7 @@ ATPrepAlterColumnType(List **wqueue,
ListCell *child;
List *children;
- children = find_all_inheritors(relid, lockmode, NULL);
+ children = find_all_inheritors(relid, lockmode, NULL, false);
/*
* find_all_inheritors does the recursive search of the inheritance
@@ -11443,7 +11443,7 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode)
* We use weakest lock we can on child's children, namely AccessShareLock.
*/
children = find_all_inheritors(RelationGetRelid(child_rel),
- AccessShareLock, NULL);
+ AccessShareLock, NULL, false);
if (list_member_oid(children, RelationGetRelid(parent_rel)))
ereport(ERROR,
@@ -14126,7 +14126,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
* weaker lock now and the stronger one only when needed.
*/
attachrel_children = find_all_inheritors(RelationGetRelid(attachrel),
- AccessExclusiveLock, NULL);
+ AccessExclusiveLock, NULL, false);
if (list_member_oid(attachrel_children, RelationGetRelid(rel)))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_TABLE),
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 24de0c58c0..34c4cc0ef8 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -364,7 +364,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE;
if (partition_recurse)
list_free(find_all_inheritors(RelationGetRelid(rel),
- ShareRowExclusiveLock, NULL));
+ ShareRowExclusiveLock, NULL, false));
/* Compute tgtype */
TRIGGER_CLEAR_TYPE(tgtype);
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index d90cb9a902..74049741a7 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -479,7 +479,7 @@ expand_vacuum_rel(VacuumRelation *vrel)
*/
if (include_parts)
{
- List *part_oids = find_all_inheritors(relid, NoLock, NULL);
+ List *part_oids = find_all_inheritors(relid, NoLock, NULL, false);
ListCell *part_lc;
foreach(part_lc, part_oids)
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 7a4665cc4e..bfe2d1e1d6 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -89,7 +89,7 @@ ExecSetupPartitionTupleRouting(ModifyTableState *mtstate, Relation rel)
* Get the information about the partition tree after locking all the
* partitions.
*/
- (void) find_all_inheritors(RelationGetRelid(rel), RowExclusiveLock, NULL);
+ (void) find_all_inheritors(RelationGetRelid(rel), RowExclusiveLock, NULL, false);
proute = (PartitionTupleRouting *) palloc0(sizeof(PartitionTupleRouting));
proute->partition_dispatch_info =
RelationGetPartitionDispatchInfo(rel, &proute->num_dispatch,
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 0ab4014be6..3019d4a335 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -1556,7 +1556,7 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
lockmode = AccessShareLock;
/* Scan for all members of inheritance set, acquire needed locks */
- inhOIDs = find_all_inheritors(parentOID, lockmode, NULL);
+ inhOIDs = find_all_inheritors(parentOID, lockmode, NULL, false);
/*
* Check that there's at least one descendant, else treat as no-child
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index b19c76acc8..dcfe452a94 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -629,7 +629,7 @@ check_default_partition_contents(Relation parent, Relation default_rel,
*/
if (default_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
all_parts = find_all_inheritors(RelationGetRelid(default_rel),
- AccessExclusiveLock, NULL);
+ AccessExclusiveLock, NULL, false);
else
all_parts = list_make1_oid(RelationGetRelid(default_rel));
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index bdfb66fa74..82397eb9f5 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1325,7 +1325,8 @@ ProcessUtilitySlow(ParseState *pstate,
ListCell *lc;
List *inheritors = NIL;
- inheritors = find_all_inheritors(relid, lockmode, NULL);
+ inheritors = find_all_inheritors(relid, lockmode,
+ NULL, false);
foreach(lc, inheritors)
{
char relkind = get_rel_relkind(lfirst_oid(lc));
diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h
index a89b3f44a5..ccbf756ce5 100644
--- a/src/include/catalog/pg_inherits.h
+++ b/src/include/catalog/pg_inherits.h
@@ -47,7 +47,7 @@ typedef FormData_pg_inherits *Form_pg_inherits;
extern List *find_inheritance_children(Oid parentrelId, LOCKMODE lockmode,
bool skip_locked, bool *skipped);
extern List *find_all_inheritors(Oid parentrelId, LOCKMODE lockmode,
- List **parents);
+ List **parents, bool skip_locked);
extern bool has_subclass(Oid relationId);
extern bool has_superclass(Oid relationId);
extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId);
--
2.16.2