88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.2 2002/07/16 06:58:44 ishii Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.3 2002/07/25 10:07:10 ishii Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
1515#include "postgres.h"
1616
1717#include "access/heapam.h"
1818#include "catalog/catname.h"
19+ #include "catalog/dependency.h"
1920#include "catalog/indexing.h"
21+ #include "catalog/pg_class.h"
2022#include "catalog/pg_conversion.h"
2123#include "catalog/namespace.h"
2224#include "utils/builtins.h"
25+ #include "utils/lsyscache.h"
2326#include "utils/syscache.h"
27+ #include "utils/catcache.h"
2428#include "mb/pg_wchar.h"
2529#include "utils/fmgroids.h"
2630#include "utils/acl.h"
2731#include "miscadmin.h"
2832
2933/* ----------------
3034 * ConversionCreate
35+ *
36+ * Add a new tuple to pg_coversion.
3137 * ---------------
3238 */
3339Oid ConversionCreate (const char * conname ,Oid connamespace ,
@@ -43,6 +49,8 @@ OidConversionCreate(const char *conname, Oid connamespace,
4349Datum values [Natts_pg_conversion ];
4450NameData cname ;
4551Oid oid ;
52+ ObjectAddress myself ,
53+ referenced ;
4654
4755/* sanity checks */
4856if (!conname )
@@ -85,7 +93,10 @@ OidConversionCreate(const char *conname, Oid connamespace,
8593values [Anum_pg_conversion_conforencoding - 1 ]= Int32GetDatum (conforencoding );
8694values [Anum_pg_conversion_contoencoding - 1 ]= Int32GetDatum (contoencoding );
8795values [Anum_pg_conversion_conproc - 1 ]= ObjectIdGetDatum (conproc );
88- values [Anum_pg_conversion_condefault - 1 ]= BoolGetDatum (def );
96+ if (def == true)
97+ values [Anum_pg_conversion_condefault - 1 ]= BoolGetDatum (def );
98+ else
99+ nulls [Anum_pg_conversion_condefault - 1 ]= 'n' ;
89100
90101tup = heap_formtuple (tupDesc ,values ,nulls );
91102
@@ -103,23 +114,39 @@ OidConversionCreate(const char *conname, Oid connamespace,
103114CatalogCloseIndices (Num_pg_conversion_indices ,idescs );
104115}
105116
117+ myself .classId = get_system_catalog_relid (ConversionRelationName );
118+ myself .objectId = HeapTupleGetOid (tup );
119+ myself .objectSubId = 0 ;
120+
121+ /* dependency on conversion procedure */
122+ referenced .classId = RelOid_pg_proc ;
123+ referenced .objectId = conproc ;
124+ referenced .objectSubId = 0 ;
125+ recordDependencyOn (& myself ,& referenced ,DEPENDENCY_NORMAL );
126+
127+ heap_freetuple (tup );
106128heap_close (rel ,RowExclusiveLock );
107129
108130return oid ;
109131}
110132
111133/* ----------------
112134 * ConversionDrop
135+ *
136+ * Drop a conversion and do dependency check.
113137 * ---------------
114138 */
115- void ConversionDrop (const char * conname ,Oid connamespace ,int32 conowner )
139+ void ConversionDrop (const char * conname ,Oid connamespace ,
140+ int32 conowner ,DropBehavior behavior )
116141{
117142Relation rel ;
118143TupleDesc tupDesc ;
119144HeapTuple tuple ;
120145HeapScanDesc scan ;
121146ScanKeyData scanKeyData ;
122147Form_pg_conversion body ;
148+ ObjectAddress object ;
149+ Oid myoid ;
123150
124151/* sanity checks */
125152if (!conname )
@@ -132,7 +159,7 @@ voidConversionDrop(const char *conname, Oid connamespace, int32 conowner)
132159ObjectIdGetDatum (connamespace ));
133160
134161/* open pg_conversion */
135- rel = heap_openr (ConversionRelationName ,RowExclusiveLock );
162+ rel = heap_openr (ConversionRelationName ,AccessShareLock );
136163tupDesc = rel -> rd_att ;
137164
138165scan = heap_beginscan (rel ,SnapshotNow ,
@@ -155,18 +182,65 @@ voidConversionDrop(const char *conname, Oid connamespace, int32 conowner)
155182if (!superuser ()&& ((Form_pg_conversion )GETSTRUCT (tuple ))-> conowner != GetUserId ())
156183elog (ERROR ,"permission denied" );
157184
158- simple_heap_delete (rel ,& tuple -> t_self );
185+ myoid = HeapTupleGetOid (tuple );
186+ heap_endscan (scan );
187+ heap_close (rel ,AccessShareLock );
188+
189+ /*
190+ * Do the deletion
191+ */
192+ object .classId = get_system_catalog_relid (ConversionRelationName );
193+ object .objectId = myoid ;
194+ object .objectSubId = 0 ;
195+
196+ performDeletion (& object ,behavior );
197+ }
198+
199+ /* ----------------
200+ * RemoveConversionById
201+ *
202+ * Remove a tuple from pg_conversion by Oid. This function is soley
203+ * called inside catalog/dependency.c
204+ * --------------- */
205+ void
206+ RemoveConversionById (Oid conversionOid )
207+ {
208+ Relation rel ;
209+ TupleDesc tupDesc ;
210+ HeapTuple tuple ;
211+ HeapScanDesc scan ;
212+ ScanKeyData scanKeyData ;
213+
214+ ScanKeyEntryInitialize (& scanKeyData ,
215+ 0 ,
216+ ObjectIdAttributeNumber ,
217+ F_OIDEQ ,
218+ ObjectIdGetDatum (conversionOid ));
159219
220+ /* open pg_conversion */
221+ rel = heap_openr (ConversionRelationName ,RowExclusiveLock );
222+ tupDesc = rel -> rd_att ;
223+
224+ scan = heap_beginscan (rel ,SnapshotNow ,
225+ 1 ,& scanKeyData );
226+
227+ /* search for the target tuple */
228+ if (HeapTupleIsValid (tuple = heap_getnext (scan ,ForwardScanDirection )))
229+ simple_heap_delete (rel ,& tuple -> t_self );
230+ else
231+ elog (ERROR ,"Conversion %u does not exist" ,conversionOid );
160232heap_endscan (scan );
161233heap_close (rel ,RowExclusiveLock );
162234}
163235
164236/* ----------------
165237 * FindDefaultConversion
166238 *
167- * find default conversion proc by for_encoding and to_encoding in this name space
239+ * Find "default" conversion proc by for_encoding and to_encoding in this name space.
240+ * If found, returns the procedure's oid, otherwise InvalidOid.
168241 * ---------------
169242 */
243+ #ifdef NOT_USED
170244Oid FindDefaultConversion (Oid name_space ,int4 for_encoding ,int4 to_encoding )
171245{
172246Relation rel ;
@@ -205,11 +279,44 @@ Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
205279heap_close (rel ,AccessShareLock );
206280return proc ;
207281}
282+ #endif
283+
284+ Oid FindDefaultConversion (Oid name_space ,int4 for_encoding ,int4 to_encoding )
285+ {
286+ CatCList * catlist ;
287+ HeapTuple tuple ;
288+ Form_pg_conversion body ;
289+ Oid proc = InvalidOid ;
290+ int i ;
291+
292+ /* Check we have usage rights in target namespace */
293+ if (pg_namespace_aclcheck (name_space ,GetUserId (),ACL_USAGE )!= ACLCHECK_OK )
294+ return proc ;
295+
296+ catlist = SearchSysCacheList (CONDEFAULT ,3 ,
297+ ObjectIdGetDatum (name_space ),
298+ Int32GetDatum (for_encoding ),
299+ Int32GetDatum (to_encoding ),
300+ 0 );
301+
302+ for (i = 0 ;i < catlist -> n_members ;i ++ )
303+ {
304+ tuple = & catlist -> members [i ]-> tuple ;
305+ body = (Form_pg_conversion )GETSTRUCT (tuple );
306+ if (body -> condefault == TRUE)
307+ {
308+ proc = body -> conproc ;
309+ break ;
310+ }
311+ }
312+ ReleaseSysCacheList (catlist );
313+ return proc ;
314+ }
208315
209316/* ----------------
210317 * FindConversionByName
211318 *
212- *find conversion proc by possibly qualified conversion name.
319+ *Find conversion proc by possibly qualified conversion name.
213320 * ---------------
214321 */
215322Oid FindConversionByName (List * name )