regproc.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:7k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1.  /*-------------------------------------------------------------------------
  2.  *
  3.  * regproc.c
  4.  *   Functions for the built-in type "RegProcedure".
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.37.2.1 1999/08/02 05:24:57 scrappy Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include "postgres.h"
  15. #include "access/genam.h"
  16. #include "access/heapam.h"
  17. #include "catalog/catname.h"
  18. #include "catalog/indexing.h"
  19. #include "catalog/pg_proc.h"
  20. #include "catalog/pg_type.h"
  21. #include "miscadmin.h"
  22. #include "utils/builtins.h"
  23. #include "utils/syscache.h"
  24. /*****************************************************************************
  25.  *  USER I/O ROUTINES  *
  26.  *****************************************************************************/
  27. /*
  28.  * regprocin - converts "proname" or "proid" to proid
  29.  *
  30.  * proid of '-' signifies unknown, for consistency with regprocout
  31.  */
  32. int32
  33. regprocin(char *pro_name_or_oid)
  34. {
  35. HeapTuple proctup = NULL;
  36. HeapTupleData tuple;
  37. RegProcedure result = InvalidOid;
  38. if (pro_name_or_oid == NULL)
  39. return InvalidOid;
  40. if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '')
  41. return InvalidOid;
  42. if (!IsBootstrapProcessingMode())
  43. {
  44. /*
  45.  * we need to use the oid because there can be multiple entries
  46.  * with the same name. We accept int4eq_1323 and 1323.
  47.  */
  48. if (pro_name_or_oid[0] >= '0' &&
  49. pro_name_or_oid[0] <= '9')
  50. {
  51. proctup = SearchSysCacheTuple(PROOID,
  52. ObjectIdGetDatum(oidin(pro_name_or_oid)),
  53.   0, 0, 0);
  54. if (HeapTupleIsValid(proctup))
  55. result = (RegProcedure) proctup->t_data->t_oid;
  56. else
  57. elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
  58. }
  59. else
  60. {
  61. Relation hdesc;
  62. Relation idesc;
  63. IndexScanDesc sd;
  64. ScanKeyData skey[1];
  65. RetrieveIndexResult indexRes;
  66. Buffer buffer;
  67. int matches = 0;
  68. ScanKeyEntryInitialize(&skey[0],
  69.    (bits16) 0x0,
  70.    (AttrNumber) 1,
  71.    (RegProcedure) F_NAMEEQ,
  72.    PointerGetDatum(pro_name_or_oid));
  73. hdesc = heap_openr(ProcedureRelationName);
  74. idesc = index_openr(ProcedureNameIndex);
  75. sd = index_beginscan(idesc, false, 1, skey);
  76. while ((indexRes = index_getnext(sd, ForwardScanDirection)))
  77. {
  78. tuple.t_self = indexRes->heap_iptr;
  79. heap_fetch(hdesc, SnapshotNow,
  80.    &tuple,
  81.    &buffer);
  82. pfree(indexRes);
  83. if (tuple.t_data != NULL)
  84. {
  85. result = (RegProcedure) tuple.t_data->t_oid;
  86. ReleaseBuffer(buffer);
  87. if (++matches > 1)
  88. break;
  89. }
  90. }
  91. index_endscan(sd);
  92. pfree(sd);
  93. index_close(idesc);
  94. if (matches > 1)
  95. elog(ERROR, "There is more than one procedure named %s.ntSupply the pg_proc oid inside single quotes.", pro_name_or_oid);
  96. else if (matches == 0)
  97. elog(ERROR, "No procedure with name %s", pro_name_or_oid);
  98. }
  99. }
  100. else
  101. {
  102. Relation proc;
  103. HeapScanDesc procscan;
  104. ScanKeyData key;
  105. bool isnull;
  106. proc = heap_openr(ProcedureRelationName);
  107. if (!RelationIsValid(proc))
  108. {
  109. elog(ERROR, "regprocin: could not open %s",
  110.  ProcedureRelationName);
  111. return 0;
  112. }
  113. ScanKeyEntryInitialize(&key,
  114.    (bits16) 0,
  115.    (AttrNumber) 1,
  116.    (RegProcedure) F_NAMEEQ,
  117.    (Datum) pro_name_or_oid);
  118. procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
  119. if (!HeapScanIsValid(procscan))
  120. {
  121. heap_close(proc);
  122. elog(ERROR, "regprocin: could not being scan of %s",
  123.  ProcedureRelationName);
  124. return 0;
  125. }
  126. proctup = heap_getnext(procscan, 0);
  127. if (HeapTupleIsValid(proctup))
  128. {
  129. result = (RegProcedure) heap_getattr(proctup,
  130.  ObjectIdAttributeNumber,
  131.  RelationGetDescr(proc),
  132.  &isnull);
  133. if (isnull)
  134. elog(FATAL, "regprocin: null procedure %s", pro_name_or_oid);
  135. }
  136. else
  137. result = (RegProcedure) 0;
  138. heap_endscan(procscan);
  139. heap_close(proc);
  140. }
  141. return (int32) result;
  142. }
  143. /*
  144.  * regprocout - converts proid to "pro_name"
  145.  */
  146. char *
  147. regprocout(RegProcedure proid)
  148. {
  149. HeapTuple proctup;
  150. char    *result;
  151. result = (char *) palloc(NAMEDATALEN);
  152. if (!IsBootstrapProcessingMode())
  153. {
  154. proctup = SearchSysCacheTuple(PROOID,
  155.   ObjectIdGetDatum(proid),
  156.   0, 0, 0);
  157. if (HeapTupleIsValid(proctup))
  158. {
  159. char    *s;
  160. s = ((Form_pg_proc) GETSTRUCT(proctup))->proname.data;
  161. StrNCpy(result, s, NAMEDATALEN);
  162. }
  163. else
  164. {
  165. result[0] = '-';
  166. result[1] = '';
  167. }
  168. }
  169. else
  170. {
  171. Relation proc;
  172. HeapScanDesc procscan;
  173. ScanKeyData key;
  174. proc = heap_openr(ProcedureRelationName);
  175. if (!RelationIsValid(proc))
  176. {
  177. elog(ERROR, "regprocout: could not open %s", ProcedureRelationName);
  178. return 0;
  179. }
  180. ScanKeyEntryInitialize(&key,
  181.    (bits16) 0,
  182.    (AttrNumber) ObjectIdAttributeNumber,
  183.    (RegProcedure) F_INT4EQ,
  184.    (Datum) proid);
  185. procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
  186. if (!HeapScanIsValid(procscan))
  187. {
  188. heap_close(proc);
  189. elog(ERROR, "regprocout: could not being scan of %s",
  190.  ProcedureRelationName);
  191. return 0;
  192. }
  193. proctup = heap_getnext(procscan, 0);
  194. if (HeapTupleIsValid(proctup))
  195. {
  196. char    *s;
  197. bool isnull;
  198. s = (char *) heap_getattr(proctup, 1,
  199.   RelationGetDescr(proc), &isnull);
  200. if (!isnull)
  201. StrNCpy(result, s, NAMEDATALEN);
  202. else
  203. elog(FATAL, "regprocout: null procedure %u", proid);
  204. }
  205. else
  206. {
  207. result[0] = '-';
  208. result[1] = '';
  209. }
  210. heap_endscan(procscan);
  211. heap_close(proc);
  212. return result;
  213. }
  214. return result;
  215. }
  216. /*
  217.  * int8typeout - converts int8 type oids to "typname" list
  218.  */
  219. text *
  220. oid8types(Oid *oidArray)
  221. {
  222. HeapTuple typetup;
  223. text    *result;
  224. int num;
  225. Oid    *sp;
  226. if (oidArray == NULL)
  227. {
  228. result = (text *) palloc(VARHDRSZ);
  229. VARSIZE(result) = 0;
  230. return result;
  231. }
  232. result = (text *) palloc(NAMEDATALEN * 8 + 8 + VARHDRSZ);
  233. *VARDATA(result) = '';
  234. sp = oidArray;
  235. for (num = 8; num != 0; num--, sp++)
  236. {
  237. if (*sp != InvalidOid)
  238. {
  239. typetup = SearchSysCacheTuple(TYPOID,
  240.   ObjectIdGetDatum(*sp),
  241.   0, 0, 0);
  242. if (HeapTupleIsValid(typetup))
  243. {
  244. char    *s;
  245. s = ((Form_pg_type) GETSTRUCT(typetup))->typname.data;
  246. StrNCpy(VARDATA(result) + strlen(VARDATA(result)), s,
  247. NAMEDATALEN);
  248. strcat(VARDATA(result), " ");
  249. }
  250. }
  251. }
  252. VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ;
  253. return result;
  254. }
  255. /*****************************************************************************
  256.  *  PUBLIC ROUTINES  *
  257.  *****************************************************************************/
  258. /* regproctooid()
  259.  * Lowercase version of RegprocToOid() to allow case-insensitive SQL.
  260.  * Define RegprocToOid() as a macro in builtins.h.
  261.  * Referenced in pg_proc.h. - tgl 97/04/26
  262.  */
  263. Oid
  264. regproctooid(RegProcedure rp)
  265. {
  266. return (Oid) rp;
  267. }
  268. /* (see int.c for comparison/operation routines) */
  269. /* ========== PRIVATE ROUTINES ========== */