]> granicus.if.org Git - postgresql/blobdiff - src/backend/utils/cache/lsyscache.c
Create the planner mechanism for optimizing simple MIN and MAX queries
[postgresql] / src / backend / utils / cache / lsyscache.c
index 20c10802bc4346dfd99387f1f1ad054e9f690895..2c4d20576a5552da22c9e6912c261d646a711798 100644 (file)
@@ -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
- *       $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.
@@ -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
  *
@@ -465,6 +491,29 @@ get_opname(Oid opno)
                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
  *
@@ -749,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;
@@ -772,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;
@@ -1151,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
@@ -1165,7 +1263,7 @@ get_type_io_data(Oid typid,
                                 bool *typbyval,
                                 char *typalign,
                                 char *typdelim,
-                                Oid *typelem,
+                                Oid *typioparam,
                                 Oid *func)
 {
        HeapTuple       typeTuple;
@@ -1182,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:
@@ -1332,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,
@@ -1584,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;
@@ -1608,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);
 }
@@ -1619,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;
@@ -1644,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);
@@ -1656,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;
@@ -1680,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);
 }
@@ -1691,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;
@@ -1716,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);
@@ -1947,7 +2045,7 @@ get_namespace_name(Oid nspid)
 AclId
 get_usesysid(const char *username)
 {
-       int32           result;
+       AclId           userId;
        HeapTuple       userTup;
 
        userTup = SearchSysCache(SHADOWNAME,
@@ -1958,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;
+}
+