2121 * ExecEndIndexOnlyScan releases all storage.
2222 * ExecIndexOnlyMarkPos marks scan position.
2323 * ExecIndexOnlyRestrPos restores scan position.
24+ * ExecIndexOnlyScanEstimate estimates DSM space needed for
25+ * parallel index-only scan
26+ * ExecIndexOnlyScanInitializeDSM initialize DSM for parallel
27+ * index-only scan
28+ * ExecIndexOnlyScanInitializeWorker attach to DSM info in parallel worker
2429 */
2530#include "postgres.h"
2631
@@ -277,6 +282,16 @@ ExecIndexOnlyScan(IndexOnlyScanState *node)
277282void
278283ExecReScanIndexOnlyScan (IndexOnlyScanState * node )
279284{
285+ bool reset_parallel_scan = true;
286+
287+ /*
288+ * If we are here to just update the scan keys, then don't reset parallel
289+ * scan. For detailed reason behind this look in the comments for
290+ * ExecReScanIndexScan.
291+ */
292+ if (node -> ioss_NumRuntimeKeys != 0 && !node -> ioss_RuntimeKeysReady )
293+ reset_parallel_scan = false;
294+
280295 /*
281296 * If we are doing runtime key calculations (ie, any of the index key
282297 * values weren't simple Consts), compute the new key values. But first,
@@ -296,10 +311,16 @@ ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
296311 node -> ioss_RuntimeKeysReady = true;
297312
298313 /* reset index scan */
299- index_rescan (node -> ioss_ScanDesc ,
300- node -> ioss_ScanKeys , node -> ioss_NumScanKeys ,
301- node -> ioss_OrderByKeys , node -> ioss_NumOrderByKeys );
314+ if (node -> ioss_ScanDesc )
315+ {
316+
317+ index_rescan (node -> ioss_ScanDesc ,
318+ node -> ioss_ScanKeys , node -> ioss_NumScanKeys ,
319+ node -> ioss_OrderByKeys , node -> ioss_NumOrderByKeys );
302320
321+ if (reset_parallel_scan && node -> ioss_ScanDesc -> parallel_scan )
322+ index_parallelrescan (node -> ioss_ScanDesc );
323+ }
303324 ExecScanReScan (& node -> ss );
304325}
305326
@@ -536,29 +557,124 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
536557 /*
537558 * Initialize scan descriptor.
538559 */
539- indexstate -> ioss_ScanDesc = index_beginscan (currentRelation ,
540- indexstate -> ioss_RelationDesc ,
541- estate -> es_snapshot ,
560+ if (!node -> scan .plan .parallel_aware )
561+ {
562+ indexstate -> ioss_ScanDesc = index_beginscan (currentRelation ,
563+ indexstate -> ioss_RelationDesc ,
564+ estate -> es_snapshot ,
542565 indexstate -> ioss_NumScanKeys ,
543566 indexstate -> ioss_NumOrderByKeys );
544567
545- /* Set it up for index-only scan */
546- indexstate -> ioss_ScanDesc -> xs_want_itup = true;
547- indexstate -> ioss_VMBuffer = InvalidBuffer ;
548568
549- /*
550- * If no run-time keys to calculate, go ahead and pass the scankeys to the
551- * index AM.
552- */
553- if (indexstate -> ioss_NumRuntimeKeys == 0 )
554- index_rescan (indexstate -> ioss_ScanDesc ,
555- indexstate -> ioss_ScanKeys ,
556- indexstate -> ioss_NumScanKeys ,
557- indexstate -> ioss_OrderByKeys ,
558- indexstate -> ioss_NumOrderByKeys );
569+ /* Set it up for index-only scan */
570+ indexstate -> ioss_ScanDesc -> xs_want_itup = true;
571+ indexstate -> ioss_VMBuffer = InvalidBuffer ;
572+
573+ /*
574+ * If no run-time keys to calculate, go ahead and pass the scankeys to
575+ * the index AM.
576+ */
577+ if (indexstate -> ioss_NumRuntimeKeys == 0 )
578+ index_rescan (indexstate -> ioss_ScanDesc ,
579+ indexstate -> ioss_ScanKeys ,
580+ indexstate -> ioss_NumScanKeys ,
581+ indexstate -> ioss_OrderByKeys ,
582+ indexstate -> ioss_NumOrderByKeys );
583+ }
559584
560585 /*
561586 * all done.
562587 */
563588 return indexstate ;
564589}
590+
591+ /* ----------------------------------------------------------------
592+ * Parallel Index-only Scan Support
593+ * ----------------------------------------------------------------
594+ */
595+
596+ /* ----------------------------------------------------------------
597+ * ExecIndexOnlyScanEstimate
598+ *
599+ * estimates the space required to serialize index-only scan node.
600+ * ----------------------------------------------------------------
601+ */
602+ void
603+ ExecIndexOnlyScanEstimate (IndexOnlyScanState * node ,
604+ ParallelContext * pcxt )
605+ {
606+ EState * estate = node -> ss .ps .state ;
607+
608+ node -> ioss_PscanLen = index_parallelscan_estimate (node -> ioss_RelationDesc ,
609+ estate -> es_snapshot );
610+ shm_toc_estimate_chunk (& pcxt -> estimator , node -> ioss_PscanLen );
611+ shm_toc_estimate_keys (& pcxt -> estimator , 1 );
612+ }
613+
614+ /* ----------------------------------------------------------------
615+ * ExecIndexOnlyScanInitializeDSM
616+ *
617+ * Set up a parallel index-only scan descriptor.
618+ * ----------------------------------------------------------------
619+ */
620+ void
621+ ExecIndexOnlyScanInitializeDSM (IndexOnlyScanState * node ,
622+ ParallelContext * pcxt )
623+ {
624+ EState * estate = node -> ss .ps .state ;
625+ ParallelIndexScanDesc piscan ;
626+
627+ piscan = shm_toc_allocate (pcxt -> toc , node -> ioss_PscanLen );
628+ index_parallelscan_initialize (node -> ss .ss_currentRelation ,
629+ node -> ioss_RelationDesc ,
630+ estate -> es_snapshot ,
631+ piscan );
632+ shm_toc_insert (pcxt -> toc , node -> ss .ps .plan -> plan_node_id , piscan );
633+ node -> ioss_ScanDesc =
634+ index_beginscan_parallel (node -> ss .ss_currentRelation ,
635+ node -> ioss_RelationDesc ,
636+ node -> ioss_NumScanKeys ,
637+ node -> ioss_NumOrderByKeys ,
638+ piscan );
639+ node -> ioss_ScanDesc -> xs_want_itup = true;
640+ node -> ioss_VMBuffer = InvalidBuffer ;
641+
642+ /*
643+ * If no run-time keys to calculate, go ahead and pass the scankeys to
644+ * the index AM.
645+ */
646+ if (node -> ioss_NumRuntimeKeys == 0 )
647+ index_rescan (node -> ioss_ScanDesc ,
648+ node -> ioss_ScanKeys , node -> ioss_NumScanKeys ,
649+ node -> ioss_OrderByKeys , node -> ioss_NumOrderByKeys );
650+ }
651+
652+ /* ----------------------------------------------------------------
653+ * ExecIndexOnlyScanInitializeWorker
654+ *
655+ * Copy relevant information from TOC into planstate.
656+ * ----------------------------------------------------------------
657+ */
658+ void
659+ ExecIndexOnlyScanInitializeWorker (IndexOnlyScanState * node , shm_toc * toc )
660+ {
661+ ParallelIndexScanDesc piscan ;
662+
663+ piscan = shm_toc_lookup (toc , node -> ss .ps .plan -> plan_node_id );
664+ node -> ioss_ScanDesc =
665+ index_beginscan_parallel (node -> ss .ss_currentRelation ,
666+ node -> ioss_RelationDesc ,
667+ node -> ioss_NumScanKeys ,
668+ node -> ioss_NumOrderByKeys ,
669+ piscan );
670+ node -> ioss_ScanDesc -> xs_want_itup = true;
671+
672+ /*
673+ * If no run-time keys to calculate, go ahead and pass the scankeys to the
674+ * index AM.
675+ */
676+ if (node -> ioss_NumRuntimeKeys == 0 )
677+ index_rescan (node -> ioss_ScanDesc ,
678+ node -> ioss_ScanKeys , node -> ioss_NumScanKeys ,
679+ node -> ioss_OrderByKeys , node -> ioss_NumOrderByKeys );
680+ }
0 commit comments