]> granicus.if.org Git - postgresql/commitdiff
Fix lost persistence setting during REINDEX INDEX
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 30 Mar 2015 19:01:44 +0000 (16:01 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 30 Mar 2015 19:01:44 +0000 (16:01 -0300)
ReindexIndex() trusts a parser-built RangeVar with the persistence to
use for the new copy of the index; but the parser naturally does not
know what's the persistence of the original index.  To find out the
correct persistence, grab it from relcache.

This bug was introduced by commit 85b506bbfc2937c9, and therefore no
backpatch is necessary.

Bug reported by Thom Brown, analysis and patch by Michael Paquier; test
case provided by Fabrízio de Royes Mello.

src/backend/commands/indexcmds.c
src/test/regress/expected/create_table.out
src/test/regress/sql/create_table.sql

index 1c1d0da448d83708e3ee898a8acffa9f0d45e68f..99acd4a6a2ca614c19481c98e588b57bad7925ff 100644 (file)
@@ -1685,14 +1685,28 @@ ReindexIndex(RangeVar *indexRelation)
 {
        Oid                     indOid;
        Oid                     heapOid = InvalidOid;
+       Relation        irel;
+       char            persistence;
 
-       /* lock level used here should match index lock reindex_index() */
+       /*
+        * Find and lock index, and check permissions on table; use callback to
+        * obtain lock on table first, to avoid deadlock hazard.  The lock level
+        * used here must match the index lock obtained in reindex_index().
+        */
        indOid = RangeVarGetRelidExtended(indexRelation, AccessExclusiveLock,
                                                                          false, false,
                                                                          RangeVarCallbackForReindexIndex,
                                                                          (void *) &heapOid);
 
-       reindex_index(indOid, false, indexRelation->relpersistence);
+       /*
+        * Obtain the current persistence of the existing index.  We already hold
+        * lock on the index.
+        */
+       irel = index_open(indOid, NoLock);
+       persistence = irel->rd_rel->relpersistence;
+       index_close(irel, NoLock);
+
+       reindex_index(indOid, false, persistence);
 
        return indOid;
 }
index 34b5fc113d09b06b5a084e710fe07daab35efd08..8ba7bbc1113ad207c91ac63c9e2d897330e40bb0 100644 (file)
@@ -208,6 +208,28 @@ CREATE TABLE IF NOT EXISTS test_tsvector(
 );
 NOTICE:  relation "test_tsvector" already exists, skipping
 CREATE UNLOGGED TABLE unlogged1 (a int primary key);                   -- OK
+CREATE TEMPORARY TABLE unlogged2 (a int primary key);                  -- OK
+SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname;
+    relname     | relkind | relpersistence 
+----------------+---------+----------------
+ unlogged1      | r       | u
+ unlogged1_pkey | i       | u
+ unlogged2      | r       | t
+ unlogged2_pkey | i       | t
+(4 rows)
+
+REINDEX INDEX unlogged1_pkey;
+REINDEX INDEX unlogged2_pkey;
+SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname;
+    relname     | relkind | relpersistence 
+----------------+---------+----------------
+ unlogged1      | r       | u
+ unlogged1_pkey | i       | u
+ unlogged2      | r       | t
+ unlogged2_pkey | i       | t
+(4 rows)
+
+DROP TABLE unlogged2;
 INSERT INTO unlogged1 VALUES (42);
 CREATE UNLOGGED TABLE public.unlogged2 (a int primary key);            -- also OK
 CREATE UNLOGGED TABLE pg_temp.unlogged3 (a int primary key);   -- not OK
index 08029a99b0a6a3e2439bad5d2a42d10c071bfa4e..03bb5ff704e494c5c70f29e5493bf4e0f6f341dc 100644 (file)
@@ -246,6 +246,12 @@ CREATE TABLE IF NOT EXISTS test_tsvector(
 );
 
 CREATE UNLOGGED TABLE unlogged1 (a int primary key);                   -- OK
+CREATE TEMPORARY TABLE unlogged2 (a int primary key);                  -- OK
+SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname;
+REINDEX INDEX unlogged1_pkey;
+REINDEX INDEX unlogged2_pkey;
+SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname;
+DROP TABLE unlogged2;
 INSERT INTO unlogged1 VALUES (42);
 CREATE UNLOGGED TABLE public.unlogged2 (a int primary key);            -- also OK
 CREATE UNLOGGED TABLE pg_temp.unlogged3 (a int primary key);   -- not OK