diff options
Diffstat (limited to 'src/backend/utils')
| -rw-r--r-- | src/backend/utils/adt/regproc.c | 221 | ||||
| -rw-r--r-- | src/backend/utils/cache/catcache.c | 17 | ||||
| -rw-r--r-- | src/backend/utils/cache/lsyscache.c | 72 | ||||
| -rw-r--r-- | src/backend/utils/cache/syscache.c | 39 | ||||
| -rw-r--r-- | src/backend/utils/sort/tuplesort.c | 58 |
5 files changed, 197 insertions, 210 deletions
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index eb6ab3f464..3ae65c6c8e 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); diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index f5f16e7718..ce4363706b 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.81 2001/06/22 19:16:23 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.82 2001/08/21 16:36:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #include "access/hash.h" #include "access/heapam.h" #include "access/valid.h" +#include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" #include "catalog/pg_type.h" #include "catalog/catname.h" @@ -812,7 +813,7 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey) sd = heap_beginscan(rel, false, SnapshotNow, 1, &key); ntp = heap_getnext(sd, 0); if (!HeapTupleIsValid(ntp)) - elog(ERROR, "SearchSelfReferences: %s not found in %s", + elog(ERROR, "IndexScanOK: %s not found in %s", IndexRelidIndex, RelationRelationName); indexSelfOid = ntp->t_data->t_oid; heap_endscan(sd); @@ -823,6 +824,16 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey) if (DatumGetObjectId(cur_skey[0].sk_argument) == indexSelfOid) return false; } + else if (cache->id == AMOPSTRATEGY || + cache->id == AMPROCNUM) + { + /* Looking for an OID or INT2 btree operator or function? */ + Oid lookup_oid = DatumGetObjectId(cur_skey[0].sk_argument); + + if (lookup_oid == OID_BTREE_OPS_OID || + lookup_oid == INT2_BTREE_OPS_OID) + return false; + } else if (cache->id == OPEROID) { /* Looking for an OID comparison function? */ @@ -858,7 +869,7 @@ SearchCatCache(CatCache *cache, MemoryContext oldcxt; /* - * one-time startup overhead + * one-time startup overhead for each cache */ if (cache->cc_tupdesc == NULL) CatalogCacheInitializeCache(cache); diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 587213d48f..1637abe999 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.56 2001/06/14 01:09:22 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.57 2001/08/21 16:36:05 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -16,6 +16,8 @@ #include "postgres.h" #include "access/tupmacs.h" +#include "catalog/pg_amop.h" +#include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" #include "catalog/pg_shadow.h" @@ -30,19 +32,48 @@ /* ---------- AMOP CACHES ---------- */ /* - * op_class + * op_in_opclass * - * Return t iff operator 'opno' is in operator class 'opclass' for - * access method 'amopid'. + * Return t iff operator 'opno' is in operator class 'opclass'. */ bool -op_class(Oid opno, Oid opclass, Oid amopid) +op_in_opclass(Oid opno, Oid opclass) { return SearchSysCacheExists(AMOPOPID, ObjectIdGetDatum(opclass), ObjectIdGetDatum(opno), - ObjectIdGetDatum(amopid), - 0); + 0, 0); +} + +/* + * op_requires_recheck + * + * Return t if operator 'opno' requires a recheck when used as a + * member of opclass 'opclass' (ie, this opclass is lossy for this + * operator). + * + * Caller should already have verified that opno is a member of opclass, + * therefore we raise an error if the tuple is not found. + */ +bool +op_requires_recheck(Oid opno, Oid opclass) +{ + HeapTuple tp; + Form_pg_amop amop_tup; + bool result; + + tp = SearchSysCache(AMOPOPID, + ObjectIdGetDatum(opclass), + ObjectIdGetDatum(opno), + 0, 0); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "op_requires_recheck: op %u is not a member of opclass %u", + opno, opclass); + amop_tup = (Form_pg_amop) GETSTRUCT(tp); + + result = amop_tup->amopreqcheck; + ReleaseSysCache(tp); + return result; } /* ---------- ATTRIBUTE CACHES ---------- */ @@ -222,6 +253,33 @@ get_atttypetypmod(Oid relid, AttrNumber attnum, /* watch this space... */ +/* ---------- OPCLASS CACHE ---------- */ + +/* + * opclass_is_btree + * + * Returns TRUE iff the specified opclass is associated with the + * btree index access method. + */ +bool +opclass_is_btree(Oid opclass) +{ + HeapTuple tp; + Form_pg_opclass cla_tup; + bool result; + + tp = SearchSysCache(CLAOID, + ObjectIdGetDatum(opclass), + 0, 0, 0); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for opclass %u", opclass); + cla_tup = (Form_pg_opclass) GETSTRUCT(tp); + + result = (cla_tup->opcamid == BTREE_AM_OID); + ReleaseSysCache(tp); + return result; +} + /* ---------- OPERATOR CACHE ---------- */ /* diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index a407d39f5d..6020597f2a 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.64 2001/08/10 18:57:37 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.65 2001/08/21 16:36:05 tgl Exp $ * * NOTES * These routines allow the parser/planner/executor to perform @@ -27,6 +27,7 @@ #include "catalog/indexing.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_amop.h" +#include "catalog/pg_amproc.h" #include "catalog/pg_group.h" #include "catalog/pg_index.h" #include "catalog/pg_inherits.h" @@ -113,23 +114,33 @@ static struct cachedesc cacheinfo[] = { 0 }}, {AccessMethodOperatorRelationName, /* AMOPOPID */ - AccessMethodOpidIndex, + AccessMethodOperatorIndex, 0, - 3, + 2, { Anum_pg_amop_amopclaid, Anum_pg_amop_amopopr, - Anum_pg_amop_amopid, + 0, 0 }}, {AccessMethodOperatorRelationName, /* AMOPSTRATEGY */ AccessMethodStrategyIndex, 0, - 3, + 2, { - Anum_pg_amop_amopid, Anum_pg_amop_amopclaid, Anum_pg_amop_amopstrategy, + 0, + 0 + }}, + {AccessMethodProcedureRelationName, /* AMPROCNUM */ + AccessMethodProcedureIndex, + 0, + 2, + { + Anum_pg_amproc_amopclaid, + Anum_pg_amproc_amprocnum, + 0, 0 }}, {AttributeRelationName, /* ATTNAME */ @@ -152,22 +163,22 @@ static struct cachedesc cacheinfo[] = { 0, 0 }}, - {OperatorClassRelationName, /* CLADEFTYPE */ - OpclassDeftypeIndex, + {OperatorClassRelationName, /* CLAAMNAME */ + OpclassAmNameIndex, 0, - 1, + 2, { - Anum_pg_opclass_opcdeftype, - 0, + Anum_pg_opclass_opcamid, + Anum_pg_opclass_opcname, 0, 0 }}, - {OperatorClassRelationName, /* CLANAME */ - OpclassNameIndex, + {OperatorClassRelationName, /* CLAOID */ + OpclassOidIndex, 0, 1, { - Anum_pg_opclass_opcname, + ObjectIdAttributeNumber, 0, 0, 0 diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 1391ea88c2..f4e2faaa2b 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -78,7 +78,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.17 2001/06/02 19:01:52 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.18 2001/08/21 16:36:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2055,7 +2055,7 @@ SelectSortFunction(Oid sortOperator, { Relation relation; HeapScanDesc scan; - ScanKeyData skey[3]; + ScanKeyData skey[1]; HeapTuple tuple; Form_pg_operator optup; Oid opclass = InvalidOid; @@ -2068,25 +2068,20 @@ SelectSortFunction(Oid sortOperator, * If the operator is registered the same way in multiple opclasses, * assume we can use the associated comparator function from any one. */ - relation = heap_openr(AccessMethodOperatorRelationName, - AccessShareLock); - - ScanKeyEntryInitialize(&skey[0], 0, - Anum_pg_amop_amopid, - F_OIDEQ, - ObjectIdGetDatum(BTREE_AM_OID)); - - ScanKeyEntryInitialize(&skey[1], 0, + ScanKeyEntryInitialize(&skey[0], 0x0, Anum_pg_amop_amopopr, F_OIDEQ, ObjectIdGetDatum(sortOperator)); - scan = heap_beginscan(relation, false, SnapshotNow, 2, skey); + relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock); + scan = heap_beginscan(relation, false, SnapshotNow, 1, skey); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) { Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple); + if (!opclass_is_btree(aform->amopclaid)) + continue; if (aform->amopstrategy == BTLessStrategyNumber) { opclass = aform->amopclaid; @@ -2107,39 +2102,18 @@ SelectSortFunction(Oid sortOperator, if (OidIsValid(opclass)) { /* Found a suitable opclass, get its comparator support function */ - relation = heap_openr(AccessMethodProcedureRelationName, - AccessShareLock); - - ScanKeyEntryInitialize(&skey[0], 0, - Anum_pg_amproc_amid, - F_OIDEQ, - ObjectIdGetDatum(BTREE_AM_OID)); - - ScanKeyEntryInitialize(&skey[1], 0, - Anum_pg_amproc_amopclaid, - F_OIDEQ, - ObjectIdGetDatum(opclass)); - - ScanKeyEntryInitialize(&skey[2], 0, - Anum_pg_amproc_amprocnum, - F_INT2EQ, - Int16GetDatum(BTORDER_PROC)); - - scan = heap_beginscan(relation, false, SnapshotNow, 3, skey); - - *sortFunction = InvalidOid; - - if (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) + tuple = SearchSysCache(AMPROCNUM, + ObjectIdGetDatum(opclass), + Int16GetDatum(BTORDER_PROC), + 0, 0); + if (HeapTupleIsValid(tuple)) { Form_pg_amproc aform = (Form_pg_amproc) GETSTRUCT(tuple); *sortFunction = aform->amproc; - } - - heap_endscan(scan); - heap_close(relation, AccessShareLock); - - if (RegProcedureIsValid(*sortFunction)) + ReleaseSysCache(tuple); + Assert(RegProcedureIsValid(*sortFunction)); return; + } } /* @@ -2158,7 +2132,7 @@ SelectSortFunction(Oid sortOperator, *kind = SORTFUNC_REVLT; else *kind = SORTFUNC_LT; - *sortFunction = optup->oprcode; + *sortFunction = optup->oprcode; ReleaseSysCache(tuple); Assert(RegProcedureIsValid(*sortFunction)); |
