1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
diff -ruN postgresql-7.4.7-old/src/backend/executor/functions.c postgresql-7.4.7/src/backend/executor/functions.c
--- postgresql-7.4.7-old/src/backend/executor/functions.c 2004-09-06 20:23:09.000000000 +0200
+++ postgresql-7.4.7/src/backend/executor/functions.c 2007-02-04 21:50:39.000000000 +0100
@@ -56,7 +56,7 @@
*/
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 @@
/* 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 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 @@
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 @@
Form_pg_type typeStruct;
SQLFunctionCachePtr fcache;
Oid *argOidVect;
- bool haspolyarg;
char *src;
int nargs;
Datum tmp;
@@ -226,12 +227,9 @@
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 @@
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 @@
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 -ruN postgresql-7.4.7-old/src/backend/optimizer/util/clauses.c postgresql-7.4.7/src/backend/optimizer/util/clauses.c
--- postgresql-7.4.7-old/src/backend/optimizer/util/clauses.c 2004-01-28 01:05:25.000000000 +0100
+++ postgresql-7.4.7/src/backend/optimizer/util/clauses.c 2007-02-04 21:50:39.000000000 +0100
@@ -1747,7 +1747,6 @@
{
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;
@@ -1781,10 +1780,8 @@
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;
}
@@ -1803,7 +1800,6 @@
if (argtypes[i] == ANYARRAYOID ||
argtypes[i] == ANYELEMENTOID)
{
- polymorphic = true;
argtypes[i] = exprType((Node *) nth(i, args));
}
}
@@ -1880,16 +1876,14 @@
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
|