From 1b83e9675caf8002c7d59bcf1f4a76f39c233e6d Mon Sep 17 00:00:00 2001
From: amitlan <amitlangote09@gmail.com>
Date: Fri, 18 Nov 2022 20:45:06 +0900
Subject: [PATCH v26 2/4] ConcatRTEPermissionInfoLists() -> CombineRangeTable()

---
 src/backend/optimizer/plan/subselect.c    | 13 ++++------
 src/backend/optimizer/prep/prepjointree.c | 28 ++++++++--------------
 src/backend/parser/parse_relation.c       |  2 +-
 src/backend/rewrite/rewriteHandler.c      | 19 ++++++++-------
 src/backend/rewrite/rewriteManip.c        | 29 ++++++++++++++---------
 src/include/rewrite/rewriteManip.h        |  6 ++---
 6 files changed, 47 insertions(+), 50 deletions(-)

diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index cbeb0191fb..14e67d8c4c 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -1497,15 +1497,12 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink,
 		return NULL;
 
 	/*
-	 * Add subquery's RTEPermissionInfos into the upper query.  This also
-	 * updates the subquery's RTEs' perminfoindex.
+	 * Now we can attach the modified subquery rtable to the parent.
+	 * This also adds subquery's RTEPermissionInfos into the upper query.
 	 */
-	parse->rtepermlist = ConcatRTEPermissionInfoLists(parse->rtepermlist,
-													  subselect->rtepermlist,
-													  subselect->rtable);
-
-	/* Now we can attach the modified subquery rtable to the parent */
-	parse->rtable = list_concat(parse->rtable, subselect->rtable);
+	parse->rtable = CombineRangeTables(parse->rtable, subselect->rtable, false,
+									   subselect->rtepermlist,
+									   &parse->rtepermlist);
 
 	/*
 	 * And finally, build the JoinExpr node.
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 8ac0a41d0e..a608a4e071 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -1198,21 +1198,16 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
 		}
 	}
 
-	/*
-	 * Add subquery's RTEPermissionInfos into the upper query.  This also
-	 * updates the subquery's RTEs' perminfoindex.
-	 */
-	parse->rtepermlist = ConcatRTEPermissionInfoLists(parse->rtepermlist,
-													  subquery->rtepermlist,
-													  subquery->rtable);
-
 	/*
 	 * Now append the adjusted rtable entries to upper query. (We hold off
 	 * until after fixing the upper rtable entries; no point in running that
 	 * code on the subquery ones too.)
+	 *
+	 * This also adds subquery's RTEPermissionInfos into the upper query.
 	 */
-	parse->rtable = list_concat(parse->rtable, subquery->rtable);
-
+	parse->rtable = CombineRangeTables(parse->rtable, subquery->rtable, false,
+									   subquery->rtepermlist,
+									   &parse->rtepermlist);
 	/*
 	 * Pull up any FOR UPDATE/SHARE markers, too.  (OffsetVarNodes already
 	 * adjusted the marker rtindexes, so just concat the lists.)
@@ -1346,17 +1341,14 @@ pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
 		}
 	}
 
-	/*
-	 * Add subquery's RTEPermissionInfos into the upper query.  This also
-	 * updates the subquery's RTEs' perminfoindex.
-	 */
-	root->parse->rtepermlist = ConcatRTEPermissionInfoLists(root->parse->rtepermlist,
-															subquery->rtepermlist,
-															rtable);
 	/*
 	 * Append child RTEs to parent rtable.
+	 *
+	 * This also adds subquery's RTEPermissionInfos into the upper query.
 	 */
-	root->parse->rtable = list_concat(root->parse->rtable, rtable);
+	root->parse->rtable = CombineRangeTables(root->parse->rtable, rtable,
+											 false, subquery->rtepermlist,
+											 &root->parse->rtepermlist);
 
 	/*
 	 * Recursively scan the subquery's setOperations tree and add
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 177558a158..40ce0dc308 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -3757,7 +3757,7 @@ GetRTEPermissionInfo(List *rtepermlist, RangeTblEntry *rte)
 	perminfo = list_nth_node(RTEPermissionInfo, rtepermlist,
 							 rte->perminfoindex - 1);
 	if (perminfo->relid != rte->relid)
-		elog(ERROR, "permission info at index %u (with relid=%u) does not match requested RTE (with relid=%u)",
+		elog(ERROR, "permission info at index %u (with relid=%u) does not match provided RTE (with relid=%u)",
 			 rte->perminfoindex, perminfo->relid, rte->relid);
 
 	return perminfo;
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index dde9788755..971e273681 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -353,7 +353,6 @@ rewriteRuleAction(Query *parsetree,
 	Query	   *sub_action;
 	Query	  **sub_action_ptr;
 	acquireLocksOnSubLinks_context context;
-	List	   *query_rtable;
 
 	context.for_execute = true;
 
@@ -417,15 +416,17 @@ rewriteRuleAction(Query *parsetree,
 	 * NOTE: because planner will destructively alter rtable and rtepermlist,
 	 * we must ensure that rule action's lists are separate and shares no
 	 * substructure with the main query's lists.  Hence do a deep copy here
-	 * for both.  Copy rtable before calling ConcatRTEPermissionInfoLists(),
-	 * because perminfoindex of those RTEs will be updated there.
+	 * for both.
+	 *
+	 * NB: Must pass parstree->rtable as the src_rtable so that its
+	 * RTE's perminfoindex are updated, though they must appear before the
+	 * sub_action's RTEs, so pass true for 'prepend'.
 	 */
