Commit a2566508 authored by Robert Haas's avatar Robert Haas

Fix bugs in RelationGetPartitionDispatchInfo.

The previous coding was not quite right for cases involving multiple
levels of partitioning.

Amit Langote
parent 4b9a98e1
...@@ -950,7 +950,8 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode, ...@@ -950,7 +950,8 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
*parted_rels; *parted_rels;
ListCell *lc; ListCell *lc;
int i, int i,
k; k,
offset;
/* /*
* Lock partitions and make a list of the partitioned ones to prepare * Lock partitions and make a list of the partitioned ones to prepare
...@@ -990,11 +991,19 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode, ...@@ -990,11 +991,19 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
*/ */
} }
/* Generate PartitionDispatch objects for all partitioned tables */ /*
* We want to create two arrays - one for leaf partitions and another for
* partitioned tables (including the root table and internal partitions).
* While we only create the latter here, leaf partition array of suitable
* objects (such as, ResultRelInfo) is created by the caller using the
* list of OIDs we return. Indexes into these arrays get assigned in a
* breadth-first manner, whereby partitions of any given level are placed
* consecutively in the respective arrays.
*/
pd = (PartitionDispatchData **) palloc(*num_parted * pd = (PartitionDispatchData **) palloc(*num_parted *
sizeof(PartitionDispatchData *)); sizeof(PartitionDispatchData *));
*leaf_part_oids = NIL; *leaf_part_oids = NIL;
i = k = 0; i = k = offset = 0;
foreach(lc, parted_rels) foreach(lc, parted_rels)
{ {
Relation partrel = lfirst(lc); Relation partrel = lfirst(lc);
...@@ -1010,6 +1019,16 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode, ...@@ -1010,6 +1019,16 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
pd[i]->partdesc = partdesc; pd[i]->partdesc = partdesc;
pd[i]->indexes = (int *) palloc(partdesc->nparts * sizeof(int)); pd[i]->indexes = (int *) palloc(partdesc->nparts * sizeof(int));
/*
* Indexes corresponding to the internal partitions are multiplied by
* -1 to distinguish them from those of leaf partitions. Encountering
* an index >= 0 means we found a leaf partition, which is immediately
* returned as the partition we are looking for. A negative index
* means we found a partitioned table, whose PartitionDispatch object
* is located at the above index multiplied back by -1. Using the
* PartitionDispatch object, search is continued further down the
* partition tree.
*/
m = 0; m = 0;
for (j = 0; j < partdesc->nparts; j++) for (j = 0; j < partdesc->nparts; j++)
{ {
...@@ -1023,14 +1042,22 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode, ...@@ -1023,14 +1042,22 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
else else
{ {
/* /*
* We can assign indexes this way because of the way * offset denotes the number of partitioned tables of upper
* parted_rels has been generated. * levels including those of the current level. Any partition
* of this table must belong to the next level and hence will
* be placed after the last partitioned table of this level.
*/ */
pd[i]->indexes[j] = -(i + 1 + m); pd[i]->indexes[j] = -(1 + offset + m);
m++; m++;
} }
} }
i++; i++;
/*
* This counts the number of partitioned tables at upper levels
* including those of the current level.
*/
offset += m;
} }
return pd; return pd;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment