Tom Lane wrote:
> Joe Conway <[EMAIL PROTECTED]> 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;
  

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org

Reply via email to