From 11b3395bb5bcc4a2bcff6fed8078dbbf3cda81b1 Mon Sep 17 00:00:00 2001
From: Andy Fan <yizhi.fzh@alibaba-inc.com>
Date: Tue, 1 Feb 2022 17:37:27 +0800
Subject: [PATCH v2 4/6] Remove duplicated qual executing for executor.

Take the SELECT * FROM t1, t2 WHERE t1.a = t2.a and t2.a > 3 for example,
we can derive t1.a > 3 with EC filter infrastructure.  However if it generate a
plan like below, the new generated qual does not deserve to execute.

Nest Loop
   Seq Scan (t1.a > 3)
   Index Scan t2_a
      (a = t1.a) (t2.a > 3)

This patch remove the "t2.a > 3" for the above case.
---
 src/backend/optimizer/path/equivclass.c | 22 +++++++++++++++++++
 src/backend/optimizer/plan/createplan.c | 29 +++++++++++++++++++++++--
 src/include/optimizer/paths.h           |  2 ++
 src/test/regress/parallel_schedule      |  2 ++
 4 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 6ed9e8c9064..9ce0249b10d 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -3350,6 +3350,28 @@ is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist)
 	return false;
 }
 
+
+bool
+is_correlated_derived_clause(RestrictInfo *rinfo, List *clauselist)
+{
+	EquivalenceClass *derived_ec = rinfo->derived;
+	ListCell   *lc;
+
+	/* Fail if it's not a potentially-derived clause from some EC */
+	if (derived_ec == NULL)
+		return false;
+
+	foreach(lc, clauselist)
+	{
+		RestrictInfo *otherrinfo = (RestrictInfo *) lfirst(lc);
+
+		if (otherrinfo->parent_ec == derived_ec)
+			return true;
+	}
+
+	return false;
+}
+
 /*
  * is_redundant_with_indexclauses
  *		Test whether rinfo is redundant with any clause in the IndexClause
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index cd6d72c7633..03c5207ede0 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -556,11 +556,14 @@ static Plan *
 create_scan_plan(PlannerInfo *root, Path *best_path, int flags)
 {
 	RelOptInfo *rel = best_path->parent;
-	List	   *scan_clauses;
+	List	   *scan_clauses = NIL;
 	List	   *gating_clauses;
 	List	   *tlist;
 	Plan	   *plan;
 
+	List	*ppi_clauses = best_path->param_info ? best_path->param_info->ppi_clauses : NIL;
+	ListCell	*lc;
+
 	/*
 	 * Extract the relevant restriction clauses from the parent relation. The
 	 * executor must apply all these restrictions during the scan, except for
@@ -591,8 +594,18 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags)
 	 * For paranoia's sake, don't modify the stored baserestrictinfo list.
 	 */
 	if (best_path->param_info)
-		scan_clauses = list_concat_copy(scan_clauses,
+	{
+		List *stripped_quals = NIL;
+		foreach(lc, rel->baserestrictinfo)
+		{
+			RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
+
+			if (!is_correlated_derived_clause(rinfo, ppi_clauses))
+				stripped_quals = lappend(stripped_quals, rinfo);
+		}
+		scan_clauses = list_concat_copy(stripped_quals,
 										best_path->param_info->ppi_clauses);
+	}
 
 	/*
 	 * Detect whether we have any pseudoconstant quals to deal with.  Then, if
@@ -4912,6 +4925,7 @@ fix_indexqual_references(PlannerInfo *root, IndexPath *index_path,
 	List	   *stripped_indexquals;
 	List	   *fixed_indexquals;
 	ListCell   *lc;
+	List	*ppi_clauses = index_path->path.param_info ? index_path->path.param_info->ppi_clauses : NIL;
 
 	stripped_indexquals = fixed_indexquals = NIL;
 
@@ -4921,6 +4935,17 @@ fix_indexqual_references(PlannerInfo *root, IndexPath *index_path,
 		int			indexcol = iclause->indexcol;
 		ListCell   *lc2;
 
+		if (is_correlated_derived_clause(iclause->rinfo, ppi_clauses))
+		{
+			/*
+			 * bitmapscan will read this indexquals as well. so we can't just igrore
+			 * it for now. we can totally delete it.
+			 */
+			index_path->indexclauses = foreach_delete_current(index_path->indexclauses, lc);
+			continue;
+		}
+
+
 		foreach(lc2, iclause->indexquals)
 		{
 			RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index ce2aac7d3aa..08d8612cdba 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -188,6 +188,8 @@ extern bool eclass_useful_for_merging(PlannerInfo *root,
 extern bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist);
 extern bool is_redundant_with_indexclauses(RestrictInfo *rinfo,
 										   List *indexclauses);
+extern bool is_correlated_derived_clause(RestrictInfo *rinfo, List *clauselist);
+
 
 /*
  * pathkeys.c
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 861c30a73ae..b071324b961 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -134,3 +134,5 @@ test: fast_default
 
 # run stats by itself because its delay may be insufficient under heavy load
 test: stats
+
+test: ec_filter
\ No newline at end of file
-- 
2.21.0

