PostgreSQL Source Code  git master
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-2019, 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/execdebug.h"
32 
34 
35 /* ----------------------------------------------------------------
36  * Scan Support
37  * ----------------------------------------------------------------
38  */
39 /* ----------------------------------------------------------------
40  * SubqueryNext
41  *
42  * This is a workhorse for ExecSubqueryScan
43  * ----------------------------------------------------------------
44  */
45 static 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  */
66 static 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  */
82 static TupleTableSlot *
84 {
86 
87  return ExecScan(&node->ss,
90 }
91 
92 /* ----------------------------------------------------------------
93  * ExecInitSubqueryScan
94  * ----------------------------------------------------------------
95  */
97 ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
98 {
99  SubqueryScanState *subquerystate;
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  */
111  subquerystate = makeNode(SubqueryScanState);
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  */
131  ExecInitScanTupleSlot(estate, &subquerystate->ss,
132  ExecGetResultType(subquerystate->subplan),
133  ExecGetResultSlotOps(subquerystate->subplan, NULL));
134 
135  /*
136  * The slot used as the scantuple isn't the slot above (outside of EPQ),
137  * but the one from the node below.
138  */
139  subquerystate->ss.ps.scanopsset = true;
140  subquerystate->ss.ps.scanops = ExecGetResultSlotOps(subquerystate->subplan,
141  &subquerystate->ss.ps.scanopsfixed);
142  subquerystate->ss.ps.resultopsset = true;
143  subquerystate->ss.ps.resultops = subquerystate->ss.ps.scanops;
144  subquerystate->ss.ps.resultopsfixed = subquerystate->ss.ps.scanopsfixed;
145 
146  /*
147  * Initialize result type and projection.
148  */
149  ExecInitResultTypeTL(&subquerystate->ss.ps);
150  ExecAssignScanProjectionInfo(&subquerystate->ss);
151 
152  /*
153  * initialize child expressions
154  */
155  subquerystate->ss.ps.qual =
156  ExecInitQual(node->scan.plan.qual, (PlanState *) subquerystate);
157 
158  return subquerystate;
159 }
160 
161 /* ----------------------------------------------------------------
162  * ExecEndSubqueryScan
163  *
164  * frees any storage allocated through C routines.
165  * ----------------------------------------------------------------
166  */
167 void
169 {
170  /*
171  * Free the exprcontext
172  */
173  ExecFreeExprContext(&node->ss.ps);
174 
175  /*
176  * clean out the upper tuple table
177  */
178  if (node->ss.ps.ps_ResultTupleSlot)
181 
182  /*
183  * close down subquery
184  */
185  ExecEndNode(node->subplan);
186 }
187 
188 /* ----------------------------------------------------------------
189  * ExecReScanSubqueryScan
190  *
191  * Rescans the relation.
192  * ----------------------------------------------------------------
193  */
194 void
196 {
197  ExecScanReScan(&node->ss);
198 
199  /*
200  * ExecReScan doesn't know about my subplan, so I have to do
201  * changed-parameter signaling myself. This is just as well, because the
202  * subplan has its own memory context in which its chgParam state lives.
203  */
204  if (node->ss.ps.chgParam != NULL)
206 
207  /*
208  * if chgParam of subnode is not null then plan will be re-scanned by
209  * first ExecProcNode.
210  */
211  if (node->subplan->chgParam == NULL)
212  ExecReScan(node->subplan);
213 }
List * qual
Definition: plannodes.h:141
Plan plan
Definition: plannodes.h:340
static TupleTableSlot * ExecSubqueryScan(PlanState *pstate)
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
Definition: execUtils.c:463
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:426
#define castNode(_type_, nodeptr)
Definition: nodes.h:594
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:538
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:158
void ExecReScan(PlanState *node)
Definition: execAmi.c:77
static TupleTableSlot * SubqueryNext(SubqueryScanState *node)
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1334
EState * state
Definition: execnodes.h:942
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:614
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:207
const TupleTableSlotOps * resultops
Definition: execnodes.h:1015
void ExecEndSubqueryScan(SubqueryScanState *node)
PlanState ps
Definition: execnodes.h:1331
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:978
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:272
#define innerPlan(node)
Definition: plannodes.h:169
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1776
const TupleTableSlotOps * scanops
Definition: execnodes.h:1012
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1720
SubqueryScanState * ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
PlanState * subplan
Definition: execnodes.h:1638
bool resultopsset
Definition: execnodes.h:1023
Bitmapset * chgParam
Definition: execnodes.h:972
#define outerPlan(node)
Definition: plannodes.h:170
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:426
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:946
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition: executor.h:235
void ExecReScanSubqueryScan(SubqueryScanState *node)
Plan * plan
Definition: execnodes.h:940
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:802
bool scanopsfixed
Definition: execnodes.h:1016
#define makeNode(_type_)
Definition: nodes.h:573
static bool SubqueryRecheck(SubqueryScanState *node, TupleTableSlot *slot)
#define Assert(condition)
Definition: c.h:732
#define EXEC_FLAG_MARK
Definition: executor.h:59
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:444
bool scanopsset
Definition: execnodes.h:1020
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:454
ExprState * qual
Definition: execnodes.h:961
bool resultopsfixed
Definition: execnodes.h:1019
void ExecScanReScan(ScanState *node)
Definition: execScan.c:299
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:425
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:139
Plan * subplan
Definition: plannodes.h:511