aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/plancat.c
diff options
context:
space:
mode:
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