Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a256650

Browse files
committed
Fix bugs in RelationGetPartitionDispatchInfo.
The previous coding was not quite right for cases involving multiple levels of partitioning. Amit Langote
1 parent 4b9a98e commit a256650

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

src/backend/catalog/partition.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,8 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
950950
*parted_rels;
951951
ListCell *lc;
952952
int i,
953-
k;
953+
k,
954+
offset;
954955

955956
/*
956957
* Lock partitions and make a list of the partitioned ones to prepare
@@ -990,11 +991,19 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
990991
*/
991992
}
992993

993-
/* Generate PartitionDispatch objects for all partitioned tables */
994+
/*
995+
* We want to create two arrays - one for leaf partitions and another for
996+
* partitioned tables (including the root table and internal partitions).
997+
* While we only create the latter here, leaf partition array of suitable
998+
* objects (such as, ResultRelInfo) is created by the caller using the
999+
* list of OIDs we return. Indexes into these arrays get assigned in a
1000+
* breadth-first manner, whereby partitions of any given level are placed
1001+
* consecutively in the respective arrays.
1002+
*/
9941003
pd = (PartitionDispatchData **) palloc(*num_parted *
9951004
sizeof(PartitionDispatchData *));
9961005
*leaf_part_oids = NIL;
997-
i = k = 0;
1006+
i = k = offset = 0;
9981007
foreach(lc, parted_rels)
9991008
{
10001009
Relation partrel = lfirst(lc);
@@ -1010,6 +1019,16 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
10101019
pd[i]->partdesc = partdesc;
10111020
pd[i]->indexes = (int *) palloc(partdesc->nparts * sizeof(int));
10121021

1022+
/*
1023+
* Indexes corresponding to the internal partitions are multiplied by
1024+
* -1 to distinguish them from those of leaf partitions. Encountering
1025+
* an index >= 0 means we found a leaf partition, which is immediately
1026+
* returned as the partition we are looking for. A negative index
1027+
* means we found a partitioned table, whose PartitionDispatch object
1028+
* is located at the above index multiplied back by -1. Using the
1029+
* PartitionDispatch object, search is continued further down the
1030+
* partition tree.
1031+
*/
10131032
m = 0;
10141033
for (j = 0; j < partdesc->nparts; j++)
10151034
{
@@ -1023,14 +1042,22 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
10231042
else
10241043
{
10251044
/*
1026-
* We can assign indexes this way because of the way
1027-
* parted_rels has been generated.
1045+
* offset denotes the number of partitioned tables of upper
1046+
* levels including those of the current level. Any partition
1047+
* of this table must belong to the next level and hence will
1048+
* be placed after the last partitioned table of this level.
10281049
*/
1029-
pd[i]->indexes[j] = -(i + 1 + m);
1050+
pd[i]->indexes[j] = -(1 + offset + m);
10301051
m++;
10311052
}
10321053
}
10331054
i++;
1055+
1056+
/*
1057+
* This counts the number of partitioned tables at upper levels
1058+
* including those of the current level.
1059+
*/
1060+
offset += m;
10341061
}
10351062

10361063
return pd;

0 commit comments

Comments
 (0)