X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=src%2Fbackend%2Futils%2Fcache%2Flsyscache.c;h=2c4d20576a5552da22c9e6912c261d646a711798;hb=addc42c339208d6a7a1d652fbf388e8aea7f80b9;hp=237cf97e6c70f68c8533b8ed6b46ff0f361605d4;hpb=7f8f7665fca489e171d9cce7e8c36a034c3da086;p=postgresql diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 237cf97e6c..2c4d20576a 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -3,11 +3,11 @@ * lsyscache.c * Convenience routines for common queries in the system catalog cache. * - * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.112 2003/12/03 17:45:09 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.123 2005/04/11 23:06:56 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -25,6 +25,7 @@ #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" #include "catalog/pg_shadow.h" +#include "catalog/pg_group.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" @@ -52,6 +53,31 @@ op_in_opclass(Oid opno, Oid opclass) 0, 0); } +/* + * get_op_opclass_strategy + * + * Get the operator's strategy number within the specified opclass, + * or 0 if it's not a member of the opclass. + */ +int +get_op_opclass_strategy(Oid opno, Oid opclass) +{ + HeapTuple tp; + Form_pg_amop amop_tup; + int result; + + tp = SearchSysCache(AMOPOPID, + ObjectIdGetDatum(opno), + ObjectIdGetDatum(opclass), + 0, 0); + if (!HeapTupleIsValid(tp)) + return 0; + amop_tup = (Form_pg_amop) GETSTRUCT(tp); + result = amop_tup->amopstrategy; + ReleaseSysCache(tp); + return result; +} + /* * get_op_opclass_properties * @@ -772,15 +798,36 @@ get_func_rettype(Oid funcid) return result; } +/* + * get_func_nargs + * Given procedure id, return the number of arguments. + */ +int +get_func_nargs(Oid funcid) +{ + HeapTuple tp; + int result; + + tp = SearchSysCache(PROCOID, + ObjectIdGetDatum(funcid), + 0, 0, 0); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for function %u", funcid); + + result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs; + ReleaseSysCache(tp); + return result; +} + /* * get_func_signature * Given procedure id, return the function's argument and result types. * (The return value is the result type.) * - * argtypes must point to a vector of size FUNC_MAX_ARGS. + * The arguments are returned as a palloc'd array. */ Oid -get_func_signature(Oid funcid, Oid *argtypes, int *nargs) +get_func_signature(Oid funcid, Oid **argtypes, int *nargs) { HeapTuple tp; Form_pg_proc procstruct; @@ -795,8 +842,10 @@ get_func_signature(Oid funcid, Oid *argtypes, int *nargs) procstruct = (Form_pg_proc) GETSTRUCT(tp); result = procstruct->prorettype; - memcpy(argtypes, procstruct->proargtypes, FUNC_MAX_ARGS * sizeof(Oid)); *nargs = (int) procstruct->pronargs; + Assert(*nargs == procstruct->proargtypes.dim1); + *argtypes = (Oid *) palloc(*nargs * sizeof(Oid)); + memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid)); ReleaseSysCache(tp); return result; @@ -1174,11 +1223,37 @@ get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, ReleaseSysCache(tp); } +/* + * getTypeIOParam + * Given a pg_type row, select the type OID to pass to I/O functions + * + * Formerly, all I/O functions were passed pg_type.typelem as their second + * parameter, but we now have a more complex rule about what to pass. + * This knowledge is intended to be centralized here --- direct references + * to typelem elsewhere in the code are wrong, if they are associated with + * I/O calls and not with actual subscripting operations! (But see + * bootstrap.c, which can't conveniently use this routine.) + */ +Oid +getTypeIOParam(HeapTuple typeTuple) +{ + Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple); + + /* + * Composite types get their own OID as parameter; array types get + * their typelem as parameter; everybody else gets zero. + */ + if (typeStruct->typtype == 'c') + return HeapTupleGetOid(typeTuple); + else + return typeStruct->typelem; +} + /* * get_type_io_data * * A six-fer: given the type OID, return typlen, typbyval, typalign, - * typdelim, typelem, and IO function OID. The IO function + * typdelim, typioparam, and IO function OID. The IO function * returned is controlled by IOFuncSelector */ void @@ -1188,7 +1263,7 @@ get_type_io_data(Oid typid, bool *typbyval, char *typalign, char *typdelim, - Oid *typelem, + Oid *typioparam, Oid *func) { HeapTuple typeTuple; @@ -1205,7 +1280,7 @@ get_type_io_data(Oid typid, *typbyval = typeStruct->typbyval; *typalign = typeStruct->typalign; *typdelim = typeStruct->typdelim; - *typelem = typeStruct->typelem; + *typioparam = getTypeIOParam(typeTuple); switch (which_func) { case IOFunc_input: @@ -1355,7 +1430,7 @@ get_typdefault(Oid typid) /* Convert C string to a value of the given type */ datum = OidFunctionCall3(type->typinput, CStringGetDatum(strDefaultVal), - ObjectIdGetDatum(type->typelem), + ObjectIdGetDatum(getTypeIOParam(typeTuple)), Int32GetDatum(-1)); /* Build a Const node containing the value */ expr = (Node *) makeConst(typid, @@ -1607,7 +1682,7 @@ get_array_type(Oid typid) * Get info needed for converting values of a type to internal form */ void -getTypeInputInfo(Oid type, Oid *typInput, Oid *typElem) +getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam) { HeapTuple typeTuple; Form_pg_type pt; @@ -1631,7 +1706,7 @@ getTypeInputInfo(Oid type, Oid *typInput, Oid *typElem) format_type_be(type)))); *typInput = pt->typinput; - *typElem = pt->typelem; + *typIOParam = getTypeIOParam(typeTuple); ReleaseSysCache(typeTuple); } @@ -1642,7 +1717,7 @@ getTypeInputInfo(Oid type, Oid *typInput, Oid *typElem) * Get info needed for printing values of a type */ void -getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typElem, +getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typIOParam, bool *typIsVarlena) { HeapTuple typeTuple; @@ -1667,7 +1742,7 @@ getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typElem, format_type_be(type)))); *typOutput = pt->typoutput; - *typElem = pt->typelem; + *typIOParam = getTypeIOParam(typeTuple); *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1); ReleaseSysCache(typeTuple); @@ -1679,7 +1754,7 @@ getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typElem, * Get info needed for binary input of values of a type */ void -getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typElem) +getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam) { HeapTuple typeTuple; Form_pg_type pt; @@ -1703,7 +1778,7 @@ getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typElem) format_type_be(type)))); *typReceive = pt->typreceive; - *typElem = pt->typelem; + *typIOParam = getTypeIOParam(typeTuple); ReleaseSysCache(typeTuple); } @@ -1714,7 +1789,7 @@ getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typElem) * Get info needed for binary output of values of a type */ void -getTypeBinaryOutputInfo(Oid type, Oid *typSend, Oid *typElem, +getTypeBinaryOutputInfo(Oid type, Oid *typSend, Oid *typIOParam, bool *typIsVarlena) { HeapTuple typeTuple; @@ -1739,7 +1814,7 @@ getTypeBinaryOutputInfo(Oid type, Oid *typSend, Oid *typElem, format_type_be(type)))); *typSend = pt->typsend; - *typElem = pt->typelem; + *typIOParam = getTypeIOParam(typeTuple); *typIsVarlena = (!pt->typbyval) && (pt->typlen == -1); ReleaseSysCache(typeTuple); @@ -1970,7 +2045,7 @@ get_namespace_name(Oid nspid) AclId get_usesysid(const char *username) { - int32 result; + AclId userId; HeapTuple userTup; userTup = SearchSysCache(SHADOWNAME, @@ -1981,9 +2056,39 @@ get_usesysid(const char *username) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("user \"%s\" does not exist", username))); - result = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid; + userId = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid; ReleaseSysCache(userTup); - return result; + return userId; } + +/* + * get_grosysid + * + * Given a group name, look up the group's sysid. + * Raises an error if no such group (rather than returning zero, + * which might possibly be a valid grosysid). + * + */ +AclId +get_grosysid(char *groname) +{ + AclId groupId; + HeapTuple groupTup; + + groupTup = SearchSysCache(GRONAME, + PointerGetDatum(groname), + 0, 0, 0); + if (!HeapTupleIsValid(groupTup)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("group \"%s\" does not exist", groname))); + + groupId = ((Form_pg_group) GETSTRUCT(groupTup))->grosysid; + + ReleaseSysCache(groupTup); + + return groupId; +} +