summaryrefslogtreecommitdiff
path: root/src/backend/utils/fmgr
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/fmgr')
-rw-r--r--src/backend/utils/fmgr/dfmgr.c441
-rw-r--r--src/backend/utils/fmgr/fmgr.c390
2 files changed, 437 insertions, 394 deletions
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 079c9d0a17..0be7524290 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* dfmgr.c--
- * Dynamic function manager code.
+ * Dynamic function manager code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.9 1997/09/01 08:06:17 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.10 1997/09/07 04:53:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,15 +18,15 @@
#include "postgres.h"
-#include "config.h" /* for MAXPATHLEN */
-#include "fmgr.h" /* generated by Gen_fmgrtab.sh */
+#include "config.h" /* for MAXPATHLEN */
+#include "fmgr.h" /* generated by Gen_fmgrtab.sh */
#include "utils/dynamic_loader.h"
#include "utils/elog.h"
#include "utils/builtins.h"
#include "access/heapam.h"
#include "nodes/pg_list.h"
-#include "port-protos.h" /* system specific function prototypes */
+#include "port-protos.h" /* system specific function prototypes */
#ifdef __ultrix
#include <dl.h>
#endif
@@ -39,178 +39,197 @@ static DynamicFileList *file_list = (DynamicFileList *) NULL;
static DynamicFileList *file_tail = (DynamicFileList *) NULL;
#define NOT_EQUAL(A, B) (((A).st_ino != (B).inode) \
- || ((A).st_dev != (B).device))
+ || ((A).st_dev != (B).device))
-static Oid procedureId_save = -1;
-static int pronargs_save;
+static Oid procedureId_save = -1;
+static int pronargs_save;
static func_ptr user_fn_save = (func_ptr) NULL;
static func_ptr handle_load(char *filename, char *funcname);
-func_ptr trigger_dynamic (char *filename, char *funcname);
+func_ptr trigger_dynamic(char *filename, char *funcname);
func_ptr
fmgr_dynamic(Oid procedureId, int *pronargs)
{
- HeapTuple procedureTuple;
- Form_pg_proc procedureStruct;
- char *proname;
- char *probinattr, *probinstring;
- func_ptr user_fn;
- Relation rdesc;
- bool isnull;
-
- if (procedureId == procedureId_save) {
- *pronargs = pronargs_save;
- return(user_fn_save);
- }
-
- /*
- * The procedure isn't a builtin, so we'll have to do a catalog
- * lookup to find its pg_proc entry.
- */
- procedureTuple = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(procedureId),
- 0,0,0);
- if (!HeapTupleIsValid(procedureTuple)) {
- elog(WARN, "fmgr: Cache lookup failed for procedure %d\n",
- procedureId);
- return((func_ptr) NULL);
- }
-
- procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
- proname = procedureStruct->proname.data;
- pronargs_save = *pronargs = procedureStruct->pronargs;
-
- /*
- * Extract the procedure info from the pg_proc tuple.
- * Since probin is varlena, do a amgetattr() on the procedure
- * tuple. To do that, we need the rdesc for the procedure
- * relation, so...
- */
-
- /* open pg_procedure */
-
- rdesc = heap_openr(ProcedureRelationName);
- if (!RelationIsValid(rdesc)) {
- elog(WARN, "fmgr: Could not open relation %s",
- ProcedureRelationName);
- return((func_ptr) NULL);
- }
- probinattr = heap_getattr(procedureTuple, (Buffer) 0,
- Anum_pg_proc_probin,
- RelationGetTupleDescriptor(rdesc), &isnull);
- if (!PointerIsValid(probinattr) /*|| isnull*/) {
- heap_close(rdesc);
- elog(WARN, "fmgr: Could not extract probin for %d from %s",
- procedureId, ProcedureRelationName);
- return((func_ptr) NULL);
- }
- probinstring = textout((struct varlena *) probinattr);
-
- user_fn = handle_load(probinstring, proname);
-
- procedureId_save = procedureId;
- user_fn_save = user_fn;
-
- return(user_fn);
+ HeapTuple procedureTuple;
+ Form_pg_proc procedureStruct;
+ char *proname;
+ char *probinattr,
+ *probinstring;
+ func_ptr user_fn;
+ Relation rdesc;
+ bool isnull;
+
+ if (procedureId == procedureId_save)
+ {
+ *pronargs = pronargs_save;
+ return (user_fn_save);
+ }
+
+ /*
+ * The procedure isn't a builtin, so we'll have to do a catalog lookup
+ * to find its pg_proc entry.
+ */
+ procedureTuple = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(procedureId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(procedureTuple))
+ {
+ elog(WARN, "fmgr: Cache lookup failed for procedure %d\n",
+ procedureId);
+ return ((func_ptr) NULL);
+ }
+
+ procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
+ proname = procedureStruct->proname.data;
+ pronargs_save = *pronargs = procedureStruct->pronargs;
+
+ /*
+ * Extract the procedure info from the pg_proc tuple. Since probin is
+ * varlena, do a amgetattr() on the procedure tuple. To do that, we
+ * need the rdesc for the procedure relation, so...
+ */
+
+ /* open pg_procedure */
+
+ rdesc = heap_openr(ProcedureRelationName);
+ if (!RelationIsValid(rdesc))
+ {
+ elog(WARN, "fmgr: Could not open relation %s",
+ ProcedureRelationName);
+ return ((func_ptr) NULL);
+ }
+ probinattr = heap_getattr(procedureTuple, (Buffer) 0,
+ Anum_pg_proc_probin,
+ RelationGetTupleDescriptor(rdesc), &isnull);
+ if (!PointerIsValid(probinattr) /* || isnull */ )
+ {
+ heap_close(rdesc);
+ elog(WARN, "fmgr: Could not extract probin for %d from %s",
+ procedureId, ProcedureRelationName);
+ return ((func_ptr) NULL);
+ }
+ probinstring = textout((struct varlena *) probinattr);
+
+ user_fn = handle_load(probinstring, proname);
+
+ procedureId_save = procedureId;
+ user_fn_save = user_fn;
+
+ return (user_fn);
}
-static func_ptr
+static func_ptr
handle_load(char *filename, char *funcname)
{
- DynamicFileList *file_scanner = (DynamicFileList *) NULL;
- func_ptr retval = (func_ptr) NULL;
- char *load_error;
- struct stat stat_buf;
-
- /*
- * Do this because loading files may screw up the dynamic function
- * manager otherwise.
- */
- procedureId_save = -1;
-
- /*
- * Scan the list of loaded FILES to see if the function
- * has been loaded.
- */
-
- if (filename != (char *) NULL) {
- for (file_scanner = file_list;
- file_scanner != (DynamicFileList *) NULL
- && file_scanner->filename != (char *) NULL
- && strcmp(filename, file_scanner->filename) != 0;
- file_scanner = file_scanner->next)
- ;
- if (file_scanner == (DynamicFileList *) NULL) {
- if (stat(filename, &stat_buf) == -1) {
- elog(WARN, "stat failed on file %s", filename);
- }
-
- for (file_scanner = file_list;
- file_scanner != (DynamicFileList *) NULL
- && (NOT_EQUAL(stat_buf, *file_scanner));
- file_scanner = file_scanner->next)
- ;
- /*
- * Same files - different paths (ie, symlink or link)
- */
- if (file_scanner != (DynamicFileList *) NULL)
- strcpy(file_scanner->filename, filename);
-
- }
- } else {
- file_scanner = (DynamicFileList *) NULL;
- }
-
- /*
- * File not loaded yet.
- */
-
- if (file_scanner == (DynamicFileList *) NULL) {
- if (file_list == (DynamicFileList *) NULL) {
- file_list = (DynamicFileList *)
- malloc(sizeof(DynamicFileList));
- file_scanner = file_list;
- } else {
- file_tail->next = (DynamicFileList *)
- malloc(sizeof(DynamicFileList));
- file_scanner = file_tail->next;
- }
- memset((char *) file_scanner, 0, sizeof(DynamicFileList));
-
- strcpy(file_scanner->filename, filename);
- file_scanner->device = stat_buf.st_dev;
- file_scanner->inode = stat_buf.st_ino;
- file_scanner->next = (DynamicFileList *) NULL;
-
- file_scanner->handle = pg_dlopen(filename);
- if (file_scanner->handle == (void *)NULL) {
- load_error = (char *) pg_dlerror();
- if (file_scanner == file_list) {
- file_list = (DynamicFileList *) NULL;
- } else {
- file_tail->next = (DynamicFileList *) NULL;
- }
-
- free((char *) file_scanner);
- elog(WARN, "Load of file %s failed: %s", filename, load_error);
- }
-
+ DynamicFileList *file_scanner = (DynamicFileList *) NULL;
+ func_ptr retval = (func_ptr) NULL;
+ char *load_error;
+ struct stat stat_buf;
+
+ /*
+ * Do this because loading files may screw up the dynamic function
+ * manager otherwise.
+ */
+ procedureId_save = -1;
+
/*
- * Just load the file - we are done with that so return.
+ * Scan the list of loaded FILES to see if the function has been
+ * loaded.
*/
- file_tail = file_scanner;
-
- if (funcname == (char *) NULL)
- return((func_ptr) NULL);
- }
-
- retval = (func_ptr) pg_dlsym(file_scanner->handle, funcname);
-
- if (retval == (func_ptr) NULL) {
- elog(WARN, "Can't find function %s in file %s", funcname, filename);
- }
-
- return(retval);
+
+ if (filename != (char *) NULL)
+ {
+ for (file_scanner = file_list;
+ file_scanner != (DynamicFileList *) NULL
+ && file_scanner->filename != (char *) NULL
+ && strcmp(filename, file_scanner->filename) != 0;
+ file_scanner = file_scanner->next)
+ ;
+ if (file_scanner == (DynamicFileList *) NULL)
+ {
+ if (stat(filename, &stat_buf) == -1)
+ {
+ elog(WARN, "stat failed on file %s", filename);
+ }
+
+ for (file_scanner = file_list;
+ file_scanner != (DynamicFileList *) NULL
+ && (NOT_EQUAL(stat_buf, *file_scanner));
+ file_scanner = file_scanner->next)
+ ;
+
+ /*
+ * Same files - different paths (ie, symlink or link)
+ */
+ if (file_scanner != (DynamicFileList *) NULL)
+ strcpy(file_scanner->filename, filename);
+
+ }
+ }
+ else
+ {
+ file_scanner = (DynamicFileList *) NULL;
+ }
+
+ /*
+ * File not loaded yet.
+ */
+
+ if (file_scanner == (DynamicFileList *) NULL)
+ {
+ if (file_list == (DynamicFileList *) NULL)
+ {
+ file_list = (DynamicFileList *)
+ malloc(sizeof(DynamicFileList));
+ file_scanner = file_list;
+ }
+ else
+ {
+ file_tail->next = (DynamicFileList *)
+ malloc(sizeof(DynamicFileList));
+ file_scanner = file_tail->next;
+ }
+ memset((char *) file_scanner, 0, sizeof(DynamicFileList));
+
+ strcpy(file_scanner->filename, filename);
+ file_scanner->device = stat_buf.st_dev;
+ file_scanner->inode = stat_buf.st_ino;
+ file_scanner->next = (DynamicFileList *) NULL;
+
+ file_scanner->handle = pg_dlopen(filename);
+ if (file_scanner->handle == (void *) NULL)
+ {
+ load_error = (char *) pg_dlerror();
+ if (file_scanner == file_list)
+ {
+ file_list = (DynamicFileList *) NULL;
+ }
+ else
+ {
+ file_tail->next = (DynamicFileList *) NULL;
+ }
+
+ free((char *) file_scanner);
+ elog(WARN, "Load of file %s failed: %s", filename, load_error);
+ }
+
+ /*
+ * Just load the file - we are done with that so return.
+ */
+ file_tail = file_scanner;
+
+ if (funcname == (char *) NULL)
+ return ((func_ptr) NULL);
+ }
+
+ retval = (func_ptr) pg_dlsym(file_scanner->handle, funcname);
+
+ if (retval == (func_ptr) NULL)
+ {
+ elog(WARN, "Can't find function %s in file %s", funcname, filename);
+ }
+
+ return (retval);
}
/*
@@ -218,7 +237,7 @@ handle_load(char *filename, char *funcname)
*
* If the file is already loaded:
* o Zero out that file's loaded space (so it doesn't screw up linking)
- * o Free all space associated with that file
+ * o Free all space associated with that file
* o Free that file's descriptor.
*
* Now load the file by calling handle_load with a NULL argument as the
@@ -227,49 +246,61 @@ handle_load(char *filename, char *funcname)
void
load_file(char *filename)
{
- DynamicFileList *file_scanner, *p;
- struct stat stat_buf;
-
- int done = 0;
-
- if (stat(filename, &stat_buf) == -1) {
- elog(WARN, "stat failed on file %s", filename);
- }
-
- if (file_list != (DynamicFileList *) NULL
- && !NOT_EQUAL(stat_buf, *file_list)) {
- file_scanner = file_list;
- file_list = file_list->next;
- pg_dlclose(file_scanner->handle);
- free((char *) file_scanner);
- } else if (file_list != (DynamicFileList *) NULL) {
- file_scanner = file_list;
- while (!done) {
- if (file_scanner->next == (DynamicFileList *) NULL) {
- done = 1;
- } else if (!NOT_EQUAL(stat_buf, *(file_scanner->next))) {
- done = 1;
- } else {
- file_scanner = file_scanner->next;
- }
- }
-
- if (file_scanner->next != (DynamicFileList *) NULL) {
- p = file_scanner->next;
- file_scanner->next = file_scanner->next->next;
- pg_dlclose(file_scanner->handle);
- free((char *)p);
- }
- }
- handle_load(filename, (char *) NULL);
+ DynamicFileList *file_scanner,
+ *p;
+ struct stat stat_buf;
+
+ int done = 0;
+
+ if (stat(filename, &stat_buf) == -1)
+ {
+ elog(WARN, "stat failed on file %s", filename);
+ }
+
+ if (file_list != (DynamicFileList *) NULL
+ && !NOT_EQUAL(stat_buf, *file_list))
+ {
+ file_scanner = file_list;
+ file_list = file_list->next;
+ pg_dlclose(file_scanner->handle);
+ free((char *) file_scanner);
+ }
+ else if (file_list != (DynamicFileList *) NULL)
+ {
+ file_scanner = file_list;
+ while (!done)
+ {
+ if (file_scanner->next == (DynamicFileList *) NULL)
+ {
+ done = 1;
+ }
+ else if (!NOT_EQUAL(stat_buf, *(file_scanner->next)))
+ {
+ done = 1;
+ }
+ else
+ {
+ file_scanner = file_scanner->next;
+ }
+ }
+
+ if (file_scanner->next != (DynamicFileList *) NULL)
+ {
+ p = file_scanner->next;
+ file_scanner->next = file_scanner->next->next;
+ pg_dlclose(file_scanner->handle);
+ free((char *) p);
+ }
+ }
+ handle_load(filename, (char *) NULL);
}
func_ptr
-trigger_dynamic (char *filename, char *funcname)
+trigger_dynamic(char *filename, char *funcname)
{
- func_ptr trigger_fn;
-
- trigger_fn = handle_load (filename, funcname);
-
- return (trigger_fn);
+ func_ptr trigger_fn;
+
+ trigger_fn = handle_load(filename, funcname);
+
+ return (trigger_fn);
}
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 1da0ab1877..f7d7b29d0a 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* fmgr.c--
- * Interface routines for the table-driven function manager.
+ * Interface routines for the table-driven function manager.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.3 1997/08/19 21:35:21 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.4 1997/09/07 04:53:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include "postgres.h"
/* these 2 files are generated by Gen_fmgrtab.sh; contain the declarations */
-#include "fmgr.h"
+#include "fmgr.h"
#include "utils/fmgrtab.h"
#include "nodes/pg_list.h"
@@ -29,173 +29,183 @@
#include "utils/elog.h"
-char *
+char *
fmgr_c(func_ptr user_fn,
- Oid func_id,
- int n_arguments,
- FmgrValues *values,
- bool *isNull)
+ Oid func_id,
+ int n_arguments,
+ FmgrValues * values,
+ bool * isNull)
{
- char *returnValue = (char *) NULL;
+ char *returnValue = (char *) NULL;
-
- if (user_fn == (func_ptr) NULL) {
- /*
- * a NULL func_ptr denotes untrusted function (in postgres 4.2).
- * Untrusted functions have very limited use and is clumsy. We
- * just get rid of it.
- */
- elog(WARN, "internal error: untrusted function not supported.");
- }
-
- switch (n_arguments) {
- case 0:
- returnValue = (*user_fn)();
- break;
- case 1:
- /* NullValue() uses isNull to check if args[0] is NULL */
- returnValue = (*user_fn)(values->data[0], isNull);
- break;
- case 2:
- returnValue = (*user_fn)(values->data[0], values->data[1]);
- break;
- case 3:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2]);
- break;
- case 4:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3]);
- break;
- case 5:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4]);
- break;
- case 6:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4], values->data[5]);
- break;
- case 7:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4], values->data[5],
- values->data[6]);
- break;
- case 8:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4], values->data[5],
- values->data[6], values->data[7]);
- break;
- case 9:
- /*
- * XXX Note that functions with >8 arguments can only be
- * called from inside the system, not from the user level,
- * since the catalogs only store 8 argument types for user
- * type-checking!
- */
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4], values->data[5],
- values->data[6], values->data[7],
- values->data[8]);
- break;
- default:
- elog(WARN, "fmgr_c: function %d: too many arguments (%d > %d)",
- func_id, n_arguments, MAXFMGRARGS);
- break;
- }
- return(returnValue);
+
+ if (user_fn == (func_ptr) NULL)
+ {
+
+ /*
+ * a NULL func_ptr denotes untrusted function (in postgres 4.2).
+ * Untrusted functions have very limited use and is clumsy. We
+ * just get rid of it.
+ */
+ elog(WARN, "internal error: untrusted function not supported.");
+ }
+
+ switch (n_arguments)
+ {
+ case 0:
+ returnValue = (*user_fn) ();
+ break;
+ case 1:
+ /* NullValue() uses isNull to check if args[0] is NULL */
+ returnValue = (*user_fn) (values->data[0], isNull);
+ break;
+ case 2:
+ returnValue = (*user_fn) (values->data[0], values->data[1]);
+ break;
+ case 3:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2]);
+ break;
+ case 4:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3]);
+ break;
+ case 5:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4]);
+ break;
+ case 6:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4], values->data[5]);
+ break;
+ case 7:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4], values->data[5],
+ values->data[6]);
+ break;
+ case 8:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4], values->data[5],
+ values->data[6], values->data[7]);
+ break;
+ case 9:
+
+ /*
+ * XXX Note that functions with >8 arguments can only be called
+ * from inside the system, not from the user level, since the
+ * catalogs only store 8 argument types for user type-checking!
+ */
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4], values->data[5],
+ values->data[6], values->data[7],
+ values->data[8]);
+ break;
+ default:
+ elog(WARN, "fmgr_c: function %d: too many arguments (%d > %d)",
+ func_id, n_arguments, MAXFMGRARGS);
+ break;
+ }
+ return (returnValue);
}
void
-fmgr_info(Oid procedureId, func_ptr *function, int *nargs)
+fmgr_info(Oid procedureId, func_ptr * function, int *nargs)
{
- func_ptr user_fn = NULL;
- FmgrCall *fcp;
- HeapTuple procedureTuple;
- FormData_pg_proc *procedureStruct;
- Oid language;
-
- if (!(fcp = fmgr_isbuiltin(procedureId))) {
- procedureTuple = SearchSysCacheTuple(PROOID,
- ObjectIdGetDatum(procedureId),
- 0,0,0);
- if (!HeapTupleIsValid(procedureTuple)) {
- elog(WARN, "fmgr_info: function %d: cache lookup failed\n",
- procedureId);
+ func_ptr user_fn = NULL;
+ FmgrCall *fcp;
+ HeapTuple procedureTuple;
+ FormData_pg_proc *procedureStruct;
+ Oid language;
+
+ if (!(fcp = fmgr_isbuiltin(procedureId)))
+ {
+ procedureTuple = SearchSysCacheTuple(PROOID,
+ ObjectIdGetDatum(procedureId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(procedureTuple))
+ {
+ elog(WARN, "fmgr_info: function %d: cache lookup failed\n",
+ procedureId);
+ }
+ procedureStruct = (FormData_pg_proc *)
+ GETSTRUCT(procedureTuple);
+ if (!procedureStruct->proistrusted)
+ {
+ *function = (func_ptr) NULL;
+ *nargs = procedureStruct->pronargs;
+ return;
+ }
+ language = procedureStruct->prolang;
+ switch (language)
+ {
+ case INTERNALlanguageId:
+ user_fn = fmgr_lookupByName(procedureStruct->proname.data);
+ if (!user_fn)
+ elog(WARN, "fmgr_info: function %s: not in internal table",
+ procedureStruct->proname.data);
+ break;
+ case ClanguageId:
+ user_fn = fmgr_dynamic(procedureId, nargs);
+ break;
+ case SQLlanguageId:
+ user_fn = (func_ptr) NULL;
+ *nargs = procedureStruct->pronargs;
+ break;
+ default:
+ elog(WARN, "fmgr_info: function %d: unknown language %d",
+ procedureId, language);
+ }
}
- procedureStruct = (FormData_pg_proc *)
- GETSTRUCT(procedureTuple);
- if (!procedureStruct->proistrusted) {
- *function = (func_ptr) NULL;
- *nargs = procedureStruct->pronargs;
- return;
+ else
+ {
+ user_fn = fcp->func;
+ *nargs = fcp->nargs;
}
- language = procedureStruct->prolang;
- switch (language) {
- case INTERNALlanguageId:
- user_fn = fmgr_lookupByName(procedureStruct->proname.data);
- if (!user_fn)
- elog(WARN, "fmgr_info: function %s: not in internal table",
- procedureStruct->proname.data);
- break;
- case ClanguageId:
- user_fn = fmgr_dynamic(procedureId, nargs);
- break;
- case SQLlanguageId:
- user_fn = (func_ptr) NULL;
- *nargs = procedureStruct->pronargs;
- break;
- default:
- elog(WARN, "fmgr_info: function %d: unknown language %d",
- procedureId, language);
- }
- } else {
- user_fn = fcp->func;
- *nargs = fcp->nargs;
- }
- *function = user_fn;
+ *function = user_fn;
}
/*
- * fmgr - return the value of a function call
+ * fmgr - return the value of a function call
*
- * If the function is a system routine, it's compiled in, so call
- * it directly.
+ * If the function is a system routine, it's compiled in, so call
+ * it directly.
*
- * Otherwise pass it to the the appropriate 'language' function caller.
+ * Otherwise pass it to the the appropriate 'language' function caller.
*
- * Returns the return value of the invoked function if succesful,
- * 0 if unsuccessful.
+ * Returns the return value of the invoked function if succesful,
+ * 0 if unsuccessful.
*/
-char *
-fmgr(Oid procedureId, ... )
+char *
+fmgr(Oid procedureId,...)
{
- va_list pvar;
- register i;
- int pronargs;
- FmgrValues values;
- func_ptr user_fn;
- bool isNull = false;
-
- va_start(pvar, procedureId);
-
- fmgr_info(procedureId, &user_fn, &pronargs);
-
- if (pronargs > MAXFMGRARGS) {
- elog(WARN, "fmgr: function %d: too many arguments (%d > %d)",
- procedureId, pronargs, MAXFMGRARGS);
- }
- for (i = 0; i < pronargs; ++i)
- values.data[i] = va_arg(pvar, char *);
- va_end(pvar);
-
- /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
- return(fmgr_c(user_fn, procedureId, pronargs, &values,
- &isNull));
+ va_list pvar;
+ register i;
+ int pronargs;
+ FmgrValues values;
+ func_ptr user_fn;
+ bool isNull = false;
+
+ va_start(pvar, procedureId);
+
+ fmgr_info(procedureId, &user_fn, &pronargs);
+
+ if (pronargs > MAXFMGRARGS)
+ {
+ elog(WARN, "fmgr: function %d: too many arguments (%d > %d)",
+ procedureId, pronargs, MAXFMGRARGS);
+ }
+ for (i = 0; i < pronargs; ++i)
+ values.data[i] = va_arg(pvar, char *);
+ va_end(pvar);
+
+ /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
+ return (fmgr_c(user_fn, procedureId, pronargs, &values,
+ &isNull));
}
/*
@@ -204,33 +214,35 @@ fmgr(Oid procedureId, ... )
* if you have all of this information you're likely to just jump through
* the pointer, but it's available for use with macros in fmgr.h if you
* want this routine to do sanity-checking for you.
- *
+ *
* func_ptr, func_id, n_arguments, args...
*/
#ifdef NOT_USED
-char *
-fmgr_ptr(func_ptr user_fn, Oid func_id, ...)
+char *
+fmgr_ptr(func_ptr user_fn, Oid func_id,...)
{
- va_list pvar;
- register i;
- int n_arguments;
- FmgrValues values;
- bool isNull = false;
-
- va_start(pvar, func_id);
- n_arguments = va_arg(pvar, int);
- if (n_arguments > MAXFMGRARGS) {
- elog(WARN, "fmgr_ptr: function %d: too many arguments (%d > %d)",
- func_id, n_arguments, MAXFMGRARGS);
- }
- for (i = 0; i < n_arguments; ++i)
- values.data[i] = va_arg(pvar, char *);
- va_end(pvar);
-
- /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
- return(fmgr_c(user_fn, func_id, n_arguments, &values,
- &isNull));
+ va_list pvar;
+ register i;
+ int n_arguments;
+ FmgrValues values;
+ bool isNull = false;
+
+ va_start(pvar, func_id);
+ n_arguments = va_arg(pvar, int);
+ if (n_arguments > MAXFMGRARGS)
+ {
+ elog(WARN, "fmgr_ptr: function %d: too many arguments (%d > %d)",
+ func_id, n_arguments, MAXFMGRARGS);
+ }
+ for (i = 0; i < n_arguments; ++i)
+ values.data[i] = va_arg(pvar, char *);
+ va_end(pvar);
+
+ /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
+ return (fmgr_c(user_fn, func_id, n_arguments, &values,
+ &isNull));
}
+
#endif
/*
@@ -238,19 +250,19 @@ fmgr_ptr(func_ptr user_fn, Oid func_id, ...)
* function pointer field to FuncIndexInfo, it will be replace by calls
* to fmgr_c().
*/
-char *
-fmgr_array_args(Oid procedureId, int nargs, char *args[], bool *isNull)
+char *
+fmgr_array_args(Oid procedureId, int nargs, char *args[], bool * isNull)
{
- func_ptr user_fn;
- int true_arguments;
-
- fmgr_info(procedureId, &user_fn, &true_arguments);
-
- /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
- return
- (fmgr_c(user_fn,
- procedureId,
- true_arguments,
- (FmgrValues*)args,
- isNull));
+ func_ptr user_fn;
+ int true_arguments;
+
+ fmgr_info(procedureId, &user_fn, &true_arguments);
+
+ /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
+ return
+ (fmgr_c(user_fn,
+ procedureId,
+ true_arguments,
+ (FmgrValues *) args,
+ isNull));
}