Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 060baf2

Browse files
committed
Merge the Constraint and FkConstraint node types into a single type.
This was foreseen to be a good idea long ago, but nobody had got round to doing it. The recent patch for deferred unique constraints made transformConstraintAttrs() ugly enough that I decided it was time. This change will also greatly simplify parsing of deferred CHECK constraints, if anyone ever gets around to implementing that. While at it, add a location field to Constraint, and use that to provide an error cursor for some of the constraint-related error messages.
1 parent 78aef14 commit 060baf2

File tree

12 files changed

+387
-508
lines changed

12 files changed

+387
-508
lines changed

src/backend/catalog/heap.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.355 2009/07/28 02:56:29 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.356 2009/07/30 02:45:36 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -1870,11 +1870,11 @@ AddRelationNewConstraints(Relation rel,
18701870
/*
18711871
* Check name uniqueness, or generate a name if none was given.
18721872
*/
1873-
if (cdef->name != NULL)
1873+
if (cdef->conname != NULL)
18741874
{
18751875
ListCell *cell2;
18761876

1877-
ccname = cdef->name;
1877+
ccname = cdef->conname;
18781878
/* Check against other new constraints */
18791879
/* Needed because we don't do CommandCounterIncrement in loop */
18801880
foreach(cell2, checknames)

src/backend/commands/tablecmds.c

+68-80
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.293 2009/07/29 20:56:18 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.294 2009/07/30 02:45:36 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -154,7 +154,7 @@ typedef struct NewConstraint
154154
Oid refrelid; /* PK rel, if FOREIGN */
155155
Oid refindid; /* OID of PK's index, if FOREIGN */
156156
Oid conid; /* OID of pg_constraint entry, if FOREIGN */
157-
Node *qual; /* Check expr or FkConstraint struct */
157+
Node *qual; /* Check expr or CONSTR_FOREIGN Constraint */
158158
List *qualstate; /* Execution state for CHECK */
159159
} NewConstraint;
160160

@@ -247,10 +247,10 @@ static Oid transformFkeyCheckAttrs(Relation pkrel,
247247
int numattrs, int16 *attnums,
248248
Oid *opclasses);
249249
static void checkFkeyPermissions(Relation rel, int16 *attnums, int natts);
250-
static void validateForeignKeyConstraint(FkConstraint *fkconstraint,
250+
static void validateForeignKeyConstraint(Constraint *fkconstraint,
251251
Relation rel, Relation pkrel,
252252
Oid pkindOid, Oid constraintOid);
253-
static void createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
253+
static void createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
254254
Oid constraintOid, Oid indexOid);
255255
static void ATController(Relation rel, List *cmds, bool recurse);
256256
static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
@@ -293,13 +293,13 @@ static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
293293
IndexStmt *stmt, bool is_rebuild);
294294
static void ATExecAddConstraint(List **wqueue,
295295
AlteredTableInfo *tab, Relation rel,
296-
Node *newConstraint, bool recurse);
296+
Constraint *newConstraint, bool recurse);
297297
static void ATAddCheckConstraint(List **wqueue,
298298
AlteredTableInfo *tab, Relation rel,
299299
Constraint *constr,
300300
bool recurse, bool recursing);
301301
static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
302-
FkConstraint *fkconstraint);
302+
Constraint *fkconstraint);
303303
static void ATExecDropConstraint(Relation rel, const char *constrName,
304304
DropBehavior behavior,
305305
bool recurse, bool recursing,
@@ -2637,10 +2637,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
26372637
ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true);
26382638
break;
26392639
case AT_AddConstraint: /* ADD CONSTRAINT */
2640-
ATExecAddConstraint(wqueue, tab, rel, cmd->def, false);
2640+
ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
2641+
false);
26412642
break;
26422643
case AT_AddConstraintRecurse: /* ADD CONSTRAINT with recursion */
2643-
ATExecAddConstraint(wqueue, tab, rel, cmd->def, true);
2644+
ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
2645+
true);
26442646
break;
26452647
case AT_DropConstraint: /* DROP CONSTRAINT */
26462648
ATExecDropConstraint(rel, cmd->name, cmd->behavior,
@@ -2905,7 +2907,7 @@ ATRewriteTables(List **wqueue)
29052907

29062908
if (con->contype == CONSTR_FOREIGN)
29072909
{
2908-
FkConstraint *fkconstraint = (FkConstraint *) con->qual;
2910+
Constraint *fkconstraint = (Constraint *) con->qual;
29092911
Relation refrel;
29102912

29112913
if (rel == NULL)
@@ -4405,69 +4407,55 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
44054407
*/
44064408
static void
44074409
ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
4408-
Node *newConstraint, bool recurse)
4410+
Constraint *newConstraint, bool recurse)
44094411
{
4410-
switch (nodeTag(newConstraint))
4412+
Assert(IsA(newConstraint, Constraint));
4413+
4414+
/*
4415+
* Currently, we only expect to see CONSTR_CHECK and CONSTR_FOREIGN nodes
4416+
* arriving here (see the preprocessing done in parse_utilcmd.c). Use a
4417+
* switch anyway to make it easier to add more code later.
4418+
*/
4419+
switch (newConstraint->contype)
44114420
{
4412-
case T_Constraint:
4413-
{
4414-
Constraint *constr = (Constraint *) newConstraint;
4421+
case CONSTR_CHECK:
4422+
ATAddCheckConstraint(wqueue, tab, rel,
4423+
newConstraint, recurse, false);
4424+
break;
44154425

4416-
/*
4417-
* Currently, we only expect to see CONSTR_CHECK nodes
4418-
* arriving here (see the preprocessing done in
4419-
* parse_utilcmd.c). Use a switch anyway to make it easier to
4420-
* add more code later.
4421-
*/
4422-
switch (constr->contype)
4423-
{
4424-
case CONSTR_CHECK:
4425-
ATAddCheckConstraint(wqueue, tab, rel,
4426-
constr, recurse, false);
4427-
break;
4428-
default:
4429-
elog(ERROR, "unrecognized constraint type: %d",
4430-
(int) constr->contype);
4431-
}
4432-
break;
4433-
}
4434-
case T_FkConstraint:
4426+
case CONSTR_FOREIGN:
4427+
/*
4428+
* Note that we currently never recurse for FK constraints, so
4429+
* the "recurse" flag is silently ignored.
4430+
*
4431+
* Assign or validate constraint name
4432+
*/
4433+
if (newConstraint->conname)
44354434
{
4436-
FkConstraint *fkconstraint = (FkConstraint *) newConstraint;
4437-
4438-
/*
4439-
* Note that we currently never recurse for FK constraints, so
4440-
* the "recurse" flag is silently ignored.
4441-
*
4442-
* Assign or validate constraint name
4443-
*/
4444-
if (fkconstraint->constr_name)
4445-
{
4446-
if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
4447-
RelationGetRelid(rel),
4448-
RelationGetNamespace(rel),
4449-
fkconstraint->constr_name))
4450-
ereport(ERROR,
4451-
(errcode(ERRCODE_DUPLICATE_OBJECT),
4452-
errmsg("constraint \"%s\" for relation \"%s\" already exists",
4453-
fkconstraint->constr_name,
4454-
RelationGetRelationName(rel))));
4455-
}
4456-
else
4457-
fkconstraint->constr_name =
4458-
ChooseConstraintName(RelationGetRelationName(rel),
4459-
strVal(linitial(fkconstraint->fk_attrs)),
4460-
"fkey",
4461-
RelationGetNamespace(rel),
4462-
NIL);
4463-
4464-
ATAddForeignKeyConstraint(tab, rel, fkconstraint);
4465-
4466-
break;
4435+
if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
4436+
RelationGetRelid(rel),
4437+
RelationGetNamespace(rel),
4438+
newConstraint->conname))
4439+
ereport(ERROR,
4440+
(errcode(ERRCODE_DUPLICATE_OBJECT),
4441+
errmsg("constraint \"%s\" for relation \"%s\" already exists",
4442+
newConstraint->conname,
4443+
RelationGetRelationName(rel))));
44674444
}
4445+
else
4446+
newConstraint->conname =
4447+
ChooseConstraintName(RelationGetRelationName(rel),
4448+
strVal(linitial(newConstraint->fk_attrs)),
4449+
"fkey",
4450+
RelationGetNamespace(rel),
4451+
NIL);
4452+
4453+
ATAddForeignKeyConstraint(tab, rel, newConstraint);
4454+
break;
4455+
44684456
default:
4469-
elog(ERROR, "unrecognized node type: %d",
4470-
(int) nodeTag(newConstraint));
4457+
elog(ERROR, "unrecognized constraint type: %d",
4458+
(int) newConstraint->contype);
44714459
}
44724460
}
44734461

