Raise error on concurrent drop of partitioned index
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 1 Sep 2020 17:40:43 +0000 (13:40 -0400)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 1 Sep 2020 17:40:43 +0000 (13:40 -0400)
We were already raising an error for DROP INDEX CONCURRENTLY on a
partitioned table, albeit a different and confusing one:
  ERROR:  DROP INDEX CONCURRENTLY must be first action in transaction

Change that to throw a more comprehensible error:
  ERROR:  cannot drop partitioned index \"%s\" concurrently

Michael Paquier authored the test case for indexes on temporary
partitioned tables.

Backpatch to 11, where indexes on partitioned tables were added.

Reported-by: Jan Mussler <jan.mussler@zalando.de>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/16594-d2956ca909585067@postgresql.org

doc/src/sgml/ref/drop_index.sgml
src/backend/commands/tablecmds.c
src/test/regress/expected/indexing.out
src/test/regress/sql/indexing.sql

index 0aedd71bd68da258a661d1aa4caaa52a05635800..85cf23bca20aa06219e548aa675b9aab99aa1dc6 100644 (file)
@@ -57,6 +57,8 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] <replaceable class="parameter">name</r
       Also, regular <command>DROP INDEX</command> commands can be
       performed within a transaction block, but
       <command>DROP INDEX CONCURRENTLY</command> cannot.
+      Lastly, indexes on partitioned tables cannot be dropped using this
+      option.
      </para>
      <para>
       For temporary tables, <command>DROP INDEX</command> is always
index d2b15a3387b0bee7529471f2fb532ce96a63c2fa..3e57c7f9e1dbe708e1276b6ef29563c9eaa653f9 100644 (file)
@@ -1373,6 +1373,17 @@ RemoveRelations(DropStmt *drop)
            flags |= PERFORM_DELETION_CONCURRENTLY;
        }
 
+       /*
+        * Concurrent index drop cannot be used with partitioned indexes,
+        * either.
+        */
+       if ((flags & PERFORM_DELETION_CONCURRENTLY) != 0 &&
+           get_rel_relkind(relOid) == RELKIND_PARTITIONED_INDEX)
+           ereport(ERROR,
+                   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                    errmsg("cannot drop partitioned index \"%s\" concurrently",
+                           rel->relname)));
+
        /* OK, we're ready to delete this one */
        obj.classId = RelationRelationId;
        obj.objectId = relOid;
index f78865ef81b802fb836614e52da41a0143b66d87..7e78a07af8b8bcd0efe4e2524f698cff518a4f98 100644 (file)
@@ -174,6 +174,8 @@ create table idxpart1 partition of idxpart for values from (0) to (10);
 drop index idxpart1_a_idx; -- no way
 ERROR:  cannot drop index idxpart1_a_idx because index idxpart_a_idx requires it
 HINT:  You can drop index idxpart_a_idx instead.
+drop index concurrently idxpart_a_idx; -- unsupported
+ERROR:  cannot drop partitioned index "idxpart_a_idx" concurrently
 drop index idxpart_a_idx;  -- both indexes go away
 select relname, relkind from pg_class
   where relname like 'idxpart%' order by relname;
@@ -194,6 +196,24 @@ select relname, relkind from pg_class
 (2 rows)
 
 drop table idxpart;
+-- DROP behavior with temporary partitioned indexes
+create temp table idxpart_temp (a int) partition by range (a);
+create index on idxpart_temp(a);
+create temp table idxpart1_temp partition of idxpart_temp
+  for values from (0) to (10);
+drop index idxpart1_temp_a_idx; -- error
+ERROR:  cannot drop index idxpart1_temp_a_idx because index idxpart_temp_a_idx requires it
+HINT:  You can drop index idxpart_temp_a_idx instead.
+-- non-concurrent drop is enforced here, so it is a valid case.
+drop index concurrently idxpart_temp_a_idx;
+select relname, relkind from pg_class
+  where relname like 'idxpart_temp%' order by relname;
+   relname    | relkind 
+--------------+---------
+ idxpart_temp | p
+(1 row)
+
+drop table idxpart_temp;
 -- ALTER INDEX .. ATTACH, error cases
 create table idxpart (a int, b int) partition by range (a, b);
 create table idxpart1 partition of idxpart for values from (0, 0) to (10, 10);
index 35d159f41b925a741f41ff3f371c662a438844a4..42f398b67c2c4dc5fdeba06625c6014543f38a00 100644 (file)
@@ -92,6 +92,7 @@ create table idxpart (a int) partition by range (a);
 create index on idxpart (a);
 create table idxpart1 partition of idxpart for values from (0) to (10);
 drop index idxpart1_a_idx; -- no way
+drop index concurrently idxpart_a_idx; -- unsupported
 drop index idxpart_a_idx;  -- both indexes go away
 select relname, relkind from pg_class
   where relname like 'idxpart%' order by relname;
@@ -101,6 +102,18 @@ select relname, relkind from pg_class
   where relname like 'idxpart%' order by relname;
 drop table idxpart;
 
+-- DROP behavior with temporary partitioned indexes
+create temp table idxpart_temp (a int) partition by range (a);
+create index on idxpart_temp(a);
+create temp table idxpart1_temp partition of idxpart_temp
+  for values from (0) to (10);
+drop index idxpart1_temp_a_idx; -- error
+-- non-concurrent drop is enforced here, so it is a valid case.
+drop index concurrently idxpart_temp_a_idx;
+select relname, relkind from pg_class
+  where relname like 'idxpart_temp%' order by relname;
+drop table idxpart_temp;
+
 -- ALTER INDEX .. ATTACH, error cases
 create table idxpart (a int, b int) partition by range (a, b);
 create table idxpart1 partition of idxpart for values from (0, 0) to (10, 10);