Fix handling of pg_class.relispartition at swap phase in REINDEX CONCURRENTLY
authorMichael Paquier <[email protected]>
Tue, 29 Oct 2019 02:08:09 +0000 (11:08 +0900)
committerMichael Paquier <[email protected]>
Tue, 29 Oct 2019 02:08:09 +0000 (11:08 +0900)
When cancelling REINDEX CONCURRENTLY after swapping the old and new
indexes (for example interruption at step 5), the old index remains
around and is marked as invalid.  The old index should also be manually
droppable to clean up the parent relation from any invalid indexes still
remaining.  For a partition index reindexed, pg_class.relispartition was
not getting updated, causing the index to not be droppable as DROP INDEX
would look for dependencies in a partition tree, which do not exist
anymore after the swap phase is done.

The fix here is simple: when swapping the old and new indexes, make sure
that pg_class.relispartition is correctly switched, similarly to what is
done for the index name.

Reported-by: Justin Pryzby
Author: Michael Paquier
Discussion: https://postgr.es/m/20191015164047[email protected]
Backpatch-through: 12

src/backend/catalog/index.c

index 78896da391bd9d340e44752ca4c8e7cd3ec39fab..f6c31ccd7660f6e37a5dfc938d212d536ceb223c 100644 (file)
@@ -1462,6 +1462,7 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
                                newIndexTuple;
        Form_pg_index oldIndexForm,
                                newIndexForm;
+       bool            isPartition;
        Oid                     indexConstraintOid;
        List       *constraintOids = NIL;
        ListCell   *lc;
@@ -1491,8 +1492,10 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
        namestrcpy(&newClassForm->relname, NameStr(oldClassForm->relname));
        namestrcpy(&oldClassForm->relname, oldName);
 
-       /* Copy partition flag to track inheritance properly */
+       /* Swap the partition flags to track inheritance properly */
+       isPartition = newClassForm->relispartition;
        newClassForm->relispartition = oldClassForm->relispartition;
+       oldClassForm->relispartition = isPartition;
 
        CatalogTupleUpdate(pg_class, &oldClassTuple->t_self, oldClassTuple);
        CatalogTupleUpdate(pg_class, &newClassTuple->t_self, newClassTuple);