From 408ba4affd8660f28d874e9c0e89b2020a9753bd Mon Sep 17 00:00:00 2001
From: Alexander Pyhalov <a.pyhalov@postgrespro.ru>
Date: Fri, 23 Apr 2021 16:16:53 +0300
Subject: [PATCH 2/2] Try prune partitions

---
 src/backend/optimizer/plan/initsplan.c | 43 ++++++++++++++++++++++++--
 src/backend/optimizer/plan/subselect.c | 10 ++++++
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 3a172ae0f70..7421be1cfef 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -33,6 +33,7 @@
 #include "optimizer/subselect.h"
 #include "parser/analyze.h"
 #include "parser/parsetree.h"
+#include "partitioning/partprune.h"
 #include "rewrite/rewriteManip.h"
 #include "utils/lsyscache.h"
 #include "utils/typcache.h"
@@ -2551,11 +2552,25 @@ static void
 distribute_baserestrictinfo_to_childs(PlannerInfo *root, RelOptInfo *rel)
 {
 	int			part;
+	bool set_dummy = false;
 	RangeTblEntry *rte;
+	Bitmapset  *live_parts;
+	List       *live_childrels = NIL;
+
+	live_parts = prune_append_rel_partitions(rel);
 
 	for (part = 0; part < rel->nparts; part++)
 	{
-		RelOptInfo *child_rel = rel->part_rels[part];
+		RelOptInfo *child_rel;
+
+		child_rel = rel->part_rels[part];
+
+		if (!bms_is_member(part ,live_parts))
+		{
+			mark_dummy_rel(child_rel);
+			set_dummy = true;
+			continue;
+		}
 
 		if (child_rel->rtekind == RTE_RELATION)
 		{
@@ -2566,10 +2581,32 @@ distribute_baserestrictinfo_to_childs(PlannerInfo *root, RelOptInfo *rel)
 
 			rte = root->simple_rte_array[childRTindex];
 
-			apply_child_basequals(root, rel, child_rel, rte, appinfo);
-			/* How can we process dummy relations */
+			if (!apply_child_basequals(root, rel, child_rel, rte, appinfo))
+			{
+				mark_dummy_rel(child_rel);
+				set_dummy = true;
+				continue;
+			}
 		}
 
+		child_rel->partial_pathlist = NIL;
+		child_rel->consider_parallel = false;
+
+		/* Relation is not dummy */
+		live_childrels = lappend(live_childrels, child_rel);
+
+	}
+
+	if (set_dummy)
+	{
+		/* Partial paths are harmful for initplans */
+		rel->consider_parallel = false;
+
+		add_paths_to_append_rel(root, rel, live_childrels);
+
+		rel->partial_pathlist = NIL;
+
+		set_cheapest(rel);
 	}
 }
 
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index b3895f69be5..e10ffa5756e 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -1272,6 +1272,16 @@ SS_replan_ctes(PlannerInfo *root)
 				if (replan_needed)
 				{
 					final_rel = fetch_upper_rel(subroot, UPPERREL_FINAL, NULL);
+
+					/*
+					 * Forget about any partial paths and clear consider_parallel, too;
+					 * they're not usable if we attached an initPlan (all CTEs are).
+					 */
+					final_rel->partial_pathlist = NIL;
+					final_rel->consider_parallel = false;
+
+					set_cheapest(final_rel);
+
 					best_path = final_rel->cheapest_total_path;
 					plan = create_plan(subroot, best_path);
 
-- 
2.25.1

