Commit a253dcdb authored by Tom Lane's avatar Tom Lane

Give a better error message if an SQL-language function is

called through fmgr.  Someday we should try to actually execute the function,
but that looks like it might be a major feature addition.
Not something to try during beta phase.
parent 4ed92696
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.23 1999/03/29 01:30:36 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.24 1999/04/03 22:57:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -33,23 +33,33 @@ ...@@ -33,23 +33,33 @@
#include "commands/trigger.h" #include "commands/trigger.h"
/*
* Interface for PL functions
*
* XXX: use of global fmgr_pl_finfo variable is really ugly. FIXME
*/
static char * static char *
fmgr_pl(char *arg0,...) fmgr_pl(char *arg0,...)
{ {
va_list pvar; va_list pvar;
FmgrValues values; FmgrValues values;
int n_arguments = fmgr_pl_finfo->fn_nargs;
bool isNull = false; bool isNull = false;
int i; int i;
memset(&values, 0, sizeof(values)); memset(&values, 0, sizeof(values));
if (fmgr_pl_finfo->fn_nargs > 0) if (n_arguments > 0)
{ {
values.data[0] = arg0; values.data[0] = arg0;
if (fmgr_pl_finfo->fn_nargs > 1) if (n_arguments > 1)
{ {
if (n_arguments > MAXFMGRARGS)
elog(ERROR, "fmgr_pl: function %d: too many arguments (%d > %d)",
fmgr_pl_finfo->fn_oid, n_arguments, MAXFMGRARGS);
va_start(pvar, arg0); va_start(pvar, arg0);
for (i = 1; i < fmgr_pl_finfo->fn_nargs; i++) for (i = 1; i < n_arguments; i++)
values.data[i] = va_arg(pvar, char *); values.data[i] = va_arg(pvar, char *);
va_end(pvar); va_end(pvar);
} }
...@@ -63,6 +73,43 @@ fmgr_pl(char *arg0,...) ...@@ -63,6 +73,43 @@ fmgr_pl(char *arg0,...)
} }
/*
* Interface for untrusted functions
*/
static char *
fmgr_untrusted(char *arg0,...)
{
/* Currently these are unsupported. Someday we might do something like
* forking a subprocess to execute 'em.
*/
elog(ERROR, "Untrusted functions not supported.");
return NULL; /* keep compiler happy */
}
/*
* Interface for SQL-language functions
*/
static char *
fmgr_sql(char *arg0,...)
{
/*
* XXX It'd be really nice to support SQL functions anywhere that builtins
* are supported. What would we have to do? What pitfalls are there?
*/
elog(ERROR, "SQL-language function not supported in this context.");
return NULL; /* keep compiler happy */
}
/*
* fmgr_c is not really for C functions only; it can be called for functions
* in any language. Many parts of the system use this entry point if they
* want to pass the arguments in an array rather than as explicit arguments.
*/
char * char *
fmgr_c(FmgrInfo *finfo, fmgr_c(FmgrInfo *finfo,
FmgrValues *values, FmgrValues *values,
...@@ -72,18 +119,6 @@ fmgr_c(FmgrInfo *finfo, ...@@ -72,18 +119,6 @@ fmgr_c(FmgrInfo *finfo,
int n_arguments = finfo->fn_nargs; int n_arguments = finfo->fn_nargs;
func_ptr user_fn = fmgr_faddr(finfo); func_ptr user_fn = fmgr_faddr(finfo);
if (user_fn == (func_ptr) NULL)
{
/*
* a NULL func_ptr denotet untrusted function (in postgres 4.2).
* Untrusted functions have very limited use and is clumsy. We
* just get rid of it.
*/
elog(ERROR, "internal error: untrusted function not supported.");
}
/* /*
* If finfo contains a PL handler for this function, call that * If finfo contains a PL handler for this function, call that
* instead. * instead.
...@@ -91,6 +126,9 @@ fmgr_c(FmgrInfo *finfo, ...@@ -91,6 +126,9 @@ fmgr_c(FmgrInfo *finfo,
if (finfo->fn_plhandler != NULL) if (finfo->fn_plhandler != NULL)
return (*(finfo->fn_plhandler)) (finfo, values, isNull); return (*(finfo->fn_plhandler)) (finfo, values, isNull);
if (user_fn == (func_ptr) NULL)
elog(ERROR, "Internal error: fmgr_c received NULL function pointer.");
switch (n_arguments) switch (n_arguments)
{ {
case 0: case 0:
...@@ -155,6 +193,10 @@ fmgr_c(FmgrInfo *finfo, ...@@ -155,6 +193,10 @@ fmgr_c(FmgrInfo *finfo,
return returnValue; return returnValue;
} }
/*
* Expand a regproc OID into an FmgrInfo cache struct.
*/
void void
fmgr_info(Oid procedureId, FmgrInfo *finfo) fmgr_info(Oid procedureId, FmgrInfo *finfo)
{ {
...@@ -188,7 +230,7 @@ fmgr_info(Oid procedureId, FmgrInfo *finfo) ...@@ -188,7 +230,7 @@ fmgr_info(Oid procedureId, FmgrInfo *finfo)
procedureStruct = (FormData_pg_proc *) GETSTRUCT(procedureTuple); procedureStruct = (FormData_pg_proc *) GETSTRUCT(procedureTuple);
if (!procedureStruct->proistrusted) if (!procedureStruct->proistrusted)
{ {
finfo->fn_addr = (func_ptr) NULL; finfo->fn_addr = (func_ptr) fmgr_untrusted;
finfo->fn_nargs = procedureStruct->pronargs; finfo->fn_nargs = procedureStruct->pronargs;
return; return;
} }
...@@ -207,7 +249,7 @@ fmgr_info(Oid procedureId, FmgrInfo *finfo) ...@@ -207,7 +249,7 @@ fmgr_info(Oid procedureId, FmgrInfo *finfo)
finfo->fn_addr = fmgr_dynamic(procedureId, &(finfo->fn_nargs)); finfo->fn_addr = fmgr_dynamic(procedureId, &(finfo->fn_nargs));
break; break;
case SQLlanguageId: case SQLlanguageId:
finfo->fn_addr = (func_ptr) NULL; finfo->fn_addr = (func_ptr) fmgr_sql;
finfo->fn_nargs = procedureStruct->pronargs; finfo->fn_nargs = procedureStruct->pronargs;
break; break;
default: default:
...@@ -227,13 +269,12 @@ fmgr_info(Oid procedureId, FmgrInfo *finfo) ...@@ -227,13 +269,12 @@ fmgr_info(Oid procedureId, FmgrInfo *finfo)
"Cache lookup for language %d failed", "Cache lookup for language %d failed",
ObjectIdGetDatum(procedureStruct->prolang)); ObjectIdGetDatum(procedureStruct->prolang));
} }
languageStruct = (Form_pg_language) languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
GETSTRUCT(languageTuple);
if (languageStruct->lanispl) if (languageStruct->lanispl)
{ {
FmgrInfo plfinfo; FmgrInfo plfinfo;
fmgr_info(((Form_pg_language) GETSTRUCT(languageTuple))->lanplcallfoid, &plfinfo); fmgr_info(languageStruct->lanplcallfoid, &plfinfo);
finfo->fn_addr = (func_ptr) fmgr_pl; finfo->fn_addr = (func_ptr) fmgr_pl;
finfo->fn_plhandler = plfinfo.fn_addr; finfo->fn_plhandler = plfinfo.fn_addr;
finfo->fn_nargs = procedureStruct->pronargs; finfo->fn_nargs = procedureStruct->pronargs;
...@@ -269,16 +310,14 @@ fmgr(Oid procedureId,...) ...@@ -269,16 +310,14 @@ fmgr(Oid procedureId,...)
FmgrInfo finfo; FmgrInfo finfo;
bool isNull = false; bool isNull = false;
va_start(pvar, procedureId);
fmgr_info(procedureId, &finfo); fmgr_info(procedureId, &finfo);
pronargs = finfo.fn_nargs; pronargs = finfo.fn_nargs;
if (pronargs > MAXFMGRARGS) if (pronargs > MAXFMGRARGS)
{
elog(ERROR, "fmgr: function %d: too many arguments (%d > %d)", elog(ERROR, "fmgr: function %d: too many arguments (%d > %d)",
procedureId, pronargs, MAXFMGRARGS); procedureId, pronargs, MAXFMGRARGS);
}
va_start(pvar, procedureId);
for (i = 0; i < pronargs; ++i) for (i = 0; i < pronargs; ++i)
values.data[i] = va_arg(pvar, char *); values.data[i] = va_arg(pvar, char *);
va_end(pvar); va_end(pvar);
...@@ -296,7 +335,8 @@ fmgr(Oid procedureId,...) ...@@ -296,7 +335,8 @@ fmgr(Oid procedureId,...)
* *
* funcinfo, n_arguments, args... * funcinfo, n_arguments, args...
*/ */
#ifdef NOT_USED #ifdef TRACE_FMGR_PTR
char * char *
fmgr_ptr(FmgrInfo *finfo,...) fmgr_ptr(FmgrInfo *finfo,...)
{ {
...@@ -343,7 +383,7 @@ fmgr_array_args(Oid procedureId, int nargs, char *args[], bool *isNull) ...@@ -343,7 +383,7 @@ fmgr_array_args(Oid procedureId, int nargs, char *args[], bool *isNull)
finfo.fn_nargs = nargs; finfo.fn_nargs = nargs;
/* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */ /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
return (fmgr_c(&finfo, return fmgr_c(&finfo,
(FmgrValues *) args, (FmgrValues *) args,
isNull)); isNull);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment