*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.94 2002/09/18 21:35:20 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.94.2.1 2007/02/02 00:04:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "utils/syscache.h"
-static void checkretval(Oid rettype, char fn_typtype, List *queryTreeList);
Datum fmgr_internal_validator(PG_FUNCTION_ARGS);
Datum fmgr_c_validator(PG_FUNCTION_ARGS);
Datum fmgr_sql_validator(PG_FUNCTION_ARGS);
}
/*
- * checkretval() -- check return value of a list of sql parse trees.
+ * check_sql_fn_retval() -- check return value of a list of sql parse trees.
*
* The return value of a sql function is the value returned by
* the final query in the function. We do some ad-hoc define-time
* type checking here to be sure that the user is returning the
* type he claims.
*/
-static void
-checkretval(Oid rettype, char fn_typtype, List *queryTreeList)
+void
+check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
{
Query *parse;
int cmd;
prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp));
querytree_list = pg_parse_and_rewrite(prosrc, proc->proargtypes, proc->pronargs);
- checkretval(proc->prorettype, functyptype, querytree_list);
+ check_sql_fn_retval(proc->prorettype, functyptype, querytree_list);
ReleaseSysCache(tuple);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.57.2.1 2003/06/12 17:29:37 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.57.2.2 2007/02/02 00:04:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "tcop/tcopprot.h"
#include "tcop/utility.h"
#include "utils/builtins.h"
+#include "utils/lsyscache.h"
#include "utils/syscache.h"
typedef struct
{
- int typlen; /* length of the return type */
+ int16 typlen; /* length of the return type */
bool typbyval; /* true if return type is pass by value */
bool returnsTuple; /* true if return type is a tuple */
bool shutdown_reg; /* true if registered shutdown callback */
/* non-export function prototypes */
static execution_state *init_execution_state(char *src,
- Oid *argOidVect, int nargs);
+ Oid *argOidVect, int nargs,
+ Oid rettype);
static void init_sql_fcache(FmgrInfo *finfo);
static void postquel_start(execution_state *es);
static TupleTableSlot *postquel_getnext(execution_state *es);
static execution_state *
-init_execution_state(char *src, Oid *argOidVect, int nargs)
+init_execution_state(char *src, Oid *argOidVect, int nargs,
+ Oid rettype)
{
execution_state *firstes;
execution_state *preves;
queryTree_list = pg_parse_and_rewrite(src, argOidVect, nargs);
+ /*
+ * Check that the function returns the type it claims to. Although
+ * this was already done when the function was defined,
+ * we have to recheck because database objects used in the function's
+ * queries might have changed type.
+ */
+ check_sql_fn_retval(rettype, get_typtype(rettype), queryTree_list);
+
firstes = NULL;
preves = NULL;
init_sql_fcache(FmgrInfo *finfo)
{
Oid foid = finfo->fn_oid;
+ Oid rettype;
HeapTuple procedureTuple;
HeapTuple typeTuple;
Form_pg_proc procedureStruct;
/*
* get the return type from the procedure tuple
*/
+ rettype = procedureStruct->prorettype;
+
typeTuple = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(procedureStruct->prorettype),
+ ObjectIdGetDatum(rettype),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "init_sql_fcache: Cache lookup failed for type %u",
- procedureStruct->prorettype);
+ rettype);
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
fcache->typlen = typeStruct->typlen;
if (typeStruct->typtype != 'c' &&
- procedureStruct->prorettype != RECORDOID)
+ rettype != RECORDOID)
{
/* The return type is not a composite type, so just use byval */
fcache->typbyval = typeStruct->typbyval;
foid);
src = DatumGetCString(DirectFunctionCall1(textout, tmp));
- fcache->func_state = init_execution_state(src, argOidVect, nargs);
+ fcache->func_state = init_execution_state(src, argOidVect, nargs, rettype);
pfree(src);