From 202812a09e1b7500d23a4a29edb8223e32d83555 Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Tue, 12 Dec 2017 13:46:26 +0900
Subject: [PATCH v23 3/5] Move some code of set_append_rel_size to separate
 function

The code that initializes basic properties of a partition RelOptInfo
from the information in parent's RelOptInfo.  It will be needed to be
called by the pairwise-join related code to minimally initialize the
partitions that earlier planning would have considered pruned and
hence left untouched.  That's not true currently, because the current
pruning method touches each partition (setting its basic properties)
before considering it pruned.
---
 src/backend/optimizer/path/allpaths.c | 80 ++-----------------------------
 src/backend/optimizer/util/relnode.c  | 90 +++++++++++++++++++++++++++++++++++
 src/include/optimizer/pathnode.h      |  4 ++
 3 files changed, 97 insertions(+), 77 deletions(-)

diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index fd1a58336b..fd68374e20 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -921,85 +921,11 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
 		childrel = find_base_rel(root, childRTindex);
 		Assert(childrel->reloptkind == RELOPT_OTHER_MEMBER_REL);
 
-		if (rel->part_scheme)
-		{
-			AttrNumber	attno;
-
-			/*
-			 * We need attr_needed data for building targetlist of a join
-			 * relation representing join between matching partitions for
-			 * partition-wise join. A given attribute of a child will be
-			 * needed in the same highest joinrel where the corresponding
-			 * attribute of parent is needed. Hence it suffices to use the
-			 * same Relids set for parent and child.
-			 */
-			for (attno = rel->min_attr; attno <= rel->max_attr; attno++)
-			{
-				int			index = attno - rel->min_attr;
-				Relids		attr_needed = rel->attr_needed[index];
-
-				/* System attributes do not need translation. */
-				if (attno <= 0)
-				{
-					Assert(rel->min_attr == childrel->min_attr);
-					childrel->attr_needed[index] = attr_needed;
-				}
-				else
-				{
-					Var		   *var = list_nth_node(Var,
-													appinfo->translated_vars,
-													attno - 1);
-					int			child_index;
-
-					/*
-					 * Ignore any column dropped from the parent.
-					 * Corresponding Var won't have any translation. It won't
-					 * have attr_needed information, since it can not be
-					 * referenced in the query.
-					 */
-					if (var == NULL)
-					{
-						Assert(attr_needed == NULL);
-						continue;
-					}
-
-					child_index = var->varattno - childrel->min_attr;
-					childrel->attr_needed[child_index] = attr_needed;
-				}
-			}
-		}
-
-		/*
-		 * Copy/Modify targetlist. Even if this child is deemed empty, we need
-		 * its targetlist in case it falls on nullable side in a child-join
-		 * because of partition-wise join.
-		 *
-		 * NB: the resulting childrel->reltarget->exprs may contain arbitrary
-		 * expressions, which otherwise would not occur in a rel's targetlist.
-		 * Code that might be looking at an appendrel child must cope with
-		 * such.  (Normally, a rel's targetlist would only include Vars and
-		 * PlaceHolderVars.)  XXX we do not bother to update the cost or width
-		 * fields of childrel->reltarget; not clear if that would be useful.
-		 */
-		childrel->reltarget->exprs = (List *)
-			adjust_appendrel_attrs(root,
-								   (Node *) rel->reltarget->exprs,
-								   1, &appinfo);
-
 		/*
-		 * We have to make child entries in the EquivalenceClass data
-		 * structures as well.  This is needed either if the parent
-		 * participates in some eclass joins (because we will want to consider
-		 * inner-indexscan joins on the individual children) or if the parent
-		 * has useful pathkeys (because we should try to build MergeAppend
-		 * paths that produce those sort orderings). Even if this child is
-		 * deemed dummy, it may fall on nullable side in a child-join, which
-		 * in turn may participate in a MergeAppend, where we will need the
-		 * EquivalenceClass data structures.
+		 * Initialize some properties of child rel from the parent rel, such
+		 * target list, equivalence class members, etc.
 		 */
