From 9b69647824b8ceb4c2bc1b9127f5faf5f2a70129 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 30 Mar 2010 21:58:18 +0000 Subject: [PATCH] Fix "constraint_exclusion = partition" logic so that it will also attempt constraint exclusion on an inheritance set that is the target of an UPDATE or DELETE query. Per gripe from Marc Cousin. Back-patch to 8.4 where the feature was introduced. --- src/backend/nodes/outfuncs.c | 3 ++- src/backend/optimizer/plan/planner.c | 4 +++- src/backend/optimizer/util/plancat.c | 7 +++++-- src/include/nodes/relation.h | 7 ++++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 93aec9928c..78cab4f534 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.360.2.1 2009/10/06 00:55:34 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.360.2.2 2010/03/30 21:58:18 tgl Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* @@ -1498,6 +1498,7 @@ _outPlannerInfo(StringInfo str, PlannerInfo *node) WRITE_NODE_FIELD(sort_pathkeys); WRITE_FLOAT_FIELD(total_table_pages, "%.0f"); WRITE_FLOAT_FIELD(tuple_fraction, "%.4f"); + WRITE_BOOL_FIELD(hasInheritedTarget); WRITE_BOOL_FIELD(hasJoinRTEs); WRITE_BOOL_FIELD(hasHavingQual); WRITE_BOOL_FIELD(hasPseudoConstantQuals); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 3f344b3a14..50200805a3 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.256 2009/06/11 14:48:59 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.256.2.1 2010/03/30 21:58:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -287,6 +287,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse, root->cte_plan_ids = NIL; root->eq_classes = NIL; root->append_rel_list = NIL; + root->hasInheritedTarget = false; root->hasRecursion = hasRecursion; if (hasRecursion) @@ -663,6 +664,7 @@ inheritance_planner(PlannerInfo *root) appinfo); subroot.returningLists = NIL; subroot.init_plans = NIL; + subroot.hasInheritedTarget = true; /* We needn't modify the child's append_rel_list */ /* There shouldn't be any OJ info to translate, as yet */ Assert(subroot.join_info_list == NIL); diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 4f07cade68..f7dd970e39 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.158 2009/06/11 14:48:59 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.158.2.1 2010/03/30 21:58:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -576,7 +576,10 @@ relation_excluded_by_constraints(PlannerInfo *root, /* Skip the test 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)) + !(rel->reloptkind == RELOPT_OTHER_MEMBER_REL || + (root->hasInheritedTarget && + rel->reloptkind == RELOPT_BASEREL && + rel->relid == root->parse->resultRelation)))) return false; /* diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 7eb15dbeec..5d306d7860 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.173 2009/06/11 14:49:11 momjian Exp $ + * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.173.2.1 2010/03/30 21:58:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -192,6 +192,11 @@ typedef struct PlannerInfo /* These fields are used only when hasRecursion is true: */ int wt_param_id; /* PARAM_EXEC ID for the work table */ struct Plan *non_recursive_plan; /* plan for non-recursive term */ + + /* Added at end to minimize ABI breakage in 8.4 branch: */ + + bool hasInheritedTarget; /* true if parse->resultRelation is an + * inheritance child rel */ } PlannerInfo; -- 2.50.1