From 25eec71bd88fd3363af7859715c98452dcd3ca01 Mon Sep 17 00:00:00 2001
From: "dgrowley@gmail.com" <dgrowley@gmail.com>
Date: Fri, 20 Apr 2018 17:41:14 +1200
Subject: [PATCH] Add GUC to allow partition pruning to be disabled

This both disables the plan-time partition pruning and also run-time partition
pruning.  We may one day want to consider two individual switches for turning
off each of these features, but at the moment there seems to be no strong
argument for that.
---
 doc/src/sgml/config.sgml                | 17 +++++++++++++++++
 src/backend/optimizer/path/allpaths.c   |  3 ++-
 src/backend/optimizer/path/costsize.c   |  1 +
 src/backend/optimizer/plan/createplan.c |  3 ++-
 src/backend/optimizer/util/plancat.c    |  2 +-
 src/backend/utils/misc/guc.c            |  9 +++++++++
 src/include/optimizer/cost.h            |  1 +
 src/test/regress/expected/sysviews.out  |  3 ++-
 8 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 5d5f2d23c4..5dc5d27c04 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -3826,6 +3826,23 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-enable-partition-pruning" xreflabel="enable_partition_pruning">
+      <term><varname>enable_partition_pruning</varname> (<type>boolean</type>)
+       <indexterm>
+        <primary><varname>enable_partition_pruning</varname> configuration parameter</primary>
+       </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Enables or disables the query planner's ability to eliminate a
+        partitioned table's subpartitions from query plans.  This also
+        controls the planner's ability to generate query plans which allow the
+        query executor to remove or ignoring partitions during query
+        execution.  The default is <literal>on</literal>.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-enable-partitionwise-join" xreflabel="enable_partitionwise_join">
       <term><varname>enable_partitionwise_join</varname> (<type>boolean</type>)
       <indexterm>
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 3ba3f87eb7..9ed73da0f7 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -901,7 +901,8 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
 	 * store the relids of all partitions which could possibly contain a
 	 * matching tuple, and skip anything else in the loop below.
 	 */
-	if (rte->relkind == RELKIND_PARTITIONED_TABLE &&
+	if (enable_partition_pruning &&
+		rte->relkind == RELKIND_PARTITIONED_TABLE &&
 		rel->baserestrictinfo != NIL)
 	{
 		live_children = prune_append_rel_partitions(rel);
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 47729de896..fc0617ec35 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -138,6 +138,7 @@ bool		enable_partitionwise_join = false;
 bool		enable_partitionwise_aggregate = false;
 bool		enable_parallel_append = true;
 bool		enable_parallel_hash = true;
+bool		enable_partition_pruning = true;
 
 typedef struct
 {
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 280f21cd45..ea5de0cb1b 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -1077,7 +1077,8 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path)
 		subplans = lappend(subplans, subplan);
 	}
 
-	if (rel->reloptkind == RELOPT_BASEREL &&
+	if (enable_partition_pruning &&
+		rel->reloptkind == RELOPT_BASEREL &&
 		best_path->partitioned_rels != NIL)
 	{
 		List	   *prunequal;
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 1ff0ef4866..98b353b80b 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -1272,7 +1272,7 @@ get_relation_constraints(PlannerInfo *root,
 	 * descriptor, instead of constraint exclusion which is driven by the
 	 * individual partition's partition constraint.
 	 */
-	if (root->parse->commandType != CMD_SELECT)
+	if (enable_partition_pruning && root->parse->commandType != CMD_SELECT)
 	{
 		List	   *pcqual = RelationGetPartitionQual(relation);
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index fa92ce2e68..c51a9270e4 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -951,6 +951,15 @@ static struct config_bool ConfigureNamesBool[] =
 		true,
 		NULL, NULL, NULL
 	},
+	{
+		{"enable_partition_pruning", PGC_USERSET, QUERY_TUNING_METHOD,
+			gettext_noop("Enables the planner's ability to remove non-required partitions from the query plan."),
+			NULL
+		},
+		&enable_partition_pruning,
+		true,
+		NULL, NULL, NULL
+	},
 	{
 		{"geqo", PGC_USERSET, QUERY_TUNING_GEQO,
 			gettext_noop("Enables genetic query optimization."),
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index d3269eae71..2995c4d26d 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -71,6 +71,7 @@ extern PGDLLIMPORT bool enable_partitionwise_join;
 extern PGDLLIMPORT bool enable_partitionwise_aggregate;
 extern PGDLLIMPORT bool enable_parallel_append;
 extern PGDLLIMPORT bool enable_parallel_hash;
+extern PGDLLIMPORT bool enable_partition_pruning;
 extern PGDLLIMPORT int	constraint_exclusion;
 
 extern double clamp_row_est(double nrows);
diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out
index a19ee08749..a1c90eb905 100644
--- a/src/test/regress/expected/sysviews.out
+++ b/src/test/regress/expected/sysviews.out
@@ -83,12 +83,13 @@ select name, setting from pg_settings where name like 'enable%';
  enable_nestloop                | on
  enable_parallel_append         | on
  enable_parallel_hash           | on
+ enable_partition_pruning       | on
  enable_partitionwise_aggregate | off
  enable_partitionwise_join      | off
  enable_seqscan                 | on
  enable_sort                    | on
  enable_tidscan                 | on
-(16 rows)
+(17 rows)
 
 -- Test that the pg_timezone_names and pg_timezone_abbrevs views are
 -- more-or-less working.  We can't test their contents in any great detail
-- 
2.16.2.windows.1

