v9-0002-Add-skip_locked-argument-to-find_inheritance_chil.patch
application/octet-stream
Filename: v9-0002-Add-skip_locked-argument-to-find_inheritance_chil.patch
Type: application/octet-stream
Part: 5
Patch
Format: format-patch
Series: patch v9-0002
Subject: Add skip_locked argument to find_inheritance_children().
| File | + | − |
|---|---|---|
| src/backend/catalog/pg_inherits.c | 23 | 3 |
| src/backend/commands/lockcmds.c | 1 | 1 |
| src/backend/commands/tablecmds.c | 8 | 8 |
| src/backend/commands/trigger.c | 1 | 1 |
| src/backend/utils/cache/partcache.c | 1 | 1 |
| src/include/catalog/pg_inherits.h | 2 | 1 |
From ad3cb733a4fa60f42734aeeddbaa82656e2e9085 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Wed, 5 Sep 2018 14:42:55 +0000
Subject: [PATCH v9 2/7] Add skip_locked argument to
find_inheritance_children().
---
src/backend/catalog/pg_inherits.c | 26 +++++++++++++++++++++++---
src/backend/commands/lockcmds.c | 2 +-
src/backend/commands/tablecmds.c | 16 ++++++++--------
src/backend/commands/trigger.c | 2 +-
src/backend/utils/cache/partcache.c | 2 +-
src/include/catalog/pg_inherits.h | 3 ++-
6 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 85baca54cc..1b936123c5 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -51,9 +51,14 @@ typedef struct SeenRelsEntry
* 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.
+ *
+ * If skip_locked is true, any child relations that cannot be locked immediately
+ * without waiting are not added to the returned OID list, and skipped will be
+ * set to true if it is provided. Otherwise, skipped will be set to false if it
+ * is provided.
*/
List *
-find_inheritance_children(Oid parentrelId, LOCKMODE lockmode)
+find_inheritance_children(Oid parentrelId, LOCKMODE lockmode, bool skip_locked, bool *skipped)
{
List *list = NIL;
Relation relation;
@@ -65,13 +70,19 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode)
int maxoids,
numoids,
i;
+ bool did_skip = false;
/*
* Can skip the scan if pg_class shows the relation has never had a
* subclass.
*/
if (!has_subclass(parentrelId))
+ {
+ if (skipped != NULL)
+ *skipped = did_skip;
+
return NIL;
+ }
/*
* Scan pg_inherits and build a working array of subclass OIDs.
@@ -124,7 +135,13 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode)
if (lockmode != NoLock)
{
/* Get the lock to synchronize against concurrent drop */
- LockRelationOid(inhrelid, lockmode);
+ if (!skip_locked)
+ LockRelationOid(inhrelid, lockmode);
+ else if (!ConditionalLockRelationOid(inhrelid, lockmode))
+ {
+ did_skip = true;
+ continue;
+ }
/*
* Now that we have the lock, double-check to see if the relation
@@ -145,6 +162,9 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode)
pfree(oidarr);
+ if (skipped != NULL)
+ *skipped = did_skip;
+
return list;
}
@@ -199,7 +219,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);
+ currentchildren = find_inheritance_children(currentrel, lockmode, false, NULL);
/*
* Add to the queue only those children not already seen. This avoids
diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c
index 71278b38cf..ef4d4a8c9d 100644
--- a/src/backend/commands/lockcmds.c
+++ b/src/backend/commands/lockcmds.c
@@ -119,7 +119,7 @@ LockTableRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, Oid userid)
List *children;
ListCell *lc;
- children = find_inheritance_children(reloid, NoLock);
+ children = find_inheritance_children(reloid, NoLock, false, NULL);
foreach(lc, children)
{
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index f9e83c2456..7520de1b56 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -2824,7 +2824,7 @@ renameatt_internal(Oid myrelid,
* expected_parents will only be 0 if we are not already recursing.
*/
if (expected_parents == 0 &&
- find_inheritance_children(myrelid, NoLock) != NIL)
+ find_inheritance_children(myrelid, NoLock, false, NULL) != NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("inherited column \"%s\" must be renamed in child tables too",
@@ -3023,7 +3023,7 @@ rename_constraint_internal(Oid myrelid,
else
{
if (expected_parents == 0 &&
- find_inheritance_children(myrelid, NoLock) != NIL)
+ find_inheritance_children(myrelid, NoLock, false, NULL) != NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("inherited constraint \"%s\" must be renamed in child tables too",
@@ -5478,7 +5478,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
*/
if (colDef->identity &&
recurse &&
- find_inheritance_children(myrelid, NoLock) != NIL)
+ find_inheritance_children(myrelid, NoLock, false, NULL) != NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("cannot recursively add identity column to table that has child tables")));
@@ -5720,7 +5720,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
* routines, we have to do this one level of recursion at a time; we can't
* use find_all_inheritors to do it in one pass.
*/
- children = find_inheritance_children(RelationGetRelid(rel), lockmode);
+ children = find_inheritance_children(RelationGetRelid(rel), lockmode, false, NULL);
/*
* If we are told not to recurse, there had better not be any child
@@ -6823,7 +6823,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
* routines, we have to do this one level of recursion at a time; we can't
* use find_all_inheritors to do it in one pass.
*/
- children = find_inheritance_children(RelationGetRelid(rel), lockmode);
+ children = find_inheritance_children(RelationGetRelid(rel), lockmode, false, NULL);
if (children)
{
@@ -7275,7 +7275,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
* routines, we have to do this one level of recursion at a time; we can't
* use find_all_inheritors to do it in one pass.
*/
- children = find_inheritance_children(RelationGetRelid(rel), lockmode);
+ children = find_inheritance_children(RelationGetRelid(rel), lockmode, false, NULL);
/*
* Check if ONLY was specified with ALTER TABLE. If so, allow the
@@ -8964,7 +8964,7 @@ ATExecDropConstraint(Relation rel, const char *constrName,
* use find_all_inheritors to do it in one pass.
*/
if (!is_no_inherit_constraint)
- children = find_inheritance_children(RelationGetRelid(rel), lockmode);
+ children = find_inheritance_children(RelationGetRelid(rel), lockmode, false, NULL);
else
children = NIL;
@@ -9306,7 +9306,7 @@ ATPrepAlterColumnType(List **wqueue,
}
}
else if (!recursing &&
- find_inheritance_children(RelationGetRelid(rel), NoLock) != NIL)
+ find_inheritance_children(RelationGetRelid(rel), NoLock, false, NULL) != NIL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("type of inherited column \"%s\" must be changed in child tables too",
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 2436692eb8..f2617cfb1d 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -1109,7 +1109,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
ListCell *l;
List *idxs = NIL;
- idxs = find_inheritance_children(indexOid, ShareRowExclusiveLock);
+ idxs = find_inheritance_children(indexOid, ShareRowExclusiveLock, false, NULL);
foreach(l, idxs)
childTbls = lappend_oid(childTbls,
IndexGetRelation(lfirst_oid(l),
diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c
index 115a9fe78f..c160e755e2 100644
--- a/src/backend/utils/cache/partcache.c
+++ b/src/backend/utils/cache/partcache.c
@@ -285,7 +285,7 @@ RelationBuildPartitionDesc(Relation rel)
PartitionRangeBound **rbounds = NULL;
/* Get partition oids from pg_inherits */
- inhoids = find_inheritance_children(RelationGetRelid(rel), NoLock);
+ inhoids = find_inheritance_children(RelationGetRelid(rel), NoLock, false, NULL);
/* Collect bound spec nodes in a list */
i = 0;
diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h
index 2a98e02c6a..a89b3f44a5 100644
--- a/src/include/catalog/pg_inherits.h
+++ b/src/include/catalog/pg_inherits.h
@@ -44,7 +44,8 @@ CATALOG(pg_inherits,2611,InheritsRelationId) BKI_WITHOUT_OIDS
typedef FormData_pg_inherits *Form_pg_inherits;
-extern List *find_inheritance_children(Oid parentrelId, LOCKMODE lockmode);
+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);
extern bool has_subclass(Oid relationId);
--
2.16.2