Adapt optimizer.
authorRobert Haas <[email protected]>
Wed, 19 Dec 2018 15:44:29 +0000 (10:44 -0500)
committerRobert Haas <[email protected]>
Wed, 19 Dec 2018 15:44:29 +0000 (10:44 -0500)
src/backend/optimizer/prep/prepunion.c
src/backend/optimizer/util/plancat.c
src/include/nodes/relation.h

index da278f785effb711cbc793fb74b0b507630167f3..16f5889d6531db2d60e4856ab54d28d54dc38567 100644 (file)
@@ -48,6 +48,7 @@
 #include "optimizer/tlist.h"
 #include "parser/parse_coerce.h"
 #include "parser/parsetree.h"
+#include "partitioning/partdir.h"
 #include "utils/lsyscache.h"
 #include "utils/rel.h"
 #include "utils/selfuncs.h"
@@ -104,8 +105,7 @@ static void expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte,
 static void expand_partitioned_rtentry(PlannerInfo *root,
                                                   RangeTblEntry *parentrte,
                                                   Index parentRTindex, Relation parentrel,
-                                                  PlanRowMark *top_parentrc, LOCKMODE lockmode,
-                                                  List **appinfos);
+                                                  PlanRowMark *top_parentrc, List **appinfos);
 static void expand_single_inheritance_child(PlannerInfo *root,
                                                                RangeTblEntry *parentrte,
                                                                Index parentRTindex, Relation parentrel,
@@ -1518,7 +1518,6 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
        Oid                     parentOID;
        PlanRowMark *oldrc;
        Relation        oldrelation;
-       LOCKMODE        lockmode;
        List       *inhOIDs;
        ListCell   *l;
 
@@ -1541,37 +1540,13 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
        }
 
        /*
-        * The rewriter should already have obtained an appropriate lock on each
-        * relation named in the query.  However, for each child relation we add
-        * to the query, we must obtain an appropriate lock, because this will be
-        * the first use of those relations in the parse/rewrite/plan pipeline.
-        * Child rels should use the same lockmode as their parent.
-        */
-       lockmode = rte->rellockmode;
-
-       /* Scan for all members of inheritance set, acquire needed locks */
-       inhOIDs = find_all_inheritors(parentOID, lockmode, NULL);
-
-       /*
-        * Check that there's at least one descendant, else treat as no-child
-        * case.  This could happen despite above has_subclass() check, if table
-        * once had a child but no longer does.
-        */
-       if (list_length(inhOIDs) < 2)
-       {
-               /* Clear flag before returning */
-               rte->inh = false;
-               return;
-       }
-
-       /*
-        * If parent relation is selected FOR UPDATE/SHARE, we need to mark its
-        * PlanRowMark as isParent = true, and generate a new PlanRowMark for each
-        * child.
+        * If parent relation is selected FOR UPDATE/SHARE, we will need to mark
+        * its PlanRowMark as isParent = true, and generate a new PlanRowMark for
+        * each child. expand_single_inheritance_child() will handle this, but we
+        * need to pass down the rowmark for the original parent to make it
+        * possible.
         */
        oldrc = get_plan_rowmark(root->rowMarks, rti);
-       if (oldrc)
-               oldrc->isParent = true;
 
        /*
         * Must open the parent relation to examine its tupdesc.  We need not lock
@@ -1584,13 +1559,16 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
        {
                Assert(rte->relkind == RELKIND_PARTITIONED_TABLE);
 
+               if (root->partition_directory == NULL)
+                       root->partition_directory = CreatePartitionDirectory(CurrentMemoryContext);
+
                /*
                 * If this table has partitions, recursively expand them in the order
                 * in which they appear in the PartitionDesc.  While at it, also
                 * extract the partition key columns of all the partitioned tables.
                 */
                expand_partitioned_rtentry(root, rte, rti, oldrelation, oldrc,
-                                                                  lockmode, &root->append_rel_list);
+                                                                  &root->append_rel_list);
        }
        else
        {
@@ -1598,9 +1576,12 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
                RangeTblEntry *childrte;
                Index           childRTindex;
 
+               /* Scan for all members of inheritance set, acquire needed locks */
+               inhOIDs = find_all_inheritors(parentOID, rte->rellockmode, NULL);
+
                /*
-                * This table has no partitions.  Expand any plain inheritance
-                * children in the order the OIDs were returned by
+                * This is not a partitioned table, but it has plain inheritance
+                * children.  Expand them in the order that the OIDs were returned by
                 * find_all_inheritors.
                 */
                foreach(l, inhOIDs)
@@ -1622,7 +1603,7 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
                         */
                        if (childOID != parentOID && RELATION_IS_OTHER_TEMP(newrelation))
                        {
-                               heap_close(newrelation, lockmode);
+                               heap_close(newrelation, rte->rellockmode);
                                continue;
                        }
 
@@ -1637,11 +1618,11 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
                }
 
                /*
-                * If all the children were temp tables, pretend it's a
-                * non-inheritance situation; we don't need Append node in that case.
-                * The duplicate RTE we added for the parent table is harmless, so we
-                * don't bother to get rid of it; ditto for the useless PlanRowMark
-                * node.
+                * If all the children were temp tables, or there were none, pretend
+                * it's a non-inheritance situation; we don't need Append node in that
+                * case.  The duplicate RTE we added for the parent table is harmless,
+                * so we don't bother to get rid of it; ditto for the useless
+                * PlanRowMark node.
                 */
                if (list_length(appinfos) < 2)
                        rte->inh = false;
