]> granicus.if.org Git - postgresql/commitdiff
Here is a patch for Composite and Set returning function support. I made
authorBruce Momjian <bruce@momjian.us>
Thu, 20 Jun 2002 17:19:08 +0000 (17:19 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 20 Jun 2002 17:19:08 +0000 (17:19 +0000)
two small changes to the API since last patch, which hopefully completes
the decoupling of composite function support from SRF specific support.

Joe Conway

src/backend/access/common/tupdesc.c
src/backend/executor/execTuples.c
src/backend/utils/adt/regproc.c
src/backend/utils/fmgr/Makefile
src/include/utils/builtins.h

index 605ffb1bed7960b33cba4377ae8936ba7dcd8710..8bd1d7b529995bd0be994709e584f35419c37696 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.78 2002/03/29 19:05:59 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.79 2002/06/20 17:19:08 momjian Exp $
  *
  * NOTES
  *       some of the executor utility code such as "ExecTypeFromTL" should be
@@ -19,6 +19,9 @@
 
 #include "postgres.h"
 
+#include "funcapi.h"
+#include "access/heapam.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_type.h"
 #include "nodes/parsenodes.h"
 #include "parser/parse_type.h"
@@ -549,3 +552,109 @@ BuildDescForRelation(List *schema)
        }
        return desc;
 }
+
+
+/*
+ * RelationNameGetTupleDesc
+ *
+ * Given a (possibly qualified) relation name, build a TupleDesc.
+ */
+TupleDesc
+RelationNameGetTupleDesc(char *relname)
+{
+       RangeVar   *relvar;
+       Relation        rel;
+       TupleDesc       tupdesc;
+       List       *relname_list;
+
+       /* Open relation and get the tuple description */
+       relname_list = stringToQualifiedNameList(relname, "RelationNameGetTupleDesc");
+       relvar = makeRangeVarFromNameList(relname_list);
+       rel = heap_openrv(relvar, AccessShareLock);
+       tupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
+       relation_close(rel, AccessShareLock);
+
+       return tupdesc;
+}
+
+/*
+ * TypeGetTupleDesc
+ *
+ * Given a type Oid, build a TupleDesc.
+ *
+ * If the type is composite, *and* a colaliases List is provided, *and*
+ * the List is of natts length, use the aliases instead of the relation
+ * attnames.
+ *
+ * If the type is a base type, a single item alias List is required.
+ */
+TupleDesc
+TypeGetTupleDesc(Oid typeoid, List *colaliases)
+{
+       Oid                     relid = typeidTypeRelid(typeoid);
+       TupleDesc       tupdesc;
+
+       /*
+        * Build a suitable tupledesc representing the output rows
+        */
+       if (OidIsValid(relid))
+       {
+               /* Composite data type, i.e. a table's row type */
+               Relation        rel;
+               int                     natts;
+
+               rel = relation_open(relid, AccessShareLock);
+               tupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
+               natts = tupdesc->natts;
+               relation_close(rel, AccessShareLock);
+
+               /* check to see if we've given column aliases */
+               if(colaliases != NIL)
+               {
+                       char       *label;
+                       int                     varattno;
+
+                       /* does the List length match the number of attributes */
+                       if (length(colaliases) != natts)
+                               elog(ERROR, "TypeGetTupleDesc: number of aliases does not match number of attributes");
+
+                       /* OK, use the aliases instead */
+                       for (varattno = 0; varattno < natts; varattno++)
+                       {
+                               label = strVal(nth(varattno, colaliases));
+
+                               if (label != NULL)
+                                       namestrcpy(&(tupdesc->attrs[varattno]->attname), label);
+                               else
+                                       MemSet(NameStr(tupdesc->attrs[varattno]->attname), 0, NAMEDATALEN);
+                       }
+               }
+       }
+       else
+       {
+               /* Must be a base data type, i.e. scalar */
+               char       *attname;
+
+               /* the alias List is required for base types */
+               if (colaliases == NIL)
+                       elog(ERROR, "TypeGetTupleDesc: no column alias was provided");
+
+               /* the alias List length must be 1 */
+               if (length(colaliases) != 1)
+                       elog(ERROR, "TypeGetTupleDesc: number of aliases does not match number of attributes");
+
+               /* OK, get the column alias */
+               attname = strVal(lfirst(colaliases));
+
+               tupdesc = CreateTemplateTupleDesc(1);
+               TupleDescInitEntry(tupdesc,
+                                                  (AttrNumber) 1,
+                                                  attname,
+                                                  typeoid,
+                                                  -1,
+                                                  0,
+                                                  false);
+       }
+
+       return tupdesc;
+}
index 504876e738fff656f39a6bb6ace61f6918b6eee4..85efe1d69fde9f92e5e4d1535b3e9269d6afdd35 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.51 2002/03/21 06:21:04 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.52 2002/06/20 17:19:08 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
  */
 #include "postgres.h"
 
