aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/plancat.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2018-04-23 17:57:43 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2018-04-23 17:57:43 -0300
commit055fb8d33da6ff9003e3da4b9944bdcd2e2b2a49 (patch)
tree2ee3763bb11d1211f10432a80fd28de7bd035d5e /src/backend/optimizer/util/plancat.c
parent4df58f7ed7f9ddc5a3196fcbad35690d1b3218de (diff)
downloadpostgresql-055fb8d33da6ff9003e3da4b9944bdcd2e2b2a49.tar.gz
postgresql-055fb8d33da6ff9003e3da4b9944bdcd2e2b2a49.zip
Add GUC enable_partition_pruning
This controls both plan-time and execution-time new-style partition pruning. While finer-grain control is possible (maybe using an enum GUC instead of boolean), there doesn't seem to be much need for that. This new parameter controls partition pruning for all queries: trivially, SELECT queries that affect partitioned tables are naturally under its control since they are using the new technology. However, while UPDATE/DELETE queries do not use the new code, we make the new GUC control their behavior also (stealing control from constraint_exclusion), because it is more natural, and it leads to a more natural transition to the future in which those queries will also use the new pruning code. Constraint exclusion still controls pruning for regular inheritance situations (those not involving partitioned tables). Author: David Rowley Review: Amit Langote, Ashutosh Bapat, Justin Pryzby, David G. Johnston Discussion: https://postgr.es/m/CAKJS1f_0HwsxJG9m+nzU+CizxSdGtfe6iF_ykPYBiYft302DCw@mail.gmail.com
Diffstat (limited to 'src/backend/optimizer/util/plancat.c')
-rw-r--r--src/backend/optimizer/util/plancat.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 1ff0ef4866b..6973fe34586 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);
@@ -1415,14 +1415,41 @@ relation_excluded_by_constraints(PlannerInfo *root,
return true;
}
- /* Skip further tests if constraint exclusion is disabled for the rel */
- if (constraint_exclusion == CONSTRAINT_EXCLUSION_OFF ||
- (constraint_exclusion == CONSTRAINT_EXCLUSION_PARTITION &&
- !(rel->reloptkind == RELOPT_OTHER_MEMBER_REL ||
- (root->hasInheritedTarget &&
- rel->reloptkind == RELOPT_BASEREL &&
- rel->relid == root->parse->resultRelation))))
- return false;
+ /*
+ * Skip further tests, depending on constraint_exclusion.
+ */
+ switch (constraint_exclusion)
+ {
+ case CONSTRAINT_EXCLUSION_OFF:
+ /*
+ * Don't prune if feature turned off -- except if the relation is
+ * a partition. While partprune.c-style partition pruning is not
+ * yet in use for all cases (update/delete is not handled), it
+ * would be a UI horror to use different user-visible controls
+ * depending on such a volatile implementation detail. Therefore,
+ * for partitioned tables we use enable_partition_pruning to
+ * control this behavior.
+ */
+ if (root->inhTargetKind == INHKIND_PARTITIONED)
+ break;
+ return false;
+
+ case CONSTRAINT_EXCLUSION_PARTITION:
+ /*
+ * When constraint_exclusion is set to 'partition' we only handle
+ * OTHER_MEMBER_RELs, or BASERELs in cases where the result target
+ * is an inheritance parent or a partitioned table.
+ */
+ if ((rel->reloptkind != RELOPT_OTHER_MEMBER_REL) &&
+ !(rel->reloptkind == RELOPT_BASEREL &&
+ root->inhTargetKind != INHKIND_NONE &&
+ rel->relid == root->parse->resultRelation))
+ return false;
+ break;
+
+ case CONSTRAINT_EXCLUSION_ON:
+ break; /* always try to exclude */
+ }
/*
* Check for self-contradictory restriction clauses. We dare not make