diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/tablecmds.c | 148 | ||||
-rw-r--r-- | src/backend/commands/trigger.c | 10 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 56 |
3 files changed, 99 insertions, 115 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 0d3e3bc1670..53abfec6976 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.293 2009/07/29 20:56:18 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.294 2009/07/30 02:45:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -154,7 +154,7 @@ typedef struct NewConstraint Oid refrelid; /* PK rel, if FOREIGN */ Oid refindid; /* OID of PK's index, if FOREIGN */ Oid conid; /* OID of pg_constraint entry, if FOREIGN */ - Node *qual; /* Check expr or FkConstraint struct */ + Node *qual; /* Check expr or CONSTR_FOREIGN Constraint */ List *qualstate; /* Execution state for CHECK */ } NewConstraint; @@ -247,10 +247,10 @@ static Oid transformFkeyCheckAttrs(Relation pkrel, int numattrs, int16 *attnums, Oid *opclasses); static void checkFkeyPermissions(Relation rel, int16 *attnums, int natts); -static void validateForeignKeyConstraint(FkConstraint *fkconstraint, +static void validateForeignKeyConstraint(Constraint *fkconstraint, Relation rel, Relation pkrel, Oid pkindOid, Oid constraintOid); -static void createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, +static void createForeignKeyTriggers(Relation rel, Constraint *fkconstraint, Oid constraintOid, Oid indexOid); static void ATController(Relation rel, List *cmds, bool recurse); static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, @@ -293,13 +293,13 @@ static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel, IndexStmt *stmt, bool is_rebuild); static void ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, - Node *newConstraint, bool recurse); + Constraint *newConstraint, bool recurse); static void ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, Constraint *constr, bool recurse, bool recursing); static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, - FkConstraint *fkconstraint); + Constraint *fkconstraint); static void ATExecDropConstraint(Relation rel, const char *constrName, DropBehavior behavior, bool recurse, bool recursing, @@ -2637,10 +2637,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true); break; case AT_AddConstraint: /* ADD CONSTRAINT */ - ATExecAddConstraint(wqueue, tab, rel, cmd->def, false); + ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def, + false); break; case AT_AddConstraintRecurse: /* ADD CONSTRAINT with recursion */ - ATExecAddConstraint(wqueue, tab, rel, cmd->def, true); + ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def, + true); break; case AT_DropConstraint: /* DROP CONSTRAINT */ ATExecDropConstraint(rel, cmd->name, cmd->behavior, @@ -2905,7 +2907,7 @@ ATRewriteTables(List **wqueue) if (con->contype == CONSTR_FOREIGN) { - FkConstraint *fkconstraint = (FkConstraint *) con->qual; + Constraint *fkconstraint = (Constraint *) con->qual; Relation refrel; if (rel == NULL) @@ -4405,69 +4407,55 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, */ static void ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, - Node *newConstraint, bool recurse) + Constraint *newConstraint, bool recurse) { - switch (nodeTag(newConstraint)) + Assert(IsA(newConstraint, Constraint)); + + /* + * Currently, we only expect to see CONSTR_CHECK and CONSTR_FOREIGN nodes + * arriving here (see the preprocessing done in parse_utilcmd.c). Use a + * switch anyway to make it easier to add more code later. + */ + switch (newConstraint->contype) { - case T_Constraint: - { - Constraint *constr = (Constraint *) newConstraint; + case CONSTR_CHECK: + ATAddCheckConstraint(wqueue, tab, rel, + newConstraint, recurse, false); + break; - /* - * Currently, we only expect to see CONSTR_CHECK nodes - * arriving here (see the preprocessing done in - * parse_utilcmd.c). Use a switch anyway to make it easier to - * add more code later. - */ - switch (constr->contype) - { - case CONSTR_CHECK: - ATAddCheckConstraint(wqueue, tab, rel, - constr, recurse, false); - break; - default: - elog(ERROR, "unrecognized constraint type: %d", - (int) constr->contype); - } - break; - } - case T_FkConstraint: + case CONSTR_FOREIGN: + /* + * Note that we currently never recurse for FK constraints, so + * the "recurse" flag is silently ignored. + * + * Assign or validate constraint name + */ + if (newConstraint->conname) { - FkConstraint *fkconstraint = (FkConstraint *) newConstraint; - - /* - * Note that we currently never recurse for FK constraints, so - * the "recurse" flag is silently ignored. - * - * Assign or validate constraint name - */ - if (fkconstraint->constr_name) - { - if (ConstraintNameIsUsed(CONSTRAINT_RELATION, - RelationGetRelid(rel), - RelationGetNamespace(rel), - fkconstraint->constr_name)) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("constraint \"%s\" for relation \"%s\" already exists", - fkconstraint->constr_name, - RelationGetRelationName(rel)))); - } - else - fkconstraint->constr_name = - ChooseConstraintName(RelationGetRelationName(rel), - strVal(linitial(fkconstraint->fk_attrs)), - "fkey", - RelationGetNamespace(rel), - NIL); - - ATAddForeignKeyConstraint(tab, rel, fkconstraint); - - break; + if (ConstraintNameIsUsed(CONSTRAINT_RELATION, + RelationGetRelid(rel), + RelationGetNamespace(rel), + newConstraint->conname)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("constraint \"%s\" for relation \"%s\" already exists", + newConstraint->conname, + RelationGetRelationName(rel)))); } + else + newConstraint->conname = + ChooseConstraintName(RelationGetRelationName(rel), + strVal(linitial(newConstraint->fk_attrs)), + "fkey", + RelationGetNamespace(rel), + NIL); + + ATAddForeignKeyConstraint(tab, rel, newConstraint); + break; + default: - elog(ERROR, "unrecognized node type: %d", - (int) nodeTag(newConstraint)); + elog(ERROR, "unrecognized constraint type: %d", + (int) newConstraint->contype); } } @@ -4526,12 +4514,12 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, tab->constraints = lappend(tab->constraints, newcon); /* Save the actually assigned name if it was defaulted */ - if (constr->name == NULL) - constr->name = ccon->name; + if (constr->conname == NULL) + constr->conname = ccon->name; } /* At this point we must have a locked-down name to use */ - Assert(constr->name != NULL); + Assert(constr->conname != NULL); /* Advance command counter in case same table is visited multiple times */ CommandCounterIncrement(); @@ -4583,7 +4571,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, */ static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, - FkConstraint *fkconstraint) + Constraint *fkconstraint) { Relation pkrel; int16 pkattnum[INDEX_MAX_KEYS]; @@ -4798,7 +4786,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("foreign key constraint \"%s\" " "cannot be implemented", - fkconstraint->constr_name), + fkconstraint->conname), errdetail("Key columns \"%s\" and \"%s\" " "are of incompatible types: %s and %s.", strVal(list_nth(fkconstraint->fk_attrs, i)), @@ -4814,7 +4802,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, /* * Record the FK constraint in pg_constraint. */ - constrOid = CreateConstraintEntry(fkconstraint->constr_name, + constrOid = CreateConstraintEntry(fkconstraint->conname, RelationGetNamespace(rel), CONSTRAINT_FOREIGN, fkconstraint->deferrable, @@ -4854,7 +4842,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, NewConstraint *newcon; newcon = (NewConstraint *) palloc0(sizeof(NewConstraint)); - newcon->name = fkconstraint->constr_name; + newcon->name = fkconstraint->conname; newcon->contype = CONSTR_FOREIGN; newcon->refrelid = RelationGetRelid(pkrel); newcon->refindid = indexOid; @@ -5156,7 +5144,7 @@ checkFkeyPermissions(Relation rel, int16 *attnums, int natts) * Caller must have opened and locked both relations. */ static void -validateForeignKeyConstraint(FkConstraint *fkconstraint, +validateForeignKeyConstraint(Constraint *fkconstraint, Relation rel, Relation pkrel, Oid pkindOid, @@ -5171,7 +5159,7 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint, */ MemSet(&trig, 0, sizeof(trig)); trig.tgoid = InvalidOid; - trig.tgname = fkconstraint->constr_name; + trig.tgname = fkconstraint->conname; trig.tgenabled = TRIGGER_FIRES_ON_ORIGIN; trig.tgisconstraint = TRUE; trig.tgconstrrelid = RelationGetRelid(pkrel); @@ -5228,13 +5216,13 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint, } static void -CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint, +CreateFKCheckTrigger(RangeVar *myRel, Constraint *fkconstraint, Oid constraintOid, Oid indexOid, bool on_insert) { CreateTrigStmt *fk_trigger; fk_trigger = makeNode(CreateTrigStmt); - fk_trigger->trigname = fkconstraint->constr_name; + fk_trigger->trigname = fkconstraint->conname; fk_trigger->relation = myRel; fk_trigger->before = false; fk_trigger->row = true; @@ -5268,7 +5256,7 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint, * Create the triggers that implement an FK constraint. */ static void -createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, +createForeignKeyTriggers(Relation rel, Constraint *fkconstraint, Oid constraintOid, Oid indexOid) { RangeVar *myRel; @@ -5296,7 +5284,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, * DELETE action on the referenced table. */ fk_trigger = makeNode(CreateTrigStmt); - fk_trigger->trigname = fkconstraint->constr_name; + fk_trigger->trigname = fkconstraint->conname; fk_trigger->relation = fkconstraint->pktable; fk_trigger->before = false; fk_trigger->row = true; @@ -5348,7 +5336,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, * UPDATE action on the referenced table. */ fk_trigger = makeNode(CreateTrigStmt); - fk_trigger->trigname = fkconstraint->constr_name; + fk_trigger->trigname = fkconstraint->conname; fk_trigger->relation = fkconstraint->pktable; fk_trigger->before = false; fk_trigger->row = true; diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index b84731126a1..7bc82127893 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.250 2009/07/29 20:56:18 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.251 2009/07/30 02:45:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -607,12 +607,14 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid) /* OK, we have a set, so make the FK constraint ALTER TABLE cmd */ AlterTableStmt *atstmt = makeNode(AlterTableStmt); AlterTableCmd *atcmd = makeNode(AlterTableCmd); - FkConstraint *fkcon = makeNode(FkConstraint); + Constraint *fkcon = makeNode(Constraint); ereport(NOTICE, (errmsg("converting trigger group into constraint \"%s\" %s", constr_name, buf.data), errdetail("%s", _(funcdescr[funcnum])))); + fkcon->contype = CONSTR_FOREIGN; + fkcon->location = -1; if (funcnum == 2) { /* This trigger is on the FK table */ @@ -642,9 +644,9 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid) atcmd->subtype = AT_AddConstraint; atcmd->def = (Node *) fkcon; if (strcmp(constr_name, "<unnamed>") == 0) - fkcon->constr_name = NULL; + fkcon->conname = NULL; else - fkcon->constr_name = constr_name; + fkcon->conname = constr_name; fkcon->fk_attrs = fk_attrs; fkcon->pk_attrs = pk_attrs; fkcon->fk_matchtype = fk_matchtype; diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 1d3077cc324..5fa2ac6bc90 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.136 2009/07/28 02:56:30 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.137 2009/07/30 02:45:36 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -867,22 +867,11 @@ DefineDomain(CreateDomainStmt *stmt) */ foreach(listptr, schema) { - Node *newConstraint = lfirst(listptr); - Constraint *constr; - - /* Check for unsupported constraint types */ - if (IsA(newConstraint, FkConstraint)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("foreign key constraints not possible for domains"))); + Constraint *constr = lfirst(listptr); - /* otherwise it should be a plain Constraint */ - if (!IsA(newConstraint, Constraint)) + if (!IsA(constr, Constraint)) elog(ERROR, "unrecognized node type: %d", - (int) nodeTag(newConstraint)); - - constr = (Constraint *) newConstraint; - + (int) nodeTag(constr)); switch (constr->contype) { case CONSTR_DEFAULT: @@ -995,6 +984,12 @@ DefineDomain(CreateDomainStmt *stmt) errmsg("primary key constraints not possible for domains"))); break; + case CONSTR_FOREIGN: + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("foreign key constraints not possible for domains"))); + break; + case CONSTR_ATTR_DEFERRABLE: case CONSTR_ATTR_NOT_DEFERRABLE: case CONSTR_ATTR_DEFERRED: @@ -1849,13 +1844,6 @@ AlterDomainAddConstraint(List *names, Node *newConstraint) /* Check it's a domain and check user has permission for ALTER DOMAIN */ checkDomainOwner(tup, typename); - /* Check for unsupported constraint types */ - if (IsA(newConstraint, FkConstraint)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("foreign key constraints not possible for domains"))); - - /* otherwise it should be a plain Constraint */ if (!IsA(newConstraint, Constraint)) elog(ERROR, "unrecognized node type: %d", (int) nodeTag(newConstraint)); @@ -1880,6 +1868,12 @@ AlterDomainAddConstraint(List *names, Node *newConstraint) errmsg("primary key constraints not possible for domains"))); break; + case CONSTR_FOREIGN: + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("foreign key constraints not possible for domains"))); + break; + case CONSTR_ATTR_DEFERRABLE: case CONSTR_ATTR_NOT_DEFERRABLE: case CONSTR_ATTR_DEFERRED: @@ -2188,23 +2182,23 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, /* * Assign or validate constraint name */ - if (constr->name) + if (constr->conname) { if (ConstraintNameIsUsed(CONSTRAINT_DOMAIN, domainOid, domainNamespace, - constr->name)) + constr->conname)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("constraint \"%s\" for domain \"%s\" already exists", - constr->name, domainName))); + constr->conname, domainName))); } else - constr->name = ChooseConstraintName(domainName, - NULL, - "check", - domainNamespace, - NIL); + constr->conname = ChooseConstraintName(domainName, + NULL, + "check", + domainNamespace, + NIL); /* * Convert the A_EXPR in raw_expr into an EXPR @@ -2284,7 +2278,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, /* * Store the constraint in pg_constraint */ - CreateConstraintEntry(constr->name, /* Constraint Name */ + CreateConstraintEntry(constr->conname, /* Constraint Name */ domainNamespace, /* namespace */ CONSTRAINT_CHECK, /* Constraint Type */ false, /* Is Deferrable */ |