summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/catalog/pg_proc.c11
-rw-r--r--src/backend/executor/functions.c31
-rw-r--r--src/backend/optimizer/util/clauses.c26
3 files changed, 30 insertions, 38 deletions
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 7e797fbd4b0..8dde0578cb7 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.109.2.1 2005/05/03 16:51:45 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.109.2.2 2007/02/02 00:04:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -350,11 +350,10 @@ ProcedureCreate(const char *procedureName,
* the final query in the function. We do some ad-hoc type checking here
* to be sure that the user is returning the type he claims.
*
- * This is normally applied during function definition, but in the case
- * of a function with polymorphic arguments, we instead apply it during
- * function execution startup. The rettype is then the actual resolved
- * output type of the function, rather than the declared type. (Therefore,
- * we should never see ANYARRAY or ANYELEMENT as rettype.)
+ * For a polymorphic function the passed rettype must be the actual resolved
+ * output type of the function; we should never see ANYARRAY or ANYELEMENT
+ * as rettype. (This means we can't check the type during function definition
+ * of a polymorphic function.)
*/
void
check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 6346d1abc76..b23607fb0fc 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.75.2.1 2004/09/06 18:23:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.75.2.2 2007/02/02 00:04:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -56,7 +56,7 @@ typedef struct local_es
*/
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 */
@@ -77,7 +77,7 @@ typedef SQLFunctionCache *SQLFunctionCachePtr;
/* non-export function prototypes */
static execution_state *init_execution_state(char *src,
Oid *argOidVect, int nargs,
- Oid rettype, bool haspolyarg);
+ Oid rettype);
static void init_sql_fcache(FmgrInfo *finfo);
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache);
static TupleTableSlot *postquel_getnext(execution_state *es);
@@ -93,7 +93,7 @@ static void ShutdownSQLFunction(Datum arg);
static execution_state *
init_execution_state(char *src, Oid *argOidVect, int nargs,
- Oid rettype, bool haspolyarg)
+ Oid rettype)
{
execution_state *firstes;
execution_state *preves;
@@ -103,11 +103,13 @@ init_execution_state(char *src, Oid *argOidVect, int nargs,
queryTree_list = pg_parse_and_rewrite(src, argOidVect, nargs);
/*
- * If the function has any arguments declared as polymorphic types,
- * then it wasn't type-checked at definition time; must do so now.
+ * Check that the function returns the type it claims to. Although
+ * in simple cases 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. We'd have to do it anyway if the
+ * function had any polymorphic arguments.
*/
- if (haspolyarg)
- check_sql_fn_retval(rettype, get_typtype(rettype), queryTree_list);
+ check_sql_fn_retval(rettype, get_typtype(rettype), queryTree_list);
firstes = NULL;
preves = NULL;
@@ -150,7 +152,6 @@ init_sql_fcache(FmgrInfo *finfo)
Form_pg_type typeStruct;
SQLFunctionCachePtr fcache;
Oid *argOidVect;
- bool haspolyarg;
char *src;
int nargs;
Datum tmp;
@@ -226,12 +227,9 @@ init_sql_fcache(FmgrInfo *finfo)
fcache->funcSlot = NULL;
/*
- * Parse and plan the queries. We need the argument type info to pass
- * to the parser.
+ * We need the argument type info to pass to the parser.
*/
nargs = procedureStruct->pronargs;
- haspolyarg = false;
-
if (nargs > 0)
{
int argnum;
@@ -254,13 +252,15 @@ init_sql_fcache(FmgrInfo *finfo)
errmsg("could not determine actual type of argument declared %s",
format_type_be(argOidVect[argnum]))));
argOidVect[argnum] = argtype;
- haspolyarg = true;
}
}
}
else
argOidVect = (Oid *) NULL;
+ /*
+ * Parse and rewrite the queries in the function text.
+ */
tmp = SysCacheGetAttr(PROCOID,
procedureTuple,
Anum_pg_proc_prosrc,
@@ -269,8 +269,7 @@ init_sql_fcache(FmgrInfo *finfo)
elog(ERROR, "null prosrc for function %u", foid);
src = DatumGetCString(DirectFunctionCall1(textout, tmp));
- fcache->func_state = init_execution_state(src, argOidVect, nargs,
- rettype, haspolyarg);
+ fcache->func_state = init_execution_state(src, argOidVect, nargs, rettype);
pfree(src);
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 75c1e947792..ca1f1623bd0 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.154.2.4 2005/04/14 21:44:35 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.154.2.5 2007/02/02 00:04:02 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -1758,7 +1758,6 @@ inline_function(Oid funcid, Oid result_type, List *args,
{
Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
char result_typtype;
- bool polymorphic = false;
Oid argtypes[FUNC_MAX_ARGS];
char *src;
Datum tmp;
@@ -1792,10 +1791,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
if (result_typtype != 'b' &&
result_typtype != 'd')
{
- if (funcform->prorettype == ANYARRAYOID ||
- funcform->prorettype == ANYELEMENTOID)
- polymorphic = true;
- else
+ if (funcform->prorettype != ANYARRAYOID &&
+ funcform->prorettype != ANYELEMENTOID)
return NULL;
}
@@ -1814,7 +1811,6 @@ inline_function(Oid funcid, Oid result_type, List *args,
if (argtypes[i] == ANYARRAYOID ||
argtypes[i] == ANYELEMENTOID)
{
- polymorphic = true;
argtypes[i] = exprType((Node *) nth(i, args));
}
}
@@ -1891,16 +1887,14 @@ inline_function(Oid funcid, Oid result_type, List *args,
newexpr = (Node *) ((TargetEntry *) lfirst(querytree->targetList))->expr;
/*
- * If the function has any arguments declared as polymorphic types,
- * then it wasn't type-checked at definition time; must do so now.
- * (This will raise an error if wrong, but that's okay since the
- * function would fail at runtime anyway. Note we do not try this
- * until we have verified that no rewriting was needed; that's
- * probably not important, but let's be careful.)
+ * Make sure the function (still) returns what it's declared to. This will
+ * raise an error if wrong, but that's okay since the function would fail
+ * at runtime anyway. Note we do not try this until we have verified that
+ * no rewriting was needed; that's probably not important, but let's be
+ * careful.
*/
- if (polymorphic)
- check_sql_fn_retval(result_type, get_typtype(result_type),
- querytree_list);
+ check_sql_fn_retval(result_type, get_typtype(result_type),
+ querytree_list);
/*
* Additional validity checks on the expression. It mustn't return a