|
|
|
|
@@ -20,6 +20,10 @@
|
|
|
|
|
* index_insert - insert an index tuple into a relation
|
|
|
|
|
* index_markpos - mark a scan position
|
|
|
|
|
* index_restrpos - restore a scan position
|
|
|
|
|
* index_parallelscan_estimate - estimate shared memory for parallel scan
|
|
|
|
|
* index_parallelscan_initialize - initialize parallel scan
|
|
|
|
|
* index_parallelrescan - (re)start a parallel scan of an index
|
|
|
|
|
* index_beginscan_parallel - join parallel index scan
|
|
|
|
|
* index_getnext_tid - get the next TID from a scan
|
|
|
|
|
* index_fetch_heap - get the scan's next heap tuple
|
|
|
|
|
* index_getnext - get the next heap tuple from a scan
|
|
|
|
|
@@ -120,7 +124,8 @@ do { \
|
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
static IndexScanDesc index_beginscan_internal(Relation indexRelation,
|
|
|
|
|
int nkeys, int norderbys, Snapshot snapshot);
|
|
|
|
|
int nkeys, int norderbys, Snapshot snapshot,
|
|
|
|
|
ParallelIndexScanDesc pscan, bool temp_snap);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
|
|
|
|
@@ -219,7 +224,7 @@ index_beginscan(Relation heapRelation,
|
|
|
|
|
{
|
|
|
|
|
IndexScanDesc scan;
|
|
|
|
|
|
|
|
|
|
scan = index_beginscan_internal(indexRelation, nkeys, norderbys, snapshot);
|
|
|
|
|
scan = index_beginscan_internal(indexRelation, nkeys, norderbys, snapshot, NULL, false);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Save additional parameters into the scandesc. Everything else was set
|
|
|
|
|
@@ -244,7 +249,7 @@ index_beginscan_bitmap(Relation indexRelation,
|
|
|
|
|
{
|
|
|
|
|
IndexScanDesc scan;
|
|
|
|
|
|
|
|
|
|
scan = index_beginscan_internal(indexRelation, nkeys, 0, snapshot);
|
|
|
|
|
scan = index_beginscan_internal(indexRelation, nkeys, 0, snapshot, NULL, false);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Save additional parameters into the scandesc. Everything else was set
|
|
|
|
|
@@ -260,8 +265,11 @@ index_beginscan_bitmap(Relation indexRelation,
|
|
|
|
|
*/
|
|
|
|
|
static IndexScanDesc
|
|
|
|
|
index_beginscan_internal(Relation indexRelation,
|
|
|
|
|
int nkeys, int norderbys, Snapshot snapshot)
|
|
|
|
|
int nkeys, int norderbys, Snapshot snapshot,
|
|
|
|
|
ParallelIndexScanDesc pscan, bool temp_snap)
|
|
|
|
|
{
|
|
|
|
|
IndexScanDesc scan;
|
|
|
|
|
|
|
|
|
|
RELATION_CHECKS;
|
|
|
|
|
CHECK_REL_PROCEDURE(ambeginscan);
|
|
|
|
|
|
|
|
|
|
@@ -276,8 +284,13 @@ index_beginscan_internal(Relation indexRelation,
|
|
|
|
|
/*
|
|
|
|
|
* Tell the AM to open a scan.
|
|
|
|
|
*/
|
|
|
|
|
return indexRelation->rd_amroutine->ambeginscan(indexRelation, nkeys,
|
|
|
|
|
scan = indexRelation->rd_amroutine->ambeginscan(indexRelation, nkeys,
|
|
|
|
|
norderbys);
|
|
|
|
|
/* Initialize information for parallel scan. */
|
|
|
|
|
scan->parallel_scan = pscan;
|
|
|
|
|
scan->xs_temp_snap = temp_snap;
|
|
|
|
|
|
|
|
|
|
return scan;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
|
@@ -341,6 +354,9 @@ index_endscan(IndexScanDesc scan)
|
|
|
|
|
/* Release index refcount acquired by index_beginscan */
|
|
|
|
|
RelationDecrementReferenceCount(scan->indexRelation);
|
|
|
|
|
|
|
|
|
|
if (scan->xs_temp_snap)
|
|
|
|
|
UnregisterSnapshot(scan->xs_snapshot);
|
|
|
|
|
|
|
|
|
|
/* Release the scan data structure itself */
|
|
|
|
|
IndexScanEnd(scan);
|
|
|
|
|
}
|
|
|
|
|
@@ -389,6 +405,115 @@ index_restrpos(IndexScanDesc scan)
|
|
|
|
|
scan->indexRelation->rd_amroutine->amrestrpos(scan);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* index_parallelscan_estimate - estimate shared memory for parallel scan
|
|
|
|
|
*
|
|
|
|
|
* Currently, we don't pass any information to the AM-specific estimator,
|
|
|
|
|
* so it can probably only return a constant. In the future, we might need
|
|
|
|
|
* to pass more information.
|
|
|
|
|
*/
|
|
|
|
|
Size
|
|
|
|
|
index_parallelscan_estimate(Relation indexRelation, Snapshot snapshot)
|
|
|
|
|
{
|
|
|
|
|
Size nbytes;
|
|
|
|
|
|
|
|
|
|
RELATION_CHECKS;
|
|
|
|
|
|
|
|
|
|
nbytes = offsetof(ParallelIndexScanDescData, ps_snapshot_data);
|
|
|
|
|
nbytes = add_size(nbytes, EstimateSnapshotSpace(snapshot));
|
|
|
|
|
nbytes = MAXALIGN(nbytes);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If amestimateparallelscan is not provided, assume there is no
|
|
|
|
|
* AM-specific data needed. (It's hard to believe that could work, but
|
|
|
|
|
* it's easy enough to cater to it here.)
|
|
|
|
|
*/
|
|
|
|
|
if (indexRelation->rd_amroutine->amestimateparallelscan != NULL)
|
|
|
|
|
nbytes = add_size(nbytes,
|
|
|
|
|
indexRelation->rd_amroutine->amestimateparallelscan());
|
|
|
|
|
|
|
|
|
|
return nbytes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* index_parallelscan_initialize - initialize parallel scan
|
|
|
|
|
*
|
|
|
|
|
* We initialize both the ParallelIndexScanDesc proper and the AM-specific
|
|
|
|
|
* information which follows it.
|
|
|
|
|
*
|
|
|
|
|
* This function calls access method specific initialization routine to
|
|
|
|
|
* initialize am specific information. Call this just once in the leader
|
|
|
|
|
* process; then, individual workers attach via index_beginscan_parallel.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
index_parallelscan_initialize(Relation heapRelation, Relation indexRelation,
|
|
|
|
|
Snapshot snapshot, ParallelIndexScanDesc target)
|
|
|
|
|
{
|
|
|
|
|
Size offset;
|
|
|
|
|
|
|
|
|
|
RELATION_CHECKS;
|
|
|
|
|
|
|
|
|
|
offset = add_size(offsetof(ParallelIndexScanDescData, ps_snapshot_data),
|
|
|
|
|
EstimateSnapshotSpace(snapshot));
|
|
|
|
|
offset = MAXALIGN(offset);
|
|
|
|
|
|
|
|
|
|
target->ps_relid = RelationGetRelid(heapRelation);
|
|
|
|
|
target->ps_indexid = RelationGetRelid(indexRelation);
|
|
|
|
|
target->ps_offset = offset;
|
|
|
|
|
SerializeSnapshot(snapshot, target->ps_snapshot_data);
|
|
|
|
|
|
|
|
|
|
/* aminitparallelscan is optional; assume no-op if not provided by AM */
|
|
|
|
|
if (indexRelation->rd_amroutine->aminitparallelscan != NULL)
|
|
|
|
|
{
|
|
|
|
|
void *amtarget;
|
|
|
|
|
|
|
|
|
|
amtarget = OffsetToPointer(target, offset);
|
|
|
|
|
indexRelation->rd_amroutine->aminitparallelscan(amtarget);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
|
* index_parallelrescan - (re)start a parallel scan of an index
|
|
|
|
|
* ----------------
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
index_parallelrescan(IndexScanDesc scan)
|
|
|
|
|
{
|
|
|
|
|
SCAN_CHECKS;
|
|
|
|
|
|
|
|
|
|
/* amparallelrescan is optional; assume no-op if not provided by AM */
|
|
|
|
|
if (scan->indexRelation->rd_amroutine->amparallelrescan != NULL)
|
|
|
|
|
scan->indexRelation->rd_amroutine->amparallelrescan(scan);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* index_beginscan_parallel - join parallel index scan
|
|
|
|
|
*
|
|
|
|
|
* Caller must be holding suitable locks on the heap and the index.
|
|
|
|
|
*/
|
|
|
|
|
IndexScanDesc
|
|
|
|
|
index_beginscan_parallel(Relation heaprel, Relation indexrel, int nkeys,
|
|
|
|
|
int norderbys, ParallelIndexScanDesc pscan)
|
|
|
|
|
{
|
|
|
|
|
Snapshot snapshot;
|
|
|
|
|
IndexScanDesc scan;
|
|
|
|
|
|
|
|
|
|
Assert(RelationGetRelid(heaprel) == pscan->ps_relid);
|
|
|
|
|
snapshot = RestoreSnapshot(pscan->ps_snapshot_data);
|
|
|
|
|
RegisterSnapshot(snapshot);
|
|
|
|
|
scan = index_beginscan_internal(indexrel, nkeys, norderbys, snapshot,
|
|
|
|
|
pscan, true);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Save additional parameters into the scandesc. Everything else was set
|
|
|
|
|
* up by index_beginscan_internal.
|
|
|
|
|
*/
|
|
|
|
|
scan->heapRelation = heaprel;
|
|
|
|
|
scan->xs_snapshot = snapshot;
|
|
|
|
|
|
|
|
|
|
return scan;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
|
* index_getnext_tid - get the next TID from a scan
|
|
|
|
|
*
|
|
|
|
|
|