@@ -1661,16 +1642,17 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
 static void
 expand_partitioned_rtentry(PlannerInfo *root, RangeTblEntry *parentrte,
                                                   Index parentRTindex, Relation parentrel,
-                                                  PlanRowMark *top_parentrc, LOCKMODE lockmode,
-                                                  List **appinfos)
+                                                  PlanRowMark *top_parentrc, List **appinfos)
 {
        int                     i;
        RangeTblEntry *childrte;
        Index           childRTindex;
-       PartitionDesc partdesc = RelationGetPartitionDesc(parentrel);
+       PartitionDesc partdesc;
 
        check_stack_depth();
 
+       partdesc = PartitionDirectoryLookup(root->partition_directory, parentrel);
+
        /* A partitioned table should always have a partition descriptor. */
        Assert(partdesc);
 
@@ -1707,8 +1689,8 @@ expand_partitioned_rtentry(PlannerInfo *root, RangeTblEntry *parentrte,
                Oid                     childOID = partdesc->oids[i];
                Relation        childrel;
 
-               /* Open rel; we already have required locks */
-               childrel = heap_open(childOID, NoLock);
+               /* Open and lock child rel */
+               childrel = heap_open(childOID, parentrte->rellockmode);
 
                /*
                 * Temporary partitions belonging to other sessions should have been
@@ -1725,8 +1707,7 @@ expand_partitioned_rtentry(PlannerInfo *root, RangeTblEntry *parentrte,
                /* If this child is itself partitioned, recurse */
                if (childrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
                        expand_partitioned_rtentry(root, childrte, childRTindex,
-                                                                          childrel, top_parentrc, lockmode,
-                                                                          appinfos);
+                                                                          childrel, top_parentrc, appinfos);
 
                /* Close child relation, but keep locks */
                heap_close(childrel, NoLock);
@@ -1862,6 +1843,14 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
                /* Include child's rowmark type in top parent's allMarkTypes */
                top_parentrc->allMarkTypes |= childrc->allMarkTypes;
 
+               /*
+                * If we create at least one child rowmark, isParent should be set
+                * on the original rowmark. That's very cheap, so just do it here
+                * unconditionally without worrying about whether it has been done
+                * previously.
+                */
+               top_parentrc->isParent = true;
+
                root->rowMarks = lappend(root->rowMarks, childrc);
        }
 }
index a570ac0aabe3223d5c4a04abf82a258fc2fe06ed..f0e5ef070f134c040d6fbed5f0f2aa935e35bd94 100644 (file)
@@ -39,6 +39,7 @@
 #include "optimizer/predtest.h"
 #include "optimizer/prep.h"
 #include "partitioning/partbounds.h"
+#include "partitioning/partdir.h"
 #include "parser/parse_relation.h"
 #include "parser/parsetree.h"
 #include "rewrite/rewriteManip.h"
@@ -1903,7 +1904,10 @@ set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
 
        Assert(relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
 
-       partdesc = RelationGetPartitionDesc(relation);
+       /* shouldn't reach here unless expand_inherited_rtentry initialized this */
+       Assert(root->partition_directory != NULL);
+
+       partdesc = PartitionDirectoryLookup(root->partition_directory, relation);
        partkey = RelationGetPartitionKey(relation);
        rel->part_scheme = find_partition_scheme(root, relation);
        Assert(partdesc != NULL && rel->part_scheme != NULL);
index 6fd24203dd6f71b4054fdb650d8c9ff67df67131..bcf2054838567f4cbe3a38afe937335488c87d2a 100644 (file)
@@ -19,6 +19,7 @@
 #include "lib/stringinfo.h"
 #include "nodes/params.h"
 #include "nodes/parsenodes.h"
+#include "partitioning/partdefs.h"
 #include "storage/block.h"
 
 
@@ -343,6 +344,9 @@ typedef struct PlannerInfo
 
        /* Does this query modify any partition key columns? */
        bool            partColsUpdated;
+
+       /* Partition directory. */
+       PartitionDirectory      partition_directory;
 } PlannerInfo;