|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.8 2002/04/24 02:38:58 momjian Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.9 2002/04/24 02:48:54 momjian Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -2846,6 +2846,123 @@ renamerel(Oid relid, const char *newrelname)
|
2846 | 2846 | relation_close(targetrelation,NoLock);
|
2847 | 2847 | }
|
2848 | 2848 |
|
| 2849 | +/* |
| 2850 | + *renametrig- changes the name of a trigger on a relation |
| 2851 | + * |
| 2852 | + *trigger name is changed in trigger catalog. |
| 2853 | + *No record of the previous name is kept. |
| 2854 | + * |
| 2855 | + *get proper relrelation from relation catalog (if not arg) |
| 2856 | + *scan trigger catalog |
| 2857 | + *for name conflict (within rel) |
| 2858 | + *for original trigger (if not arg) |
| 2859 | + *modify tgname in trigger tuple |
| 2860 | + *insert modified trigger in trigger catalog |
| 2861 | + *delete original trigger from trigger catalog |
| 2862 | + */ |
| 2863 | +externvoidrenametrig(Oidrelid, |
| 2864 | +constchar*oldname, |
| 2865 | +constchar*newname) |
| 2866 | +{ |
| 2867 | +Relationtargetrel; |
| 2868 | +Relationtgrel; |
| 2869 | +HeapTupletuple; |
| 2870 | +SysScanDesctgscan; |
| 2871 | +ScanKeyDatakey; |
| 2872 | +boolfound= FALSE; |
| 2873 | +Relationidescs[Num_pg_trigger_indices]; |
| 2874 | + |
| 2875 | +/* |
| 2876 | + * Grab an exclusive lock on the target table, which we will NOT |
| 2877 | + * release until end of transaction. |
| 2878 | + */ |
| 2879 | +targetrel=heap_open(relid,AccessExclusiveLock); |
| 2880 | + |
| 2881 | +/* |
| 2882 | + * Scan pg_trigger twice for existing triggers on relation. We do this in |
| 2883 | + * order to ensure a trigger does not exist with newname (The unique index |
| 2884 | + * on tgrelid/tgname would complain anyway) and to ensure a trigger does |
| 2885 | + * exist with oldname. |
| 2886 | + * |
| 2887 | + * NOTE that this is cool only because we have AccessExclusiveLock on the |
| 2888 | + * relation, so the trigger set won't be changing underneath us. |
| 2889 | + */ |
| 2890 | +tgrel=heap_openr(TriggerRelationName,RowExclusiveLock); |
| 2891 | + |
| 2892 | +/* |
| 2893 | + * First pass -- look for name conflict |
| 2894 | + */ |
| 2895 | +ScanKeyEntryInitialize(&key,0, |
| 2896 | +Anum_pg_trigger_tgrelid, |
| 2897 | +F_OIDEQ, |
| 2898 | +ObjectIdGetDatum(relid)); |
| 2899 | +tgscan=systable_beginscan(tgrel,TriggerRelidNameIndex, true, |
| 2900 | +SnapshotNow,1,&key); |
| 2901 | +while (HeapTupleIsValid(tuple=systable_getnext(tgscan))) |
| 2902 | +{ |
| 2903 | +Form_pg_triggerpg_trigger= (Form_pg_trigger)GETSTRUCT(tuple); |
| 2904 | + |
| 2905 | +if (namestrcmp(&(pg_trigger->tgname),newname)==0) |
| 2906 | +elog(ERROR,"renametrig: trigger %s already defined on relation %s", |
| 2907 | +newname,RelationGetRelationName(targetrel)); |
| 2908 | +} |
| 2909 | +systable_endscan(tgscan); |
| 2910 | + |
| 2911 | +/* |
| 2912 | + * Second pass -- look for trigger existing with oldname and update |
| 2913 | + */ |
| 2914 | +ScanKeyEntryInitialize(&key,0, |
| 2915 | +Anum_pg_trigger_tgrelid, |
| 2916 | +F_OIDEQ, |
| 2917 | +ObjectIdGetDatum(relid)); |
| 2918 | +tgscan=systable_beginscan(tgrel,TriggerRelidNameIndex, true, |
| 2919 | +SnapshotNow,1,&key); |
| 2920 | +while (HeapTupleIsValid(tuple=systable_getnext(tgscan))) |
| 2921 | +{ |
| 2922 | +Form_pg_triggerpg_trigger= (Form_pg_trigger)GETSTRUCT(tuple); |
| 2923 | + |
| 2924 | +if (namestrcmp(&(pg_trigger->tgname),oldname)==0) |
| 2925 | +{ |
| 2926 | +/* |
| 2927 | + * Update pg_trigger tuple with new tgname. |
| 2928 | + * (Scribbling on tuple is OK because it's a copy...) |
| 2929 | + */ |
| 2930 | +namestrcpy(&(pg_trigger->tgname),newname); |
| 2931 | +simple_heap_update(tgrel,&tuple->t_self,tuple); |
| 2932 | + |
| 2933 | +/* |
| 2934 | + * keep system catalog indices current |
| 2935 | + */ |
| 2936 | +CatalogOpenIndices(Num_pg_trigger_indices,Name_pg_trigger_indices,idescs); |
| 2937 | +CatalogIndexInsert(idescs,Num_pg_trigger_indices,tgrel,tuple); |
| 2938 | +CatalogCloseIndices(Num_pg_trigger_indices,idescs); |
| 2939 | + |
| 2940 | +/* |
| 2941 | + * Invalidate relation's relcache entry so that other |
| 2942 | + * backends (and this one too!) are sent SI message to make them |
| 2943 | + * rebuild relcache entries. |
| 2944 | + */ |
| 2945 | +CacheInvalidateRelcache(relid); |
| 2946 | + |
| 2947 | +found= TRUE; |
| 2948 | +break; |
| 2949 | +} |
| 2950 | +} |
| 2951 | +systable_endscan(tgscan); |
| 2952 | + |
| 2953 | +heap_close(tgrel,RowExclusiveLock); |
| 2954 | + |
| 2955 | +if (!found) |
| 2956 | +elog(ERROR,"renametrig: trigger %s not defined on relation %s", |
| 2957 | +oldname,RelationGetRelationName(targetrel)); |
| 2958 | + |
| 2959 | +/* |
| 2960 | + * Close rel, but keep exclusive lock! |
| 2961 | + */ |
| 2962 | +heap_close(targetrel,NoLock); |
| 2963 | +} |
| 2964 | + |
| 2965 | + |
2849 | 2966 | /*
|
2850 | 2967 | * Given a trigger function OID, determine whether it is an RI trigger,
|
2851 | 2968 | * and if so whether it is attached to PK or FK relation.
|
|