* 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
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.110 2003/11/12 21:15:55 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.
#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"
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
*
return NULL;
}
+/*
+ * op_input_types
+ *
+ * Returns the left and right input datatypes for an operator
+ * (InvalidOid if not relevant).
+ */
+void
+op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
+{
+ HeapTuple tp;
+ Form_pg_operator optup;
+
+ tp = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tp)) /* shouldn't happen */
+ elog(ERROR, "cache lookup failed for operator %u", opno);
+ optup = (Form_pg_operator) GETSTRUCT(tp);
+ *lefttype = optup->oprleft;
+ *righttype = optup->oprright;
+ ReleaseSysCache(tp);
+}
+
/*
* op_mergejoinable
*
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;
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;
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
bool *typbyval,
char *typalign,
char *typdelim,
- Oid *typelem,
+ Oid *typioparam,
Oid *func)
{
HeapTuple typeTuple;
*typbyval = typeStruct->typbyval;
*typalign = typeStruct->typalign;
*typdelim = typeStruct->typdelim;
- *typelem = typeStruct->typelem;
+ *typioparam = getTypeIOParam(typeTuple);
switch (which_func)
{
case IOFunc_input:
/* 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,
* 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;
format_type_be(type))));
*typInput = pt->typinput;
- *typElem = pt->typelem;
+ *typIOParam = getTypeIOParam(typeTuple);
ReleaseSysCache(typeTuple);
}
* 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;
format_type_be(type))));
*typOutput = pt->typoutput;
- *typElem = pt->typelem;
+ *typIOParam = getTypeIOParam(typeTuple);
*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
ReleaseSysCache(typeTuple);
* 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;
format_type_be(type))));
*typReceive = pt->typreceive;
- *typElem = pt->typelem;
+ *typIOParam = getTypeIOParam(typeTuple);
ReleaseSysCache(typeTuple);
}
* 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;
format_type_be(type))));
*typSend = pt->typsend;
- *typElem = pt->typelem;
+ *typIOParam = getTypeIOParam(typeTuple);
*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
ReleaseSysCache(typeTuple);
AclId
get_usesysid(const char *username)
{
- int32 result;
+ AclId userId;
HeapTuple userTup;
userTup = SearchSysCache(SHADOWNAME,
(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;
+}
+