-	query_rtable = copyObject(parsetree->rtable);
-	sub_action->rtepermlist =
-		ConcatRTEPermissionInfoLists(copyObject(sub_action->rtepermlist),
-									 parsetree->rtepermlist,
-									 query_rtable);
-	sub_action->rtable = list_concat(query_rtable, sub_action->rtable);
+	sub_action->rtable = CombineRangeTables(sub_action->rtable,
+											copyObject(parsetree->rtable),
+											true,
+											copyObject(parsetree->rtepermlist),
+											&sub_action->rtepermlist);
 
 	/*
 	 * There could have been some SubLinks in parsetree's rtable, in which
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index 8f6446a435..a2090f1d73 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -1533,31 +1533,38 @@ ReplaceVarsFromTargetList(Node *node,
 }
 
 /*
- * ConcatRTEPermissionInfoLists
- * 		Add RTEPermissionInfos found in src_rtepermlist into *dest_rtepermlist
+ * ConcatRangeTables
+ * 		Adds the RTEs of 'src_rtable' into 'dest_rtable'
  *
- * Also updates perminfoindex of the RTEs in src_rtable to point to the
- * "source" perminfos after they have been added into *dest_rtepermlist.
+ * If 'prepend' is true, they are added at the head of the list.
+ *
+ * This also adds the RTEPermissionInfos of 'rtepermlist2' (belonging to the
+ * RTEs in 'rtable2') into *rtepermlist1 and updates perminfoindex of the RTEs
+ * in src_rtable to now point to their perminfos' indexes in
+ * *dest_rtepermlist.
  */
 List *
-ConcatRTEPermissionInfoLists(List *dest_rtepermlist, List *src_rtepermlist,
-							 List *src_rtable)
+CombineRangeTables(List *dest_rtable, List *src_rtable, bool prepend,
+				   List *src_rtepermlist, List **dest_rtepermlist)
 {
 	ListCell   *l;
-	int			offset = list_length(dest_rtepermlist);
+	int			permlist_offset = list_length(*dest_rtepermlist);
 
-	dest_rtepermlist = list_concat(dest_rtepermlist, src_rtepermlist);
+	*dest_rtepermlist = list_concat(*dest_rtepermlist, src_rtepermlist);
 
-	if (offset > 0)
+	if (permlist_offset > 0)
 	{
 		foreach(l, src_rtable)
 		{
 			RangeTblEntry  *rte = lfirst_node(RangeTblEntry, l);
 
 			if (rte->perminfoindex > 0)
-				rte->perminfoindex += offset;
+				rte->perminfoindex += permlist_offset;
 		}
 	}
 
-	return dest_rtepermlist;
+	if (prepend)
+		return list_concat(src_rtable, dest_rtable);
+
+	return list_concat(dest_rtable, src_rtable);
 }
diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h
index 76699c8e13..8987c366f7 100644
--- a/src/include/rewrite/rewriteManip.h
+++ b/src/include/rewrite/rewriteManip.h
@@ -83,8 +83,8 @@ extern Node *ReplaceVarsFromTargetList(Node *node,
 									   ReplaceVarsNoMatchOption nomatch_option,
 									   int nomatch_varno,
 									   bool *outer_hasSubLinks);
-extern List *ConcatRTEPermissionInfoLists(List *dest_rtepermlist,
-							 List *src_rtepermlist,
-							 List *src_rtable);
+extern List *CombineRangeTables(List *dest_rtable, List *src_rtable,
+				   bool prepend, List *src_rtepermlist,
+				   List **dest_rtepermlist);
 
 #endif							/* REWRITEMANIP_H */
-- 
2.35.3

