Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a253dcd

Browse files
committed
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.
1 parent 4ed9269 commit a253dcd

File tree

1 file changed

+69
-29
lines changed

1 file changed

+69
-29
lines changed

src/backend/utils/fmgr/fmgr.c

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.23 1999/03/29 01:30:36 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.24 1999/04/03 22:57:29 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -33,23 +33,33 @@
3333
#include "commands/trigger.h"
3434

3535

36+
/*
37+
* Interface for PL functions
38+
*
39+
* XXX: use of global fmgr_pl_finfo variable is really ugly. FIXME
40+
*/
41+
3642
static char *
3743
fmgr_pl(char *arg0,...)
3844
{
3945
va_list pvar;
4046
FmgrValues values;
47+
int n_arguments = fmgr_pl_finfo->fn_nargs;
4148
bool isNull = false;
4249
int i;
4350

4451
memset(&values, 0, sizeof(values));
4552

46-
if (fmgr_pl_finfo->fn_nargs > 0)
53+
if (n_arguments > 0)
4754
{
4855
values.data[0] = arg0;
49-
if (fmgr_pl_finfo->fn_nargs > 1)
56+
if (n_arguments > 1)
5057
{
58+
if (n_arguments > MAXFMGRARGS)
59+
elog(ERROR, "fmgr_pl: function %d: too many arguments (%d > %d)",
60+
fmgr_pl_finfo->fn_oid, n_arguments, MAXFMGRARGS);
5161
va_start(pvar, arg0);
52-
for (i = 1; i < fmgr_pl_finfo->fn_nargs; i++)
62+
for (i = 1; i < n_arguments; i++)
5363
values.data[i] = va_arg(pvar, char *);
5464
va_end(pvar);
5565
}
@@ -63,6 +73,43 @@ fmgr_pl(char *arg0,...)
6373
}
6474

6575

76+
/*
77+
* Interface for untrusted functions
78+
*/
79+
80+
static char *
81+
fmgr_untrusted(char *arg0,...)
82+
{
83+
/* Currently these are unsupported. Someday we might do something like
84+
* forking a subprocess to execute 'em.
85+
*/
86+
elog(ERROR, "Untrusted functions not supported.");
87+
return NULL; /* keep compiler happy */
88+
}
89+
90+
91+
/*
92+
* Interface for SQL-language functions
93+
*/
94+
95+
static char *
96+
fmgr_sql(char *arg0,...)
97+
{
98+
/*
99+
* XXX It'd be really nice to support SQL functions anywhere that builtins
100+
* are supported. What would we have to do? What pitfalls are there?
101+
*/
102+
elog(ERROR, "SQL-language function not supported in this context.");
103+
return NULL; /* keep compiler happy */
104+
}
105+
106+
107+
/*
108+
* fmgr_c is not really for C functions only; it can be called for functions
109+
* in any language. Many parts of the system use this entry point if they
110+
* want to pass the arguments in an array rather than as explicit arguments.
111+
*/
112+
66113
char *
67114
fmgr_c(FmgrInfo *finfo,
68115
FmgrValues *values,
@@ -72,25 +119,16 @@ fmgr_c(FmgrInfo *finfo,
72119
int n_arguments = finfo->fn_nargs;
73120
func_ptr user_fn = fmgr_faddr(finfo);
74121

75-
76-
if (user_fn == (func_ptr) NULL)
77-
{
78-
79-
/*
80-
* a NULL func_ptr denotet untrusted function (in postgres 4.2).
81-
* Untrusted functions have very limited use and is clumsy. We
82-
* just get rid of it.
83-
*/
84-
elog(ERROR, "internal error: untrusted function not supported.");
85-
}
86-
87122
/*
88123
* If finfo contains a PL handler for this function, call that
89124
* instead.
90125
*/
91126
if (finfo->fn_plhandler != NULL)
92127
return (*(finfo->fn_plhandler)) (finfo, values, isNull);
93128

129+
if (user_fn == (func_ptr) NULL)
130+
elog(ERROR, "Internal error: fmgr_c received NULL function pointer.");
131+
94132
switch (n_arguments)
95133
{
96134
case 0:
@@ -155,6 +193,10 @@ fmgr_c(FmgrInfo *finfo,
155193
return returnValue;
156194
}
157195

196+
/*
197+
* Expand a regproc OID into an FmgrInfo cache struct.
198+
*/
199+
158200
void
159201
fmgr_info(Oid procedureId, FmgrInfo *finfo)
160202
{
@@ -188,7 +230,7 @@ fmgr_info(Oid procedureId, FmgrInfo *finfo)
188230
procedureStruct = (FormData_pg_proc *) GETSTRUCT(procedureTuple);
189231
if (!procedureStruct->proistrusted)
190232
{
191-
finfo->fn_addr = (func_ptr) NULL;
233+
finfo->fn_addr = (func_ptr) fmgr_untrusted;
192234
finfo->fn_nargs = procedureStruct->pronargs;
193235
return;
194236
}
@@ -207,7 +249,7 @@ fmgr_info(Oid procedureId, FmgrInfo *finfo)
207249
finfo->fn_addr = fmgr_dynamic(procedureId, &(finfo->fn_nargs));
208250
break;
209251
case SQLlanguageId:
210-
finfo->fn_addr = (func_ptr) NULL;
252+
finfo->fn_addr = (func_ptr) fmgr_sql;
211253
finfo->fn_nargs = procedureStruct->pronargs;
212254
break;
213255
default:
@@ -227,13 +269,12 @@ fmgr_info(Oid procedureId, FmgrInfo *finfo)
227269
"Cache lookup for language %d failed",
228270
ObjectIdGetDatum(procedureStruct->prolang));
229271
}
230-
languageStruct = (Form_pg_language)
231-
GETSTRUCT(languageTuple);
272+
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
232273
if (languageStruct->lanispl)
233274
{
234275
FmgrInfo plfinfo;
235276

236-
fmgr_info(((Form_pg_language) GETSTRUCT(languageTuple))->lanplcallfoid, &plfinfo);
277+
fmgr_info(languageStruct->lanplcallfoid, &plfinfo);
237278
finfo->fn_addr = (func_ptr) fmgr_pl;
238279
finfo->fn_plhandler = plfinfo.fn_addr;
239280
finfo->fn_nargs = procedureStruct->pronargs;
@@ -269,16 +310,14 @@ fmgr(Oid procedureId,...)
269310
FmgrInfo finfo;
270311
bool isNull = false;
271312

272-
va_start(pvar, procedureId);
273-
274313
fmgr_info(procedureId, &finfo);
275314
pronargs = finfo.fn_nargs;
276315

277316
if (pronargs > MAXFMGRARGS)
278-
{
279317
elog(ERROR, "fmgr: function %d: too many arguments (%d > %d)",
280318
procedureId, pronargs, MAXFMGRARGS);
281-
}
319+
320+
va_start(pvar, procedureId);
282321
for (i = 0; i < pronargs; ++i)
283322
values.data[i] = va_arg(pvar, char *);
284323
va_end(pvar);
@@ -296,7 +335,8 @@ fmgr(Oid procedureId,...)
296335
*
297336
* funcinfo, n_arguments, args...
298337
*/
299-
#ifdef NOT_USED
338+
#ifdef TRACE_FMGR_PTR
339+
300340
char *
301341
fmgr_ptr(FmgrInfo *finfo,...)
302342
{
@@ -343,7 +383,7 @@ fmgr_array_args(Oid procedureId, int nargs, char *args[], bool *isNull)
343383
finfo.fn_nargs = nargs;
344384

345385
/* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
346-
return (fmgr_c(&finfo,
347-
(FmgrValues *) args,
348-
isNull));
386+
return fmgr_c(&finfo,
387+
(FmgrValues *) args,
388+
isNull);
349389
}

0 commit comments

Comments
 (0)