aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/test_decoding/expected/rewrite.out4
-rw-r--r--contrib/test_decoding/sql/rewrite.sql5
-rw-r--r--src/backend/catalog/index.c42
-rw-r--r--src/backend/catalog/indexing.c21
-rw-r--r--src/test/regress/expected/create_index.out18
-rw-r--r--src/test/regress/sql/create_index.sql21
6 files changed, 91 insertions, 20 deletions
diff --git a/contrib/test_decoding/expected/rewrite.out b/contrib/test_decoding/expected/rewrite.out
index 3bf2afa9315..28998b86f9e 100644
--- a/contrib/test_decoding/expected/rewrite.out
+++ b/contrib/test_decoding/expected/rewrite.out
@@ -103,6 +103,10 @@ COMMIT;
-- repeated rewrites in different transactions
VACUUM FULL pg_class;
VACUUM FULL pg_class;
+-- reindexing of important relations / indexes
+REINDEX TABLE pg_class;
+REINDEX INDEX pg_class_oid_index;
+REINDEX INDEX pg_class_tblspc_relfilenode_index;
INSERT INTO replication_example(somedata, testcolumn1) VALUES (5, 3);
BEGIN;
INSERT INTO replication_example(somedata, testcolumn1) VALUES (6, 4);
diff --git a/contrib/test_decoding/sql/rewrite.sql b/contrib/test_decoding/sql/rewrite.sql
index 4271b82bead..c9503a0da59 100644
--- a/contrib/test_decoding/sql/rewrite.sql
+++ b/contrib/test_decoding/sql/rewrite.sql
@@ -74,6 +74,11 @@ COMMIT;
VACUUM FULL pg_class;
VACUUM FULL pg_class;
+-- reindexing of important relations / indexes
+REINDEX TABLE pg_class;
+REINDEX INDEX pg_class_oid_index;
+REINDEX INDEX pg_class_tblspc_relfilenode_index;
+
INSERT INTO replication_example(somedata, testcolumn1) VALUES (5, 3);
BEGIN;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index b8c1daf09a4..d1012bfa2aa 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3290,29 +3290,35 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
*/
TransferPredicateLocksToHeapRelation(iRel);
+ /* Fetch info needed for index_build */
+ indexInfo = BuildIndexInfo(iRel);
+
+ /* If requested, skip checking uniqueness/exclusion constraints */
+ if (skip_constraint_checks)
+ {
+ if (indexInfo->ii_Unique || indexInfo->ii_ExclusionOps != NULL)
+ skipped_constraint = true;
+ indexInfo->ii_Unique = false;
+ indexInfo->ii_ExclusionOps = NULL;
+ indexInfo->ii_ExclusionProcs = NULL;
+ indexInfo->ii_ExclusionStrats = NULL;
+ }
+
+ /*
+ * Build a new physical relation for the index. Need to do that before
+ * "officially" starting the reindexing with SetReindexProcessing -
+ * otherwise the necessary pg_class changes cannot be made with
+ * encountering assertions.
+ */
+ RelationSetNewRelfilenode(iRel, persistence, InvalidTransactionId,
+ InvalidMultiXactId);
+
+ /* ensure SetReindexProcessing state isn't leaked */
PG_TRY();
{
/* Suppress use of the target index while rebuilding it */
SetReindexProcessing(heapId, indexId);
- /* Fetch info needed for index_build */
- indexInfo = BuildIndexInfo(iRel);
-
- /* If requested, skip checking uniqueness/exclusion constraints */
- if (skip_constraint_checks)
- {
- if (indexInfo->ii_Unique || indexInfo->ii_ExclusionOps != NULL)
- skipped_constraint = true;
- indexInfo->ii_Unique = false;
- indexInfo->ii_ExclusionOps = NULL;
- indexInfo->ii_ExclusionProcs = NULL;
- indexInfo->ii_ExclusionStrats = NULL;
- }
-
- /* We'll build a new physical relation for the index */
- RelationSetNewRelfilenode(iRel, persistence, InvalidTransactionId,
- InvalidMultiXactId);
-
/* Initialize the index and rebuild */
/* Note: we do not need to re-establish pkey setting */
index_build(heapRelation, iRel, indexInfo, false, true);
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index 0231084c7c9..2d6e140087d 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -80,9 +80,15 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
Datum values[INDEX_MAX_KEYS];
bool isnull[INDEX_MAX_KEYS];
- /* HOT update does not require index inserts */
+ /*
+ * HOT update does not require index inserts. But with asserts enabled we
+ * want to check that it'd be legal to currently insert into the
+ * table/index.
+ */
+#ifndef USE_ASSERT_CHECKING
if (HeapTupleIsHeapOnly(heapTuple))
return;
+#endif
/*
* Get information from the state structure. Fall out if nothing to do.
@@ -104,8 +110,10 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
for (i = 0; i < numIndexes; i++)
{
IndexInfo *indexInfo;
+ Relation index;
indexInfo = indexInfoArray[i];
+ index = relationDescs[i];
/* If the index is marked as read-only, ignore it */
if (!indexInfo->ii_ReadyForInserts)
@@ -118,7 +126,16 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
Assert(indexInfo->ii_Expressions == NIL);
Assert(indexInfo->ii_Predicate == NIL);
Assert(indexInfo->ii_ExclusionOps == NULL);
- Assert(relationDescs[i]->rd_index->indimmediate);
+ Assert(index->rd_index->indimmediate);
+
+ /* see earlier check above */
+#ifdef USE_ASSERT_CHECKING
+ if (HeapTupleIsHeapOnly(heapTuple))
+ {
+ Assert(!ReindexIsProcessingIndex(RelationGetRelid(index)));
+ continue;
+ }
+#endif /* USE_ASSERT_CHECKING */
/*
* FormIndexDatum fills in its values and isnull parameters with the
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 9c0f3e3b57b..59f1d8e22c6 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2921,6 +2921,24 @@ REINDEX (VERBOSE) TABLE reindex_verbose;
INFO: index "reindex_verbose_pkey" was reindexed
DROP TABLE reindex_verbose;
--
+-- check that system tables can be reindexed
+--
+-- whole tables
+REINDEX TABLE pg_class; -- mapped, non-shared, critical
+REINDEX TABLE pg_index; -- non-mapped, non-shared, critical
+REINDEX TABLE pg_operator; -- non-mapped, non-shared, critical
+REINDEX TABLE pg_database; -- mapped, shared, critical
+REINDEX TABLE pg_shdescription; -- mapped, shared non-critical
+-- Check that individual system indexes can be reindexed. That's a bit
+-- different from the entire-table case because reindex_relation
+-- treats e.g. pg_class special.
+REINDEX INDEX pg_class_oid_index; -- mapped, non-shared, critical
+REINDEX INDEX pg_class_relname_nsp_index; -- mapped, non-shared, non-critical
+REINDEX INDEX pg_index_indexrelid_index; -- non-mapped, non-shared, critical
+REINDEX INDEX pg_index_indrelid_index; -- non-mapped, non-shared, non-critical
+REINDEX INDEX pg_database_oid_index; -- mapped, shared, critical
+REINDEX INDEX pg_shdescription_o_c_index; -- mapped, shared, non-critical
+--
-- REINDEX SCHEMA
--
REINDEX SCHEMA schema_to_reindex; -- failure, schema does not exist
diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql
index b199c2368ea..8d3c9d116b4 100644
--- a/src/test/regress/sql/create_index.sql
+++ b/src/test/regress/sql/create_index.sql
@@ -990,6 +990,27 @@ REINDEX (VERBOSE) TABLE reindex_verbose;
DROP TABLE reindex_verbose;
--
+-- check that system tables can be reindexed
+--
+
+-- whole tables
+REINDEX TABLE pg_class; -- mapped, non-shared, critical
+REINDEX TABLE pg_index; -- non-mapped, non-shared, critical
+REINDEX TABLE pg_operator; -- non-mapped, non-shared, critical
+REINDEX TABLE pg_database; -- mapped, shared, critical
+REINDEX TABLE pg_shdescription; -- mapped, shared non-critical
+
+-- Check that individual system indexes can be reindexed. That's a bit
+-- different from the entire-table case because reindex_relation
+-- treats e.g. pg_class special.
+REINDEX INDEX pg_class_oid_index; -- mapped, non-shared, critical
+REINDEX INDEX pg_class_relname_nsp_index; -- mapped, non-shared, non-critical
+REINDEX INDEX pg_index_indexrelid_index; -- non-mapped, non-shared, critical
+REINDEX INDEX pg_index_indrelid_index; -- non-mapped, non-shared, non-critical
+REINDEX INDEX pg_database_oid_index; -- mapped, shared, critical
+REINDEX INDEX pg_shdescription_o_c_index; -- mapped, shared, non-critical
+
+--
-- REINDEX SCHEMA
--
REINDEX SCHEMA schema_to_reindex; -- failure, schema does not exist