@@ -999,12 +999,16 @@ get_partition_qual_relid(Oid relid)
999
999
* RelationGetPartitionDispatchInfo
1000
1000
* Returns information necessary to route tuples down a partition tree
1001
1001
*
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.
1005
1009
*/
1006
1010
PartitionDispatch *
1007
- RelationGetPartitionDispatchInfo (Relation rel , int lockmode ,
1011
+ RelationGetPartitionDispatchInfo (Relation rel ,
1008
1012
int * num_parted , List * * leaf_part_oids )
1009
1013
{
1010
1014
PartitionDispatchData * * pd ;
@@ -1019,14 +1023,18 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
1019
1023
offset ;
1020
1024
1021
1025
/*
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.
1024
1031
*
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.
1030
1038
*/
1031
1039
* num_parted = 1 ;
1032
1040
parted_rels = list_make1 (rel );
@@ -1035,29 +1043,24 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
1035
1043
APPEND_REL_PARTITION_OIDS (rel , all_parts , all_parents );
1036
1044
forboth (lc1 , all_parts , lc2 , all_parents )
1037
1045
{
1038
- Relation partrel = heap_open ( lfirst_oid (lc1 ), lockmode );
1046
+ Oid partrelid = lfirst_oid (lc1 );
1039
1047
Relation parent = lfirst (lc2 );
1040
- PartitionDesc partdesc = RelationGetPartitionDesc (partrel );
1041
1048
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 )
1047
1050
{
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
+
1048
1059
(* num_parted )++ ;
1049
1060
parted_rels = lappend (parted_rels , partrel );
1050
1061
parted_rel_parents = lappend (parted_rel_parents , parent );
1051
1062
APPEND_REL_PARTITION_OIDS (partrel , all_parts , all_parents );
1052
1063
}
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
- */
1061
1064
}
1062
1065
1063
1066
/*
0 commit comments