PostgreSQL Source Code git master
Loading...
Searching...
No Matches
nodeSubqueryscan.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * nodeSubqueryscan.c
4 * Support routines for scanning subqueries (subselects in rangetable).
5 *
6 * This is just enough different from sublinks (nodeSubplan.c) to mean that
7 * we need two sets of code. Ought to look at trying to unify the cases.
8 *
9 *
10 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
11 * Portions Copyright (c) 1994, Regents of the University of California
12 *
13 *
14 * IDENTIFICATION
15 * src/backend/executor/nodeSubqueryscan.c
16 *
17 *-------------------------------------------------------------------------
18 */
19/*
20 * INTERFACE ROUTINES
21 * ExecSubqueryScan scans a subquery.
22 * ExecSubqueryNext retrieve next tuple in sequential order.
23 * ExecInitSubqueryScan creates and initializes a subqueryscan node.
24 * ExecEndSubqueryScan releases any storage allocated.
25 * ExecReScanSubqueryScan rescans the relation
26 *
27 */
28#include "postgres.h"
29
30#include "executor/executor.h"
32
34
35/* ----------------------------------------------------------------
36 * Scan Support
37 * ----------------------------------------------------------------
38 */
39/* ----------------------------------------------------------------
40 * SubqueryNext
41 *
42 * This is a workhorse for ExecSubqueryScan
43 * ----------------------------------------------------------------
44 */
45static TupleTableSlot *
47{
48 TupleTableSlot *slot;
49
50 /*
51 * Get the next tuple from the sub-query.
52 */
53 slot = ExecProcNode(node->subplan);
54
55 /*
56 * We just return the subplan's result slot, rather than expending extra
57 * cycles for ExecCopySlot(). (Our own ScanTupleSlot is used only for
58 * EvalPlanQual rechecks.)
59 */
60 return slot;
61}
62
63/*
64 * SubqueryRecheck -- access method routine to recheck a tuple in EvalPlanQual
65 */
66static bool
68{
69 /* nothing to check */
70 return true;
71}
72
73/* ----------------------------------------------------------------
74 * ExecSubqueryScan(node)
75 *
76 * Scans the subquery sequentially and returns the next qualifying
77 * tuple.
78 * We call the ExecScan() routine and pass it the appropriate
79 * access method functions.
80 * ----------------------------------------------------------------
81 */
82static TupleTableSlot *
91
92/* ----------------------------------------------------------------
93 * ExecInitSubqueryScan
94 * ----------------------------------------------------------------
95 */
97ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
98{
100
101 /* check for unsupported flags */
102 Assert(!(eflags & EXEC_FLAG_MARK));
103
104 /* SubqueryScan should not have any "normal" children */
105 Assert(outerPlan(node) == NULL);
106 Assert(innerPlan(node) == NULL);
107
108 /*
109 * create state structure
110 */
112 subquerystate->ss.ps.plan = (Plan *) node;
113 subquerystate->ss.ps.state = estate;
114 subquerystate->ss.ps.ExecProcNode = ExecSubqueryScan;
115
116 /*
117 * Miscellaneous initialization
118 *
119 * create expression context for node
120 */
121 ExecAssignExprContext(estate, &subquerystate->ss.ps);
122
123 /*
124 * initialize subquery
125 */
126 subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
127
128 /*
129 * Initialize scan slot and type (needed by ExecAssignScanProjectionInfo)
130 */
134 0);
135
136 /*
137 * The slot used as the scantuple isn't the slot above (outside of EPQ),
138 * but the one from the node below.
139 */
140 subquerystate->ss.ps.scanopsset = true;
141 subquerystate->ss.ps.scanops = ExecGetResultSlotOps(subquerystate->subplan,
142 &subquerystate->ss.ps.scanopsfixed);
143 subquerystate->ss.ps.resultopsset = true;
144 subquerystate->ss.ps.resultops = subquerystate->ss.ps.scanops;
145 subquerystate->ss.ps.resultopsfixed = subquerystate->ss.ps.scanopsfixed;
146
147 /*
148 * Initialize result type and projection.
149 */
152
153 /*
154 * initialize child expressions
155 */
156 subquerystate->ss.ps.qual =
157 ExecInitQual(node->scan.plan.qual, (PlanState *) subquerystate);
158
159 return subquerystate;
160}
161
162/* ----------------------------------------------------------------
163 * ExecEndSubqueryScan
164 *
165 * frees any storage allocated through C routines.
166 * ----------------------------------------------------------------
167 */
168void
170{
171 /*
172 * close down subquery
173 */
174 ExecEndNode(node->subplan);
175}
176
177/* ----------------------------------------------------------------
178 * ExecReScanSubqueryScan
179 *
180 * Rescans the relation.
181 * ----------------------------------------------------------------
182 */
183void
185{
186 ExecScanReScan(&node->ss);
187
188 /*
189 * ExecReScan doesn't know about my subplan, so I have to do
190 * changed-parameter signaling myself. This is just as well, because the
191 * subplan has its own memory context in which its chgParam state lives.
192 */
193 if (node->ss.ps.chgParam != NULL)
195
196 /*
197 * if chgParam of subnode is not null then plan will be re-scanned by
198 * first ExecProcNode.
199 */
200 if (node->subplan->chgParam == NULL)
201 ExecReScan(node->subplan);
202}
#define Assert(condition)
Definition c.h:945
void ExecReScan(PlanState *node)
Definition execAmi.c:78
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition execExpr.c:250
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition execScan.c:47
void ExecAssignScanProjectionInfo(ScanState *node)
Definition execScan.c:81
void ExecScanReScan(ScanState *node)
Definition execScan.c:108
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops, uint16 flags)
void ExecInitResultTypeTL(PlanState *planstate)
TupleDesc ExecGetResultType(PlanState *planstate)
Definition execUtils.c:500
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition execUtils.c:490
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition execUtils.c:915
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
Definition execUtils.c:509
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition executor.h:583
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition executor.h:315
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition executor.h:582
#define EXEC_FLAG_MARK
Definition executor.h:71
void ExecEndSubqueryScan(SubqueryScanState *node)
static TupleTableSlot * SubqueryNext(SubqueryScanState *node)
void ExecReScanSubqueryScan(SubqueryScanState *node)
SubqueryScanState * ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
static TupleTableSlot * ExecSubqueryScan(PlanState *pstate)
static bool SubqueryRecheck(SubqueryScanState *node, TupleTableSlot *slot)
#define makeNode(_type_)
Definition nodes.h:161
#define castNode(_type_, nodeptr)
Definition nodes.h:182
#define innerPlan(node)
Definition plannodes.h:264
#define outerPlan(node)
Definition plannodes.h:265
static int fb(int x)
Bitmapset * chgParam
Definition execnodes.h:1209
PlanState ps
Definition execnodes.h:1633
PlanState * subplan
Definition execnodes.h:1910
Plan * subplan
Definition plannodes.h:772