diff --git a/src/backend/distributed/commands/index.c b/src/backend/distributed/commands/index.c index b43090d45..cfdd6ad63 100644 --- a/src/backend/distributed/commands/index.c +++ b/src/backend/distributed/commands/index.c @@ -24,6 +24,7 @@ #include "distributed/commands.h" #include "distributed/commands/utility_hook.h" #include "distributed/deparse_shard_query.h" +#include "distributed/deparser.h" #include "distributed/distributed_planner.h" #include "distributed/listutils.h" #include "distributed/local_executor.h" @@ -71,6 +72,7 @@ static void RangeVarCallbackForReindexIndex(const RangeVar *rel, Oid relOid, Oid oldRelOid, void *arg); static void ErrorIfUnsupportedIndexStmt(IndexStmt *createIndexStatement); +static void ErrorIfUnsupportedDropIndexStmt(DropStmt *dropIndexStatement); static List * DropIndexTaskList(Oid relationId, Oid indexId, DropStmt *dropStmt); @@ -676,21 +678,9 @@ PreprocessDropIndexStmt(Node *node, const char *dropIndexCommand, bool isCitusRelation = IsCitusTable(relationId); if (isCitusRelation) { - if (OidIsValid(distributedIndexId)) - { - /* - * We already have a distributed index in the list, and Citus - * currently only support dropping a single distributed index. - */ - ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot drop multiple distributed objects in " - "a single command"), - errhint("Try dropping each object in a separate DROP " - "command."))); - } - distributedIndexId = indexId; distributedRelationId = relationId; + break; } } @@ -698,6 +688,8 @@ PreprocessDropIndexStmt(Node *node, const char *dropIndexCommand, { DDLJob *ddlJob = palloc0(sizeof(DDLJob)); + ErrorIfUnsupportedDropIndexStmt(dropIndexStatement); + if (AnyForeignKeyDependsOnIndex(distributedIndexId)) { MarkInvalidateForeignKeyGraph(); @@ -1159,6 +1151,26 @@ ErrorIfUnsupportedIndexStmt(IndexStmt *createIndexStatement) } +/* + * ErrorIfUnsupportedDropIndexStmt checks if the corresponding drop index statement is + * supported for distributed tables and errors out if it is not. + */ +static void +ErrorIfUnsupportedDropIndexStmt(DropStmt *dropIndexStatement) +{ + Assert(dropIndexStatement->removeType == OBJECT_INDEX); + + if (list_length(dropIndexStatement->objects) > 1) + { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot drop multiple distributed objects in a " + "single command"), + errhint("Try dropping each object in a separate DROP " + "command."))); + } +} + + /* * DropIndexTaskList builds a list of tasks to execute a DROP INDEX command * against a specified distributed table. diff --git a/src/test/regress/expected/multi_index_statements.out b/src/test/regress/expected/multi_index_statements.out index 875eb3634..aab013acf 100644 --- a/src/test/regress/expected/multi_index_statements.out +++ b/src/test/regress/expected/multi_index_statements.out @@ -255,16 +255,11 @@ DROP INDEX lineitem_orderkey_index, lineitem_partial_index; ERROR: cannot drop multiple distributed objects in a single command HINT: Try dropping each object in a separate DROP command. -- Verify that we can succesfully drop indexes +DROP INDEX lineitem_orderkey_index; +DROP INDEX lineitem_orderkey_index_new; DROP INDEX lineitem_partkey_desc_index; DROP INDEX lineitem_partial_index; DROP INDEX lineitem_colref_index; --- Verify that we can drop distributed indexes with local indexes -CREATE TABLE local_table(a int, b int); -CREATE INDEX local_index ON local_table(a); -CREATE INDEX local_index2 ON local_table(b); -DROP INDEX lineitem_orderkey_index, local_index; -DROP INDEX IF EXISTS lineitem_orderkey_index_new, local_index2, non_existing_index; -NOTICE: index "non_existing_index" does not exist, skipping -- Verify that we handle if exists statements correctly DROP INDEX non_existent_index; ERROR: index "non_existent_index" does not exist @@ -301,14 +296,15 @@ SELECT * FROM pg_indexes WHERE tablename LIKE 'index_test_%' ORDER BY indexname; (5 rows) \c - - - :worker_1_port -SELECT indrelid::regclass, indexrelid::regclass FROM pg_index WHERE indrelid = (SELECT relname FROM pg_class WHERE relname LIKE 'lineitem%' ORDER BY relname LIMIT 1)::regclass AND NOT indisprimary AND indexrelid::regclass::text NOT LIKE 'lineitem_time_index%' ORDER BY 1,2; +SET citus.override_table_visibility TO FALSE; +SELECT indrelid::regclass, indexrelid::regclass FROM pg_index WHERE indrelid = (SELECT relname FROM pg_class WHERE relname SIMILAR TO 'lineitem%\d' ORDER BY relname LIMIT 1)::regclass AND NOT indisprimary AND indexrelid::regclass::text NOT LIKE 'lineitem_time_index%' ORDER BY 1,2; indrelid | indexrelid --------------------------------------------------------------------- lineitem_360000 | lineitem_l_orderkey_idx_360000 lineitem_360000 | lineitem_l_shipdate_idx_360000 (2 rows) -SELECT * FROM pg_indexes WHERE tablename LIKE 'index_test_%' ORDER BY indexname; +SELECT * FROM pg_indexes WHERE tablename SIMILAR TO 'index_test_%\d' ORDER BY indexname; schemaname | tablename | indexname | tablespace | indexdef --------------------------------------------------------------------- multi_index_statements | index_test_hash_102082 | index_test_hash_a_idx_102082 | | CREATE UNIQUE INDEX index_test_hash_a_idx_102082 ON multi_index_statements.index_test_hash_102082 USING btree (a) @@ -413,6 +409,10 @@ CREATE INDEX ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creat ON test_index_creation1 USING btree (tenant_id, timeperiod); NOTICE: identifier "ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creation1" will be truncated to "ix_test_index_creation1_ix_test_index_creation1_ix_test_index_c" +DEBUG: identifier "ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creation1" will be truncated to "ix_test_index_creation1_ix_test_index_creation1_ix_test_index_c" +DETAIL: from localhost:xxxxx +DEBUG: identifier "ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creation1_ix_test_index_creation1" will be truncated to "ix_test_index_creation1_ix_test_index_creation1_ix_test_index_c" +DETAIL: from localhost:xxxxx RESET client_min_messages; CREATE TABLE test_index_creation1_p2020_09_26 PARTITION OF test_index_creation1 FOR VALUES FROM ('2020-09-26 00:00:00') TO ('2020-09-27 00:00:00'); CREATE TABLE test_index_creation1_p2020_09_27 PARTITION OF test_index_creation1 FOR VALUES FROM ('2020-09-27 00:00:00') TO ('2020-09-28 00:00:00'); diff --git a/src/test/regress/multi_1_schedule b/src/test/regress/multi_1_schedule index e82db0161..906e40329 100644 --- a/src/test/regress/multi_1_schedule +++ b/src/test/regress/multi_1_schedule @@ -150,6 +150,7 @@ test: with_executors with_join with_partitioning with_transactions with_dml # ---------- # Tests around DDL statements run on distributed tables # ---------- +test: multi_index_statements test: multi_alter_table_statements test: multi_alter_table_add_constraints @@ -193,7 +194,6 @@ test: multi_repartition_udt multi_repartitioned_subquery_udf multi_subtransactio test: multi_modifying_xacts test: check_mx test: turn_mx_off -test: multi_index_statements test: multi_generate_ddl_commands multi_repair_shards test: multi_create_shards test: multi_transaction_recovery diff --git a/src/test/regress/sql/multi_index_statements.sql b/src/test/regress/sql/multi_index_statements.sql index e6ae776a6..6c22a8403 100644 --- a/src/test/regress/sql/multi_index_statements.sql +++ b/src/test/regress/sql/multi_index_statements.sql @@ -159,17 +159,12 @@ REINDEX SYSTEM regression; DROP INDEX lineitem_orderkey_index, lineitem_partial_index; -- Verify that we can succesfully drop indexes +DROP INDEX lineitem_orderkey_index; +DROP INDEX lineitem_orderkey_index_new; DROP INDEX lineitem_partkey_desc_index; DROP INDEX lineitem_partial_index; DROP INDEX lineitem_colref_index; --- Verify that we can drop distributed indexes with local indexes -CREATE TABLE local_table(a int, b int); -CREATE INDEX local_index ON local_table(a); -CREATE INDEX local_index2 ON local_table(b); -DROP INDEX lineitem_orderkey_index, local_index; -DROP INDEX IF EXISTS lineitem_orderkey_index_new, local_index2, non_existing_index; - -- Verify that we handle if exists statements correctly DROP INDEX non_existent_index; @@ -193,8 +188,9 @@ DROP INDEX CONCURRENTLY lineitem_concurrently_index; SELECT indrelid::regclass, indexrelid::regclass FROM pg_index WHERE indrelid = (SELECT relname FROM pg_class WHERE relname LIKE 'lineitem%' ORDER BY relname LIMIT 1)::regclass AND NOT indisprimary AND indexrelid::regclass::text NOT LIKE 'lineitem_time_index%' ORDER BY 1,2; SELECT * FROM pg_indexes WHERE tablename LIKE 'index_test_%' ORDER BY indexname; \c - - - :worker_1_port -SELECT indrelid::regclass, indexrelid::regclass FROM pg_index WHERE indrelid = (SELECT relname FROM pg_class WHERE relname LIKE 'lineitem%' ORDER BY relname LIMIT 1)::regclass AND NOT indisprimary AND indexrelid::regclass::text NOT LIKE 'lineitem_time_index%' ORDER BY 1,2; -SELECT * FROM pg_indexes WHERE tablename LIKE 'index_test_%' ORDER BY indexname; +SET citus.override_table_visibility TO FALSE; +SELECT indrelid::regclass, indexrelid::regclass FROM pg_index WHERE indrelid = (SELECT relname FROM pg_class WHERE relname SIMILAR TO 'lineitem%\d' ORDER BY relname LIMIT 1)::regclass AND NOT indisprimary AND indexrelid::regclass::text NOT LIKE 'lineitem_time_index%' ORDER BY 1,2; +SELECT * FROM pg_indexes WHERE tablename SIMILAR TO 'index_test_%\d' ORDER BY indexname; -- create index that will conflict with master operations CREATE INDEX CONCURRENTLY ith_b_idx_102089 ON multi_index_statements.index_test_hash_102089(b);