aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/regproc.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2001-08-21 16:36:06 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2001-08-21 16:36:06 +0000
commitf933766ba7c5446a28d714904ae0c46d8b21b86a (patch)
tree81c8ecd2a2f8161d91670f5325331ba1704c2ab7 /src/backend/utils/adt/regproc.c
parentc2d156691292d7be998eacf5b99dce3ea3c29ab2 (diff)
downloadpostgresql-f933766ba7c5446a28d714904ae0c46d8b21b86a.tar.gz
postgresql-f933766ba7c5446a28d714904ae0c46d8b21b86a.zip
Restructure pg_opclass, pg_amop, and pg_amproc per previous discussions in
pgsql-hackers. pg_opclass now has a row for each opclass supported by each index AM, not a row for each opclass name. This allows pg_opclass to show directly whether an AM supports an opclass, and furthermore makes it possible to store additional information about an opclass that might be AM-dependent. pg_opclass and pg_amop now store "lossy" and "haskeytype" information that we previously expected the user to remember to provide in CREATE INDEX commands. Lossiness is no longer an index-level property, but is associated with the use of a particular operator in a particular index opclass. Along the way, IndexSupportInitialize now uses the syscaches to retrieve pg_amop and pg_amproc entries. I find this reduces backend launch time by about ten percent, at the cost of a couple more special cases in catcache.c's IndexScanOK. Initial work by Oleg Bartunov and Teodor Sigaev, further hacking by Tom Lane. initdb forced.
Diffstat (limited to 'src/backend/utils/adt/regproc.c')
-rw-r--r--src/backend/utils/adt/regproc.c221
1 files changed, 77 insertions, 144 deletions
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index eb6ab3f4646..3ae65c6c8e5 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.62 2001/06/22 19:16:23 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.63 2001/08/21 16:36:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,12 +19,12 @@
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "catalog/pg_proc.h"
-#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/syscache.h"
+
/*****************************************************************************
* USER I/O ROUTINES *
*****************************************************************************/
@@ -32,126 +32,103 @@
/*
* regprocin - converts "proname" or "proid" to proid
*
+ * We need to accept an OID for cases where the name is ambiguous.
+ *
* proid of '-' signifies unknown, for consistency with regprocout
*/
Datum
regprocin(PG_FUNCTION_ARGS)
{
char *pro_name_or_oid = PG_GETARG_CSTRING(0);
- HeapTuple proctup;
- HeapTupleData tuple;
RegProcedure result = InvalidOid;
+ int matches = 0;
+ ScanKeyData skey[1];
if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '\0')
PG_RETURN_OID(InvalidOid);
- if (!IsIgnoringSystemIndexes())
+ if (pro_name_or_oid[0] >= '0' &&
+ pro_name_or_oid[0] <= '9')
{
+ Oid searchOid;
+
+ searchOid = DatumGetObjectId(DirectFunctionCall1(oidin,
+ CStringGetDatum(pro_name_or_oid)));
+ result = (RegProcedure) GetSysCacheOid(PROCOID,
+ ObjectIdGetDatum(searchOid),
+ 0, 0, 0);
+ if (!RegProcedureIsValid(result))
+ elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
+ matches = 1;
+ }
+ else if (!IsIgnoringSystemIndexes())
+ {
+ Relation hdesc;
+ Relation idesc;
+ IndexScanDesc sd;
+ RetrieveIndexResult indexRes;
+ HeapTupleData tuple;
+ Buffer buffer;
+
+ ScanKeyEntryInitialize(&skey[0], 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) F_NAMEEQ,
+ CStringGetDatum(pro_name_or_oid));
- /*
- * we need to use the oid because there can be multiple entries
- * with the same name. We accept int4eq_1323 and 1323.
- */
- if (pro_name_or_oid[0] >= '0' &&
- pro_name_or_oid[0] <= '9')
- {
- result = (RegProcedure)
- GetSysCacheOid(PROCOID,
- DirectFunctionCall1(oidin,
- CStringGetDatum(pro_name_or_oid)),
- 0, 0, 0);
- if (!RegProcedureIsValid(result))
- elog(ERROR, "No procedure with oid %s", pro_name_or_oid);
- }
- else
- {
- Relation hdesc;
- Relation idesc;
- IndexScanDesc sd;
- ScanKeyData skey[1];
- RetrieveIndexResult indexRes;
- Buffer buffer;
- int matches = 0;
-
- ScanKeyEntryInitialize(&skey[0],
- (bits16) 0x0,
- (AttrNumber) 1,
- (RegProcedure) F_NAMEEQ,
- CStringGetDatum(pro_name_or_oid));
-
- hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
- idesc = index_openr(ProcedureNameIndex);
+ hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
+ idesc = index_openr(ProcedureNameIndex);
+ sd = index_beginscan(idesc, false, 1, skey);
- sd = index_beginscan(idesc, false, 1, skey);
- while ((indexRes = index_getnext(sd, ForwardScanDirection)))
+ while ((indexRes = index_getnext(sd, ForwardScanDirection)))
+ {
+ tuple.t_datamcxt = NULL;
+ tuple.t_data = NULL;
+ tuple.t_self = indexRes->heap_iptr;
+ heap_fetch(hdesc, SnapshotNow, &tuple, &buffer, sd);
+ pfree(indexRes);
+ if (tuple.t_data != NULL)
{
- tuple.t_datamcxt = NULL;
- tuple.t_data = NULL;
- tuple.t_self = indexRes->heap_iptr;
- heap_fetch(hdesc, SnapshotNow,
- &tuple,
- &buffer,
- sd);
- pfree(indexRes);
- if (tuple.t_data != NULL)
- {
- result = (RegProcedure) tuple.t_data->t_oid;
- ReleaseBuffer(buffer);
-
- if (++matches > 1)
- break;
- }
+ result = (RegProcedure) tuple.t_data->t_oid;
+ ReleaseBuffer(buffer);
+ if (++matches > 1)
+ break;
}
-
- index_endscan(sd);
- index_close(idesc);
- heap_close(hdesc, AccessShareLock);
-
- if (matches > 1)
- elog(ERROR, "There is more than one procedure named %s.\n\tSupply the pg_proc oid inside single quotes.", pro_name_or_oid);
- else if (matches == 0)
- elog(ERROR, "No procedure with name %s", pro_name_or_oid);
}
+
+ index_endscan(sd);
+ index_close(idesc);
+ heap_close(hdesc, AccessShareLock);
}
else
{
Relation proc;
HeapScanDesc procscan;
- ScanKeyData key;
- bool isnull;
+ HeapTuple proctup;
- proc = heap_openr(ProcedureRelationName, AccessShareLock);
- ScanKeyEntryInitialize(&key,
- (bits16) 0,
- (AttrNumber) 1,
+ ScanKeyEntryInitialize(&skey[0], 0x0,
+ (AttrNumber) Anum_pg_proc_proname,
(RegProcedure) F_NAMEEQ,
CStringGetDatum(pro_name_or_oid));
- procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
- if (!HeapScanIsValid(procscan))
- {
- heap_close(proc, AccessShareLock);
- elog(ERROR, "regprocin: could not begin scan of %s",
- ProcedureRelationName);
- PG_RETURN_OID(InvalidOid);
- }
- proctup = heap_getnext(procscan, 0);
- if (HeapTupleIsValid(proctup))
+ proc = heap_openr(ProcedureRelationName, AccessShareLock);
+ procscan = heap_beginscan(proc, 0, SnapshotNow, 1, skey);
+
+ while (HeapTupleIsValid(proctup = heap_getnext(procscan, 0)))
{
- result = (RegProcedure) heap_getattr(proctup,
- ObjectIdAttributeNumber,
- RelationGetDescr(proc),
- &isnull);
- if (isnull)
- elog(ERROR, "regprocin: null procedure %s", pro_name_or_oid);
+ result = proctup->t_data->t_oid;
+ if (++matches > 1)
+ break;
}
- else
- elog(ERROR, "No procedure with name %s", pro_name_or_oid);
heap_endscan(procscan);
heap_close(proc, AccessShareLock);
}
+ if (matches > 1)
+ elog(ERROR, "There is more than one procedure named %s.\n\tSupply the pg_proc oid inside single quotes.", pro_name_or_oid);
+ else if (matches == 0)
+ elog(ERROR, "No procedure with name %s", pro_name_or_oid);
+
PG_RETURN_OID(result);
}
@@ -174,66 +151,22 @@ regprocout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result);
}
- if (!IsBootstrapProcessingMode())
- {
- proctup = SearchSysCache(PROCOID,
- ObjectIdGetDatum(proid),
- 0, 0, 0);
+ proctup = SearchSysCache(PROCOID,
+ ObjectIdGetDatum(proid),
+ 0, 0, 0);
- if (HeapTupleIsValid(proctup))
- {
- char *s;
+ if (HeapTupleIsValid(proctup))
+ {
+ char *s;
- s = NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname);
- StrNCpy(result, s, NAMEDATALEN);
- ReleaseSysCache(proctup);
- }
- else
- {
- result[0] = '-';
- result[1] = '\0';
- }
+ s = NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname);
+ StrNCpy(result, s, NAMEDATALEN);
+ ReleaseSysCache(proctup);
}
else
{
- Relation proc;
- HeapScanDesc procscan;
- ScanKeyData key;
-
- proc = heap_openr(ProcedureRelationName, AccessShareLock);
- ScanKeyEntryInitialize(&key,
- (bits16) 0,
- (AttrNumber) ObjectIdAttributeNumber,
- (RegProcedure) F_INT4EQ,
- ObjectIdGetDatum(proid));
-
- procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
- if (!HeapScanIsValid(procscan))
- {
- heap_close(proc, AccessShareLock);
- elog(ERROR, "regprocout: could not begin scan of %s",
- ProcedureRelationName);
- }
- proctup = heap_getnext(procscan, 0);
- if (HeapTupleIsValid(proctup))
- {
- char *s;
- bool isnull;
-
- s = (char *) heap_getattr(proctup, 1,
- RelationGetDescr(proc), &isnull);
- if (!isnull)
- StrNCpy(result, s, NAMEDATALEN);
- else
- elog(ERROR, "regprocout: null procedure %u", proid);
- }
- else
- {
- result[0] = '-';
- result[1] = '\0';
- }
- heap_endscan(procscan);
- heap_close(proc, AccessShareLock);
+ result[0] = '-';
+ result[1] = '\0';
}
PG_RETURN_CSTRING(result);