From e4fb7ae7099615ca0d68455f13c2a43d3f33f015 Mon Sep 17 00:00:00 2001
From: Richard Guo <guofenglinux@gmail.com>
Date: Mon, 13 Mar 2023 17:32:39 +0800
Subject: [PATCH v1] Draft group RestrictInfos

---
 src/backend/optimizer/plan/initsplan.c    | 10 ++++++++++
 src/backend/optimizer/util/relnode.c      | 17 ++++++++++++++++-
 src/backend/optimizer/util/restrictinfo.c |  1 +
 src/include/nodes/pathnodes.h             |  2 ++
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index c6c21a7338..73e12d75b2 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -123,6 +123,7 @@ static void distribute_qual_to_rels(PlannerInfo *root, Node *clause,
 									bool allow_equivalence,
 									bool has_clone,
 									bool is_clone,
+									List **group_rinfo_list,
 									List **postponed_oj_qual_list);
 static bool check_redundant_nullability_qual(PlannerInfo *root, Node *clause);
 static Relids get_join_domain_min_rels(PlannerInfo *root, Relids domain_relids);
@@ -2100,6 +2101,7 @@ distribute_quals_to_rels(PlannerInfo *root, List *clauses,
 						 List **postponed_oj_qual_list)
 {
 	ListCell   *lc;
+	List	   *group_rinfo_list = NULL;
 
 	foreach(lc, clauses)
 	{
@@ -2115,6 +2117,7 @@ distribute_quals_to_rels(PlannerInfo *root, List *clauses,
 								allow_equivalence,
 								has_clone,
 								is_clone,
+								&group_rinfo_list,
 								postponed_oj_qual_list);
 	}
 }
@@ -2170,6 +2173,7 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
 						bool allow_equivalence,
 						bool has_clone,
 						bool is_clone,
+						List **group_rinfo_list,
 						List **postponed_oj_qual_list)
 {
 	Relids		relids;
@@ -2394,6 +2398,12 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
 	restrictinfo->has_clone = has_clone;
 	restrictinfo->is_clone = is_clone;
 
+	if (has_clone || is_clone)
+	{
+		*group_rinfo_list = lappend(*group_rinfo_list, restrictinfo);
+		restrictinfo->group_rinfos = *group_rinfo_list;
+	}
+
 	/*
 	 * If it's a join clause, add vars used in the clause to targetlists of
 	 * their relations, so that they will be emitted by the plan nodes that
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 68fd033595..f28e42e378 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -1308,10 +1308,25 @@ subbuild_joinrel_restrictlist(PlannerInfo *root,
 			 */
 			if (rinfo->has_clone || rinfo->is_clone)
 			{
+				ListCell   *lc;
+				Relids		group_clause_relids = bms_copy(rinfo->clause_relids);
+
 				Assert(!RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids));
+				Assert(rinfo->group_rinfos != NULL);
+
+				foreach(lc, rinfo->group_rinfos)
+				{
+					RestrictInfo *otherinfo = (RestrictInfo *) lfirst(lc);
+
+					if (otherinfo == rinfo)
+						continue;
+					group_clause_relids = bms_add_members(group_clause_relids,
+														  otherinfo->clause_relids);
+				}
+
 				if (!bms_is_subset(rinfo->required_relids, both_input_relids))
 					continue;
-				if (!clause_is_computable_at(root, rinfo->clause_relids,
+				if (!clause_is_computable_at(root, group_clause_relids,
 											 both_input_relids))
 					continue;
 			}
diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c
index c44bd2f815..0c111f6934 100644
--- a/src/backend/optimizer/util/restrictinfo.c
+++ b/src/backend/optimizer/util/restrictinfo.c
@@ -119,6 +119,7 @@ make_restrictinfo_internal(PlannerInfo *root,
 	restrictinfo->can_join = false; /* may get set below */
 	restrictinfo->security_level = security_level;
 	restrictinfo->outer_relids = outer_relids;
+	restrictinfo->group_rinfos = NULL;
 
 	/*
 	 * If it's potentially delayable by lower-level security quals, figure out
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index d61a62da19..9cd80dc93e 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -2578,6 +2578,8 @@ typedef struct RestrictInfo
 	 */
 	int			rinfo_serial;
 
+	List	   *group_rinfos pg_node_attr(copy_as_scalar, equal_ignore, read_write_ignore);
+
 	/*
 	 * Generating EquivalenceClass.  This field is NULL unless clause is
 	 * potentially redundant.
-- 
2.31.0

