@ -21,6 +21,11 @@
* ExecEndIndexOnlyScan releases all storage .
* ExecIndexOnlyMarkPos marks scan position .
* ExecIndexOnlyRestrPos restores scan position .
* ExecIndexOnlyScanEstimate estimates DSM space needed for
* parallel index - only scan
* ExecIndexOnlyScanInitializeDSM initialize DSM for parallel
* index - only scan
* ExecIndexOnlyScanInitializeWorker attach to DSM info in parallel worker
*/
# include "postgres.h"
@ -277,6 +282,16 @@ ExecIndexOnlyScan(IndexOnlyScanState *node)
void
ExecReScanIndexOnlyScan ( IndexOnlyScanState * node )
{
bool reset_parallel_scan = true ;
/*
* If we are here to just update the scan keys , then don ' t reset parallel
* scan . For detailed reason behind this look in the comments for
* ExecReScanIndexScan .
*/
if ( node - > ioss_NumRuntimeKeys ! = 0 & & ! node - > ioss_RuntimeKeysReady )
reset_parallel_scan = false ;
/*
* If we are doing runtime key calculations ( ie , any of the index key
* values weren ' t simple Consts ) , compute the new key values . But first ,
@ -296,10 +311,16 @@ ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
node - > ioss_RuntimeKeysReady = true ;
/* reset index scan */
index_rescan ( node - > ioss_ScanDesc ,
node - > ioss_ScanKeys , node - > ioss_NumScanKeys ,
node - > ioss_OrderByKeys , node - > ioss_NumOrderByKeys ) ;
if ( node - > ioss_ScanDesc )
{
index_rescan ( node - > ioss_ScanDesc ,
node - > ioss_ScanKeys , node - > ioss_NumScanKeys ,
node - > ioss_OrderByKeys , node - > ioss_NumOrderByKeys ) ;
if ( reset_parallel_scan & & node - > ioss_ScanDesc - > parallel_scan )
index_parallelrescan ( node - > ioss_ScanDesc ) ;
}
ExecScanReScan ( & node - > ss ) ;
}
@ -536,29 +557,124 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
/*
* Initialize scan descriptor .
*/
indexstate - > ioss_ScanDesc = index_beginscan ( currentRelation ,
indexstate - > ioss_RelationDesc ,
estate - > es_snapshot ,
if ( ! node - > scan . plan . parallel_aware )
{
indexstate - > ioss_ScanDesc = index_beginscan ( currentRelation ,
indexstate - > ioss_RelationDesc ,
estate - > es_snapshot ,
indexstate - > ioss_NumScanKeys ,
indexstate - > ioss_NumOrderByKeys ) ;
/* Set it up for index-only scan */
indexstate - > ioss_ScanDesc - > xs_want_itup = true ;
indexstate - > ioss_VMBuffer = InvalidBuffer ;
/*
* If no run - time keys to calculate , go ahead and pass the scankeys to the
* index AM .
*/
if ( indexstate - > ioss_NumRuntimeKeys = = 0 )
index_rescan ( indexstate - > ioss_ScanDesc ,
indexstate - > ioss_ScanKeys ,
indexstate - > ioss_NumScanKeys ,
indexstate - > ioss_OrderByKeys ,
indexstate - > ioss_NumOrderByKeys ) ;
/* Set it up for index-only scan */
indexstate - > ioss_ScanDesc - > xs_want_itup = true ;
indexstate - > ioss_VMBuffer = InvalidBuffer ;
/*
* If no run - time keys to calculate , go ahead and pass the scankeys to
* the index AM .
*/
if ( indexstate - > ioss_NumRuntimeKeys = = 0 )
index_rescan ( indexstate - > ioss_ScanDesc ,
indexstate - > ioss_ScanKeys ,
indexstate - > ioss_NumScanKeys ,
indexstate - > ioss_OrderByKeys ,
indexstate - > ioss_NumOrderByKeys ) ;
}
/*
* all done .
*/
return indexstate ;
}
/* ----------------------------------------------------------------
* Parallel Index - only Scan Support
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
/* ----------------------------------------------------------------
* ExecIndexOnlyScanEstimate
*
* estimates the space required to serialize index - only scan node .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
void
ExecIndexOnlyScanEstimate ( IndexOnlyScanState * node ,
ParallelContext * pcxt )
{
EState * estate = node - > ss . ps . state ;
node - > ioss_PscanLen = index_parallelscan_estimate ( node - > ioss_RelationDesc ,
estate - > es_snapshot ) ;
shm_toc_estimate_chunk ( & pcxt - > estimator , node - > ioss_PscanLen ) ;
shm_toc_estimate_keys ( & pcxt - > estimator , 1 ) ;
}
/* ----------------------------------------------------------------
* ExecIndexOnlyScanInitializeDSM
*
* Set up a parallel index - only scan descriptor .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
void
ExecIndexOnlyScanInitializeDSM ( IndexOnlyScanState * node ,
ParallelContext * pcxt )
{
EState * estate = node - > ss . ps . state ;
ParallelIndexScanDesc piscan ;
piscan = shm_toc_allocate ( pcxt - > toc , node - > ioss_PscanLen ) ;
index_parallelscan_initialize ( node - > ss . ss_currentRelation ,
node - > ioss_RelationDesc ,
estate - > es_snapshot ,
piscan ) ;
shm_toc_insert ( pcxt - > toc , node - > ss . ps . plan - > plan_node_id , piscan ) ;
node - > ioss_ScanDesc =
index_beginscan_parallel ( node - > ss . ss_currentRelation ,
node - > ioss_RelationDesc ,
node - > ioss_NumScanKeys ,
node - > ioss_NumOrderByKeys ,
piscan ) ;
node - > ioss_ScanDesc - > xs_want_itup = true ;
node - > ioss_VMBuffer = InvalidBuffer ;
/*
* If no run - time keys to calculate , go ahead and pass the scankeys to
* the index AM .
*/
if ( node - > ioss_NumRuntimeKeys = = 0 )
index_rescan ( node - > ioss_ScanDesc ,
node - > ioss_ScanKeys , node - > ioss_NumScanKeys ,
node - > ioss_OrderByKeys , node - > ioss_NumOrderByKeys ) ;
}
/* ----------------------------------------------------------------
* ExecIndexOnlyScanInitializeWorker
*
* Copy relevant information from TOC into planstate .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
void
ExecIndexOnlyScanInitializeWorker ( IndexOnlyScanState * node , shm_toc * toc )
{
ParallelIndexScanDesc piscan ;
piscan = shm_toc_lookup ( toc , node - > ss . ps . plan - > plan_node_id ) ;
node - > ioss_ScanDesc =
index_beginscan_parallel ( node - > ss . ss_currentRelation ,
node - > ioss_RelationDesc ,
node - > ioss_NumScanKeys ,
node - > ioss_NumOrderByKeys ,
piscan ) ;
node - > ioss_ScanDesc - > xs_want_itup = true ;
/*
* If no run - time keys to calculate , go ahead and pass the scankeys to the
* index AM .
*/
if ( node - > ioss_NumRuntimeKeys = = 0 )
index_rescan ( node - > ioss_ScanDesc ,
node - > ioss_ScanKeys , node - > ioss_NumScanKeys ,
node - > ioss_OrderByKeys , node - > ioss_NumOrderByKeys ) ;
}