1919 * ExecInitSeqScan creates and initializes a seqscan node.
2020 * ExecEndSeqScan releases any storage allocated.
2121 * ExecReScanSeqScan rescans the relation
22+ *
23+ * ExecSeqScanEstimate estimates DSM space needed for parallel scan
24+ * ExecSeqScanInitializeDSM initialize DSM for parallel scan
25+ * ExecSeqScanInitializeWorker attach to DSM info in parallel worker
2226 */
2327#include "postgres.h"
2428
@@ -53,10 +57,22 @@ SeqNext(SeqScanState *node)
5357 /*
5458 * get information from the estate and scan state
5559 */
56- scandesc = node -> ss_currentScanDesc ;
57- estate = node -> ps .state ;
60+ scandesc = node -> ss . ss_currentScanDesc ;
61+ estate = node -> ss . ps .state ;
5862 direction = estate -> es_direction ;
59- slot = node -> ss_ScanTupleSlot ;
63+ slot = node -> ss .ss_ScanTupleSlot ;
64+
65+ if (scandesc == NULL )
66+ {
67+ /*
68+ * We reach here if the scan is not parallel, or if we're executing
69+ * a scan that was intended to be parallel serially.
70+ */
71+ scandesc = heap_beginscan (node -> ss .ss_currentRelation ,
72+ estate -> es_snapshot ,
73+ 0 , NULL );
74+ node -> ss .ss_currentScanDesc = scandesc ;
75+ }
6076
6177 /*
6278 * get the next tuple from the table
@@ -123,27 +139,19 @@ static void
123139InitScanRelation (SeqScanState * node , EState * estate , int eflags )
124140{
125141 Relation currentRelation ;
126- HeapScanDesc currentScanDesc ;
127142
128143 /*
129144 * get the relation object id from the relid'th entry in the range table,
130145 * open that relation and acquire appropriate lock on it.
131146 */
132147 currentRelation = ExecOpenScanRelation (estate ,
133- ((SeqScan * ) node -> ps .plan )-> scanrelid ,
148+ ((SeqScan * ) node -> ss . ps .plan )-> scanrelid ,
134149 eflags );
135150
136- /* initialize a heapscan */
137- currentScanDesc = heap_beginscan (currentRelation ,
138- estate -> es_snapshot ,
139- 0 ,
140- NULL );
141-
142- node -> ss_currentRelation = currentRelation ;
143- node -> ss_currentScanDesc = currentScanDesc ;
151+ node -> ss .ss_currentRelation = currentRelation ;
144152
145153 /* and report the scan tuple slot's rowtype */
146- ExecAssignScanType (node , RelationGetDescr (currentRelation ));
154+ ExecAssignScanType (& node -> ss , RelationGetDescr (currentRelation ));
147155}
148156
149157
@@ -167,44 +175,44 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
167175 * create state structure
168176 */
169177 scanstate = makeNode (SeqScanState );
170- scanstate -> ps .plan = (Plan * ) node ;
171- scanstate -> ps .state = estate ;
178+ scanstate -> ss . ps .plan = (Plan * ) node ;
179+ scanstate -> ss . ps .state = estate ;
172180
173181 /*
174182 * Miscellaneous initialization
175183 *
176184 * create expression context for node
177185 */
178- ExecAssignExprContext (estate , & scanstate -> ps );
186+ ExecAssignExprContext (estate , & scanstate -> ss . ps );
179187
180188 /*
181189 * initialize child expressions
182190 */
183- scanstate -> ps .targetlist = (List * )
191+ scanstate -> ss . ps .targetlist = (List * )
184192 ExecInitExpr ((Expr * ) node -> plan .targetlist ,
185193 (PlanState * ) scanstate );
186- scanstate -> ps .qual = (List * )
194+ scanstate -> ss . ps .qual = (List * )
187195 ExecInitExpr ((Expr * ) node -> plan .qual ,
188196 (PlanState * ) scanstate );
189197
190198 /*
191199 * tuple table initialization
192200 */
193- ExecInitResultTupleSlot (estate , & scanstate -> ps );
194- ExecInitScanTupleSlot (estate , scanstate );
201+ ExecInitResultTupleSlot (estate , & scanstate -> ss . ps );
202+ ExecInitScanTupleSlot (estate , & scanstate -> ss );
195203
196204 /*
197205 * initialize scan relation
198206 */
199207 InitScanRelation (scanstate , estate , eflags );
200208
201- scanstate -> ps .ps_TupFromTlist = false;
209+ scanstate -> ss . ps .ps_TupFromTlist = false;
202210
203211 /*
204212 * Initialize result tuple type and projection info.
205213 */
206- ExecAssignResultTypeFromTL (& scanstate -> ps );
207- ExecAssignScanProjectionInfo (scanstate );
214+ ExecAssignResultTypeFromTL (& scanstate -> ss . ps );
215+ ExecAssignScanProjectionInfo (& scanstate -> ss );
208216
209217 return scanstate ;
210218}
@@ -224,24 +232,25 @@ ExecEndSeqScan(SeqScanState *node)
224232 /*
225233 * get information from node
226234 */
227- relation = node -> ss_currentRelation ;
228- scanDesc = node -> ss_currentScanDesc ;
235+ relation = node -> ss . ss_currentRelation ;
236+ scanDesc = node -> ss . ss_currentScanDesc ;
229237
230238 /*
231239 * Free the exprcontext
232240 */
233- ExecFreeExprContext (& node -> ps );
241+ ExecFreeExprContext (& node -> ss . ps );
234242
235243 /*
236244 * clean out the tuple table
237245 */
238- ExecClearTuple (node -> ps .ps_ResultTupleSlot );
239- ExecClearTuple (node -> ss_ScanTupleSlot );
246+ ExecClearTuple (node -> ss . ps .ps_ResultTupleSlot );
247+ ExecClearTuple (node -> ss . ss_ScanTupleSlot );
240248
241249 /*
242250 * close heap scan
243251 */
244- heap_endscan (scanDesc );
252+ if (scanDesc != NULL )
253+ heap_endscan (scanDesc );
245254
246255 /*
247256 * close the heap relation.
@@ -265,10 +274,71 @@ ExecReScanSeqScan(SeqScanState *node)
265274{
266275 HeapScanDesc scan ;
267276
268- scan = node -> ss_currentScanDesc ;
277+ scan = node -> ss . ss_currentScanDesc ;
269278
270- heap_rescan (scan , /* scan desc */
271- NULL ); /* new scan keys */
279+ if (scan != NULL )
280+ heap_rescan (scan , /* scan desc */
281+ NULL ); /* new scan keys */
272282
273283 ExecScanReScan ((ScanState * ) node );
274284}
285+
286+ /* ----------------------------------------------------------------
287+ * Parallel Scan Support
288+ * ----------------------------------------------------------------
289+ */
290+
291+ /* ----------------------------------------------------------------
292+ * ExecSeqScanEstimate
293+ *
294+ * estimates the space required to serialize seqscan node.
295+ * ----------------------------------------------------------------
296+ */
297+ void
298+ ExecSeqScanEstimate (SeqScanState * node ,
299+ ParallelContext * pcxt )
300+ {
301+ EState * estate = node -> ss .ps .state ;
302+
303+ node -> pscan_len = heap_parallelscan_estimate (estate -> es_snapshot );
304+ shm_toc_estimate_chunk (& pcxt -> estimator , node -> pscan_len );
305+ shm_toc_estimate_keys (& pcxt -> estimator , 1 );
306+ }
307+
308+ /* ----------------------------------------------------------------
309+ * ExecSeqScanInitializeDSM
310+ *
311+ * Set up a parallel heap scan descriptor.
312+ * ----------------------------------------------------------------
313+ */
314+ void
315+ ExecSeqScanInitializeDSM (SeqScanState * node ,
316+ ParallelContext * pcxt )
317+ {
318+ EState * estate = node -> ss .ps .state ;
319+ ParallelHeapScanDesc pscan ;
320+
321+ pscan = shm_toc_allocate (pcxt -> toc , node -> pscan_len );
322+ heap_parallelscan_initialize (pscan ,
323+ node -> ss .ss_currentRelation ,
324+ estate -> es_snapshot );
325+ shm_toc_insert (pcxt -> toc , node -> ss .ps .plan -> plan_node_id , pscan );
326+ node -> ss .ss_currentScanDesc =
327+ heap_beginscan_parallel (node -> ss .ss_currentRelation , pscan );
328+ }
329+
330+ /* ----------------------------------------------------------------
331+ * ExecSeqScanInitializeWorker
332+ *
333+ * Copy relevant information from TOC into planstate.
334+ * ----------------------------------------------------------------
335+ */
336+ void
337+ ExecSeqScanInitializeWorker (SeqScanState * node , shm_toc * toc )
338+ {
339+ ParallelHeapScanDesc pscan ;
340+
341+ pscan = shm_toc_lookup (toc , node -> ss .ps .plan -> plan_node_id );
342+ node -> ss .ss_currentScanDesc =
343+ heap_beginscan_parallel (node -> ss .ss_currentRelation , pscan );
344+ }
0 commit comments