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