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

Commit b0ea165

Browse files
committed
Revert "Fix partition pruning setup during DETACH CONCURRENTLY"
This reverts commit 27162a6; this branch is in code freeze due to a nearing release. We can commit again after the release is out. Discussion: https://postgr.es/m/1158256.1719239648@sss.pgh.pa.us
1 parent 27162a6 commit b0ea165

File tree

1 file changed

+50
-60
lines changed

1 file changed

+50
-60
lines changed

src/backend/executor/execPartition.c

+50-60
Original file line numberDiff line numberDiff line change
@@ -1942,58 +1942,67 @@ CreatePartitionPruneState(PlanState *planstate, PartitionPruneInfo *pruneinfo)
19421942
/*
19431943
* Initialize the subplan_map and subpart_map.
19441944
*
1945-
* The set of partitions that exist now might not be the same that
1946-
* existed when the plan was made. The normal case is that it is;
1947-
* optimize for that case with a quick comparison, and just copy
1948-
* the subplan_map and make subpart_map point to the one in
1949-
* PruneInfo.
1945+
* Because we request detached partitions to be included, and
1946+
* detaching waits for old transactions, it is safe to assume that
1947+
* no partitions have disappeared since this query was planned.
19501948
*
1951-
* For the case where they aren't identical, we could have more
1952-
* partitions on either side; or even exactly the same number of
1953-
* them on both but the set of OIDs doesn't match fully. Handle
1954-
* this by creating new subplan_map and subpart_map arrays that
1955-
* corresponds to the ones in the PruneInfo where the new
1956-
* partition descriptor's OIDs match. Any that don't match can be
1957-
* set to -1, as if they were pruned. Both arrays must be in
1958-
* numerical OID order.
1949+
* However, new partitions may have been added.
19591950
*/
1951+
Assert(partdesc->nparts >= pinfo->nparts);
19601952
pprune->nparts = partdesc->nparts;
19611953
pprune->subplan_map = palloc(sizeof(int) * partdesc->nparts);
1962-
1963-
if (partdesc->nparts == pinfo->nparts &&
1964-
memcmp(partdesc->oids, pinfo->relid_map,
1965-
sizeof(int) * partdesc->nparts) == 0)
1954+
if (partdesc->nparts == pinfo->nparts)
19661955
{
1956+
/*
1957+
* There are no new partitions, so this is simple. We can
1958+
* simply point to the subpart_map from the plan, but we must
1959+
* copy the subplan_map since we may change it later.
1960+
*/
19671961
pprune->subpart_map = pinfo->subpart_map;
19681962
memcpy(pprune->subplan_map, pinfo->subplan_map,
19691963
sizeof(int) * pinfo->nparts);
1964+
1965+
/*
1966+
* Double-check that the list of unpruned relations has not
1967+
* changed. (Pruned partitions are not in relid_map[].)
1968+
*/
1969+
#ifdef USE_ASSERT_CHECKING
1970+
for (int k = 0; k < pinfo->nparts; k++)
1971+
{
1972+
Assert(partdesc->oids[k] == pinfo->relid_map[k] ||
1973+
pinfo->subplan_map[k] == -1);
1974+
}
1975+
#endif
19701976
}
19711977
else
19721978
{
19731979
int pd_idx = 0;
19741980
int pp_idx;
19751981

19761982
/*
1977-
* When the partition arrays are not identical, there could be
1978-
* some new ones but it's also possible that one was removed;
1979-
* we cope with both situations by walking the arrays and
1980-
* discarding those that don't match.
1983+
* Some new partitions have appeared since plan time, and
1984+
* those are reflected in our PartitionDesc but were not
1985+
* present in the one used to construct subplan_map and
1986+
* subpart_map. So we must construct new and longer arrays
1987+
* where the partitions that were originally present map to
1988+
* the same sub-structures, and any added partitions map to
1989+
* -1, as if the new partitions had been pruned.
19811990
*
1982-
* If the number of partitions on both sides match, it's still
1983-
* possible that one partition has been detached and another
1984-
* attached. Cope with that by creating a map that skips any
1985-
* mismatches.
1991+
* Note: pinfo->relid_map[] may contain InvalidOid entries for
1992+
* partitions pruned by the planner. We cannot tell exactly
1993+
* which of the partdesc entries these correspond to, but we
1994+
* don't have to; just skip over them. The non-pruned
1995+
* relid_map entries, however, had better be a subset of the
1996+
* partdesc entries and in the same order.
19861997
*/
19871998
pprune->subpart_map = palloc(sizeof(int) * partdesc->nparts);
1988-
19891999
for (pp_idx = 0; pp_idx < partdesc->nparts; pp_idx++)
19902000
{
19912001
/* Skip any InvalidOid relid_map entries */
19922002
while (pd_idx < pinfo->nparts &&
19932003
!OidIsValid(pinfo->relid_map[pd_idx]))
19942004
pd_idx++;
19952005

1996-
recheck:
19972006
if (pd_idx < pinfo->nparts &&
19982007
pinfo->relid_map[pd_idx] == partdesc->oids[pp_idx])
19992008
{
@@ -2003,43 +2012,24 @@ CreatePartitionPruneState(PlanState *planstate, PartitionPruneInfo *pruneinfo)
20032012
pprune->subpart_map[pp_idx] =
20042013
pinfo->subpart_map[pd_idx];
20052014
pd_idx++;
2006-
continue;
20072015
}
2008-
2009-
/*
2010-
* There isn't an exact match in the corresponding
2011-
* positions of both arrays. Peek ahead in
2012-
* pinfo->relid_map to see if we have a match for the
2013-
* current partition in partdesc. Normally if a match
2014-
* exists it's just one element ahead, and it means the
2015-
* planner saw one extra partition that we no longer see
2016-
* now (its concurrent detach finished just in between);
2017-
* so we skip that one by updating pd_idx to the new
2018-
* location and jumping above. We can then continue to
2019-
* match the rest of the elements after skipping the OID
2020-
* with no match; no future matches are tried for the
2021-
* element that was skipped, because we know the arrays to
2022-
* be in the same order.
2023-
*
2024-
* If we don't see a match anywhere in the rest of the
2025-
* pinfo->relid_map array, that means we see an element
2026-
* now that the planner didn't see, so mark that one as
2027-
* pruned and move on.
2028-
*/
2029-
for (int pd_idx2 = pd_idx + 1; pd_idx2 < pinfo->nparts; pd_idx2++)
2016+
else
20302017
{
2031-
if (pd_idx2 >= pinfo->nparts)
2032-
break;
2033-
if (pinfo->relid_map[pd_idx2] == partdesc->oids[pp_idx])
2034-
{
2035-
pd_idx = pd_idx2;
2036-
goto recheck;
2037-
}
2018+
/* this partdesc entry is not in the plan */
2019+
pprune->subplan_map[pp_idx] = -1;
2020+
pprune->subpart_map[pp_idx] = -1;
20382021
}
2039-
2040-
pprune->subpart_map[pp_idx] = -1;
2041-
pprune->subplan_map[pp_idx] = -1;
20422022
}
2023+
2024+
/*
2025+
* It might seem that we need to skip any trailing InvalidOid
2026+
* entries in pinfo->relid_map before checking that we scanned
2027+
* all of the relid_map. But we will have skipped them above,
2028+
* because they must correspond to some partdesc->oids
2029+
* entries; we just couldn't tell which.
2030+
*/
2031+
if (pd_idx != pinfo->nparts)
2032+
elog(ERROR, "could not match partition child tables to plan elements");
20432033
}
20442034

20452035
/* present_parts is also subject to later modification */

0 commit comments

Comments
 (0)