mirror of
https://github.com/postgres/postgres.git
synced 2026-06-11 01:30:11 -04:00
Pass down information on table modification to scan nodes
Pass down information to sequential scan, index [only] scan, bitmap table scan, sample scan, and TID range scan nodes on whether or not the query modifies the relation being scanned. A later commit will use this information to update the VM during on-access pruning only if the relation is not modified by the query. Author: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru> Reviewed-by: Tomas Vondra <tomas@vondra.me> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Discussion: https://postgr.es/m/4379FDA3-9446-4E2C-9C15-32EFE8D4F31B%40yandex-team.ru
This commit is contained in:
parent
349bd88202
commit
50eb5faea2
9 changed files with 59 additions and 15 deletions
|
|
@ -736,6 +736,27 @@ ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
|
|||
return bms_is_member(scanrelid, estate->es_plannedstmt->resultRelationRelids);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the scan node's relation is not modified by the query.
|
||||
*
|
||||
* This is not perfectly accurate. INSERT ... SELECT from the same table does
|
||||
* not add the scan relation to resultRelationRelids, so it will be reported
|
||||
* as read-only even though the query modifies it.
|
||||
*
|
||||
* Conversely, when any relation in the query has a modifying row mark, all
|
||||
* other relations get a ROW_MARK_REFERENCE, causing them to be reported as
|
||||
* not read-only even though they may be.
|
||||
*/
|
||||
bool
|
||||
ScanRelIsReadOnly(ScanState *ss)
|
||||
{
|
||||
Index scanrelid = ((Scan *) ss->ps.plan)->scanrelid;
|
||||
PlannedStmt *pstmt = ss->ps.state->es_plannedstmt;
|
||||
|
||||
return !bms_is_member(scanrelid, pstmt->resultRelationRelids) &&
|
||||
!bms_is_member(scanrelid, pstmt->rowMarkRelids);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecOpenScanRelation
|
||||
*
|
||||
|
|
|
|||
|
|
@ -149,7 +149,8 @@ BitmapTableScanSetup(BitmapHeapScanState *node)
|
|||
node->ss.ps.state->es_snapshot,
|
||||
0,
|
||||
NULL,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
}
|
||||
|
||||
node->ss.ss_currentScanDesc->st.rs_tbmiterator = tbmiterator;
|
||||
|
|
|
|||
|
|
@ -96,7 +96,8 @@ IndexOnlyNext(IndexOnlyScanState *node)
|
|||
node->ioss_Instrument,
|
||||
node->ioss_NumScanKeys,
|
||||
node->ioss_NumOrderByKeys,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
|
||||
node->ioss_ScanDesc = scandesc;
|
||||
|
||||
|
|
@ -796,7 +797,8 @@ ExecIndexOnlyScanInitializeDSM(IndexOnlyScanState *node,
|
|||
node->ioss_NumScanKeys,
|
||||
node->ioss_NumOrderByKeys,
|
||||
piscan,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
node->ioss_ScanDesc->xs_want_itup = true;
|
||||
node->ioss_VMBuffer = InvalidBuffer;
|
||||
|
||||
|
|
@ -863,7 +865,8 @@ ExecIndexOnlyScanInitializeWorker(IndexOnlyScanState *node,
|
|||
node->ioss_NumScanKeys,
|
||||
node->ioss_NumOrderByKeys,
|
||||
piscan,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
node->ioss_ScanDesc->xs_want_itup = true;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -114,7 +114,8 @@ IndexNext(IndexScanState *node)
|
|||
node->iss_Instrument,
|
||||
node->iss_NumScanKeys,
|
||||
node->iss_NumOrderByKeys,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
|
||||
node->iss_ScanDesc = scandesc;
|
||||
|
||||
|
|
@ -211,7 +212,8 @@ IndexNextWithReorder(IndexScanState *node)
|
|||
node->iss_Instrument,
|
||||
node->iss_NumScanKeys,
|
||||
node->iss_NumOrderByKeys,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
|
||||
node->iss_ScanDesc = scandesc;
|
||||
|
||||
|
|
@ -1733,7 +1735,8 @@ ExecIndexScanInitializeDSM(IndexScanState *node,
|
|||
node->iss_NumScanKeys,
|
||||
node->iss_NumOrderByKeys,
|
||||
piscan,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
|
||||
/*
|
||||
* If no run-time keys to calculate or they are ready, go ahead and pass
|
||||
|
|
@ -1798,7 +1801,8 @@ ExecIndexScanInitializeWorker(IndexScanState *node,
|
|||
node->iss_NumScanKeys,
|
||||
node->iss_NumOrderByKeys,
|
||||
piscan,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
|
||||
/*
|
||||
* If no run-time keys to calculate or they are ready, go ahead and pass
|
||||
|
|
|
|||
|
|
@ -299,7 +299,8 @@ tablesample_init(SampleScanState *scanstate)
|
|||
scanstate->use_bulkread,
|
||||
allow_sync,
|
||||
scanstate->use_pagemode,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&scanstate->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ SeqNext(SeqScanState *node)
|
|||
scandesc = table_beginscan(node->ss.ss_currentRelation,
|
||||
estate->es_snapshot,
|
||||
0, NULL,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
node->ss.ss_currentScanDesc = scandesc;
|
||||
}
|
||||
|
||||
|
|
@ -375,9 +376,11 @@ ExecSeqScanInitializeDSM(SeqScanState *node,
|
|||
pscan,
|
||||
estate->es_snapshot);
|
||||
shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pscan);
|
||||
|
||||
node->ss.ss_currentScanDesc =
|
||||
table_beginscan_parallel(node->ss.ss_currentRelation, pscan,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
|
|
@ -411,5 +414,6 @@ ExecSeqScanInitializeWorker(SeqScanState *node,
|
|||
pscan = shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
|
||||
node->ss.ss_currentScanDesc =
|
||||
table_beginscan_parallel(node->ss.ss_currentRelation, pscan,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,7 +246,8 @@ TidRangeNext(TidRangeScanState *node)
|
|||
estate->es_snapshot,
|
||||
&node->trss_mintid,
|
||||
&node->trss_maxtid,
|
||||
SO_NONE);
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
node->ss.ss_currentScanDesc = scandesc;
|
||||
}
|
||||
else
|
||||
|
|
@ -461,7 +462,9 @@ ExecTidRangeScanInitializeDSM(TidRangeScanState *node, ParallelContext *pcxt)
|
|||
shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pscan);
|
||||
node->ss.ss_currentScanDesc =
|
||||
table_beginscan_parallel_tidrange(node->ss.ss_currentRelation,
|
||||
pscan, SO_NONE);
|
||||
pscan,
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
|
|
@ -495,5 +498,7 @@ ExecTidRangeScanInitializeWorker(TidRangeScanState *node,
|
|||
pscan = shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
|
||||
node->ss.ss_currentScanDesc =
|
||||
table_beginscan_parallel_tidrange(node->ss.ss_currentRelation,
|
||||
pscan, SO_NONE);
|
||||
pscan,
|
||||
ScanRelIsReadOnly(&node->ss) ?
|
||||
SO_HINT_REL_READ_ONLY : SO_NONE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ typedef enum ScanOptions
|
|||
|
||||
/* unregister snapshot at scan end? */
|
||||
SO_TEMP_SNAPSHOT = 1 << 9,
|
||||
|
||||
/* set if the query doesn't modify the relation */
|
||||
SO_HINT_REL_READ_ONLY = 1 << 10,
|
||||
} ScanOptions;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -690,6 +690,8 @@ extern void ExecCreateScanSlotFromOuterPlan(EState *estate,
|
|||
|
||||
extern bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid);
|
||||
|
||||
extern bool ScanRelIsReadOnly(ScanState *ss);
|
||||
|
||||
extern Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags);
|
||||
|
||||
extern void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos,
|
||||
|
|
|
|||
Loading…
Reference in a new issue