+#include "funcapi.h"
 #include "access/heapam.h"
 #include "catalog/pg_type.h"
 #include "executor/executor.h"
 
-
 /* ----------------------------------------------------------------
  *                               tuple table create/delete functions
  * ----------------------------------------------------------------
@@ -673,3 +673,123 @@ ExecTypeFromTL(List *targetList)
 
        return typeInfo;
 }
+
+/*
+ * TupleDescGetSlot - Initialize a slot based on the supplied
+ * tupledesc
+ */
+TupleTableSlot *
+TupleDescGetSlot(TupleDesc tupdesc)
+{
+       TupleTableSlot     *slot;
+
+       /* Make a standalone slot */
+       slot = MakeTupleTableSlot();
+
+       /* Bind the tuple description to the slot */
+       ExecSetSlotDescriptor(slot, tupdesc, true);
+
+       /* Return the slot */
+       return slot;
+}
+
+/*
+ * TupleDescGetAttInMetadata - Get a pointer to AttInMetadata based on the
+ * supplied TupleDesc. AttInMetadata can be used in conjunction with C strings
+ * to produce a properly formed tuple.
+ */
+AttInMetadata *
+TupleDescGetAttInMetadata(TupleDesc tupdesc)
+{
+       int                             natts;
+       int                             i;
+       Oid                             atttypeid;
+       Oid                             attinfuncid;
+       Oid                             attelem;
+       FmgrInfo           *attinfuncinfo;
+       Oid                        *attelems;
+       int4               *atttypmods;
+       AttInMetadata  *attinmeta;
+
+       attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
+       natts = tupdesc->natts;
+
+       /*
+        * Gather info needed later to call the "in" function for each attribute
+        */
+       attinfuncinfo = (FmgrInfo *) palloc(natts * sizeof(FmgrInfo));
+       attelems = (Oid *) palloc(natts * sizeof(Oid));
+       atttypmods = (int4 *) palloc(natts * sizeof(int4));
+
+       for (i = 0; i < natts; i++)
+       {
+               atttypeid = tupdesc->attrs[i]->atttypid;
+               get_type_metadata(atttypeid, &attinfuncid, &attelem);
+
+               fmgr_info(attinfuncid, &attinfuncinfo[i]);
+               attelems[i] = attelem;
+               atttypmods[i] = tupdesc->attrs[i]->atttypmod;
+       }
+       attinmeta->tupdesc = tupdesc;
+       attinmeta->attinfuncs = attinfuncinfo;
+       attinmeta->attelems = attelems;
+       attinmeta->atttypmods = atttypmods;
+
+       return attinmeta;
+}
+
+/*
+ * BuildTupleFromCStrings - build a HeapTuple given user data in C string form.
+ * values is an array of C strings, one for each attribute of the return tuple.
+ */
+HeapTuple
+BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
+{
+       TupleDesc                       tupdesc;
+       int                                     natts;
+       HeapTuple                       tuple;
+       char                       *nulls;
+       int                                     i;
+       Datum                      *dvalues;
+       FmgrInfo                        attinfuncinfo;
+       Oid                                     attelem;
+       int4                            atttypmod;
+
+       tupdesc = attinmeta->tupdesc;
+       natts = tupdesc->natts;
+
+       dvalues = (Datum *) palloc(natts * sizeof(Datum));
+
+       /* Call the "in" function for each attribute */
+       for (i = 0; i < natts; i++)
+       {
+               if (values[i] != NULL)
+               {
+                       attinfuncinfo = attinmeta->attinfuncs[i];
+                       attelem = attinmeta->attelems[i];
+                       atttypmod = attinmeta->atttypmods[i];
+
+                       dvalues[i] = FunctionCall3(&attinfuncinfo, CStringGetDatum(values[i]),
+                                                                               ObjectIdGetDatum(attelem),
+                                                                               Int32GetDatum(atttypmod));
+               }
+               else
+                       dvalues[i] = PointerGetDatum(NULL);
+       }
+
+       /*
+        * Form a tuple
+        */
+       nulls = (char *) palloc(natts * sizeof(char));
+       for (i = 0; i < natts; i++)
+       {
+               if (DatumGetPointer(dvalues[i]) != NULL)
+                       nulls[i] = ' ';
+               else
+                       nulls[i] = 'n';
+       }
+       tuple = heap_formtuple(tupdesc, dvalues, nulls);
+
+       return tuple;
+}
+
index f9de2677969d9a8a506f2f80a49642c52d4c5744..0858d63f60ba268f8ce0a50b39847f73553a96fa 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.68 2002/05/11 00:24:16 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.69 2002/06/20 17:19:08 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -37,8 +37,6 @@
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
 
