From: Robert Haas Date: Tue, 15 Aug 2017 13:16:33 +0000 (-0400) Subject: Avoid unnecessary single-child Append nodes. X-Git-Tag: REL_11_BETA1~1803 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d57929afc7063431f80a0ac4c510fc39aacd22e6;p=postgresql Avoid unnecessary single-child Append nodes. Before commit d3cc37f1d801a6b5cad9bf179274a8, an inheritance parent whose only children were temp tables of other sessions would end up as a simple scan of the parent; but with that commit, we end up with an Append node, per a report from Ashutosh Bapat. Tweak the logic so that we go back to the old way, and update the function header comment for partitioning while we're at it. Ashutosh Bapat, reviewed by Amit Langote and adjusted by me. Discussion: http://postgr.es/m/CAFjFpReWJr1yTkHU=OqiMBmcYCMoSW3VPR39RBuQ_ovwDFBT5Q@mail.gmail.com --- diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index cf46b74782..fb283184c5 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -1360,8 +1360,12 @@ expand_inherited_tables(PlannerInfo *root) * table, but with inh = false, to represent the parent table in its role * as a simple member of the inheritance set. * - * A childless table is never considered to be an inheritance set; therefore - * a parent RTE must always have at least two associated AppendRelInfos. + * A childless table is never considered to be an inheritance set. For + * regular inheritance, a parent RTE must always have at least two associated + * AppendRelInfos: one corresponding to the parent table as a simple member of + * inheritance set and one or more corresponding to the actual children. + * Since a partitioned table is not scanned, it might have only one associated + * AppendRelInfo. */ static void expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti) @@ -1374,7 +1378,7 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti) List *inhOIDs; List *appinfos; ListCell *l; - bool need_append; + bool has_child; PartitionedChildRelInfo *pcinfo; List *partitioned_child_rels = NIL; @@ -1448,7 +1452,7 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti) /* Scan the inheritance set and expand it */ appinfos = NIL; - need_append = false; + has_child = false; foreach(l, inhOIDs) { Oid childOID = lfirst_oid(l); @@ -1502,7 +1506,10 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti) */ if (childrte->relkind != RELKIND_PARTITIONED_TABLE) { - need_append = true; + /* Remember if we saw a real child. */ + if (childOID != parentOID) + has_child = true; + appinfo = makeNode(AppendRelInfo); appinfo->parent_relid = rti; appinfo->child_relid = childRTindex; @@ -1582,7 +1589,7 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti) * the parent table is harmless, so we don't bother to get rid of it; * ditto for the useless PlanRowMark node. */ - if (!need_append) + if (!has_child) { /* Clear flag before returning */ rte->inh = false;