From 1506f411e1cfedab372318b641a71bd06c4ea8fc Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Thu, 8 Aug 2019 13:49:29 +0900
Subject: [PATCH v3 1/2] Improve RelOptInfo.partition_qual usage

This includes following improvements:

 1. Initialize partition_qual with necessary polishing in only one
    place, that is, in get_relation_info(), instead of having it be
    duplicated in multiples places where it's used

 2. get_relation_constraints() can use sometimes partition_qual
    instead of fetching it from the relcache
---
 src/backend/optimizer/util/plancat.c | 22 ++++++++++++++++++----
 src/backend/partitioning/partprune.c | 32 ++++++--------------------------
 2 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 98e99481c6..23cbee8aef 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -1267,10 +1267,14 @@ get_relation_constraints(PlannerInfo *root,
 	 */
 	if (include_partition && relation->rd_rel->relispartition)
 	{
-		List	   *pcqual = RelationGetPartitionQual(relation);
-
-		if (pcqual)
+		/* Use the already computed constraint if any */
+		if (rel->partition_qual)
+			result = list_concat(result, rel->partition_qual);
+		else
 		{
+			/* Nope, fetch from the relcache. */
+			List       *pcqual = RelationGetPartitionQual(relation);
+
 			/*
 			 * Run the partition quals through const-simplification similar to
 			 * check constraints.  We skip canonicalize_qual, though, because
@@ -2136,6 +2140,7 @@ set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
 							Relation relation)
 {
 	PartitionDesc partdesc;
+	List	   *partconstr;
 
 	/* Create the PartitionDirectory infrastructure if we didn't already */
 	if (root->glob->partition_directory == NULL)
@@ -2149,7 +2154,16 @@ set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
 	rel->boundinfo = partdesc->boundinfo;
 	rel->nparts = partdesc->nparts;
 	set_baserel_partition_key_exprs(relation, rel);
-	rel->partition_qual = RelationGetPartitionQual(relation);
+	/* Initialize the partition constraint, if any. */
+	partconstr = RelationGetPartitionQual(relation);
+	if (partconstr)
+	{
+		partconstr = (List *) expression_planner((Expr *) partconstr);
+		/* Fix Vars to have desired varno. */
+		if (rel->relid != 1)
+			ChangeVarNodes((Node *) partconstr, 1, rel->relid, 0);
+		rel->partition_qual = partconstr;
+	}
 }
 
 /*
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index 2ed1e44c18..d399df6cf5 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -631,19 +631,10 @@ gen_partprune_steps(RelOptInfo *rel, List *clauses, PartClauseTarget target,
 	 * partition qual to the clause list in this case only.  This may result
 	 * in the default partition being eliminated.
 	 */
-	if (partition_bound_has_default(rel->boundinfo) &&
-		rel->partition_qual != NIL)
+	if (partition_bound_has_default(rel->boundinfo) && rel->partition_qual)
 	{
-		List	   *partqual = rel->partition_qual;
-
-		partqual = (List *) expression_planner((Expr *) partqual);
-
-		/* Fix Vars to have the desired varno */
-		if (rel->relid != 1)
-			ChangeVarNodes((Node *) partqual, 1, rel->relid, 0);
-
 		/* Use list_copy to avoid modifying the passed-in List */
-		clauses = list_concat(list_copy(clauses), partqual);
+		clauses = list_concat(list_copy(clauses), rel->partition_qual);
 	}
 
 	/* Down into the rabbit-hole. */
@@ -1024,22 +1015,11 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context,
 		 * as contradictory and we're done.  This is particularly helpful to
 		 * prune the default partition.
 		 */
-		if (context->rel->partition_qual)
+		if (predicate_refuted_by(context->rel->partition_qual,
+								 list_make1(clause), false))
 		{
-			List	   *partconstr;
-
-			partconstr = (List *)
-				expression_planner((Expr *) context->rel->partition_qual);
-			if (context->rel->relid != 1)
-				ChangeVarNodes((Node *) partconstr, 1,
-							   context->rel->relid, 0);
-			if (predicate_refuted_by(partconstr,
-									 list_make1(clause),
-									 false))
-			{
-				context->contradictory = true;
-				return NIL;
-			}
+			context->contradictory = true;
+			return NIL;
 		}
 
 		/*
-- 
2.11.0