-
-static List *stringToQualifiedNameList(const char *string, const char *caller);
 static void parseNameAndArgTypes(const char *string, const char *caller,
                                                                 const char *type0_spelling,
                                                                 List **names, int *nargs, Oid *argtypes);
@@ -960,14 +958,10 @@ regtypeout(PG_FUNCTION_ARGS)
 }
 
 
-/*****************************************************************************
- *      SUPPORT ROUTINES                                                                                                                *
- *****************************************************************************/
-
 /*
  * Given a C string, parse it into a qualified-name list.
  */
-static List *
+List *
 stringToQualifiedNameList(const char *string, const char *caller)
 {
        char       *rawname;
@@ -997,6 +991,10 @@ stringToQualifiedNameList(const char *string, const char *caller)
        return result;
 }
 
+/*****************************************************************************
+ *      SUPPORT ROUTINES                                                                                                                *
+ *****************************************************************************/
+
 /*
  * Given a C string, parse it into a qualified function or operator name
  * followed by a parenthesized list of type names.  Reduce the
index ad96b1717db0b988e6e6fefa6369ba7ca473ac73..13dd9110292d22c18ae7d58ac8fb2885f214c7cf 100644 (file)
@@ -4,7 +4,7 @@
 #    Makefile for utils/fmgr
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/utils/fmgr/Makefile,v 1.12 2001/09/16 16:11:11 petere Exp $
+#    $Header: /cvsroot/pgsql/src/backend/utils/fmgr/Makefile,v 1.13 2002/06/20 17:19:08 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -12,7 +12,7 @@ subdir = src/backend/utils/fmgr
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-OBJS = dfmgr.o fmgr.o
+OBJS = dfmgr.o fmgr.o funcapi.o
 
 override CPPFLAGS += -DPKGLIBDIR=\"$(pkglibdir)\" -DDLSUFFIX=\"$(DLSUFFIX)\"
 
index 28ab44ce68b3b3a5e549044e8aa3ecc0f3c78e68..898f3b6047dd58a9b8f5e3f23b8106dbae4d0410 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: builtins.h,v 1.184 2002/06/13 03:40:49 tgl Exp $
+ * $Id: builtins.h,v 1.185 2002/06/20 17:19:08 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -342,6 +342,7 @@ extern Datum regclassin(PG_FUNCTION_ARGS);
 extern Datum regclassout(PG_FUNCTION_ARGS);
 extern Datum regtypein(PG_FUNCTION_ARGS);
 extern Datum regtypeout(PG_FUNCTION_ARGS);
+extern List *stringToQualifiedNameList(const char *string, const char *caller);
 
 /* ruleutils.c */
 extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);