77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.108 2002/03/26 19:15:45 tgl Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.109 2002/03/29 22:10:33 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
1818#include "catalog/catalog.h"
1919#include "catalog/catname.h"
2020#include "catalog/indexing.h"
21+ #include "catalog/namespace.h"
2122#include "catalog/pg_language.h"
2223#include "catalog/pg_proc.h"
2324#include "catalog/pg_trigger.h"
2930#include "utils/builtins.h"
3031#include "utils/fmgroids.h"
3132#include "utils/inval.h"
33+ #include "utils/lsyscache.h"
3234#include "utils/syscache.h"
3335
3436
@@ -96,20 +98,10 @@ CreateTrigger(CreateTrigStmt *stmt)
9698stmt -> trigname = constrtrigname ;
9799sprintf (constrtrigname ,"RI_ConstraintTrigger_%u" ,newoid ());
98100
99- if (stmt -> constrrel = =NULL )
100- constrrelid = InvalidOid ;
101+ if (stmt -> constrrel ! =NULL )
102+ constrrelid = RangeVarGetRelid ( stmt -> constrrel , false) ;
101103else
102- {
103- /*
104- * NoLock is probably sufficient here, since we're only
105- * interested in getting the relation's OID...
106- */
107- Relation conrel ;
108-
109- conrel = heap_openrv (stmt -> constrrel ,NoLock );
110- constrrelid = conrel -> rd_id ;
111- heap_close (conrel ,NoLock );
112- }
104+ constrrelid = InvalidOid ;
113105}
114106
115107TRIGGER_CLEAR_TYPE (tgtype );
@@ -310,8 +302,11 @@ CreateTrigger(CreateTrigStmt *stmt)
310302heap_close (rel ,NoLock );
311303}
312304
305+ /*
306+ * DropTrigger - drop an individual trigger by name
307+ */
313308void
314- DropTrigger (DropTrigStmt * stmt )
309+ DropTrigger (Oid relid , const char * trigname )
315310{
316311Relation rel ;
317312Relation tgrel ;
@@ -320,21 +315,21 @@ DropTrigger(DropTrigStmt *stmt)
320315Relation pgrel ;
321316HeapTuple tuple ;
322317Relation ridescs [Num_pg_class_indices ];
318+ int remaining = 0 ;
323319int found = 0 ;
324- int tgfound = 0 ;
325320
326- rel = heap_openrv ( stmt -> relation ,AccessExclusiveLock );
321+ rel = heap_open ( relid ,AccessExclusiveLock );
327322
328323if (rel -> rd_rel -> relkind != RELKIND_RELATION )
329324elog (ERROR ,"DropTrigger: relation \"%s\" is not a table" ,
330- stmt -> relation -> relname );
325+ RelationGetRelationName ( rel ) );
331326
332- if (!allowSystemTableMods && IsSystemRelationName (stmt -> relation -> relname ))
327+ if (!allowSystemTableMods && IsSystemRelationName (RelationGetRelationName ( rel ) ))
333328elog (ERROR ,"DropTrigger: can't drop trigger for system relation %s" ,
334- stmt -> relation -> relname );
329+ RelationGetRelationName ( rel ) );
335330
336- if (!pg_class_ownercheck (RelationGetRelid ( rel ) ,GetUserId ()))
337- elog (ERROR ,"%s: %s" ,stmt -> relation -> relname ,
331+ if (!pg_class_ownercheck (relid ,GetUserId ()))
332+ elog (ERROR ,"%s: %s" ,RelationGetRelationName ( rel ) ,
338333aclcheck_error_strings [ACLCHECK_NOT_OWNER ]);
339334
340335/*
@@ -346,33 +341,33 @@ DropTrigger(DropTrigStmt *stmt)
346341tgrel = heap_openr (TriggerRelationName ,RowExclusiveLock );
347342ScanKeyEntryInitialize (& key ,0 ,Anum_pg_trigger_tgrelid ,
348343F_OIDEQ ,
349- ObjectIdGetDatum (RelationGetRelid ( rel ) ));
344+ ObjectIdGetDatum (relid ));
350345tgscan = systable_beginscan (tgrel ,TriggerRelidIndex , true,
351346SnapshotNow ,1 ,& key );
352347while (HeapTupleIsValid (tuple = systable_getnext (tgscan )))
353348{
354349Form_pg_trigger pg_trigger = (Form_pg_trigger )GETSTRUCT (tuple );
355350
356- if (namestrcmp (& (pg_trigger -> tgname ),stmt -> trigname )== 0 )
351+ if (namestrcmp (& (pg_trigger -> tgname ),trigname )== 0 )
357352{
358353/* Delete any comments associated with this trigger */
359354DeleteComments (tuple -> t_data -> t_oid ,RelationGetRelid (tgrel ));
360355
361356simple_heap_delete (tgrel ,& tuple -> t_self );
362- tgfound ++ ;
357+ found ++ ;
363358}
364359else
365- found ++ ;
360+ remaining ++ ;
366361}
367362systable_endscan (tgscan );
368363heap_close (tgrel ,RowExclusiveLock );
369364
370- if (tgfound == 0 )
365+ if (found == 0 )
371366elog (ERROR ,"DropTrigger: there is no trigger %s on relation %s" ,
372- stmt -> trigname ,stmt -> relation -> relname );
373- if (tgfound > 1 )
367+ trigname ,RelationGetRelationName ( rel ) );
368+ if (found > 1 )/* shouldn't happen */
374369elog (NOTICE ,"DropTrigger: found (and deleted) %d triggers %s on relation %s" ,
375- tgfound , stmt -> trigname ,stmt -> relation -> relname );
370+ found , trigname ,RelationGetRelationName ( rel ) );
376371
377372/*
378373 * Update relation's pg_class entry. Crucial side-effect: other
@@ -381,26 +376,20 @@ DropTrigger(DropTrigStmt *stmt)
381376 */
382377pgrel = heap_openr (RelationRelationName ,RowExclusiveLock );
383378tuple = SearchSysCacheCopy (RELOID ,
384- ObjectIdGetDatum (RelationGetRelid ( rel ) ),
379+ ObjectIdGetDatum (relid ),
3853800 ,0 ,0 );
386381if (!HeapTupleIsValid (tuple ))
387382elog (ERROR ,"DropTrigger: relation %s not found in pg_class" ,
388- stmt -> relation -> relname );
383+ RelationGetRelationName ( rel ) );
389384
390- ((Form_pg_class )GETSTRUCT (tuple ))-> reltriggers = found ;
385+ ((Form_pg_class )GETSTRUCT (tuple ))-> reltriggers = remaining ;
391386simple_heap_update (pgrel ,& tuple -> t_self ,tuple );
392387CatalogOpenIndices (Num_pg_class_indices ,Name_pg_class_indices ,ridescs );
393388CatalogIndexInsert (ridescs ,Num_pg_class_indices ,pgrel ,tuple );
394389CatalogCloseIndices (Num_pg_class_indices ,ridescs );
395390heap_freetuple (tuple );
396391heap_close (pgrel ,RowExclusiveLock );
397392
398- /*
399- * We used to try to update the rel's relcache entry here, but that's
400- * fairly pointless since it will happen as a byproduct of the
401- * upcoming CommandCounterIncrement...
402- */
403-
404393/* Keep lock on target rel until end of xact */
405394heap_close (rel ,NoLock );
406395}
@@ -479,25 +468,12 @@ RelationRemoveTriggers(Relation rel)
479468
480469while (HeapTupleIsValid (tup = systable_getnext (tgscan )))
481470{
482- Form_pg_trigger pg_trigger ;
483- Relation refrel ;
484- DropTrigStmt * stmt = makeNode (DropTrigStmt );
485-
486- pg_trigger = (Form_pg_trigger )GETSTRUCT (tup );
487-
488- stmt -> trigname = pstrdup (NameStr (pg_trigger -> tgname ));
489-
490- /* May as well grab AccessExclusiveLock, since DropTrigger will. */
491- refrel = heap_open (pg_trigger -> tgrelid ,AccessExclusiveLock );
492- stmt -> relation = makeNode (RangeVar );
493- /* XXX bogus: what about schema? */
494- stmt -> relation -> relname = pstrdup (RelationGetRelationName (refrel ));
495- heap_close (refrel ,NoLock );
471+ Form_pg_trigger pg_trigger = (Form_pg_trigger )GETSTRUCT (tup );
496472
497473elog (NOTICE ,"DROP TABLE implicitly drops referential integrity trigger from table \"%s\"" ,
498- stmt -> relation -> relname );
474+ get_temp_rel_by_physicalname ( get_rel_name ( pg_trigger -> tgrelid )) );
499475
500- DropTrigger (stmt );
476+ DropTrigger (pg_trigger -> tgrelid , NameStr ( pg_trigger -> tgname ) );
501477
502478/*
503479 * Need to do a command counter increment here to show up new