Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 23c6c43

Browse files
committed
Don't make FK-based selectivity estimates in inheritance situations.
The foreign-key-aware logic for estimation of join sizes (added in commit 100340e) blindly tried to apply the concept to rels that are actually parents of inheritance trees. This is just plain wrong so far as the referenced relation is concerned, since the inheritance scan may well produce lots of rows that are not participating in the constraint. It's wrong for the referencing relation too, for the same reason; although on that end we could conceivably detect whether all members of the inheritance tree have equivalent FK constraints pointing to the same referenced rel, and then proceed more or less as we do now. But pending somebody writing code to do that, we must disable this, because it's producing completely silly estimates when there's an FK linking the heads of inheritance trees. Per bug #14404 from Clinton Adams. Back-patch to 9.6 where the new estimation logic came in. Report: <20161028200412.15987.96482@wrigleys.postgresql.org>
1 parent f4d865f commit 23c6c43

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/backend/optimizer/util/plancat.c

+15-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ get_relation_info_hook_type get_relation_info_hook = NULL;
5353

5454

5555
static void get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel,
56-
Relation relation);
56+
Relation relation, bool inhparent);
5757
static bool infer_collation_opclass_match(InferenceElem *elem, Relation idxRel,
5858
List *idxExprs);
5959
static int32 get_rel_data_width(Relation rel, int32 *attr_widths);
@@ -408,7 +408,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
408408
}
409409

410410
/* Collect info about relation's foreign keys, if relevant */
411-
get_relation_foreign_keys(root, rel, relation);
411+
get_relation_foreign_keys(root, rel, relation, inhparent);
412412

413413
heap_close(relation, NoLock);
414414

@@ -433,7 +433,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
433433
*/
434434
static void
435435
get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel,
436-
Relation relation)
436+
Relation relation, bool inhparent)
437437
{
438438
List *rtable = root->parse->rtable;
439439
List *cachedfkeys;
@@ -448,6 +448,15 @@ get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel,
448448
list_length(rtable) < 2)
449449
return;
450450

451+
/*
452+
* If it's the parent of an inheritance tree, ignore its FKs. We could
453+
* make useful FK-based deductions if we found that all members of the
454+
* inheritance tree have equivalent FK constraints, but detecting that
455+
* would require code that hasn't been written.
456+
*/
457+
if (inhparent)
458+
return;
459+
451460
/*
452461
* Extract data about relation's FKs from the relcache. Note that this
453462
* list belongs to the relcache and might disappear in a cache flush, so
@@ -488,6 +497,9 @@ get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel,
488497
if (rte->rtekind != RTE_RELATION ||
489498
rte->relid != cachedfk->confrelid)
490499
continue;
500+
/* Ignore if it's an inheritance parent; doesn't really match */
501+
if (rte->inh)
502+
continue;
491503
/* Ignore self-referential FKs; we only care about joins */
492504
if (rti == rel->relid)
493505
continue;

0 commit comments

Comments
 (0)