From bad467cbcfa3d8c274f37dcd461ed52fcf619ffd Mon Sep 17 00:00:00 2001
From: Beena Emerson <Beena.Emerson@EnterpriseDB.com>
Date: Tue, 14 Nov 2017 00:12:46 +0530
Subject: [PATCH 1/2] Refactor functions and structs required for runtime
 pruning

Patch by: Beena Emerson
Discussion: https://postgr.es/m/CAOG9ApE16ac-_VVZVvv0gePSgkg_BwYEV1NBqZFqDR2bBE0X0A@mail.gmail.com
---
 src/backend/catalog/partition.c     | 54 ++-----------------------------------
 src/backend/utils/cache/plancache.c |  2 +-
 src/include/catalog/partition.h     |  7 +++++
 src/include/nodes/relation.h        | 45 +++++++++++++++++++++++++++++++
 4 files changed, 55 insertions(+), 53 deletions(-)

diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index c58c735..97f3050 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -132,51 +132,6 @@ typedef struct
 } PartClause;
 
 /*
- * PartScanKeyInfo
- *		Bounding scan keys to look up a table's partitions obtained from
- *		mutually-ANDed clauses containing partitioning-compatible operators
- */
-typedef struct PartScanKeyInfo
-{
-	/*
-	 * Constants constituting the *whole* partition key compared using
-	 * partitioning-compatible equality operator(s).  When n_eqkeys > 0, other
-	 * keys (minkeys and maxkeys) are irrelevant.
-	 */
-	Datum	eqkeys[PARTITION_MAX_KEYS];
-	int		n_eqkeys;
-
-	/*
-	 * Constants that constitute the lower bound on the partition key or a
-	 * prefix thereof.  The last of those constants is compared using > or >=
-	 * operator compatible with partitioning, making this the lower bound in
-	 * a range query.
-	 */
-	Datum	minkeys[PARTITION_MAX_KEYS];
-	int		n_minkeys;
-	bool	min_incl;
-
-	/*
-	 * Constants that constitute the upper bound on the partition key or a
-	 * prefix thereof.  The last of those constants is compared using < or <=
-	 * operator compatible with partitioning, making this the upper bound in
-	 * a range query.
-	 */
-	Datum	maxkeys[PARTITION_MAX_KEYS];
-	int		n_maxkeys;
-	bool	max_incl;
-
-	/*
-	 * Specifies the type of NullTest that was applied to each of the
-	 * partition key columns or -1 if none was applied.  Partitioning handles
-	 * null partition keys specially depending on the partitioning method in
-	 * use, so get_partitions_for_keys can return partitions according to
-	 * the nullness condition for partition keys.
-	 */
-	NullTestType	keynullness[PARTITION_MAX_KEYS];
-} PartScanKeyInfo;
-
-/*
  * PartitionBoundCmpArg - Caller-defined argument to be passed to
  *						  partition_bound_cmp()
  *
@@ -242,9 +197,6 @@ static void get_partition_dispatch_recurse(Relation rel, Relation parent,
 
 static Bitmapset *get_partitions_from_clauses_guts(Relation relation,
 								List *clauses);
-static int classify_partition_bounding_keys(Relation relation, List *clauses,
-								 PartScanKeyInfo *keys, bool *constfalse,
-								 List **or_clauses);
 static void remove_redundant_clauses(PartitionKey partkey,
 						 int partattoff, List *all_clauses,
 						 List **result, bool *constfalse);
@@ -252,8 +204,6 @@ static bool partition_cmp_args(Oid partopfamily, Oid partopcintype,
 				   PartClause *op, PartClause *leftarg, PartClause *rightarg,
 				   bool *result);
 static bool partkey_datum_from_expr(const Expr *expr, Datum *value);
-static Bitmapset *get_partitions_for_keys(Relation rel,
-						PartScanKeyInfo *keys);
 
 /*
  * RelationBuildPartitionDesc
@@ -1642,7 +1592,7 @@ get_partitions_from_clauses_guts(Relation relation, List *clauses)
  * the responsibility of the caller to process the argument clauses of each of
  * the OR clauses, which would involve recursively calling this function.
  */