-		if (rel->has_eclass_joins || has_useful_pathkeys(root, rel))
-			add_child_rel_equivalences(root, appinfo, rel, childrel);
-		childrel->has_eclass_joins = rel->has_eclass_joins;
+		set_basic_child_rel_properties(root, rel, childrel, appinfo);
 
 		/*
 		 * We have to copy the parent's quals to the child, with appropriate
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index ac5a7c9553..35345ccbe9 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -1748,3 +1748,93 @@ build_joinrel_partition_info(RelOptInfo *joinrel, RelOptInfo *outer_rel,
 		joinrel->nullable_partexprs[cnt] = nullable_partexpr;
 	}
 }
+
+/*
+ * Initialize some basic properties of child rel from the parent rel, such
+ * target list, equivalence class members, etc.
+ */
+void
+set_basic_child_rel_properties(PlannerInfo *root,
+							   RelOptInfo *rel,
+							   RelOptInfo *childrel,
+							   AppendRelInfo *appinfo)
+{
+	/*
+	 * Copy/Modify targetlist. Even if this child is deemed empty, we need
+	 * its targetlist in case it falls on nullable side in a child-join
+	 * because of partition-wise join.
+	 *
+	 * NB: the resulting childrel->reltarget->exprs may contain arbitrary
+	 * expressions, which otherwise would not occur in a rel's targetlist.
+	 * Code that might be looking at an appendrel child must cope with
+	 * such.  (Normally, a rel's targetlist would only include Vars and
+	 * PlaceHolderVars.)  XXX we do not bother to update the cost or width
+	 * fields of childrel->reltarget; not clear if that would be useful.
+	 */
+	childrel->reltarget->exprs = (List *)
+			adjust_appendrel_attrs(root,
+								   (Node *) rel->reltarget->exprs,
+								   1, &appinfo);
+
+	/*
+	 * We have to make child entries in the EquivalenceClass data
+	 * structures as well.  This is needed either if the parent
+	 * participates in some eclass joins (because we will want to consider
+	 * inner-indexscan joins on the individual children) or if the parent
+	 * has useful pathkeys (because we should try to build MergeAppend
+	 * paths that produce those sort orderings). Even if this child is
+	 * deemed dummy, it may fall on nullable side in a child-join, which
+	 * in turn may participate in a MergeAppend, where we will need the
+	 * EquivalenceClass data structures.
+	 */
+	if (rel->has_eclass_joins || has_useful_pathkeys(root, rel))
+		add_child_rel_equivalences(root, appinfo, rel, childrel);
+	childrel->has_eclass_joins = rel->has_eclass_joins;
+
+	if (rel->part_scheme)
+	{
+		AttrNumber	attno;
+
+		/*
+		 * We need attr_needed data for building targetlist of a join relation
+		 * representing join between matching partitions for partition-wise
+		 * join. A given attribute of a child will be needed in the same
+		 * highest joinrel where the corresponding attribute of parent is
+		 * needed. Hence it suffices to use the same Relids set for parent and
+		 * child.
+		 */
+		for (attno = rel->min_attr; attno <= rel->max_attr; attno++)
+		{
+			int			index = attno - rel->min_attr;
+			Relids		attr_needed = rel->attr_needed[index];
+
+			/* System attributes do not need translation. */
+			if (attno <= 0)
+			{
+				Assert(rel->min_attr == childrel->min_attr);
+				childrel->attr_needed[index] = attr_needed;
+			}
+			else
+			{
+				Var		   *var = list_nth_node(Var,
+												appinfo->translated_vars,
+												attno - 1);
+				int			child_index;
+
+				/*
+				 * Ignore any column dropped from the parent.  Corresponding
+				 * Var won't have any translation. It won't have attr_needed
+				 * information, since it can not be referenced in the query.
+				 */
+				if (var == NULL)
+				{
+					Assert(attr_needed == NULL);
+					continue;
+				}
+
+				child_index = var->varattno - childrel->min_attr;
+				childrel->attr_needed[child_index] = attr_needed;
+			}
+		}
+	}
+}
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index ef7173fbf8..142eecd733 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -301,5 +301,9 @@ extern RelOptInfo *build_child_join_rel(PlannerInfo *root,
 					 RelOptInfo *outer_rel, RelOptInfo *inner_rel,
 					 RelOptInfo *parent_joinrel, List *restrictlist,
 					 SpecialJoinInfo *sjinfo, JoinType jointype);
+extern void set_basic_child_rel_properties(PlannerInfo *root,
+							   RelOptInfo *rel,
+							   RelOptInfo *childrel,
+							   AppendRelInfo *appinfo);
 
 #endif							/* PATHNODE_H */
-- 
2.11.0

