aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/functions.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-04-02 23:14:08 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-04-02 23:14:08 +0000
commit8efbe30df51a1fb3064195dfaf5189d1a9c5eee9 (patch)
treedfb96709ee9592de8d0fc4c87e4251b8b16546d6 /src/backend/executor/functions.c
parent3dd1ca035d4b6008534ba14ab991b22879b00f74 (diff)
downloadpostgresql-8efbe30df51a1fb3064195dfaf5189d1a9c5eee9.tar.gz
postgresql-8efbe30df51a1fb3064195dfaf5189d1a9c5eee9.zip
check_sql_fn_retval has always thought that we supported doing
'SELECT foo()' in a SQL function returning a rowtype, to simply pass back the results of another function returning the same rowtype. However, that hasn't actually worked in many years. Now it works again.
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r--src/backend/executor/functions.c56
1 files changed, 30 insertions, 26 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index aa7652e07ef..c07eac5faf6 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.79 2004/04/01 21:28:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.80 2004/04/02 23:14:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -73,9 +73,7 @@ typedef SQLFunctionCache *SQLFunctionCachePtr;
/* non-export function prototypes */
-static execution_state *init_execution_state(char *src,
- Oid *argOidVect, int nargs,
- Oid rettype, bool haspolyarg);
+static execution_state *init_execution_state(List *queryTree_list);
static void init_sql_fcache(FmgrInfo *finfo);
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache);
static TupleTableSlot *postquel_getnext(execution_state *es);
@@ -90,25 +88,11 @@ static void ShutdownSQLFunction(Datum arg);
static execution_state *
-init_execution_state(char *src, Oid *argOidVect, int nargs,
- Oid rettype, bool haspolyarg)
+init_execution_state(List *queryTree_list)
{
- execution_state *firstes;
- execution_state *preves;
- List *queryTree_list,
- *qtl_item;
-
- 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.
- */
- if (haspolyarg)
- check_sql_fn_retval(rettype, get_typtype(rettype), queryTree_list);
-
- firstes = NULL;
- preves = NULL;
+ execution_state *firstes = NULL;
+ execution_state *preves = NULL;
+ List *qtl_item;
foreach(qtl_item, queryTree_list)
{
@@ -151,6 +135,7 @@ init_sql_fcache(FmgrInfo *finfo)
bool haspolyarg;
char *src;
int nargs;
+ List *queryTree_list;
Datum tmp;
bool isNull;
@@ -191,7 +176,9 @@ init_sql_fcache(FmgrInfo *finfo)
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
/*
- * get the type length and by-value flag from the type tuple
+ * get the type length and by-value flag from the type tuple; also
+ * do a preliminary check for returnsTuple (this may prove inaccurate,
+ * see below).
*/
fcache->typlen = typeStruct->typlen;
fcache->typbyval = typeStruct->typbyval;
@@ -199,7 +186,7 @@ init_sql_fcache(FmgrInfo *finfo)
rettype == RECORDOID);
/*
- * Parse and plan the queries. We need the argument type info to pass
+ * Parse and rewrite the queries. We need the argument type info to pass
* to the parser.
*/
nargs = procedureStruct->pronargs;
@@ -242,8 +229,25 @@ 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);
+ 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.
+ *
+ * Also, force a type-check if the declared return type is a rowtype;
+ * we need to find out whether we are actually returning the whole
+ * tuple result, or just regurgitating a rowtype expression result.
+ * In the latter case we clear returnsTuple because we need not act
+ * different from the scalar result case.
+ */
+ if (haspolyarg || fcache->returnsTuple)
+ fcache->returnsTuple = check_sql_fn_retval(rettype,
+ get_typtype(rettype),
+ queryTree_list);
+
+ /* Finally, plan the queries */
+ fcache->func_state = init_execution_state(queryTree_list);
pfree(src);