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.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index a9bb8351bc1..6726ca97331 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -319,6 +319,8 @@ static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
static void ATExecAddConstraint(List **wqueue,
AlteredTableInfo *tab, Relation rel,
Constraint *newConstraint, bool recurse, LOCKMODE lockmode);
+static void ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
+ IndexStmt *stmt, LOCKMODE lockmode);
static void ATAddCheckConstraint(List **wqueue,
AlteredTableInfo *tab, Relation rel,
Constraint *constr,
@@ -2594,6 +2596,7 @@ AlterTableGetLockLevel(List *cmds)
case AT_DisableTrigAll:
case AT_DisableTrigUser:
case AT_AddIndex: /* from ADD CONSTRAINT */
+ case AT_AddIndexConstraint:
cmd_lockmode = ShareRowExclusiveLock;
break;
@@ -2811,6 +2814,12 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
cmd->subtype = AT_AddConstraintRecurse;
pass = AT_PASS_ADD_CONSTR;
break;
+ case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */
+ ATSimplePermissions(rel, ATT_TABLE);
+ /* This command never recurses */
+ /* No command-specific prep needed */
+ pass = AT_PASS_ADD_CONSTR;
+ break;
case AT_DropConstraint: /* DROP CONSTRAINT */
ATSimplePermissions(rel, ATT_TABLE);
/* Recursion occurs during execution phase */
@@ -3042,6 +3051,9 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
true, lockmode);
break;
+ case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */
+ ATExecAddIndexConstraint(tab, rel, (IndexStmt *) cmd->def, lockmode);
+ break;
case AT_DropConstraint: /* DROP CONSTRAINT */
ATExecDropConstraint(rel, cmd->name, cmd->behavior,
false, false,
@@ -5010,6 +5022,76 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
}
/*
+ * ALTER TABLE ADD CONSTRAINT USING INDEX
+ */
+static void
+ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
+ IndexStmt *stmt, LOCKMODE lockmode)
+{
+ Oid index_oid = stmt->indexOid;
+ Relation indexRel;
+ char *indexName;
+ IndexInfo *indexInfo;
+ char *constraintName;
+ char constraintType;
+
+ Assert(IsA(stmt, IndexStmt));
+ Assert(OidIsValid(index_oid));
+ Assert(stmt->isconstraint);
+
+ indexRel = index_open(index_oid, AccessShareLock);
+
+ indexName = pstrdup(RelationGetRelationName(indexRel));
+
+ indexInfo = BuildIndexInfo(indexRel);
+
+ /* this should have been checked at parse time */
+ if (!indexInfo->ii_Unique)
+ elog(ERROR, "index \"%s\" is not unique", indexName);
+
+ /*
+ * Determine name to assign to constraint. We require a constraint to
+ * have the same name as the underlying index; therefore, use the index's
+ * existing name as the default constraint name, and if the user explicitly
+ * gives some other name for the constraint, rename the index to match.
+ */
+ constraintName = stmt->idxname;
+ if (constraintName == NULL)
+ constraintName = indexName;
+ else if (strcmp(constraintName, indexName) != 0)
+ {
+ ereport(NOTICE,
+ (errmsg("ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"",
+ indexName, constraintName)));
+ RenameRelation(index_oid, constraintName, OBJECT_INDEX);
+ }
+
+ /* Extra checks needed if making primary key */
+ if (stmt->primary)
+ index_check_primary_key(rel, indexInfo, true);
+
+ /* Note we currently don't support EXCLUSION constraints here */
+ if (stmt->primary)
+ constraintType = CONSTRAINT_PRIMARY;
+ else
+ constraintType = CONSTRAINT_UNIQUE;
+
+ /* Create the catalog entries for the constraint */
+ index_constraint_create(rel,
+ index_oid,
+ indexInfo,
+ constraintName,
+ constraintType,
+ stmt->deferrable,
+ stmt->initdeferred,
+ stmt->primary,
+ true,
+ allowSystemTableMods);
+
+ index_close(indexRel, NoLock);
+}
+
+/*
* ALTER TABLE ADD CONSTRAINT
*/
static void