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
154154Oid refrelid ;/* PK rel, if FOREIGN */
155155Oid refindid ;/* OID of PK's index, if FOREIGN */
156156Oid conid ;/* OID of pg_constraint entry, if FOREIGN */
157- Node * qual ;/* Check expr orFkConstraint struct */
157+ Node * qual ;/* Check expr orCONSTR_FOREIGN Constraint */
158158List * qualstate ;/* Execution state for CHECK */
159159}NewConstraint ;
160160
@@ -247,10 +247,10 @@ static Oid transformFkeyCheckAttrs(Relation pkrel,
247247int numattrs ,int16 * attnums ,
248248Oid * opclasses );
249249static void checkFkeyPermissions (Relation rel ,int16 * attnums ,int natts );
250- static void validateForeignKeyConstraint (FkConstraint * fkconstraint ,
250+ static void validateForeignKeyConstraint (Constraint * fkconstraint ,
251251Relation rel ,Relation pkrel ,
252252Oid pkindOid ,Oid constraintOid );
253- static void createForeignKeyTriggers (Relation rel ,FkConstraint * fkconstraint ,
253+ static void createForeignKeyTriggers (Relation rel ,Constraint * fkconstraint ,
254254Oid constraintOid ,Oid indexOid );
255255static void ATController (Relation rel ,List * cmds ,bool recurse );
256256static void ATPrepCmd (List * * wqueue ,Relation rel ,AlterTableCmd * cmd ,
@@ -293,13 +293,13 @@ static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
293293IndexStmt * stmt ,bool is_rebuild );
294294static void ATExecAddConstraint (List * * wqueue ,
295295AlteredTableInfo * tab ,Relation rel ,
296- Node * newConstraint ,bool recurse );
296+ Constraint * newConstraint ,bool recurse );
297297static void ATAddCheckConstraint (List * * wqueue ,
298298AlteredTableInfo * tab ,Relation rel ,
299299Constraint * constr ,
300300bool recurse ,bool recursing );
301301static void ATAddForeignKeyConstraint (AlteredTableInfo * tab ,Relation rel ,
302- FkConstraint * fkconstraint );
302+ Constraint * fkconstraint );
303303static void ATExecDropConstraint (Relation rel ,const char * constrName ,
304304DropBehavior behavior ,
305305bool recurse ,bool recursing ,
@@ -2637,10 +2637,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
26372637ATExecAddIndex (tab ,rel , (IndexStmt * )cmd -> def , true);
26382638break ;
26392639case AT_AddConstraint :/* ADD CONSTRAINT */
2640- ATExecAddConstraint (wqueue ,tab ,rel ,cmd -> def , false);
2640+ ATExecAddConstraint (wqueue ,tab ,rel , (Constraint * )cmd -> def ,
2641+ false);
26412642break ;
26422643case AT_AddConstraintRecurse :/* ADD CONSTRAINT with recursion */
2643- ATExecAddConstraint (wqueue ,tab ,rel ,cmd -> def , true);
2644+ ATExecAddConstraint (wqueue ,tab ,rel , (Constraint * )cmd -> def ,
2645+ true);
26442646break ;
26452647case AT_DropConstraint :/* DROP CONSTRAINT */
26462648ATExecDropConstraint (rel ,cmd -> name ,cmd -> behavior ,
@@ -2905,7 +2907,7 @@ ATRewriteTables(List **wqueue)
29052907
29062908if (con -> contype == CONSTR_FOREIGN )
29072909{
2908- FkConstraint * fkconstraint = (FkConstraint * )con -> qual ;
2910+ Constraint * fkconstraint = (Constraint * )con -> qual ;
29092911Relation refrel ;
29102912
29112913if (rel == NULL )
@@ -4405,69 +4407,55 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
44054407 */
44064408static void
44074409ATExecAddConstraint (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+
44684456default :
4469- elog (ERROR ,"unrecognizednode type: %d" ,
4470- (int )nodeTag ( newConstraint ) );
4457+ elog (ERROR ,"unrecognizedconstraint type: %d" ,
4458+ (int )newConstraint -> contype );
44714459}
44724460}
44734461
@@ -4526,12 +4514,12 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
45264514tab -> 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 */
45374525CommandCounterIncrement ();
@@ -4583,7 +4571,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
45834571 */
45844572static void
45854573ATAddForeignKeyConstraint (AlteredTableInfo * tab ,Relation rel ,
4586- FkConstraint * fkconstraint )
4574+ Constraint * fkconstraint )
45874575{
45884576Relation pkrel ;
45894577int16 pkattnum [INDEX_MAX_KEYS ];
@@ -4798,7 +4786,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
47984786(errcode (ERRCODE_DATATYPE_MISMATCH ),
47994787errmsg ("foreign key constraint \"%s\" "
48004788"cannot be implemented" ,
4801- fkconstraint -> constr_name ),
4789+ fkconstraint -> conname ),
48024790errdetail ("Key columns \"%s\" and \"%s\" "
48034791"are of incompatible types: %s and %s." ,
48044792strVal (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 ,
48184806RelationGetNamespace (rel ),
48194807CONSTRAINT_FOREIGN ,
48204808fkconstraint -> deferrable ,
@@ -4854,7 +4842,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
48544842NewConstraint * newcon ;
48554843
48564844newcon = (NewConstraint * )palloc0 (sizeof (NewConstraint ));
4857- newcon -> name = fkconstraint -> constr_name ;
4845+ newcon -> name = fkconstraint -> conname ;
48584846newcon -> contype = CONSTR_FOREIGN ;
48594847newcon -> refrelid = RelationGetRelid (pkrel );
48604848newcon -> refindid = indexOid ;
@@ -5156,7 +5144,7 @@ checkFkeyPermissions(Relation rel, int16 *attnums, int natts)
51565144 * Caller must have opened and locked both relations.
51575145 */
51585146static void
5159- validateForeignKeyConstraint (FkConstraint * fkconstraint ,
5147+ validateForeignKeyConstraint (Constraint * fkconstraint ,
51605148Relation rel ,
51615149Relation pkrel ,
51625150Oid pkindOid ,
@@ -5171,7 +5159,7 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint,
51715159 */
51725160MemSet (& trig ,0 ,sizeof (trig ));
51735161trig .tgoid = InvalidOid ;
5174- trig .tgname = fkconstraint -> constr_name ;
5162+ trig .tgname = fkconstraint -> conname ;
51755163trig .tgenabled = TRIGGER_FIRES_ON_ORIGIN ;
51765164trig .tgisconstraint = TRUE;
51775165trig .tgconstrrelid = RelationGetRelid (pkrel );
@@ -5228,13 +5216,13 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint,
52285216}
52295217
52305218static void
5231- CreateFKCheckTrigger (RangeVar * myRel ,FkConstraint * fkconstraint ,
5219+ CreateFKCheckTrigger (RangeVar * myRel ,Constraint * fkconstraint ,
52325220Oid constraintOid ,Oid indexOid ,bool on_insert )
52335221{
52345222CreateTrigStmt * fk_trigger ;
52355223
52365224fk_trigger = makeNode (CreateTrigStmt );
5237- fk_trigger -> trigname = fkconstraint -> constr_name ;
5225+ fk_trigger -> trigname = fkconstraint -> conname ;
52385226fk_trigger -> relation = myRel ;
52395227fk_trigger -> before = false;
52405228fk_trigger -> row = true;
@@ -5268,7 +5256,7 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
52685256 * Create the triggers that implement an FK constraint.
52695257 */
52705258static void
5271- createForeignKeyTriggers (Relation rel ,FkConstraint * fkconstraint ,
5259+ createForeignKeyTriggers (Relation rel ,Constraint * fkconstraint ,
52725260Oid constraintOid ,Oid indexOid )
52735261{
52745262RangeVar * myRel ;
@@ -5296,7 +5284,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
52965284 * DELETE action on the referenced table.
52975285 */
52985286fk_trigger = makeNode (CreateTrigStmt );
5299- fk_trigger -> trigname = fkconstraint -> constr_name ;
5287+ fk_trigger -> trigname = fkconstraint -> conname ;
53005288fk_trigger -> relation = fkconstraint -> pktable ;
53015289fk_trigger -> before = false;
53025290fk_trigger -> row = true;
@@ -5348,7 +5336,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
53485336 * UPDATE action on the referenced table.
53495337 */
53505338fk_trigger = makeNode (CreateTrigStmt );
5351- fk_trigger -> trigname = fkconstraint -> constr_name ;
5339+ fk_trigger -> trigname = fkconstraint -> conname ;
53525340fk_trigger -> relation = fkconstraint -> pktable ;
53535341fk_trigger -> before = false;
53545342fk_trigger -> row = true;