LCOV - code coverage report
Current view: top level - src/backend/executor - nodeResult.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 79.7 % 59 47
Test Date: 2026-07-12 21:15:34 Functions: 66.7 % 6 4
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 69.2 % 26 18

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * nodeResult.c
       4                 :             :  *    support for constant nodes needing special code.
       5                 :             :  *
       6                 :             :  * DESCRIPTION
       7                 :             :  *
       8                 :             :  *      Result nodes are used in queries where no relations are scanned.
       9                 :             :  *      Examples of such queries are:
      10                 :             :  *
      11                 :             :  *              select 1 * 2
      12                 :             :  *
      13                 :             :  *              insert into emp values ('mike', 15000)
      14                 :             :  *
      15                 :             :  *      (Remember that in an INSERT or UPDATE, we need a plan tree that
      16                 :             :  *      generates the new rows.)
      17                 :             :  *
      18                 :             :  *      Result nodes are also used to optimise queries with constant
      19                 :             :  *      qualifications (ie, quals that do not depend on the scanned data),
      20                 :             :  *      such as:
      21                 :             :  *
      22                 :             :  *              select * from emp where 2 > 1
      23                 :             :  *
      24                 :             :  *      In this case, the plan generated is
      25                 :             :  *
      26                 :             :  *                      Result  (with 2 > 1 qual)
      27                 :             :  *                      /
      28                 :             :  *                 SeqScan (emp.*)
      29                 :             :  *
      30                 :             :  *      At runtime, the Result node evaluates the constant qual once,
      31                 :             :  *      which is shown by EXPLAIN as a One-Time Filter.  If it's
      32                 :             :  *      false, we can return an empty result set without running the
      33                 :             :  *      controlled plan at all.  If it's true, we run the controlled
      34                 :             :  *      plan normally and pass back the results.
      35                 :             :  *
      36                 :             :  *
      37                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      38                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
      39                 :             :  *
      40                 :             :  * IDENTIFICATION
      41                 :             :  *    src/backend/executor/nodeResult.c
      42                 :             :  *
      43                 :             :  *-------------------------------------------------------------------------
      44                 :             :  */
      45                 :             : 
      46                 :             : #include "postgres.h"
      47                 :             : 
      48                 :             : #include "executor/executor.h"
      49                 :             : #include "executor/nodeResult.h"
      50                 :             : #include "miscadmin.h"
      51                 :             : 
      52                 :             : 
      53                 :             : /* ----------------------------------------------------------------
      54                 :             :  *      ExecResult(node)
      55                 :             :  *
      56                 :             :  *      returns the tuples from the outer plan which satisfy the
      57                 :             :  *      qualification clause.  Since result nodes with right
      58                 :             :  *      subtrees are never planned, we ignore the right subtree
      59                 :             :  *      entirely (for now).. -cim 10/7/89
      60                 :             :  *
      61                 :             :  *      The qualification containing only constant clauses are
      62                 :             :  *      checked first before any processing is done. It always returns
      63                 :             :  *      'nil' if the constant qualification is not satisfied.
      64                 :             :  * ----------------------------------------------------------------
      65                 :             :  */
      66                 :             : static TupleTableSlot *
      67                 :     1020949 : ExecResult(PlanState *pstate)
      68                 :             : {
      69                 :     1020949 :     ResultState *node = castNode(ResultState, pstate);
      70                 :             :     TupleTableSlot *outerTupleSlot;
      71                 :             :     PlanState  *outerPlan;
      72                 :             :     ExprContext *econtext;
      73                 :             : 
      74         [ +  + ]:     1020949 :     CHECK_FOR_INTERRUPTS();
      75                 :             : 
      76                 :     1020947 :     econtext = node->ps.ps_ExprContext;
      77                 :             : 
      78                 :             :     /*
      79                 :             :      * check constant qualifications like (2 > 1), if not already done
      80                 :             :      */
      81         [ +  + ]:     1020947 :     if (node->rs_checkqual)
      82                 :             :     {
      83                 :       11581 :         bool        qualResult = ExecQual(node->resconstantqual, econtext);
      84                 :             : 
      85                 :       11581 :         node->rs_checkqual = false;
      86         [ +  + ]:       11581 :         if (!qualResult)
      87                 :             :         {
      88                 :        6808 :             node->rs_done = true;
      89                 :        6808 :             return NULL;
      90                 :             :         }
      91                 :             :     }
      92                 :             : 
      93                 :             :     /*
      94                 :             :      * Reset per-tuple memory context to free any expression evaluation
      95                 :             :      * storage allocated in the previous tuple cycle.
      96                 :             :      */
      97                 :     1014139 :     ResetExprContext(econtext);
      98                 :             : 
      99                 :             :     /*
     100                 :             :      * if rs_done is true then it means that we were asked to return a
     101                 :             :      * constant tuple and we already did the last time ExecResult() was
     102                 :             :      * called, OR that we failed the constant qual check. Either way, now we
     103                 :             :      * are through.
     104                 :             :      */
     105         [ +  + ]:     1014139 :     if (!node->rs_done)
     106                 :             :     {
     107                 :      841344 :         outerPlan = outerPlanState(node);
     108                 :             : 
     109         [ +  + ]:      841344 :         if (outerPlan != NULL)
     110                 :             :         {
     111                 :             :             /*
     112                 :             :              * retrieve tuples from the outer plan until there are no more.
     113                 :             :              */
     114                 :      623371 :             outerTupleSlot = ExecProcNode(outerPlan);
     115                 :             : 
     116   [ +  +  +  + ]:      623362 :             if (TupIsNull(outerTupleSlot))
     117                 :        5661 :                 return NULL;
     118                 :             : 
     119                 :             :             /*
     120                 :             :              * prepare to compute projection expressions, which will expect to
     121                 :             :              * access the input tuples as varno OUTER.
     122                 :             :              */
     123                 :      617701 :             econtext->ecxt_outertuple = outerTupleSlot;
     124                 :             :         }
     125                 :             :         else
     126                 :             :         {
     127                 :             :             /*
     128                 :             :              * if we don't have an outer plan, then we are just generating the
     129                 :             :              * results from a constant target list.  Do it only once.
     130                 :             :              */
     131                 :      217973 :             node->rs_done = true;
     132                 :             :         }
     133                 :             : 
     134                 :             :         /* form the result tuple using ExecProject(), and return it */
     135                 :      835674 :         return ExecProject(node->ps.ps_ProjInfo);
     136                 :             :     }
     137                 :             : 
     138                 :      172795 :     return NULL;
     139                 :             : }
     140                 :             : 
     141                 :             : /* ----------------------------------------------------------------
     142                 :             :  *      ExecResultMarkPos
     143                 :             :  * ----------------------------------------------------------------
     144                 :             :  */
     145                 :             : void
     146                 :           0 : ExecResultMarkPos(ResultState *node)
     147                 :             : {
     148                 :           0 :     PlanState  *outerPlan = outerPlanState(node);
     149                 :             : 
     150         [ #  # ]:           0 :     if (outerPlan != NULL)
     151                 :           0 :         ExecMarkPos(outerPlan);
     152                 :             :     else
     153         [ #  # ]:           0 :         elog(DEBUG2, "Result nodes do not support mark/restore");
     154                 :           0 : }
     155                 :             : 
     156                 :             : /* ----------------------------------------------------------------
     157                 :             :  *      ExecResultRestrPos
     158                 :             :  * ----------------------------------------------------------------
     159                 :             :  */
     160                 :             : void
     161                 :           0 : ExecResultRestrPos(ResultState *node)
     162                 :             : {
     163                 :           0 :     PlanState  *outerPlan = outerPlanState(node);
     164                 :             : 
     165         [ #  # ]:           0 :     if (outerPlan != NULL)
     166                 :           0 :         ExecRestrPos(outerPlan);
     167                 :             :     else
     168         [ #  # ]:           0 :         elog(ERROR, "Result nodes do not support mark/restore");
     169                 :           0 : }
     170                 :             : 
     171                 :             : /* ----------------------------------------------------------------
     172                 :             :  *      ExecInitResult
     173                 :             :  *
     174                 :             :  *      Creates the run-time state information for the result node
     175                 :             :  *      produced by the planner and initializes outer relations
     176                 :             :  *      (child nodes).
     177                 :             :  * ----------------------------------------------------------------
     178                 :             :  */
     179                 :             : ResultState *
     180                 :      172575 : ExecInitResult(Result *node, EState *estate, int eflags)
     181                 :             : {
     182                 :             :     ResultState *resstate;
     183                 :             : 
     184                 :             :     /* check for unsupported flags */
     185                 :             :     Assert(!(eflags & (EXEC_FLAG_MARK | EXEC_FLAG_BACKWARD)) ||
     186                 :             :            outerPlan(node) != NULL);
     187                 :             : 
     188                 :             :     /*
     189                 :             :      * create state structure
     190                 :             :      */
     191                 :      172575 :     resstate = makeNode(ResultState);
     192                 :      172575 :     resstate->ps.plan = (Plan *) node;
     193                 :      172575 :     resstate->ps.state = estate;
     194                 :      172575 :     resstate->ps.ExecProcNode = ExecResult;
     195                 :             : 
     196                 :      172575 :     resstate->rs_done = false;
     197                 :      172575 :     resstate->rs_checkqual = (node->resconstantqual != NULL);
     198                 :             : 
     199                 :             :     /*
     200                 :             :      * Miscellaneous initialization
     201                 :             :      *
     202                 :             :      * create expression context for node
     203                 :             :      */
     204                 :      172575 :     ExecAssignExprContext(estate, &resstate->ps);
     205                 :             : 
     206                 :             :     /*
     207                 :             :      * initialize child nodes
     208                 :             :      */
     209                 :      172575 :     outerPlanState(resstate) = ExecInitNode(outerPlan(node), estate, eflags);
     210                 :             : 
     211                 :             :     /*
     212                 :             :      * we don't use inner plan
     213                 :             :      */
     214                 :             :     Assert(innerPlan(node) == NULL);
     215                 :             : 
     216                 :             :     /*
     217                 :             :      * Initialize result slot, type and projection.
     218                 :             :      */
     219                 :      172575 :     ExecInitResultTupleSlotTL(&resstate->ps, &TTSOpsVirtual);
     220                 :      172575 :     ExecAssignProjectionInfo(&resstate->ps, NULL);
     221                 :             : 
     222                 :             :     /*
     223                 :             :      * initialize child expressions
     224                 :             :      */
     225                 :      172535 :     resstate->ps.qual =
     226                 :      172535 :         ExecInitQual(node->plan.qual, (PlanState *) resstate);
     227                 :      172535 :     resstate->resconstantqual =
     228                 :      172535 :         ExecInitQual((List *) node->resconstantqual, (PlanState *) resstate);
     229                 :             : 
     230                 :      172535 :     return resstate;
     231                 :             : }
     232                 :             : 
     233                 :             : /* ----------------------------------------------------------------
     234                 :             :  *      ExecEndResult
     235                 :             :  *
     236                 :             :  *      frees up storage allocated through C routines
     237                 :             :  * ----------------------------------------------------------------
     238                 :             :  */
     239                 :             : void
     240                 :      160845 : ExecEndResult(ResultState *node)
     241                 :             : {
     242                 :             :     /*
     243                 :             :      * shut down subplans
     244                 :             :      */
     245                 :      160845 :     ExecEndNode(outerPlanState(node));
     246                 :      160845 : }
     247                 :             : 
     248                 :             : void
     249                 :       67466 : ExecReScanResult(ResultState *node)
     250                 :             : {
     251                 :       67466 :     PlanState  *outerPlan = outerPlanState(node);
     252                 :             : 
     253                 :       67466 :     node->rs_done = false;
     254                 :       67466 :     node->rs_checkqual = (node->resconstantqual != NULL);
     255                 :             : 
     256                 :             :     /*
     257                 :             :      * If chgParam of subnode is not null then plan will be re-scanned by
     258                 :             :      * first ExecProcNode.
     259                 :             :      */
     260   [ +  +  +  + ]:       67466 :     if (outerPlan && outerPlan->chgParam == NULL)
     261                 :         139 :         ExecReScan(outerPlan);
     262                 :       67466 : }
        

Generated by: LCOV version 2.0-1