Commit 3fe773b1 authored by Alvaro Herrera's avatar Alvaro Herrera

Track detached partitions more accurately in partdescs

In d6b8d294 I (Álvaro) was sloppy about recording whether a
partition descripor does or does not include detached partitions, when
the snapshot checking does not see the pg_inherits row marked detached.
In that case no partition was omitted, yet in the relcache entry we were
saving the partdesc as omitting partitions.  Flip that (so we save it as
a partdesc not omitting partitions, which indeed it doesn't), which
hopefully makes the code easier to reason about.

Author: Amit Langote <amitlangote09@gmail.com>
Discussion: https://postgr.es/m/CA+HiwqE7GxGU4VdzwZzfiz+Ont5SsopoFkgtrZGEdPqWRL+biA@mail.gmail.com
parent c38cadc0
...@@ -96,11 +96,11 @@ RelationGetPartitionDesc(Relation rel, bool omit_detached) ...@@ -96,11 +96,11 @@ RelationGetPartitionDesc(Relation rel, bool omit_detached)
*/ */
if (omit_detached && if (omit_detached &&
rel->rd_partdesc_nodetached && rel->rd_partdesc_nodetached &&
TransactionIdIsValid(rel->rd_partdesc_nodetached_xmin) &&
ActiveSnapshotSet()) ActiveSnapshotSet())
{ {
Snapshot activesnap; Snapshot activesnap;
Assert(TransactionIdIsValid(rel->rd_partdesc_nodetached_xmin));
activesnap = GetActiveSnapshot(); activesnap = GetActiveSnapshot();
if (!XidInMVCCSnapshot(rel->rd_partdesc_nodetached_xmin, activesnap)) if (!XidInMVCCSnapshot(rel->rd_partdesc_nodetached_xmin, activesnap))
...@@ -163,6 +163,7 @@ RelationBuildPartitionDesc(Relation rel, bool omit_detached) ...@@ -163,6 +163,7 @@ RelationBuildPartitionDesc(Relation rel, bool omit_detached)
omit_detached, NoLock, omit_detached, NoLock,
&detached_exist, &detached_exist,
&detached_xmin); &detached_xmin);
nparts = list_length(inhoids); nparts = list_length(inhoids);
/* Allocate working arrays for OIDs, leaf flags, and boundspecs. */ /* Allocate working arrays for OIDs, leaf flags, and boundspecs. */
...@@ -310,10 +311,17 @@ RelationBuildPartitionDesc(Relation rel, bool omit_detached) ...@@ -310,10 +311,17 @@ RelationBuildPartitionDesc(Relation rel, bool omit_detached)
} }
/* /*
* Are we working with the partition that omits detached partitions, or * Are we working with the partdesc that omits the detached partition, or
* the one that includes them? * the one that includes it?
*
* Note that if a partition was found by the catalog's scan to have been
* detached, but the pg_inherit tuple saying so was not visible to the
* active snapshot (find_inheritance_children_extended will not have set
* detached_xmin in that case), we consider there to be no "omittable"
* detached partitions.
*/ */
is_omit = omit_detached && detached_exist && ActiveSnapshotSet(); is_omit = omit_detached && detached_exist && ActiveSnapshotSet() &&
TransactionIdIsValid(detached_xmin);
/* /*
* We have a fully valid partdesc. Reparent it so that it has the right * We have a fully valid partdesc. Reparent it so that it has the right
...@@ -343,9 +351,11 @@ RelationBuildPartitionDesc(Relation rel, bool omit_detached) ...@@ -343,9 +351,11 @@ RelationBuildPartitionDesc(Relation rel, bool omit_detached)
* For partdescs built excluding detached partitions, which we save * For partdescs built excluding detached partitions, which we save
* separately, we also record the pg_inherits.xmin of the detached * separately, we also record the pg_inherits.xmin of the detached
* partition that was omitted; this informs a future potential user of * partition that was omitted; this informs a future potential user of
* such a cached partdescs. (This might be InvalidXid; see comments * such a cached partdesc to only use it after cross-checking that the
* in struct RelationData). * xmin is indeed visible to the snapshot it is going to be working
* with.
*/ */
Assert(TransactionIdIsValid(detached_xmin));
rel->rd_partdesc_nodetached_xmin = detached_xmin; rel->rd_partdesc_nodetached_xmin = detached_xmin;
} }
else else
......
...@@ -138,9 +138,7 @@ typedef struct RelationData ...@@ -138,9 +138,7 @@ typedef struct RelationData
* rd_partdesc_nodetached. This informs a future user of that partdesc: * rd_partdesc_nodetached. This informs a future user of that partdesc:
* if this value is not in progress for the active snapshot, then the * if this value is not in progress for the active snapshot, then the
* partdesc can be used, otherwise they have to build a new one. (This * partdesc can be used, otherwise they have to build a new one. (This
* matches what find_inheritance_children_extended would do). In the rare * matches what find_inheritance_children_extended would do).
* case where the pg_inherits tuple has been frozen, this will be
* InvalidXid; behave as if the partdesc is unusable in that case.
*/ */
TransactionId rd_partdesc_nodetached_xmin; TransactionId rd_partdesc_nodetached_xmin;
......
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