oops! really meant to send this to patches.
Joe
Tom Lane wrote:
> Joe Conway <mail@joeconway.com> writes:
>>Preference of extending FunctionCallInfoData or ReturnSetInfo?
>
> Definitely ReturnSetInfo. If we put it in FunctionCallInfoData then
> that's an extra word to zero for *every* fmgr function call, not only
> table functions.
Attached adds:
+ TupleDesc queryDesc; /* descriptor for planned query */
to ReturnSetInfo, and populates ReturnSetInfo for every function call to
ExecMakeTableFunctionResult, not just when fn_retset.
> One thing to notice is that a table function that's depending on this
> info being available will have to punt if it's invoked via
> ExecMakeFunctionResult (ie, it's being called in a SELECT targetlist).
> That doesn't bother me too much, but maybe others will see it
> differently.
I haven't done it yet, but I suppose this should be documented in
xfunc.sgml. With this patch the behavior of a function called through
ExecMakeFunctionResult will be:
if (fn_retset)
ReturnSetInfo is populated but queryDesc is set to NULL
if (!fn_retset)
ReturnSetInfo is NULL
If there are no objections, please apply.
Thanks,
Joe
Index: src/backend/executor/execQual.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/backend/executor/execQual.c,v
retrieving revision 1.102
diff -c -r1.102 execQual.c
*** src/backend/executor/execQual.c 30 Aug 2002 00:28:41 -0000 1.102
--- src/backend/executor/execQual.c 30 Aug 2002 19:30:38 -0000
***************
*** 709,714 ****
--- 709,715 ----
rsinfo.econtext = econtext;
rsinfo.allowedModes = (int) SFRM_ValuePerCall;
rsinfo.returnMode = SFRM_ValuePerCall;
+ rsinfo.queryDesc = NULL;
/* isDone is filled below */
rsinfo.setResult = NULL;
rsinfo.setDesc = NULL;
***************
*** 851,856 ****
--- 852,858 ----
Tuplestorestate *
ExecMakeTableFunctionResult(Expr *funcexpr,
ExprContext *econtext,
+ TupleDesc queryDesc,
TupleDesc *returnDesc)
{
Tuplestorestate *tupstore = NULL;
***************
*** 859,865 ****
List *argList;
FunctionCachePtr fcache;
FunctionCallInfoData fcinfo;
! ReturnSetInfo rsinfo; /* for functions returning sets */
ExprDoneCond argDone;
MemoryContext callerContext;
MemoryContext oldcontext;
--- 861,867 ----
List *argList;
FunctionCachePtr fcache;
FunctionCallInfoData fcinfo;
! ReturnSetInfo rsinfo;
ExprDoneCond argDone;
MemoryContext callerContext;
MemoryContext oldcontext;
***************
*** 918,938 ****
}
/*
! * If function returns set, prepare a resultinfo node for
! * communication
*/
! if (fcache->func.fn_retset)
! {
! fcinfo.resultinfo = (Node *) &rsinfo;
! rsinfo.type = T_ReturnSetInfo;
! rsinfo.econtext = econtext;
! rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
! }
! /* we set these fields always since we examine them below */
rsinfo.returnMode = SFRM_ValuePerCall;
/* isDone is filled below */
rsinfo.setResult = NULL;
rsinfo.setDesc = NULL;
/*
* Switch to short-lived context for calling the function.
--- 920,942 ----
}
/*
! * prepare a resultinfo node for communication
*/
! fcinfo.resultinfo = (Node *) &rsinfo;
! rsinfo.type = T_ReturnSetInfo;
! rsinfo.econtext = econtext;
! rsinfo.queryDesc = queryDesc;
rsinfo.returnMode = SFRM_ValuePerCall;
/* isDone is filled below */
rsinfo.setResult = NULL;
rsinfo.setDesc = NULL;
+
+ /*
+ * If function returns set, we need to tell it what modes of return
+ * we will accept
+ */
+ if (fcache->func.fn_retset)
+ rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
/*
* Switch to short-lived context for calling the function.
Index: src/backend/executor/nodeFunctionscan.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/backend/executor/nodeFunctionscan.c,v
retrieving revision 1.8
diff -c -r1.8 nodeFunctionscan.c
*** src/backend/executor/nodeFunctionscan.c 30 Aug 2002 00:28:41 -0000 1.8
--- src/backend/executor/nodeFunctionscan.c 30 Aug 2002 19:01:25 -0000
***************
*** 79,84 ****
--- 79,85 ----
scanstate->tuplestorestate = tuplestorestate =
ExecMakeTableFunctionResult((Expr *) scanstate->funcexpr,
econtext,
+ scanstate->tupdesc,
&funcTupdesc);
/*
Index: src/include/executor/executor.h
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/include/executor/executor.h,v
retrieving revision 1.75
diff -c -r1.75 executor.h
*** src/include/executor/executor.h 30 Aug 2002 00:28:41 -0000 1.75
--- src/include/executor/executor.h 30 Aug 2002 19:02:02 -0000
***************
*** 82,87 ****
--- 82,88 ----
ExprDoneCond *isDone);
extern Tuplestorestate *ExecMakeTableFunctionResult(Expr *funcexpr,
ExprContext *econtext,
+ TupleDesc queryDesc,
TupleDesc *returnDesc);
extern Datum ExecEvalExpr(Node *expression, ExprContext *econtext,
bool *isNull, ExprDoneCond *isDone);
Index: src/include/nodes/execnodes.h
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/include/nodes/execnodes.h,v
retrieving revision 1.73
diff -c -r1.73 execnodes.h
*** src/include/nodes/execnodes.h 30 Aug 2002 00:28:41 -0000 1.73
--- src/include/nodes/execnodes.h 30 Aug 2002 19:29:36 -0000
***************
*** 152,157 ****
--- 152,158 ----
SetFunctionReturnMode returnMode; /* actual return mode */
ExprDoneCond isDone; /* status for ValuePerCall mode */
Tuplestorestate *setResult; /* return object for Materialize mode */
+ TupleDesc queryDesc; /* descriptor for planned query */
TupleDesc setDesc; /* descriptor for Materialize mode */
} ReturnSetInfo;