77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
99 * IDENTIFICATION
10- * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.220 2007/11/04 01:16:19 tgl Exp $
10+ * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.221 2007/11/04 21:25:55 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -218,7 +218,6 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid)
218218 * constraint. Ugly, but necessary for loading old dump files.
219219 */
220220 if (stmt -> isconstraint && !OidIsValid (constraintOid ) &&
221- stmt -> constrrel != NULL &&
222221 list_length (stmt -> args ) >= 6 &&
223222 (list_length (stmt -> args ) % 2 ) == 0 &&
224223 RI_FKey_trigger_type (funcoid ) != RI_TRIGGER_NONE )
@@ -482,9 +481,69 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
482481{
483482 static List * info_list = NIL ;
484483
484+ char * constr_name ;
485+ char * fk_table_name ;
486+ char * pk_table_name ;
487+ char fk_matchtype = FKCONSTR_MATCH_UNSPECIFIED ;
488+ List * fk_attrs = NIL ;
489+ List * pk_attrs = NIL ;
490+ StringInfoData buf ;
485491 bool isupd ;
486492 OldTriggerInfo * info = NULL ;
487493 ListCell * l ;
494+ int i ;
495+
496+ /* Parse out the trigger arguments */
497+ constr_name = strVal (linitial (stmt -> args ));
498+ fk_table_name = strVal (lsecond (stmt -> args ));
499+ pk_table_name = strVal (lthird (stmt -> args ));
500+ i = 0 ;
501+ foreach (l , stmt -> args )
502+ {
503+ Value * arg = (Value * ) lfirst (l );
504+
505+ i ++ ;
506+ if (i < 4 ) /* skip constraint and table names */
507+ continue ;
508+ if (i == 4 ) /* handle match type */
509+ {
510+ if (strcmp (strVal (arg ), "FULL" ) == 0 )
511+ fk_matchtype = FKCONSTR_MATCH_FULL ;
512+ else
513+ fk_matchtype = FKCONSTR_MATCH_UNSPECIFIED ;
514+ continue ;
515+ }
516+ if (i % 2 )
517+ fk_attrs = lappend (fk_attrs , arg );
518+ else
519+ pk_attrs = lappend (pk_attrs , arg );
520+ }
521+
522+ /* Prepare description of constraint for use in messages */
523+ initStringInfo (& buf );
524+ appendStringInfo (& buf , "FOREIGN KEY %s(" ,
525+ quote_identifier (fk_table_name ));
526+ i = 0 ;
527+ foreach (l , fk_attrs )
528+ {
529+ Value * arg = (Value * ) lfirst (l );
530+
531+ if (i ++ > 0 )
532+ appendStringInfoChar (& buf , ',' );
533+ appendStringInfoString (& buf , quote_identifier (strVal (arg )));
534+ }
535+ appendStringInfo (& buf , ") REFERENCES %s(" ,
536+ quote_identifier (pk_table_name ));
537+ i = 0 ;
538+ foreach (l , pk_attrs )
539+ {
540+ Value * arg = (Value * ) lfirst (l );
541+
542+ if (i ++ > 0 )
543+ appendStringInfoChar (& buf , ',' );
544+ appendStringInfoString (& buf , quote_identifier (strVal (arg )));
545+ }
546+ appendStringInfoChar (& buf , ')' );
488547
489548 /* Identify class of trigger --- update, delete, or referencing-table */
490549 switch (funcoid )
@@ -508,8 +567,8 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
508567 default :
509568 /* Ignore triggers on referencing table */
510569 ereport (NOTICE ,
511- (errmsg ("ignoring incomplete foreign-key trigger group for constraint \"%s\" on table \"%s\" " ,
512- stmt -> trigname , stmt -> relation -> relname )));
570+ (errmsg ("ignoring incomplete trigger group for constraint \"%s\" %s " ,
571+ constr_name , buf . data )));
513572 return ;
514573 }
515574
@@ -527,8 +586,8 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
527586 MemoryContext oldContext ;
528587
529588 ereport (NOTICE ,
530- (errmsg ("ignoring incomplete foreign-key trigger group for constraint \"%s\" on table \"%s\" " ,
531- stmt -> trigname , stmt -> constrrel -> relname )));
589+ (errmsg ("ignoring incomplete trigger group for constraint \"%s\" %s " ,
590+ constr_name , buf . data )));
532591 oldContext = MemoryContextSwitchTo (TopMemoryContext );
533592 info = (OldTriggerInfo * ) palloc (sizeof (OldTriggerInfo ));
534593 info -> args = copyObject (stmt -> args );
@@ -539,49 +598,36 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
539598 }
540599 else
541600 {
542- /* OK, we have a pair, so make the FK constraint */
601+ /* OK, we have a pair, so make the FK constraint ALTER TABLE cmd */
543602 AlterTableStmt * atstmt = makeNode (AlterTableStmt );
544603 AlterTableCmd * atcmd = makeNode (AlterTableCmd );
545604 FkConstraint * fkcon = makeNode (FkConstraint );
546- int i ;
547605 Oid updfunc ,
548606 delfunc ;
549607
550608 ereport (NOTICE ,
551- (errmsg ("converting foreign-key trigger group into constraint \"%s\" on table \"%s\"" ,
552- stmt -> trigname , stmt -> constrrel -> relname )));
553- atstmt -> relation = stmt -> constrrel ;
609+ (errmsg ("converting trigger group into constraint \"%s\" %s" ,
610+ constr_name , buf .data )));
611+
612+ if (stmt -> constrrel )
613+ atstmt -> relation = stmt -> constrrel ;
614+ else
615+ {
616+ /* Work around ancient pg_dump bug that omitted constrrel */
617+ atstmt -> relation = makeRangeVar (NULL , fk_table_name );
618+ }
554619 atstmt -> cmds = list_make1 (atcmd );
555620 atstmt -> relkind = OBJECT_TABLE ;
556621 atcmd -> subtype = AT_AddConstraint ;
557622 atcmd -> def = (Node * ) fkcon ;
558- if (strcmp (stmt -> trigname , "<unnamed>" ) == 0 )
623+ if (strcmp (constr_name , "<unnamed>" ) == 0 )
559624 fkcon -> constr_name = NULL ;
560625 else
561- fkcon -> constr_name = stmt -> trigname ;
626+ fkcon -> constr_name = constr_name ;
562627 fkcon -> pktable = stmt -> relation ;
563-
564- i = 0 ;
565- foreach (l , stmt -> args )
566- {
567- Value * arg = (Value * ) lfirst (l );
568-
569- i ++ ;
570- if (i < 4 ) /* ignore constraint and table names */
571- continue ;
572- if (i == 4 ) /* handle match type */
573- {
574- if (strcmp (strVal (arg ), "FULL" ) == 0 )
575- fkcon -> fk_matchtype = FKCONSTR_MATCH_FULL ;
576- else
577- fkcon -> fk_matchtype = FKCONSTR_MATCH_UNSPECIFIED ;
578- continue ;
579- }
580- if (i % 2 )
581- fkcon -> fk_attrs = lappend (fkcon -> fk_attrs , arg );
582- else
583- fkcon -> pk_attrs = lappend (fkcon -> pk_attrs , arg );
584- }
628+ fkcon -> fk_attrs = fk_attrs ;
629+ fkcon -> pk_attrs = pk_attrs ;
630+ fkcon -> fk_matchtype = fk_matchtype ;
585631
586632 if (isupd )
587633 {
@@ -638,6 +684,7 @@ ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid)
638684 fkcon -> deferrable = stmt -> deferrable ;
639685 fkcon -> initdeferred = stmt -> initdeferred ;
640686
687+ /* ... and execute it */
641688 ProcessUtility ((Node * ) atstmt ,
642689 NULL , NULL , false, None_Receiver , NULL );
643690
0 commit comments