Re: Partitioned tables and relfilenode

Robert Haas <robertmhaas@gmail.com>

From: Robert Haas <robertmhaas@gmail.com>
To: Amit Langote <Langote_Amit_f8@lab.ntt.co.jp>
Cc: Ashutosh Bapat <ashutosh.bapat@enterprisedb.com>, Michael Paquier <michael.paquier@gmail.com>, Simon Riggs <simon@2ndquadrant.com>, Pg Hackers <pgsql-hackers@postgresql.org>
Date: 2017-03-20T16:16:19Z
Lists: pgsql-hackers
On Fri, Mar 17, 2017 at 4:57 AM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:
>> Yes, but on the flip side, you're having to add code in a lot of
>> places -- I think I counted 7 -- where you turn around and ignore
>> those AppendRelInfos.
>
> Perhaps you were looking at the previous version with "minimal" appinfos
> containing the child_is_partitioned field?

Yes, I think I was.  I think this version looks a lot better.

     /*
+     * Close the root partitioned rel if we opened it above, but keep the
+     * lock.
+     */
+    if (rel != mtstate->resultRelInfo->ri_RelationDesc)
+        heap_close(rel, NoLock);

We didn't take a lock above, though, so drop everything in the comment
from "but" onward.

-    add_paths_to_append_rel(root, rel, live_childrels);
+    add_paths_to_append_rel(root, rel, live_childrels, partitioned_rels);

I think it would make more sense to put the new logic into
add_paths_to_append_rel, instead of passing this down as an additional
parameter.

+     * do not appear anywhere else in the plan.  Situation is exactly the

The situation is...

+    if (parent_rte->relkind == RELKIND_PARTITIONED_TABLE)
+    {
+        foreach(lc, root->pcinfo_list)
+        {
+            PartitionedChildRelInfo *pc = lfirst(lc);
+
+            if (pc->parent_relid == parentRTindex)
+            {
+                partitioned_rels = pc->child_rels;
+                break;
+            }
+        }
+    }

You seem to have a few copies of this logic.  I think it would be
worth factoring it out into a separate function.

+                root->glob->nonleafResultRelations =
+                    list_concat(root->glob->nonleafResultRelations,
+                                list_copy(splan->partitioned_rels));

Please add a brief comment.  One line is fine.

+            newrc->isParent = childrte->relkind == RELKIND_PARTITIONED_TABLE;

I'm not sure what project style is, but I personally find these kinds
of assignments easier to read with an extra set of parantheses:

            newrc->isParent = (childrte->relkind == RELKIND_PARTITIONED_TABLE);

+    if (partitioned_rels == NIL)
+        return;
+
+    foreach(lc, partitioned_rels)

I think the if-test is pointless; the foreach loop is going to start
by comparing the initial value with NIL.

Why doesn't ExecSerializePlan() need to transfer a proper value for
nonleafResultRelations to workers?  Seems like it should.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Commits

  1. Code review for c94e6942cefe7d20c5feed856e27f672734b1e2b.

  2. Don't allocate storage for partitioned tables.

  3. Don't scan partitioned tables.

  4. Don't uselessly rewrite, truncate, VACUUM, or ANALYZE partitioned tables.