]> granicus.if.org Git - postgresql/commitdiff
Add missing SRF file.
authorBruce Momjian <bruce@momjian.us>
Thu, 20 Jun 2002 20:37:00 +0000 (20:37 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 20 Jun 2002 20:37:00 +0000 (20:37 +0000)
src/backend/utils/fmgr/funcapi.c [new file with mode: 0644]

diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
new file mode 100644 (file)
index 0000000..bd65c39
--- /dev/null
@@ -0,0 +1,122 @@
+/*-------------------------------------------------------------------------
+ *
+ * funcapi.c
+ *       Utility and convenience functions for fmgr functions that return
+ *       sets and/or composite types.
+ *
+ * Copyright (c) 2002, PostgreSQL Global Development Group
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "funcapi.h"
+#include "catalog/pg_type.h"
+#include "utils/syscache.h"
+
+/*
+ * init_MultiFuncCall
+ * Create an empty FuncCallContext data structure
+ * and do some other basic Multi-function call setup
+ * and error checking
+ */
+FuncCallContext *
+init_MultiFuncCall(PG_FUNCTION_ARGS)
+{
+       FuncCallContext *retval;
+
+       /*
+        * Bail if we're called in the wrong context
+        */
+       if (fcinfo->resultinfo == NULL || !IsA(fcinfo->resultinfo, ReturnSetInfo))
+               elog(ERROR, "function called in context that does not accept a set result");
+
+       if (fcinfo->flinfo->fn_extra == NULL)
+       {
+               /*
+                * First call
+                */
+               MemoryContext oldcontext;
+
+               /* switch to the appropriate memory context */
+               oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
+
+               /*
+                * allocate space and zero it
+                */
+               retval = (FuncCallContext *) palloc(sizeof(FuncCallContext));
+               MemSet(retval, 0, sizeof(FuncCallContext));
+
+               /*
+                * initialize the elements
+                */
+               retval->call_cntr = 0;
+               retval->max_calls = 0;
+               retval->slot = NULL;
+               retval->fctx = NULL;
+               retval->attinmeta = NULL;
+               retval->fmctx = fcinfo->flinfo->fn_mcxt;
+
+               /*
+                * save the pointer for cross-call use
+                */
+               fcinfo->flinfo->fn_extra = retval;
+
+               /* back to the original memory context */
+               MemoryContextSwitchTo(oldcontext);
+       }
+       else    /* second and subsequent calls */
+       {
+               elog(ERROR, "init_MultiFuncCall may not be called more than once");
+
+               /* never reached, but keep compiler happy */
+               retval = NULL;
+       }
+
+       return retval;
+}
+
+/*
+ * end_MultiFuncCall
+ * Clean up after init_MultiFuncCall
+ */
+void
+end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
+{
+       MemoryContext oldcontext;
+
+       /* unbind from fcinfo */
+       fcinfo->flinfo->fn_extra = NULL;
+
+       /*
+        * Caller is responsible to free up memory for individual
+        * struct elements other than att_in_funcinfo and elements.
+        */
+       oldcontext = MemoryContextSwitchTo(funcctx->fmctx);
+
+       if (funcctx->attinmeta != NULL)
+               pfree(funcctx->attinmeta);
+
+       pfree(funcctx);
+
+       MemoryContextSwitchTo(oldcontext);
+}
+
+void
+get_type_metadata(Oid typeid, Oid *attinfuncid, Oid *attelem)
+{
+       HeapTuple               typeTuple;
+       Form_pg_type    typtup;
+
+       typeTuple = SearchSysCache(TYPEOID,
+                                                          ObjectIdGetDatum(typeid),
+                                                          0, 0, 0);
+       if (!HeapTupleIsValid(typeTuple))
+               elog(ERROR, "get_type_metadata: Cache lookup of type %u failed", typeid);
+
+       typtup = (Form_pg_type) GETSTRUCT(typeTuple);
+
+       *attinfuncid = typtup->typinput;
+       *attelem = typtup->typelem;
+
+       ReleaseSysCache(typeTuple);
+}