postgres.git / summary / log / commit / refs
commit f087d63a45b5935b5c15cecb7d88f140d5cc8b7c
Author: Michael Paquier <michael@paquier.xyz>
Date: Tue Mar 03 01:12:49 2020 +0000
First released in: 13.0, 12.3
Preserve pg_index.indisclustered across REINDEX CONCURRENTLY
If the flag value is lost, a CLUSTER query following REINDEX
CONCURRENTLY could fail. Non-concurrent REINDEX is already handling
this case consistently.
Author: Justin Pryzby
Discussion: https://postgr.es/m/20200229024202.GH29456@telsasoft.com
Backpatch-through: 12
src/backend/catalog/index.c | 8 +++++++-
src/test/regress/expected/create_index.out | 13 +++++++++++++
src/test/regress/sql/create_index.sql | 9 +++++++++
3 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index bb90fd38113..7408d495326 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1528,7 +1528,13 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
newIndexForm->indimmediate = oldIndexForm->indimmediate;
oldIndexForm->indimmediate = true;
- /* Mark old index as valid and new as invalid as index_set_state_flags */
+ /* Preserve indisclustered in the new index */
+ newIndexForm->indisclustered = oldIndexForm->indisclustered;
+
+ /*
+ * Mark the old index as valid, and the new index as invalid similarly
+ * to what index_set_state_flags() does.
+ */
newIndexForm->indisvalid = true;
oldIndexForm->indisvalid = false;
oldIndexForm->indisclustered = false;
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 593b1f37243..a649957f758 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2115,6 +2115,19 @@ SELECT obj_description('testcomment_idx1'::regclass, 'pg_class');
(1 row)
DROP TABLE testcomment;
+-- Check that indisclustered updates are preserved
+CREATE TABLE concur_clustered(i int);
+CREATE INDEX concur_clustered_i_idx ON concur_clustered(i);
+ALTER TABLE concur_clustered CLUSTER ON concur_clustered_i_idx;
+REINDEX TABLE CONCURRENTLY concur_clustered;
+SELECT indexrelid::regclass, indisclustered FROM pg_index
+ WHERE indrelid = 'concur_clustered'::regclass;
+ indexrelid | indisclustered
+------------------------+----------------
+ concur_clustered_i_idx | t
+(1 row)
+
+DROP TABLE concur_clustered;
-- Partitions
-- Create some partitioned tables
CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1);
diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql
index e4c4272a2c9..fb7da725ff0 100644
--- a/src/test/regress/sql/create_index.sql
+++ b/src/test/regress/sql/create_index.sql
@@ -852,6 +852,15 @@ SELECT obj_description('testcomment_idx1'::regclass, 'pg_class');
REINDEX TABLE CONCURRENTLY testcomment ;
SELECT obj_description('testcomment_idx1'::regclass, 'pg_class');
DROP TABLE testcomment;
+-- Check that indisclustered updates are preserved
+CREATE TABLE concur_clustered(i int);
+CREATE INDEX concur_clustered_i_idx ON concur_clustered(i);
+ALTER TABLE concur_clustered CLUSTER ON concur_clustered_i_idx;
+REINDEX TABLE CONCURRENTLY concur_clustered;
+SELECT indexrelid::regclass, indisclustered FROM pg_index
+ WHERE indrelid = 'concur_clustered'::regclass;
+DROP TABLE concur_clustered;
+
-- Partitions
-- Create some partitioned tables
CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1);
[parent: 3b5709e664c4]