1/*-------------------------------------------------------------------------
4 * support for constant nodes needing special code.
8 * Result nodes are used in queries where no relations are scanned.
9 * Examples of such queries are:
13 * insert into emp values ('mike', 15000)
15 * (Remember that in an INSERT or UPDATE, we need a plan tree that
16 * generates the new rows.)
18 * Result nodes are also used to optimise queries with constant
19 * qualifications (ie, quals that do not depend on the scanned data),
22 * select * from emp where 2 > 1
24 * In this case, the plan generated is
26 * Result (with 2 > 1 qual)
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.
37 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
38 * Portions Copyright (c) 1994, Regents of the University of California
41 * src/backend/executor/nodeResult.c
43 *-------------------------------------------------------------------------
53/* ----------------------------------------------------------------
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
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 * ----------------------------------------------------------------
79 * check constant qualifications like (2 > 1), if not already done
94 * Reset per-tuple memory context to free any expression evaluation
95 * storage allocated in the previous tuple cycle.
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
112 * retrieve tuples from the outer plan until there are no more.
120 * prepare to compute projection expressions, which will expect to
121 * access the input tuples as varno OUTER.
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.
134 /* form the result tuple using ExecProject(), and return it */
141/* ----------------------------------------------------------------
143 * ----------------------------------------------------------------
153 elog(
DEBUG2,
"Result nodes do not support mark/restore");
156/* ----------------------------------------------------------------
158 * ----------------------------------------------------------------
168 elog(
ERROR,
"Result nodes do not support mark/restore");
171/* ----------------------------------------------------------------
174 * Creates the run-time state information for the result node
175 * produced by the planner and initializes outer relations
177 * ----------------------------------------------------------------
184 /* check for unsupported flags */
189 * create state structure
200 * Miscellaneous initialization
202 * create expression context for node
207 * initialize child nodes
212 * we don't use inner plan
217 * Initialize result slot, type and projection.
223 * initialize child expressions
233/* ----------------------------------------------------------------
236 * frees up storage allocated through C routines
237 * ----------------------------------------------------------------
257 * If chgParam of subnode is not null then plan will be re-scanned by
258 * first ExecProcNode.
void ExecMarkPos(PlanState *node)
void ExecReScan(PlanState *node)
void ExecRestrPos(PlanState *node)
ExprState * ExecInitQual(List *qual, PlanState *parent)
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
const TupleTableSlotOps TTSOpsVirtual
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
#define outerPlanState(node)
#define EXEC_FLAG_BACKWARD
static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
#define ResetExprContext(econtext)
static bool ExecQual(ExprState *state, ExprContext *econtext)
static TupleTableSlot * ExecProcNode(PlanState *node)
Assert(PointerIsAligned(start, uint64))
#define CHECK_FOR_INTERRUPTS()
void ExecReScanResult(ResultState *node)
static TupleTableSlot * ExecResult(PlanState *pstate)
ResultState * ExecInitResult(Result *node, EState *estate, int eflags)
void ExecEndResult(ResultState *node)
void ExecResultRestrPos(ResultState *node)
void ExecResultMarkPos(ResultState *node)
#define castNode(_type_, nodeptr)
TupleTableSlot * ecxt_outertuple
ExprContext * ps_ExprContext
ProjectionInfo * ps_ProjInfo
ExecProcNodeMtd ExecProcNode
ExprState * resconstantqual