21
21
* ExecEndIndexOnlyScan releases all storage.
22
22
* ExecIndexOnlyMarkPos marks scan position.
23
23
* 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
24
29
*/
25
30
#include "postgres.h"
26
31
@@ -277,6 +282,16 @@ ExecIndexOnlyScan(IndexOnlyScanState *node)
277
282
void
278
283
ExecReScanIndexOnlyScan (IndexOnlyScanState * node )
279
284
{
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
+
280
295
/*
281
296
* If we are doing runtime key calculations (ie, any of the index key
282
297
* values weren't simple Consts), compute the new key values. But first,
@@ -296,10 +311,16 @@ ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
296
311
node -> ioss_RuntimeKeysReady = true;
297
312
298
313
/* 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 );
302
320
321
+ if (reset_parallel_scan && node -> ioss_ScanDesc -> parallel_scan )
322
+ index_parallelrescan (node -> ioss_ScanDesc );
323
+ }
303
324
ExecScanReScan (& node -> ss );
304
325
}
305
326
@@ -536,29 +557,124 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
536
557
/*
537
558
* Initialize scan descriptor.
538
559
*/
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 ,
542
565
indexstate -> ioss_NumScanKeys ,
543
566
indexstate -> ioss_NumOrderByKeys );
544
567
545
- /* Set it up for index-only scan */
546
- indexstate -> ioss_ScanDesc -> xs_want_itup = true;
547
- indexstate -> ioss_VMBuffer = InvalidBuffer ;
548
568
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
+ }
559
584
560
585
/*
561
586
* all done.
562
587
*/
563
588
return indexstate ;
564
589
}
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
+ }