@@ -999,12 +999,16 @@ get_partition_qual_relid(Oid relid)
999999 * RelationGetPartitionDispatchInfo
10001000 * Returns information necessary to route tuples down a partition tree
10011001 *
1002- * All the partitions will be locked with lockmode, unless it is NoLock.
1003- * A list of the OIDs of all the leaf partitions of rel is returned in
1004- * *leaf_part_oids.
1002+ * The number of elements in the returned array (that is, the number of
1003+ * PartitionDispatch objects for the partitioned tables in the partition tree)
1004+ * is returned in *num_parted and a list of the OIDs of all the leaf
1005+ * partitions of rel is returned in *leaf_part_oids.
1006+ *
1007+ * All the relations in the partition tree (including 'rel') must have been
1008+ * locked (using at least the AccessShareLock) by the caller.
10051009 */
10061010PartitionDispatch *
1007- RelationGetPartitionDispatchInfo (Relation rel , int lockmode ,
1011+ RelationGetPartitionDispatchInfo (Relation rel ,
10081012 int * num_parted , List * * leaf_part_oids )
10091013{
10101014 PartitionDispatchData * * pd ;
@@ -1019,14 +1023,18 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
10191023 offset ;
10201024
10211025 /*
1022- * Lock partitions and make a list of the partitioned ones to prepare
1023- * their PartitionDispatch objects below.
1026+ * We rely on the relcache to traverse the partition tree to build both
1027+ * the leaf partition OIDs list and the array of PartitionDispatch objects
1028+ * for the partitioned tables in the tree. That means every partitioned
1029+ * table in the tree must be locked, which is fine since we require the
1030+ * caller to lock all the partitions anyway.
10241031 *
1025- * Cannot use find_all_inheritors() here, because then the order of OIDs
1026- * in parted_rels list would be unknown, which does not help, because we
1027- * assign indexes within individual PartitionDispatch in an order that is
1028- * predetermined (determined by the order of OIDs in individual partition
1029- * descriptors).
1032+ * For every partitioned table in the tree, starting with the root
1033+ * partitioned table, add its relcache entry to parted_rels, while also
1034+ * queuing its partitions (in the order in which they appear in the
1035+ * partition descriptor) to be looked at later in the same loop. This is
1036+ * a bit tricky but works because the foreach() macro doesn't fetch the
1037+ * next list element until the bottom of the loop.
10301038 */
10311039 * num_parted = 1 ;
10321040 parted_rels = list_make1 (rel );
@@ -1035,29 +1043,24 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
10351043 APPEND_REL_PARTITION_OIDS (rel , all_parts , all_parents );
10361044 forboth (lc1 , all_parts , lc2 , all_parents )
10371045 {
1038- Relation partrel = heap_open ( lfirst_oid (lc1 ), lockmode );
1046+ Oid partrelid = lfirst_oid (lc1 );
10391047 Relation parent = lfirst (lc2 );
1040- PartitionDesc partdesc = RelationGetPartitionDesc (partrel );
10411048
1042- /*
1043- * If this partition is a partitioned table, add its children to the
1044- * end of the list, so that they are processed as well.
1045- */
1046- if (partdesc )
1049+ if (get_rel_relkind (partrelid ) == RELKIND_PARTITIONED_TABLE )
10471050 {
1051+ /*
1052+ * Already locked by the caller. Note that it is the
1053+ * responsibility of the caller to close the below relcache entry,
1054+ * once done using the information being collected here (for
1055+ * example, in ExecEndModifyTable).
1056+ */
1057+ Relation partrel = heap_open (partrelid , NoLock );
1058+
10481059 (* num_parted )++ ;
10491060 parted_rels = lappend (parted_rels , partrel );
10501061 parted_rel_parents = lappend (parted_rel_parents , parent );
10511062 APPEND_REL_PARTITION_OIDS (partrel , all_parts , all_parents );
10521063 }
1053- else
1054- heap_close (partrel , NoLock );
1055-
1056- /*
1057- * We keep the partitioned ones open until we're done using the
1058- * information being collected here (for example, see
1059- * ExecEndModifyTable).
1060- */
10611064 }
10621065
10631066 /*
0 commit comments