Re: Accessing original TupleDesc from SRF - Mailing list pgsql-hackers

From Joe Conway
Subject Re: Accessing original TupleDesc from SRF
Date
Msg-id 3D6FDA21.8020705@joeconway.com
Whole thread Raw
In response to Accessing original TupleDesc from SRF  (John Gray <jgray@azuli.co.uk>)
Responses Re: Accessing original TupleDesc from SRF  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
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-hackers by date:

Previous
From: "Tyler Mitchell"
Date:
Subject: Running postgres on a read-only file system
Next
From: Joe Conway
Date:
Subject: Re: Running postgres on a read-only file system