0003-Only-lock-partitions-that-will-be-scanned-by-a-query.patch

text/plain

Filename: 0003-Only-lock-partitions-that-will-be-scanned-by-a-query.patch
Type: text/plain
Part: 2
Message: speeding up planning with partitions

Patch

Format: format-patch
Series: patch 0003
Subject: Only lock partitions that will be scanned by a query
File+
src/backend/optimizer/prep/prepunion.c 3 5
src/backend/optimizer/util/relnode.c 10 7
From 57b8cadddce13952a0a62d37c51dd02c7a436ebc Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Thu, 23 Aug 2018 17:30:18 +0900
Subject: [PATCH 3/3] Only lock partitions that will be scanned by a query

---
 src/backend/optimizer/prep/prepunion.c |  8 +++-----
 src/backend/optimizer/util/relnode.c   | 17 ++++++++++-------
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 279f686fb0..6a2adb5f4d 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -1555,14 +1555,15 @@ 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);
+	if (rte->relkind != RELKIND_PARTITIONED_TABLE)
+		inhOIDs = find_all_inheritors(parentOID, lockmode, NULL);
 
 	/*
 	 * Check that there's at least one descendant, else treat as no-child
 	 * case.  This could happen despite above has_subclass() check, if table
 	 * once had a child but no longer does.
 	 */
-	if (list_length(inhOIDs) < 2)
+	if (rte->relkind != RELKIND_PARTITIONED_TABLE && list_length(inhOIDs) < 2)
 	{
 		/* Clear flag before returning */
 		rte->inh = false;
@@ -1579,10 +1580,7 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
 
 	/* Partitioned tables are expanded elsewhere. */
 	if (rte->relkind == RELKIND_PARTITIONED_TABLE)
-	{
-		list_free(inhOIDs);
 		return;
-	}
 
 	/*
 	 * Must open the parent relation to examine its tupdesc.  We need not lock
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index b267f07c18..f9bde0c058 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -1825,16 +1825,16 @@ build_partition_rel(PlannerInfo *root, RelOptInfo *parent, Oid partoid)
 {
 	RangeTblEntry *parentrte = root->simple_rte_array[parent->relid];
 	RelOptInfo *result;
+	Index		rootRTindex = 0;
 	Index		partRTindex = 0;
 	RangeTblEntry *partrte = NULL;
 	AppendRelInfo *appinfo = NULL;
 	PlanRowMark *rootrc = NULL;
+	int			lockmode;
 
 	/* Locate the root partitioned table and fetch its PlanRowMark, if any. */
 	if (root->rowMarks)
 	{
-		Index		rootRTindex = 0;
-
 		/*
 		 * The root partitioned table itself might be a child of UNION ALL
 		 * parent, so we must resort to finding the root parent like this.
@@ -1861,13 +1861,16 @@ build_partition_rel(PlannerInfo *root, RelOptInfo *parent, Oid partoid)
 		rootrc = get_plan_rowmark(root->rowMarks, rootRTindex);
 	}
 
-	/*
-	 * expand_inherited_rtentry alreay locked all partitions, so pass
-	 * NoLock for lockmode.
-	 */
+	/* Determine the correct lockmode to use. */
+	if (rootRTindex == root->parse->resultRelation)
+		lockmode = RowExclusiveLock;
+	else if (rootrc && RowMarkRequiresRowShareLock(rootrc->markType))
+		lockmode = RowShareLock;
+	else
+		lockmode = AccessShareLock;
 	add_inheritance_child_to_query(root, parentrte, parent->relid,
 								   parent->reltype, parent->tupdesc,
-								   rootrc, partoid, NoLock,
+								   rootrc, partoid, lockmode,
 								   &appinfo, &partrte, &partRTindex);
 
 	/* Partition turned out to be a partitioned table with 0 partitions. */
-- 
2.11.0