1 /*-------------------------------------------------------------------------
4 * Functions for the built-in type "RegProcedure".
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.35 1999/02/15 16:29:32 tgl Exp $
12 *-------------------------------------------------------------------------
16 #include "miscadmin.h"
17 #include "access/heapam.h"
18 #include "access/genam.h"
19 #include "access/itup.h"
20 #include "access/relscan.h"
21 #include "storage/bufmgr.h"
23 #include "utils/palloc.h"
24 #include "utils/syscache.h"
26 #include "catalog/catname.h"
27 #include "catalog/indexing.h"
28 #include "catalog/pg_proc.h"
29 #include "catalog/pg_type.h"
30 #include "utils/builtins.h" /* where function declarations go */
32 /*****************************************************************************
34 *****************************************************************************/
37 * regprocin - converts "proname" or "proid" to proid
39 * proid of '-' signifies unknown, for consistency with regprocout
42 regprocin(char *pro_name_or_oid)
44 HeapTuple proctup = NULL;
46 RegProcedure result = InvalidOid;
48 if (pro_name_or_oid == NULL)
50 if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '\0')
53 if (!IsBootstrapProcessingMode())
56 * we need to use the oid because there can be multiple entries
57 * with the same name. We accept int4eq_1323 and 1323.
59 if (pro_name_or_oid[0] >= '0' &&
60 pro_name_or_oid[0] <= '9')
62 proctup = SearchSysCacheTuple(PROOID,
63 ObjectIdGetDatum(oidin(pro_name_or_oid)),
65 if (HeapTupleIsValid(proctup))
66 result = (RegProcedure) proctup->t_data->t_oid;
68 elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
76 RetrieveIndexResult indexRes;
80 ScanKeyEntryInitialize(&skey[0],
83 (RegProcedure) F_NAMEEQ,
84 PointerGetDatum(pro_name_or_oid));
86 hdesc = heap_openr(ProcedureRelationName);
87 idesc = index_openr(ProcedureNameIndex);
89 sd = index_beginscan(idesc, false, 1, skey);
90 while ((indexRes = index_getnext(sd, ForwardScanDirection)))
92 tuple.t_self = indexRes->heap_iptr;
93 heap_fetch(hdesc, SnapshotNow,
97 if (tuple.t_data != NULL)
99 result = (RegProcedure) tuple.t_data->t_oid;
100 ReleaseBuffer(buffer);
112 elog(ERROR, "There is more than one procedure named %s.\n\tSupply the pg_proc oid inside single quotes.", pro_name_or_oid);
113 else if (matches == 0)
114 elog(ERROR, "No procedure with name %s", pro_name_or_oid);
120 HeapScanDesc procscan;
124 proc = heap_openr(ProcedureRelationName);
125 if (!RelationIsValid(proc))
127 elog(ERROR, "regprocin: could not open %s",
128 ProcedureRelationName);
131 ScanKeyEntryInitialize(&key,
134 (RegProcedure) F_NAMEEQ,
135 (Datum) pro_name_or_oid);
137 procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
138 if (!HeapScanIsValid(procscan))
141 elog(ERROR, "regprocin: could not being scan of %s",
142 ProcedureRelationName);
145 proctup = heap_getnext(procscan, 0);
146 if (HeapTupleIsValid(proctup))
148 result = (RegProcedure) heap_getattr(proctup,
149 ObjectIdAttributeNumber,
150 RelationGetDescr(proc),
153 elog(FATAL, "regprocin: null procedure %s", pro_name_or_oid);
156 result = (RegProcedure) 0;
158 heap_endscan(procscan);
162 return (int32) result;
166 * regprocout - converts proid to "pro_name"
169 regprocout(RegProcedure proid)
174 result = (char *) palloc(NAMEDATALEN);
176 if (!IsBootstrapProcessingMode())
178 proctup = SearchSysCacheTuple(PROOID,
179 ObjectIdGetDatum(proid),
182 if (HeapTupleIsValid(proctup))
186 s = ((Form_pg_proc) GETSTRUCT(proctup))->proname.data;
187 StrNCpy(result, s, NAMEDATALEN);
198 HeapScanDesc procscan;
201 proc = heap_openr(ProcedureRelationName);
202 if (!RelationIsValid(proc))
204 elog(ERROR, "regprocout: could not open %s", ProcedureRelationName);
207 ScanKeyEntryInitialize(&key,
209 (AttrNumber) ObjectIdAttributeNumber,
210 (RegProcedure) F_INT4EQ,
213 procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
214 if (!HeapScanIsValid(procscan))
217 elog(ERROR, "regprocout: could not being scan of %s",
218 ProcedureRelationName);
221 proctup = heap_getnext(procscan, 0);
222 if (HeapTupleIsValid(proctup))
227 s = (char *) heap_getattr(proctup, 1,
228 RelationGetDescr(proc), &isnull);
230 StrNCpy(result, s, NAMEDATALEN);
232 elog(FATAL, "regprocout: null procedure %d", proid);
239 heap_endscan(procscan);
248 * int8typeout - converts int8 type oids to "typname" list
251 oid8types(Oid *oidArray)
258 if (oidArray == NULL)
260 result = (text *) palloc(VARHDRSZ);
265 result = (text *) palloc(NAMEDATALEN * 8 + 8 + VARHDRSZ);
266 *VARDATA(result) = '\0';
269 for (num = 8; num != 0; num--, sp++)
271 if (*sp != InvalidOid)
273 typetup = SearchSysCacheTuple(TYPOID,
274 ObjectIdGetDatum(*sp),
276 if (HeapTupleIsValid(typetup))
280 s = ((Form_pg_type) GETSTRUCT(typetup))->typname.data;
281 StrNCpy(VARDATA(result) + strlen(VARDATA(result)), s,
283 strcat(VARDATA(result), " ");
287 VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ;
292 /*****************************************************************************
294 *****************************************************************************/
297 * Lowercase version of RegprocToOid() to allow case-insensitive SQL.
298 * Define RegprocToOid() as a macro in builtins.h.
299 * Referenced in pg_proc.h. - tgl 97/04/26
302 regproctooid(RegProcedure rp)
307 /* (see int.c for comparison/operation routines) */
310 /* ========== PRIVATE ROUTINES ========== */