From 32886c5b14709d1f7ad27e5e024c3e083b97026c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=80=E6=8C=83?= <yizhi.fzh@alibaba-inc.com>
Date: Sun, 25 Jul 2021 16:28:30 +0800
Subject: [PATCH v4 1/6] Just refactor pathkeys_useful_for_merging, split a new
 function

ec_useful_for_merging which is useful for UniqueKey as well.
---
 src/backend/optimizer/path/equivclass.c | 42 +++++++++++++++++++++++++
 src/backend/optimizer/path/pathkeys.c   | 33 +------------------
 src/include/optimizer/paths.h           |  2 ++
 3 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 6f1abbe47d..2f688807af 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -960,6 +960,48 @@ find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel)
 	return NULL;
 }
 
+/*
+ * ec_useful_for_merging
+ *	check if the ec exists in rel's merageable restrictinfo_lists.
+ */
+bool
+ec_useful_for_merging(PlannerInfo *root, RelOptInfo *rel,
+					  EquivalenceClass *ec)
+{
+	/*
+	 * First look into the EquivalenceClass to see if there are any members
+	 * not yet joined to the rel.
+	 */
+	if (rel->has_eclass_joins &&
+		eclass_useful_for_merging(root, ec, rel))
+		return true;
+	else
+	{
+		/*
+		 * Otherwise search the rel's joininfo list, which contains
+		 * non-EquivalenceClass-derivable join clauses that might
+		 * nonetheless be mergejoinable.
+		 */
+		ListCell	*j;
+		foreach(j, rel->joininfo)
+		{
+			RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(j);
+
+			if (restrictinfo->mergeopfamilies == NIL)
+				continue;
+			update_mergeclause_eclasses(root, restrictinfo);
+
+			if (ec == restrictinfo->left_ec ||
+			    ec == restrictinfo->right_ec)
+			{
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 /*
  * relation_can_be_sorted_early
  *		Can this relation be sorted on this EC before the final output step?
diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index 216dd26385..21f4f2d4bc 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -1751,43 +1751,12 @@ pathkeys_useful_for_merging(PlannerInfo *root, RelOptInfo *rel, List *pathkeys)
 	{
 		PathKey    *pathkey = (PathKey *) lfirst(i);
 		bool		matched = false;
-		ListCell   *j;
 
 		/* If "wrong" direction, not useful for merging */
 		if (!right_merge_direction(root, pathkey))
 			break;
 
-		/*
-		 * First look into the EquivalenceClass of the pathkey, to see if
-		 * there are any members not yet joined to the rel.  If so, it's
-		 * surely possible to generate a mergejoin clause using them.
-		 */
-		if (rel->has_eclass_joins &&
-			eclass_useful_for_merging(root, pathkey->pk_eclass, rel))
-			matched = true;
-		else
-		{
-			/*
-			 * Otherwise search the rel's joininfo list, which contains
-			 * non-EquivalenceClass-derivable join clauses that might
-			 * nonetheless be mergejoinable.
-			 */
-			foreach(j, rel->joininfo)
-			{
-				RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(j);
-
-				if (restrictinfo->mergeopfamilies == NIL)
-					continue;
-				update_mergeclause_eclasses(root, restrictinfo);
-
-				if (pathkey->pk_eclass == restrictinfo->left_ec ||
-					pathkey->pk_eclass == restrictinfo->right_ec)
-				{
-					matched = true;
-					break;
-				}
-			}
-		}
+		matched = ec_useful_for_merging(root, rel, pathkey->pk_eclass);
 
 		/*
 		 * If we didn't find a mergeclause, we're done --- any additional
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index f1d111063c..a29f616423 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -143,6 +143,8 @@ extern EquivalenceMember *find_computable_ec_member(PlannerInfo *root,
 													List *exprs,
 													Relids relids,
 													bool require_parallel_safe);
+extern bool ec_useful_for_merging(PlannerInfo *root, RelOptInfo *rel,
+								  EquivalenceClass *ec);
 extern Expr *find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel);
 extern bool relation_can_be_sorted_early(PlannerInfo *root, RelOptInfo *rel,
 										 EquivalenceClass *ec,
-- 
2.21.0

