v40-0001-Add-partsupfunc-to-PartitionSchemeData.patch

text/plain

Filename: v40-0001-Add-partsupfunc-to-PartitionSchemeData.patch
Type: text/plain
Part: 0
Message: Re: [HACKERS] path toward faster partition pruning

Patch

Format: format-patch
Series: patch v40-0001
Subject: Add partsupfunc to PartitionSchemeData
File+
src/backend/optimizer/util/plancat.c 22 2
src/include/nodes/relation.h 4 0
From d494978cf0f952a88a9942aa8584f42225f6a43d Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Fri, 9 Feb 2018 09:58:50 +0900
Subject: [PATCH v40 1/4] Add partsupfunc to PartitionSchemeData

partsupfunc is merely a cache of the value in PartitionKey to avoid
having to fetch it from the relcache at arbitrary points within the
planner.  It's needed to compare a matched operator clause's constant
argument against partition bounds when performing partition pruning.
---
 src/backend/optimizer/util/plancat.c | 24 ++++++++++++++++++++++--
 src/include/nodes/relation.h         |  4 ++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index bd3a0c4a0a..093ca5208e 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -1877,7 +1877,8 @@ find_partition_scheme(PlannerInfo *root, Relation relation)
 {
 	PartitionKey partkey = RelationGetPartitionKey(relation);
 	ListCell   *lc;
-	int			partnatts;
+	int			partnatts,
+				i;
 	PartitionScheme part_scheme;
 
 	/* A partitioned table should have a partition key. */
@@ -1895,7 +1896,7 @@ find_partition_scheme(PlannerInfo *root, Relation relation)
 			partnatts != part_scheme->partnatts)
 			continue;
 
-		/* Match the partition key types. */
+		/* Match partition key type properties. */
 		if (memcmp(partkey->partopfamily, part_scheme->partopfamily,
 				   sizeof(Oid) * partnatts) != 0 ||
 			memcmp(partkey->partopcintype, part_scheme->partopcintype,
@@ -1913,6 +1914,19 @@ find_partition_scheme(PlannerInfo *root, Relation relation)
 		Assert(memcmp(partkey->parttypbyval, part_scheme->parttypbyval,
 					  sizeof(bool) * partnatts) == 0);
 
+		/*
+		 * If partopfamily and partopcintype matched, must have the same
+		 * partition comparison functions.  Note that we cannot reliably
+		 * Assert the equality of function structs themselves for they might
+		 * be different across PartitionKey's, so just Assert for the function
+		 * OIDs.
+		 */
+#ifdef USE_ASSERT_CHECKING
+		for (i = 0; i < partkey->partnatts; i++)
+			Assert(partkey->partsupfunc[i].fn_oid ==
+				   part_scheme->partsupfunc[i].fn_oid);
+#endif
+
 		/* Found matching partition scheme. */
 		return part_scheme;
 	}
@@ -1947,6 +1961,12 @@ find_partition_scheme(PlannerInfo *root, Relation relation)
 	memcpy(part_scheme->parttypbyval, partkey->parttypbyval,
 		   sizeof(bool) * partnatts);
 
+	part_scheme->partsupfunc = (FmgrInfo *)
+		palloc(sizeof(FmgrInfo) * partnatts);
+	for (i = 0; i < partnatts; i++)
+		fmgr_info_copy(&part_scheme->partsupfunc[i], &partkey->partsupfunc[i],
+					   CurrentMemoryContext);
+
 	/* Add the partitioning scheme to PlannerInfo. */
 	root->part_schemes = lappend(root->part_schemes, part_scheme);
 
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index abbbda9e91..f151646271 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -15,6 +15,7 @@
 #define RELATION_H
 
 #include "access/sdir.h"
+#include "fmgr.h"
 #include "lib/stringinfo.h"
 #include "nodes/params.h"
 #include "nodes/parsenodes.h"
@@ -356,6 +357,9 @@ typedef struct PartitionSchemeData
 	/* Cached information about partition key data types. */
 	int16	   *parttyplen;
 	bool	   *parttypbyval;
+
+	/* Cached information about partition comparison functions. */
+	FmgrInfo   *partsupfunc;
 }			PartitionSchemeData;
 
 typedef struct PartitionSchemeData *PartitionScheme;
-- 
2.11.0