diff options
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index d88e3dee3fa..ab5ab940ade 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -743,10 +743,13 @@ RemoveRelations(DropStmt *drop) int flags = 0; LOCKMODE lockmode = AccessExclusiveLock; + /* DROP CONCURRENTLY uses a weaker lock, and has some restrictions */ if (drop->concurrent) { + flags |= PERFORM_DELETION_CONCURRENTLY; lockmode = ShareUpdateExclusiveLock; - if (list_length(drop->objects) > 1) + Assert(drop->removeType == OBJECT_INDEX); + if (list_length(drop->objects) != 1) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("DROP INDEX CONCURRENTLY does not support dropping multiple objects"))); @@ -838,19 +841,6 @@ RemoveRelations(DropStmt *drop) add_exact_object_address(&obj, objects); } - /* - * Set options and check further requirements for concurrent drop - */ - if (drop->concurrent) - { - /* - * Confirm that concurrent behaviour is restricted in grammar. - */ - Assert(drop->removeType == OBJECT_INDEX); - - flags |= PERFORM_DELETION_CONCURRENTLY; - } - performMultipleDeletions(objects, drop->behavior, flags); free_object_addresses(objects); @@ -917,7 +907,7 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid, * locking the index. index_drop() will need this anyway, and since * regular queries lock tables before their indexes, we risk deadlock if * we do it the other way around. No error if we don't find a pg_index - * entry, though --- the relation may have been droppd. + * entry, though --- the relation may have been dropped. */ if (relkind == RELKIND_INDEX && relOid != oldRelOid) { @@ -4783,6 +4773,8 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) /* * Check that the attribute is not in a primary key + * + * Note: we'll throw error even if the pkey index is not valid. */ /* Loop over all indexes on the relation */ @@ -6317,7 +6309,7 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, /* * Get the list of index OIDs for the table from the relcache, and look up * each one in the pg_index syscache until we find one marked primary key - * (hopefully there isn't more than one such). + * (hopefully there isn't more than one such). Insist it's valid, too. */ *indexOid = InvalidOid; @@ -6331,7 +6323,7 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, if (!HeapTupleIsValid(indexTuple)) elog(ERROR, "cache lookup failed for index %u", indexoid); indexStruct = (Form_pg_index) GETSTRUCT(indexTuple); - if (indexStruct->indisprimary) + if (indexStruct->indisprimary && IndexIsValid(indexStruct)) { /* * Refuse to use a deferrable primary key. This is per SQL spec, @@ -6429,10 +6421,12 @@ transformFkeyCheckAttrs(Relation pkrel, /* * Must have the right number of columns; must be unique and not a - * partial index; forget it if there are any expressions, too + * partial index; forget it if there are any expressions, too. Invalid + * indexes are out as well. */ if (indexStruct->indnatts == numattrs && indexStruct->indisunique && + IndexIsValid(indexStruct) && heap_attisnull(indexTuple, Anum_pg_index_indpred) && heap_attisnull(indexTuple, Anum_pg_index_indexprs)) { |