PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2016, 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  */
84 {
85  return ExecScan(&node->ss,
88 }
89 
90 /* ----------------------------------------------------------------
91  * ExecInitSubqueryScan
92  * ----------------------------------------------------------------
93  */
95 ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
96 {
97  SubqueryScanState *subquerystate;
98 
99  /* check for unsupported flags */
100  Assert(!(eflags & EXEC_FLAG_MARK));
101 
102  /* SubqueryScan should not have any "normal" children */
103  Assert(outerPlan(node) == NULL);
104  Assert(innerPlan(node) == NULL);
105 
106  /*
107  * create state structure
108  */
109  subquerystate = makeNode(SubqueryScanState);
110  subquerystate->ss.ps.plan = (Plan *) node;
111  subquerystate->ss.ps.state = estate;
112 
113  /*
114  * Miscellaneous initialization
115  *
116  * create expression context for node
117  */
118  ExecAssignExprContext(estate, &subquerystate->ss.ps);
119 
120  /*
121  * initialize child expressions
122  */
123  subquerystate->ss.ps.targetlist = (List *)
125  (PlanState *) subquerystate);
126  subquerystate->ss.ps.qual = (List *)
127  ExecInitExpr((Expr *) node->scan.plan.qual,
128  (PlanState *) subquerystate);
129 
130  /*
131  * tuple table initialization
132  */
133  ExecInitResultTupleSlot(estate, &subquerystate->ss.ps);
134  ExecInitScanTupleSlot(estate, &subquerystate->ss);
135 
136  /*
137  * initialize subquery
138  */
139  subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
140 
141  subquerystate->ss.ps.ps_TupFromTlist = false;
142 
143  /*
144  * Initialize scan tuple type (needed by ExecAssignScanProjectionInfo)
145  */
146  ExecAssignScanType(&subquerystate->ss,
147  ExecGetResultType(subquerystate->subplan));
148 
149  /*
150  * Initialize result tuple type and projection info.
151  */
152  ExecAssignResultTypeFromTL(&subquerystate->ss.ps);
153  ExecAssignScanProjectionInfo(&subquerystate->ss);
154 
155  return subquerystate;
156 }
157 
158 /* ----------------------------------------------------------------
159  * ExecEndSubqueryScan
160  *
161  * frees any storage allocated through C routines.
162  * ----------------------------------------------------------------
163  */
164 void
166 {
167  /*
168  * Free the exprcontext
169  */
170  ExecFreeExprContext(&node->ss.ps);
171 
172  /*
173  * clean out the upper tuple table
174  */
177 
178  /*
179  * close down subquery
180  */
181  ExecEndNode(node->subplan);
182 }
183 
184 /* ----------------------------------------------------------------
185  * ExecReScanSubqueryScan
186  *
187  * Rescans the relation.
188  * ----------------------------------------------------------------
189  */
190 void
192 {
193  ExecScanReScan(&node->ss);
194 
195  /*
196  * ExecReScan doesn't know about my subplan, so I have to do
197  * changed-parameter signaling myself. This is just as well, because the
198  * subplan has its own memory context in which its chgParam state lives.
199  */
200  if (node->ss.ps.chgParam != NULL)
202 
203  /*
204  * if chgParam of subnode is not null then plan will be re-scanned by
205  * first ExecProcNode.
206  */
207  if (node->subplan->chgParam == NULL)
208  ExecReScan(node->subplan);
209 }
List * qual
Definition: plannodes.h:122
TupleTableSlot * ExecProcNode(PlanState *node)
Definition: execProcnode.c:374
Plan plan
Definition: plannodes.h:286
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
Definition: execTuples.c:845
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:614
Definition: plannodes.h:96
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:121
void ExecReScan(PlanState *node)
Definition: execAmi.c:73
static TupleTableSlot * SubqueryNext(SubqueryScanState *node)
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:442
List * qual
Definition: execnodes.h:1042
List * targetlist
Definition: execnodes.h:1041
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1251
EState * state
Definition: execnodes.h:1029
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:696
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:435
void ExecEndSubqueryScan(SubqueryScanState *node)
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:255
PlanState ps
Definition: execnodes.h:1248
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:256
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1057
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execQual.c:4452
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:259
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:835
#define innerPlan(node)
Definition: plannodes.h:150
TupleTableSlot * ExecSubqueryScan(SubqueryScanState *node)
SubqueryScanState * ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
PlanState * subplan
Definition: execnodes.h:1483
Bitmapset * chgParam
Definition: execnodes.h:1052
#define outerPlan(node)
Definition: plannodes.h:151
void ExecReScanSubqueryScan(SubqueryScanState *node)
Plan * plan
Definition: execnodes.h:1027
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:851
#define makeNode(_type_)
Definition: nodes.h:539
#define NULL
Definition: c.h:226
static bool SubqueryRecheck(SubqueryScanState *node, TupleTableSlot *slot)
#define Assert(condition)
Definition: c.h:667
#define EXEC_FLAG_MARK
Definition: executor.h:60
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:413
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:464
List * targetlist
Definition: plannodes.h:121
void ExecScanReScan(ScanState *node)
Definition: execScan.c:351
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:720
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:136
bool ps_TupFromTlist
Definition: execnodes.h:1060
Definition: pg_list.h:45
Plan * subplan
Definition: plannodes.h:455