-static int
+int
 classify_partition_bounding_keys(Relation relation, List *clauses,
 								 PartScanKeyInfo *keys, bool *constfalse,
 								 List **or_clauses)
@@ -2406,7 +2356,7 @@ partition_cmp_args(Oid partopfamily, Oid partopcintype,
  * Outputs:
  *	Partition set satisfying the keys.
  */
-static Bitmapset *
+Bitmapset *
 get_partitions_for_keys(Relation rel, PartScanKeyInfo *keys)
 {
 	PartitionKey	partkey = RelationGetPartitionKey(rel);
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index 853c1f6..9656fa4 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -1041,7 +1041,7 @@ choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams)
 	if (plansource->num_custom_plans < 5)
 		return true;
 
-	avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans;
+	avg_custom_cost = plansource->total_custom_cost / plansource->num_custom_plans + 90000;
 
 	/*
 	 * Prefer generic plan if it's less expensive than the average custom
diff --git a/src/include/catalog/partition.h b/src/include/catalog/partition.h
index 81c626f..7956f04 100644
--- a/src/include/catalog/partition.h
+++ b/src/include/catalog/partition.h
@@ -16,6 +16,7 @@
 #include "fmgr.h"
 #include "executor/tuptable.h"
 #include "nodes/execnodes.h"
+#include "nodes/relation.h"
 #include "parser/parse_node.h"
 #include "utils/rel.h"
 
@@ -111,4 +112,10 @@ extern List *get_proposed_default_constraint(List *new_part_constaints);
 /* For partition-pruning */
 extern Bitmapset *get_partitions_from_clauses(Relation relation,
 							List *partclauses);
+extern int classify_partition_bounding_keys(Relation relation, List *clauses,
+								 PartScanKeyInfo *keys, bool *constfalse,
+								 List **or_clauses);
+Bitmapset *get_partitions_for_keys(Relation rel,
+						PartScanKeyInfo *keys);
+
 #endif							/* PARTITION_H */
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 9c67bd1..3e47de7 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -363,6 +363,51 @@ typedef struct PartitionSchemeData
 
 typedef struct PartitionSchemeData *PartitionScheme;
 
+/*
+ * PartScanKeyInfo
+ *		Bounding scan keys to look up a table's partitions obtained from
+ *		mutually-ANDed clauses containing partitioning-compatible operators
+ */
+typedef struct PartScanKeyInfo
+{
+	/*
+	 * Constants constituting the *whole* partition key compared using
+	 * partitioning-compatible equality operator(s).  When n_eqkeys > 0, other
+	 * keys (minkeys and maxkeys) are irrelevant.
+	 */
+	Datum	eqkeys[PARTITION_MAX_KEYS];
+	int		n_eqkeys;
+
+	/*
+	 * Constants that constitute the lower bound on the partition key or a
+	 * prefix thereof.  The last of those constants is compared using > or >=
+	 * operator compatible with partitioning, making this the lower bound in
+	 * a range query.
+	 */
+	Datum	minkeys[PARTITION_MAX_KEYS];
+	int		n_minkeys;
+	bool	min_incl;
+
+	/*
+	 * Constants that constitute the upper bound on the partition key or a
+	 * prefix thereof.  The last of those constants is compared using < or <=
+	 * operator compatible with partitioning, making this the upper bound in
+	 * a range query.
+	 */
+	Datum	maxkeys[PARTITION_MAX_KEYS];
+	int		n_maxkeys;
+	bool	max_incl;
+
+	/*
+	 * Specifies the type of NullTest that was applied to each of the
+	 * partition key columns or -1 if none was applied.  Partitioning handles
+	 * null partition keys specially depending on the partitioning method in
+	 * use, so get_partitions_for_keys can return partitions according to
+	 * the nullness condition for partition keys.
+	 */
+	NullTestType	keynullness[PARTITION_MAX_KEYS];
+} PartScanKeyInfo;
+
 /*----------
  * RelOptInfo
  *		Per-relation information for planning/optimization
-- 
1.8.3.1