@@ -4526,12 +4514,12 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
45264514
tab->constraints = lappend(tab->constraints, newcon);
45274515

45284516
/* Save the actually assigned name if it was defaulted */
4529-
if (constr->name == NULL)
4530-
constr->name = ccon->name;
4517+
if (constr->conname == NULL)
4518+
constr->conname = ccon->name;
45314519
}
45324520

45334521
/* At this point we must have a locked-down name to use */
4534-
Assert(constr->name != NULL);
4522+
Assert(constr->conname != NULL);
45354523

45364524
/* Advance command counter in case same table is visited multiple times */
45374525
CommandCounterIncrement();
@@ -4583,7 +4571,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
45834571
*/
45844572
static void
45854573
ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
4586-
FkConstraint *fkconstraint)
4574+
Constraint *fkconstraint)
45874575
{
45884576
Relation pkrel;
45894577
int16 pkattnum[INDEX_MAX_KEYS];
@@ -4798,7 +4786,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
47984786
(errcode(ERRCODE_DATATYPE_MISMATCH),
47994787
errmsg("foreign key constraint \"%s\" "
48004788
"cannot be implemented",
4801-
fkconstraint->constr_name),
4789+
fkconstraint->conname),
48024790
errdetail("Key columns \"%s\" and \"%s\" "
48034791
"are of incompatible types: %s and %s.",
48044792
strVal(list_nth(fkconstraint->fk_attrs, i)),
@@ -4814,7 +4802,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
48144802
/*
48154803
* Record the FK constraint in pg_constraint.
48164804
*/
4817-
constrOid = CreateConstraintEntry(fkconstraint->constr_name,
4805+
constrOid = CreateConstraintEntry(fkconstraint->conname,
48184806
RelationGetNamespace(rel),
48194807
CONSTRAINT_FOREIGN,
48204808
fkconstraint->deferrable,
@@ -4854,7 +4842,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
48544842
NewConstraint *newcon;
48554843

48564844
newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
4857-
newcon->name = fkconstraint->constr_name;
4845+
newcon->name = fkconstraint->conname;
48584846
newcon->contype = CONSTR_FOREIGN;
48594847
newcon->refrelid = RelationGetRelid(pkrel);
48604848
newcon->refindid = indexOid;
@@ -5156,7 +5144,7 @@ checkFkeyPermissions(Relation rel, int16 *attnums, int natts)
51565144
* Caller must have opened and locked both relations.
51575145
*/
51585146
static void
5159-
validateForeignKeyConstraint(FkConstraint *fkconstraint,
5147+
validateForeignKeyConstraint(Constraint *fkconstraint,
51605148
Relation rel,
51615149
Relation pkrel,
51625150
Oid pkindOid,
@@ -5171,7 +5159,7 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint,
51715159
*/
51725160
MemSet(&trig, 0, sizeof(trig));
51735161
trig.tgoid = InvalidOid;
5174-
trig.tgname = fkconstraint->constr_name;
5162+
trig.tgname = fkconstraint->conname;
51755163
trig.tgenabled = TRIGGER_FIRES_ON_ORIGIN;
51765164
trig.tgisconstraint = TRUE;
51775165
trig.tgconstrrelid = RelationGetRelid(pkrel);
@@ -5228,13 +5216,13 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint,
52285216
}
52295217

52305218
static void
5231-
CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
5219+
CreateFKCheckTrigger(RangeVar *myRel, Constraint *fkconstraint,
52325220
Oid constraintOid, Oid indexOid, bool on_insert)
52335221
{
52345222
CreateTrigStmt *fk_trigger;
52355223

52365224
fk_trigger = makeNode(CreateTrigStmt);
5237-
fk_trigger->trigname = fkconstraint->constr_name;
5225+
fk_trigger->trigname = fkconstraint->conname;
52385226
fk_trigger->relation = myRel;
52395227
fk_trigger->before = false;
52405228
fk_trigger->row = true;
@@ -5268,7 +5256,7 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
52685256
* Create the triggers that implement an FK constraint.
52695257
*/
52705258
static void
5271-
createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
5259+
createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
52725260
Oid constraintOid, Oid indexOid)
52735261
{
52745262
RangeVar *myRel;
@@ -5296,7 +5284,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
52965284
* DELETE action on the referenced table.
52975285
*/
52985286
fk_trigger = makeNode(CreateTrigStmt);
5299-
fk_trigger->trigname = fkconstraint->constr_name;
5287+
fk_trigger->trigname = fkconstraint->conname;
53005288
fk_trigger->relation = fkconstraint->pktable;
53015289
fk_trigger->before = false;
53025290
fk_trigger->row = true;
@@ -5348,7 +5336,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
53485336
* UPDATE action on the referenced table.
53495337
*/
53505338
fk_trigger = makeNode(CreateTrigStmt);
5351-
fk_trigger->trigname = fkconstraint->constr_name;
5339+
fk_trigger->trigname = fkconstraint->conname;
53525340
fk_trigger->relation = fkconstraint->pktable;
53535341
fk_trigger->before = false;
53545342
fk_trigger->row = true;

src/backend/commands/trigger.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.250 2009/07/29 20:56:18 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.251 2009/07/30 02:45:36 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -607,12 +607,14 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
607607
/* OK, we have a set, so make the FK constraint ALTER TABLE cmd */
608608
AlterTableStmt *atstmt = makeNode(AlterTableStmt);
609609
AlterTableCmd *atcmd = makeNode(AlterTableCmd);
610-
FkConstraint *fkcon = makeNode(FkConstraint);
610+
Constraint *fkcon = makeNode(Constraint);
611611

612612
ereport(NOTICE,
613613
(errmsg("converting trigger group into constraint \"%s\" %s",
614614
constr_name, buf.data),
615615
errdetail("%s", _(funcdescr[funcnum]))));
616+
fkcon->contype = CONSTR_FOREIGN;
617+
fkcon->location = -1;
616618
if (funcnum == 2)
617619
{
618620
/* This trigger is on the FK table */
@@ -642,9 +644,9 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
642644
atcmd->subtype = AT_AddConstraint;
643645
atcmd->def = (Node *) fkcon;
644646
if (strcmp(constr_name, "<unnamed>") == 0)
645-
fkcon->constr_name = NULL;
647+
fkcon->conname = NULL;
646648
else
647-
fkcon->constr_name = constr_name;
649+
fkcon->conname = constr_name;
648650
fkcon->fk_attrs = fk_attrs;
649651
fkcon->pk_attrs = pk_attrs;
650652
fkcon->fk_matchtype = fk_matchtype;

0 commit comments

Comments
 (0)