[Fwd: Re: [HACKERS] Accessing original TupleDesc from SRF] - Mailing list pgsql-patches
From | Joe Conway |
---|---|
Subject | [Fwd: Re: [HACKERS] Accessing original TupleDesc from SRF] |
Date | |
Msg-id | 3D6FDB86.9000509@joeconway.com Whole thread Raw |
List | pgsql-patches |
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;
pgsql-patches by date: