Skip to content

Commit

Permalink
Merge pull request #2383 from citusdata/pg11_drop_index
Browse files Browse the repository at this point in the history
Fix drop index bug on PG11 partitioned table
  • Loading branch information
mtuncer committed Sep 20, 2018
2 parents 9215c00 + 0f6e514 commit 14d514d
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 2 deletions.
19 changes: 17 additions & 2 deletions src/backend/distributed/executor/multi_utility.c
Expand Up @@ -3578,7 +3578,7 @@ InterShardDDLTaskList(Oid leftRelationId, Oid rightRelationId,
*
* This code is heavily borrowed from RangeVarCallbackForDropRelation() in
* commands/tablecmds.c in Postgres source. We need this to ensure the right
* order of locking while dealing with DROP INDEX statments. Because we are
* order of locking while dealing with DROP INDEX statements. Because we are
* exclusively using this callback for INDEX processing, the PARTITION-related
* logic from PostgreSQL's similar callback has been omitted as unneeded.
*/
Expand All @@ -3589,6 +3589,7 @@ RangeVarCallbackForDropIndex(const RangeVar *rel, Oid relOid, Oid oldRelOid, voi
HeapTuple tuple;
struct DropRelationCallbackState *state;
char relkind;
char expected_relkind;
Form_pg_class classform;
LOCKMODE heap_lockmode;

Expand Down Expand Up @@ -3619,7 +3620,21 @@ RangeVarCallbackForDropIndex(const RangeVar *rel, Oid relOid, Oid oldRelOid, voi
return; /* concurrently dropped, so nothing to do */
classform = (Form_pg_class) GETSTRUCT(tuple);

if (classform->relkind != relkind)
/*
* PG 11 sends relkind as partitioned index for an index
* on partitioned table. It is handled the same
* as regular index as far as we are concerned here.
*
* See tablecmds.c:RangeVarCallbackForDropRelation()
*/
expected_relkind = classform->relkind;

#if PG_VERSION_NUM >= 110000
if (expected_relkind == RELKIND_PARTITIONED_INDEX)
expected_relkind = RELKIND_INDEX;
#endif

if (expected_relkind != relkind)
ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not an index", rel->relname)));

Expand Down
36 changes: 36 additions & 0 deletions src/test/regress/expected/multi_partitioning.out
Expand Up @@ -569,6 +569,36 @@ SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'partitioning_t
partitioning_test_default | partitioning_test_default_id_idx
(9 rows)

-- test drop
-- indexes created on parent table can only be dropped on parent table
-- ie using the same index name
-- following will fail
DROP INDEX partitioning_test_2009_id_idx;
ERROR: cannot drop index partitioning_test_2009_id_idx because index partitioning_index requires it
HINT: You can drop index partitioning_index instead.
-- but dropping index on parent table will succeed
DROP INDEX partitioning_index;
-- this index was already created on partition table
DROP INDEX partitioning_2009_index;
-- test drop index on non-distributed, partitioned table
CREATE TABLE non_distributed_partitioned_table(a int, b int) PARTITION BY RANGE (a);
CREATE TABLE non_distributed_partitioned_table_1 PARTITION OF non_distributed_partitioned_table
FOR VALUES FROM (0) TO (10);
CREATE INDEX non_distributed_partitioned_table_index ON non_distributed_partitioned_table(a);
-- see index is created
SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed%' ORDER BY indexname;
tablename | indexname
-------------------------------------+-------------------------------------------
non_distributed_partitioned_table_1 | non_distributed_partitioned_table_1_a_idx
(1 row)

-- drop the index and see it is dropped
DROP INDEX non_distributed_partitioned_table_index;
SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed%' ORDER BY indexname;
tablename | indexname
-----------+-----------
(0 rows)

-- test add COLUMN
-- add COLUMN to partitioned table
ALTER TABLE partitioning_test ADD new_column int;
Expand Down Expand Up @@ -1701,3 +1731,9 @@ ORDER BY

DROP SCHEMA partitioning_schema CASCADE;
NOTICE: drop cascades to table "schema-test"
RESET SEARCH_PATH;
DROP TABLE IF EXISTS
partitioning_hash_test,
partitioning_hash_join_test,
partitioning_test_failure,
non_distributed_partitioned_table;
39 changes: 39 additions & 0 deletions src/test/regress/expected/multi_partitioning_0.out
Expand Up @@ -565,6 +565,37 @@ SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'partitioning_t
partitioning_test_2009 | partitioning_2009_index
(2 rows)

-- test drop
-- indexes created on parent table can only be dropped on parent table
-- ie using the same index name
-- following will fail
DROP INDEX partitioning_test_2009_id_idx;
ERROR: index "partitioning_test_2009_id_idx" does not exist
-- but dropping index on parent table will succeed
DROP INDEX partitioning_index;
ERROR: index "partitioning_index" does not exist
-- this index was already created on partition table
DROP INDEX partitioning_2009_index;
-- test drop index on non-distributed, partitioned table
CREATE TABLE non_distributed_partitioned_table(a int, b int) PARTITION BY RANGE (a);
CREATE TABLE non_distributed_partitioned_table_1 PARTITION OF non_distributed_partitioned_table
FOR VALUES FROM (0) TO (10);
CREATE INDEX non_distributed_partitioned_table_index ON non_distributed_partitioned_table(a);
ERROR: cannot create index on partitioned table "non_distributed_partitioned_table"
-- see index is created
SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed%' ORDER BY indexname;
tablename | indexname
-----------+-----------
(0 rows)

-- drop the index and see it is dropped
DROP INDEX non_distributed_partitioned_table_index;
ERROR: index "non_distributed_partitioned_table_index" does not exist
SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed%' ORDER BY indexname;
tablename | indexname
-----------+-----------
(0 rows)

-- test add COLUMN
-- add COLUMN to partitioned table
ALTER TABLE partitioning_test ADD new_column int;
Expand Down Expand Up @@ -1652,3 +1683,11 @@ ORDER BY

DROP SCHEMA partitioning_schema CASCADE;
NOTICE: drop cascades to table "schema-test"
RESET SEARCH_PATH;
DROP TABLE IF EXISTS
partitioning_hash_test,
partitioning_hash_join_test,
partitioning_test_failure,
non_distributed_partitioned_table;
NOTICE: table "partitioning_hash_test" does not exist, skipping
NOTICE: table "partitioning_hash_join_test" does not exist, skipping
48 changes: 48 additions & 0 deletions src/test/regress/expected/multi_partitioning_1.out
Expand Up @@ -541,6 +541,44 @@ SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'partitioning_t
-----------+-----------
(0 rows)

-- test drop
-- indexes created on parent table can only be dropped on parent table
-- ie using the same index name
-- following will fail
DROP INDEX partitioning_test_2009_id_idx;
ERROR: index "partitioning_test_2009_id_idx" does not exist
-- but dropping index on parent table will succeed
DROP INDEX partitioning_index;
ERROR: index "partitioning_index" does not exist
-- this index was already created on partition table
DROP INDEX partitioning_2009_index;
ERROR: index "partitioning_2009_index" does not exist
-- test drop index on non-distributed, partitioned table
CREATE TABLE non_distributed_partitioned_table(a int, b int) PARTITION BY RANGE (a);
ERROR: syntax error at or near "PARTITION"
LINE 1: ...E non_distributed_partitioned_table(a int, b int) PARTITION ...
^
CREATE TABLE non_distributed_partitioned_table_1 PARTITION OF non_distributed_partitioned_table
FOR VALUES FROM (0) TO (10);
ERROR: syntax error at or near "PARTITION"
LINE 1: CREATE TABLE non_distributed_partitioned_table_1 PARTITION O...
^
CREATE INDEX non_distributed_partitioned_table_index ON non_distributed_partitioned_table(a);
ERROR: relation "non_distributed_partitioned_table" does not exist
-- see index is created
SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed%' ORDER BY indexname;
tablename | indexname
-----------+-----------
(0 rows)

-- drop the index and see it is dropped
DROP INDEX non_distributed_partitioned_table_index;
ERROR: index "non_distributed_partitioned_table_index" does not exist
SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed%' ORDER BY indexname;
tablename | indexname
-----------+-----------
(0 rows)

-- test add COLUMN
-- add COLUMN to partitioned table
ALTER TABLE partitioning_test ADD new_column int;
Expand Down Expand Up @@ -1532,3 +1570,13 @@ LINE 6: logicalrelid IN ('partitioning_schema."schema-test"'::re...
^
DROP SCHEMA partitioning_schema CASCADE;
NOTICE: drop cascades to table "schema-test_2009"
RESET SEARCH_PATH;
DROP TABLE IF EXISTS
partitioning_hash_test,
partitioning_hash_join_test,
partitioning_test_failure,
non_distributed_partitioned_table;
NOTICE: table "partitioning_hash_test" does not exist, skipping
NOTICE: table "partitioning_hash_join_test" does not exist, skipping
NOTICE: table "partitioning_test_failure" does not exist, skipping
NOTICE: table "non_distributed_partitioned_table" does not exist, skipping
32 changes: 32 additions & 0 deletions src/test/regress/sql/multi_partitioning.sql
Expand Up @@ -345,6 +345,31 @@ CREATE INDEX CONCURRENTLY partitioned_2010_index ON partitioning_test_2010(id);
-- see index is created
SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'partitioning_test%' ORDER BY indexname;

-- test drop
-- indexes created on parent table can only be dropped on parent table
-- ie using the same index name
-- following will fail
DROP INDEX partitioning_test_2009_id_idx;

-- but dropping index on parent table will succeed
DROP INDEX partitioning_index;

-- this index was already created on partition table
DROP INDEX partitioning_2009_index;

-- test drop index on non-distributed, partitioned table
CREATE TABLE non_distributed_partitioned_table(a int, b int) PARTITION BY RANGE (a);
CREATE TABLE non_distributed_partitioned_table_1 PARTITION OF non_distributed_partitioned_table
FOR VALUES FROM (0) TO (10);
CREATE INDEX non_distributed_partitioned_table_index ON non_distributed_partitioned_table(a);

-- see index is created
SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed%' ORDER BY indexname;

-- drop the index and see it is dropped
DROP INDEX non_distributed_partitioned_table_index;
SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed%' ORDER BY indexname;

-- test add COLUMN
-- add COLUMN to partitioned table
ALTER TABLE partitioning_test ADD new_column int;
Expand Down Expand Up @@ -1050,3 +1075,10 @@ ORDER BY
1,2;

DROP SCHEMA partitioning_schema CASCADE;
RESET SEARCH_PATH;
DROP TABLE IF EXISTS
partitioning_hash_test,
partitioning_hash_join_test,
partitioning_test_failure,
non_distributed_partitioned_table;

0 comments on commit 14d514d

Please sign in to comment.