]> granicus.if.org Git - postgresql/commitdiff
Avoid unnecessary single-child Append nodes.
authorRobert Haas <rhaas@postgresql.org>
Tue, 15 Aug 2017 13:16:33 +0000 (09:16 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 15 Aug 2017 13:35:32 +0000 (09:35 -0400)
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

src/backend/optimizer/prep/prepunion.c

index cf46b74782c0935104f489b77d8a3e174523cff4..fb283184c580360eb618d71b4fe427e8435e0ee8 100644 (file)
@@ -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;