aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c30
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))
{