PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
indexam.c File Reference
#include "postgres.h"
#include "access/amapi.h"
#include "access/relscan.h"
#include "access/transam.h"
#include "access/xlog.h"
#include "catalog/catalog.h"
#include "catalog/index.h"
#include "pgstat.h"
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
#include "storage/predicate.h"
#include "utils/snapmgr.h"
#include "utils/tqual.h"
Include dependency graph for indexam.c:

Go to the source code of this file.

Macros

#define RELATION_CHECKS
 
#define SCAN_CHECKS
 
#define CHECK_REL_PROCEDURE(pname)
 
#define CHECK_SCAN_PROCEDURE(pname)
 

Functions

static IndexScanDesc index_beginscan_internal (Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot, ParallelIndexScanDesc pscan, bool temp_snap)
 
Relation index_open (Oid relationId, LOCKMODE lockmode)
 
void index_close (Relation relation, LOCKMODE lockmode)
 
bool index_insert (Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique, IndexInfo *indexInfo)
 
IndexScanDesc index_beginscan (Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, int norderbys)
 
IndexScanDesc index_beginscan_bitmap (Relation indexRelation, Snapshot snapshot, int nkeys)
 
void index_rescan (IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
 
void index_endscan (IndexScanDesc scan)
 
void index_markpos (IndexScanDesc scan)
 
void index_restrpos (IndexScanDesc scan)
 
Size index_parallelscan_estimate (Relation indexRelation, Snapshot snapshot)
 
void index_parallelscan_initialize (Relation heapRelation, Relation indexRelation, Snapshot snapshot, ParallelIndexScanDesc target)
 
void index_parallelrescan (IndexScanDesc scan)
 
IndexScanDesc index_beginscan_parallel (Relation heaprel, Relation indexrel, int nkeys, int norderbys, ParallelIndexScanDesc pscan)
 
ItemPointer index_getnext_tid (IndexScanDesc scan, ScanDirection direction)
 
HeapTuple index_fetch_heap (IndexScanDesc scan)
 
HeapTuple index_getnext (IndexScanDesc scan, ScanDirection direction)
 
int64 index_getbitmap (IndexScanDesc scan, TIDBitmap *bitmap)
 
IndexBulkDeleteResultindex_bulk_delete (IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
 
IndexBulkDeleteResultindex_vacuum_cleanup (IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
 
bool index_can_return (Relation indexRelation, int attno)
 
RegProcedure index_getprocid (Relation irel, AttrNumber attnum, uint16 procnum)
 
FmgrInfoindex_getprocinfo (Relation irel, AttrNumber attnum, uint16 procnum)
 

Macro Definition Documentation

#define CHECK_REL_PROCEDURE (   pname)
Value:
do { \
if (indexRelation->rd_amroutine->pname == NULL) \
elog(ERROR, "function %s is not defined for index %s", \
CppAsString(pname), RelationGetRelationName(indexRelation)); \
} while(0)
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define NULL
Definition: c.h:226
#define CppAsString(identifier)
Definition: c.h:159
#define elog
Definition: elog.h:219

Definition at line 112 of file indexam.c.

Referenced by index_beginscan_internal(), index_bulk_delete(), index_insert(), and index_vacuum_cleanup().

#define CHECK_SCAN_PROCEDURE (   pname)
Value:
do { \
if (scan->indexRelation->rd_amroutine->pname == NULL) \
elog(ERROR, "function %s is not defined for index %s", \
CppAsString(pname), RelationGetRelationName(scan->indexRelation)); \
} while(0)
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define NULL
Definition: c.h:226
#define CppAsString(identifier)
Definition: c.h:159
#define elog
Definition: elog.h:219

Definition at line 119 of file indexam.c.

Referenced by index_endscan(), index_getbitmap(), index_getnext_tid(), index_markpos(), index_rescan(), and index_restrpos().

#define RELATION_CHECKS
Value:
( \
AssertMacro(RelationIsValid(indexRelation)), \
AssertMacro(PointerIsValid(indexRelation->rd_amroutine)), \
)
#define AssertMacro(condition)
Definition: c.h:672
#define RelationIsValid(relation)
Definition: rel.h:386
bool ReindexIsProcessingIndex(Oid indexOid)
Definition: index.c:3687
#define PointerIsValid(pointer)
Definition: c.h:522
#define RelationGetRelid(relation)
Definition: rel.h:413

Definition at line 98 of file indexam.c.

Referenced by index_beginscan_internal(), index_bulk_delete(), index_can_return(), index_insert(), index_parallelscan_estimate(), index_parallelscan_initialize(), and index_vacuum_cleanup().

#define SCAN_CHECKS
Value:
( \
AssertMacro(RelationIsValid(scan->indexRelation)), \
AssertMacro(PointerIsValid(scan->indexRelation->rd_amroutine)) \
)
#define AssertMacro(condition)
Definition: c.h:672
#define RelationIsValid(relation)
Definition: rel.h:386
#define IndexScanIsValid(scan)
Definition: genam.h:128
#define PointerIsValid(pointer)
Definition: c.h:522

Definition at line 105 of file indexam.c.

Referenced by index_endscan(), index_getbitmap(), index_getnext_tid(), index_markpos(), index_parallelrescan(), index_rescan(), and index_restrpos().

Function Documentation

IndexScanDesc index_beginscan ( Relation  heapRelation,
Relation  indexRelation,
Snapshot  snapshot,
int  nkeys,
int  norderbys 
)

Definition at line 221 of file indexam.c.

References IndexScanDescData::heapRelation, index_beginscan_internal(), NULL, and IndexScanDescData::xs_snapshot.

Referenced by check_exclusion_or_unique_constraint(), copy_heap_data(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), get_actual_variable_range(), RelationFindReplTupleByIndex(), systable_beginscan(), and systable_beginscan_ordered().

225 {
226  IndexScanDesc scan;
227 
228  scan = index_beginscan_internal(indexRelation, nkeys, norderbys, snapshot, NULL, false);
229 
230  /*
231  * Save additional parameters into the scandesc. Everything else was set
232  * up by RelationGetIndexScan.
233  */
234  scan->heapRelation = heapRelation;
235  scan->xs_snapshot = snapshot;
236 
237  return scan;
238 }
Snapshot xs_snapshot
Definition: relscan.h:90
Relation heapRelation
Definition: relscan.h:88
static IndexScanDesc index_beginscan_internal(Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot, ParallelIndexScanDesc pscan, bool temp_snap)
Definition: indexam.c:268
#define NULL
Definition: c.h:226
IndexScanDesc index_beginscan_bitmap ( Relation  indexRelation,
Snapshot  snapshot,
int  nkeys 
)

Definition at line 247 of file indexam.c.

References index_beginscan_internal(), NULL, and IndexScanDescData::xs_snapshot.

Referenced by ExecInitBitmapIndexScan().

250 {
251  IndexScanDesc scan;
252 
253  scan = index_beginscan_internal(indexRelation, nkeys, 0, snapshot, NULL, false);
254 
255  /*
256  * Save additional parameters into the scandesc. Everything else was set
257  * up by RelationGetIndexScan.
258  */
259  scan->xs_snapshot = snapshot;
260 
261  return scan;
262 }
Snapshot xs_snapshot
Definition: relscan.h:90
static IndexScanDesc index_beginscan_internal(Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot, ParallelIndexScanDesc pscan, bool temp_snap)
Definition: indexam.c:268
#define NULL
Definition: c.h:226
static IndexScanDesc index_beginscan_internal ( Relation  indexRelation,
int  nkeys,
int  norderbys,
Snapshot  snapshot,
ParallelIndexScanDesc  pscan,
bool  temp_snap 
)
static

Definition at line 268 of file indexam.c.

References IndexAmRoutine::ambeginscan, IndexAmRoutine::ampredlocks, CHECK_REL_PROCEDURE, IndexScanDescData::parallel_scan, PredicateLockRelation(), RelationData::rd_amroutine, RELATION_CHECKS, RelationIncrementReferenceCount(), and IndexScanDescData::xs_temp_snap.

Referenced by index_beginscan(), index_beginscan_bitmap(), and index_beginscan_parallel().

271 {
272  IndexScanDesc scan;
273 
275  CHECK_REL_PROCEDURE(ambeginscan);
276 
277  if (!(indexRelation->rd_amroutine->ampredlocks))
278  PredicateLockRelation(indexRelation, snapshot);
279 
280  /*
281  * We hold a reference count to the relcache entry throughout the scan.
282  */
283  RelationIncrementReferenceCount(indexRelation);
284 
285  /*
286  * Tell the AM to open a scan.
287  */
288  scan = indexRelation->rd_amroutine->ambeginscan(indexRelation, nkeys,
289  norderbys);
290  /* Initialize information for parallel scan. */
291  scan->parallel_scan = pscan;
292  scan->xs_temp_snap = temp_snap;
293 
294  return scan;
295 }
ParallelIndexScanDesc parallel_scan
Definition: relscan.h:132
ambeginscan_function ambeginscan
Definition: amapi.h:208
#define RELATION_CHECKS
Definition: indexam.c:98
void PredicateLockRelation(Relation relation, Snapshot snapshot)
Definition: predicate.c:2415
bool ampredlocks
Definition: amapi.h:191
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_REL_PROCEDURE(pname)
Definition: indexam.c:112
bool xs_temp_snap
Definition: relscan.h:96
void RelationIncrementReferenceCount(Relation rel)
Definition: relcache.c:2122
IndexScanDesc index_beginscan_parallel ( Relation  heaprel,
Relation  indexrel,
int  nkeys,
int  norderbys,
ParallelIndexScanDesc  pscan 
)

Definition at line 496 of file indexam.c.

References Assert, IndexScanDescData::heapRelation, index_beginscan_internal(), ParallelIndexScanDescData::ps_relid, ParallelIndexScanDescData::ps_snapshot_data, RegisterSnapshot(), RelationGetRelid, RestoreSnapshot(), and IndexScanDescData::xs_snapshot.

Referenced by ExecIndexOnlyScanInitializeDSM(), ExecIndexOnlyScanInitializeWorker(), ExecIndexScanInitializeDSM(), and ExecIndexScanInitializeWorker().

498 {
499  Snapshot snapshot;
500  IndexScanDesc scan;
501 
502  Assert(RelationGetRelid(heaprel) == pscan->ps_relid);
503  snapshot = RestoreSnapshot(pscan->ps_snapshot_data);
504  RegisterSnapshot(snapshot);
505  scan = index_beginscan_internal(indexrel, nkeys, norderbys, snapshot,
506  pscan, true);
507 
508  /*
509  * Save additional parameters into the scandesc. Everything else was set
510  * up by index_beginscan_internal.
511  */
512  scan->heapRelation = heaprel;
513  scan->xs_snapshot = snapshot;
514 
515  return scan;
516 }
Snapshot RestoreSnapshot(char *start_address)
Definition: snapmgr.c:2072
Snapshot RegisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:858
Snapshot xs_snapshot
Definition: relscan.h:90
char ps_snapshot_data[FLEXIBLE_ARRAY_MEMBER]
Definition: relscan.h:141
Relation heapRelation
Definition: relscan.h:88
static IndexScanDesc index_beginscan_internal(Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot, ParallelIndexScanDesc pscan, bool temp_snap)
Definition: indexam.c:268
#define Assert(condition)
Definition: c.h:671
#define RelationGetRelid(relation)
Definition: rel.h:413
IndexBulkDeleteResult* index_bulk_delete ( IndexVacuumInfo info,
IndexBulkDeleteResult stats,
IndexBulkDeleteCallback  callback,
void *  callback_state 
)

Definition at line 743 of file indexam.c.

References IndexAmRoutine::ambulkdelete, CHECK_REL_PROCEDURE, IndexVacuumInfo::index, RelationData::rd_amroutine, and RELATION_CHECKS.

Referenced by lazy_vacuum_index(), and validate_index().

747 {
748  Relation indexRelation = info->index;
749 
751  CHECK_REL_PROCEDURE(ambulkdelete);
752 
753  return indexRelation->rd_amroutine->ambulkdelete(info, stats,
754  callback, callback_state);
755 }
ambulkdelete_function ambulkdelete
Definition: amapi.h:201
#define RELATION_CHECKS
Definition: indexam.c:98
Relation index
Definition: genam.h:46
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_REL_PROCEDURE(pname)
Definition: indexam.c:112
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:49
bool index_can_return ( Relation  indexRelation,
int  attno 
)

Definition at line 783 of file indexam.c.

References IndexAmRoutine::amcanreturn, NULL, RelationData::rd_amroutine, and RELATION_CHECKS.

Referenced by get_relation_info(), and indexam_property().

784 {
786 
787  /* amcanreturn is optional; assume FALSE if not provided by AM */
788  if (indexRelation->rd_amroutine->amcanreturn == NULL)
789  return false;
790 
791  return indexRelation->rd_amroutine->amcanreturn(indexRelation, attno);
792 }
#define RELATION_CHECKS
Definition: indexam.c:98
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define NULL
Definition: c.h:226
amcanreturn_function amcanreturn
Definition: amapi.h:203
void index_close ( Relation  relation,
LOCKMODE  lockmode 
)

Definition at line 176 of file indexam.c.

References Assert, LockInfoData::lockRelId, MAX_LOCKMODES, NoLock, RelationData::rd_lockInfo, RelationClose(), and UnlockRelationId().

Referenced by ATExecAddIndex(), ATExecAddIndexConstraint(), ATExecReplicaIdentity(), brin_page_items(), build_indices(), BuildEventTriggerCache(), check_index_is_clusterable(), CheckIndexCompatible(), close_lo_relation(), copy_heap_data(), DefineIndex(), enum_endpoint(), enum_range_internal(), ExecCloseIndices(), ExecEndBitmapIndexScan(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), ExecRefreshMatView(), get_actual_variable_range(), get_relation_info(), gin_clean_pending_list(), gincostestimate(), hash_bitmap_info(), index_create(), index_drop(), indexam_property(), infer_arbiter_indexes(), InitCatCachePhase2(), lookup_ts_config_cache(), pgstathashindex(), refresh_by_match_merge(), reindex_index(), ReindexIndex(), RelationFindReplTupleByIndex(), RelationGetIndexAttrBitmap(), RelationTruncateIndexes(), systable_endscan(), toast_close_indexes(), transformTableLikeClause(), TryReuseIndex(), unique_key_recheck(), vac_close_indexes(), vac_open_indexes(), and validate_index().

177 {
178  LockRelId relid = relation->rd_lockInfo.lockRelId;
179 
180  Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
181 
182  /* The relcache does the real work... */
183  RelationClose(relation);
184 
185  if (lockmode != NoLock)
186  UnlockRelationId(&relid, lockmode);
187 }
LockRelId lockRelId
Definition: rel.h:44
void UnlockRelationId(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:167
Definition: rel.h:36
#define NoLock
Definition: lockdefs.h:34
LockInfoData rd_lockInfo
Definition: rel.h:116
void RelationClose(Relation relation)
Definition: relcache.c:2155
#define MAX_LOCKMODES
Definition: lock.h:86
#define Assert(condition)
Definition: c.h:671
void index_endscan ( IndexScanDesc  scan)

Definition at line 340 of file indexam.c.

References IndexAmRoutine::amendscan, BufferIsValid, CHECK_SCAN_PROCEDURE, IndexScanDescData::indexRelation, IndexScanEnd(), InvalidBuffer, RelationData::rd_amroutine, RelationDecrementReferenceCount(), ReleaseBuffer(), SCAN_CHECKS, UnregisterSnapshot(), IndexScanDescData::xs_cbuf, IndexScanDescData::xs_snapshot, and IndexScanDescData::xs_temp_snap.

Referenced by check_exclusion_or_unique_constraint(), copy_heap_data(), ExecEndBitmapIndexScan(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), get_actual_variable_range(), RelationFindReplTupleByIndex(), systable_endscan(), and systable_endscan_ordered().

341 {
342  SCAN_CHECKS;
343  CHECK_SCAN_PROCEDURE(amendscan);
344 
345  /* Release any held pin on a heap page */
346  if (BufferIsValid(scan->xs_cbuf))
347  {
348  ReleaseBuffer(scan->xs_cbuf);
349  scan->xs_cbuf = InvalidBuffer;
350  }
351 
352  /* End the AM's scan */
353  scan->indexRelation->rd_amroutine->amendscan(scan);
354 
355  /* Release index refcount acquired by index_beginscan */
357 
358  if (scan->xs_temp_snap)
360 
361  /* Release the scan data structure itself */
362  IndexScanEnd(scan);
363 }
Snapshot xs_snapshot
Definition: relscan.h:90
#define InvalidBuffer
Definition: buf.h:25
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3292
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_SCAN_PROCEDURE(pname)
Definition: indexam.c:119
Relation indexRelation
Definition: relscan.h:89
void RelationDecrementReferenceCount(Relation rel)
Definition: relcache.c:2135
Buffer xs_cbuf
Definition: relscan.h:113
bool xs_temp_snap
Definition: relscan.h:96
amendscan_function amendscan
Definition: amapi.h:212
void IndexScanEnd(IndexScanDesc scan)
Definition: genam.c:144
void UnregisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:900
#define SCAN_CHECKS
Definition: indexam.c:105
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
HeapTuple index_fetch_heap ( IndexScanDesc  scan)

Definition at line 583 of file indexam.c.

References BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, heap_hot_search_buffer(), heap_page_prune_opt(), IndexScanDescData::heapRelation, IndexScanDescData::indexRelation, IsMVCCSnapshot, ItemPointerGetBlockNumber, IndexScanDescData::kill_prior_tuple, LockBuffer(), NULL, pgstat_count_heap_fetch, ReleaseAndReadBuffer(), HeapTupleData::t_self, IndexScanDescData::xactStartedInRecovery, IndexScanDescData::xs_cbuf, IndexScanDescData::xs_continue_hot, IndexScanDescData::xs_ctup, and IndexScanDescData::xs_snapshot.

Referenced by index_getnext(), and IndexOnlyNext().

584 {
585  ItemPointer tid = &scan->xs_ctup.t_self;
586  bool all_dead = false;
587  bool got_heap_tuple;
588 
589  /* We can skip the buffer-switching logic if we're in mid-HOT chain. */
590  if (!scan->xs_continue_hot)
591  {
592  /* Switch to correct buffer if we don't have it already */
593  Buffer prev_buf = scan->xs_cbuf;
594 
595  scan->xs_cbuf = ReleaseAndReadBuffer(scan->xs_cbuf,
596  scan->heapRelation,
598 
599  /*
600  * Prune page, but only if we weren't already on this page
601  */
602  if (prev_buf != scan->xs_cbuf)
604  }
605 
606  /* Obtain share-lock on the buffer so we can examine visibility */
608  got_heap_tuple = heap_hot_search_buffer(tid, scan->heapRelation,
609  scan->xs_cbuf,
610  scan->xs_snapshot,
611  &scan->xs_ctup,
612  &all_dead,
613  !scan->xs_continue_hot);
615 
616  if (got_heap_tuple)
617  {
618  /*
619  * Only in a non-MVCC snapshot can more than one member of the HOT
620  * chain be visible.
621  */
624  return &scan->xs_ctup;
625  }
626 
627  /* We've reached the end of the HOT chain. */
628  scan->xs_continue_hot = false;
629 
630  /*
631  * If we scanned a whole HOT chain and found only dead tuples, tell index
632  * AM to kill its entry for that TID (this will take effect in the next
633  * amgettuple call, in index_getnext_tid). We do not do this when in
634  * recovery because it may violate MVCC to do so. See comments in
635  * RelationGetIndexScan().
636  */
637  if (!scan->xactStartedInRecovery)
638  scan->kill_prior_tuple = all_dead;
639 
640  return NULL;
641 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
Snapshot xs_snapshot
Definition: relscan.h:90
Relation indexRelation
Definition: relscan.h:89
Relation heapRelation
Definition: relscan.h:88
bool heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, Snapshot snapshot, HeapTuple heapTuple, bool *all_dead, bool first_call)
Definition: heapam.c:1984
Buffer xs_cbuf
Definition: relscan.h:113
ItemPointerData t_self
Definition: htup.h:65
#define pgstat_count_heap_fetch(rel)
Definition: pgstat.h:1150
bool xactStartedInRecovery
Definition: relscan.h:101
bool xs_continue_hot
Definition: relscan.h:129
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
#define NULL
Definition: c.h:226
#define IsMVCCSnapshot(snapshot)
Definition: tqual.h:31
HeapTupleData xs_ctup
Definition: relscan.h:112
Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, BlockNumber blockNum)
Definition: bufmgr.c:1508
bool kill_prior_tuple
Definition: relscan.h:99
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
void heap_page_prune_opt(Relation relation, Buffer buffer)
Definition: pruneheap.c:75
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:66
int Buffer
Definition: buf.h:23
int64 index_getbitmap ( IndexScanDesc  scan,
TIDBitmap bitmap 
)

Definition at line 713 of file indexam.c.

References IndexAmRoutine::amgetbitmap, CHECK_SCAN_PROCEDURE, IndexScanDescData::indexRelation, IndexScanDescData::kill_prior_tuple, pgstat_count_index_tuples, RelationData::rd_amroutine, and SCAN_CHECKS.

Referenced by MultiExecBitmapIndexScan().

714 {
715  int64 ntids;
716 
717  SCAN_CHECKS;
718  CHECK_SCAN_PROCEDURE(amgetbitmap);
719 
720  /* just make sure this is false... */
721  scan->kill_prior_tuple = false;
722 
723  /*
724  * have the am's getbitmap proc do all the work.
725  */
726  ntids = scan->indexRelation->rd_amroutine->amgetbitmap(scan, bitmap);
727 
729 
730  return ntids;
731 }
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_SCAN_PROCEDURE(pname)
Definition: indexam.c:119
Relation indexRelation
Definition: relscan.h:89
amgetbitmap_function amgetbitmap
Definition: amapi.h:211
#define SCAN_CHECKS
Definition: indexam.c:105
#define pgstat_count_index_tuples(rel, n)
Definition: pgstat.h:1160
bool kill_prior_tuple
Definition: relscan.h:99
HeapTuple index_getnext ( IndexScanDesc  scan,
ScanDirection  direction 
)

Definition at line 659 of file indexam.c.

References Assert, BufferGetBlockNumber(), BufferIsValid, index_fetch_heap(), index_getnext_tid(), ItemPointerGetBlockNumber, NULL, HeapTupleData::t_self, IndexScanDescData::xs_cbuf, IndexScanDescData::xs_continue_hot, and IndexScanDescData::xs_ctup.

Referenced by check_exclusion_or_unique_constraint(), copy_heap_data(), get_actual_variable_range(), IndexNext(), IndexNextWithReorder(), RelationFindReplTupleByIndex(), systable_getnext(), and systable_getnext_ordered().

660 {
661  HeapTuple heapTuple;
662  ItemPointer tid;
663 
664  for (;;)
665  {
666  if (scan->xs_continue_hot)
667  {
668  /*
669  * We are resuming scan of a HOT chain after having returned an
670  * earlier member. Must still hold pin on current heap page.
671  */
672  Assert(BufferIsValid(scan->xs_cbuf));
675  }
676  else
677  {
678  /* Time to fetch the next TID from the index */
679  tid = index_getnext_tid(scan, direction);
680 
681  /* If we're out of index entries, we're done */
682  if (tid == NULL)
683  break;
684  }
685 
686  /*
687  * Fetch the next (or only) visible heap tuple for this index entry.
688  * If we don't find anything, loop around and grab the next TID from
689  * the index.
690  */
691  heapTuple = index_fetch_heap(scan);
692  if (heapTuple != NULL)
693  return heapTuple;
694  }
695 
696  return NULL; /* failure exit */
697 }
ItemPointer index_getnext_tid(IndexScanDesc scan, ScanDirection direction)
Definition: indexam.c:526
Buffer xs_cbuf
Definition: relscan.h:113
ItemPointerData t_self
Definition: htup.h:65
HeapTuple index_fetch_heap(IndexScanDesc scan)
Definition: indexam.c:583
bool xs_continue_hot
Definition: relscan.h:129
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
HeapTupleData xs_ctup
Definition: relscan.h:112
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2588
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:66
ItemPointer index_getnext_tid ( IndexScanDesc  scan,
ScanDirection  direction 
)

Definition at line 526 of file indexam.c.

References IndexAmRoutine::amgettuple, Assert, BufferIsValid, CHECK_SCAN_PROCEDURE, IndexScanDescData::indexRelation, InvalidBuffer, IndexScanDescData::kill_prior_tuple, NULL, pgstat_count_index_tuples, RelationData::rd_amroutine, RecentGlobalXmin, ReleaseBuffer(), SCAN_CHECKS, HeapTupleData::t_self, TransactionIdIsValid, IndexScanDescData::xs_cbuf, and IndexScanDescData::xs_ctup.

Referenced by index_getnext(), and IndexOnlyNext().

527 {
528  bool found;
529 
530  SCAN_CHECKS;
531  CHECK_SCAN_PROCEDURE(amgettuple);
532 
534 
535  /*
536  * The AM's amgettuple proc finds the next index entry matching the scan
537  * keys, and puts the TID into scan->xs_ctup.t_self. It should also set
538  * scan->xs_recheck and possibly scan->xs_itup, though we pay no attention
539  * to those fields here.
540  */
541  found = scan->indexRelation->rd_amroutine->amgettuple(scan, direction);
542 
543  /* Reset kill flag immediately for safety */
544  scan->kill_prior_tuple = false;
545 
546  /* If we're out of index entries, we're done */
547  if (!found)
548  {
549  /* ... but first, release any held pin on a heap page */
550  if (BufferIsValid(scan->xs_cbuf))
551  {
552  ReleaseBuffer(scan->xs_cbuf);
553  scan->xs_cbuf = InvalidBuffer;
554  }
555  return NULL;
556  }
557 
559 
560  /* Return the TID of the tuple we found. */
561  return &scan->xs_ctup.t_self;
562 }
amgettuple_function amgettuple
Definition: amapi.h:210
#define InvalidBuffer
Definition: buf.h:25
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3292
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_SCAN_PROCEDURE(pname)
Definition: indexam.c:119
Relation indexRelation
Definition: relscan.h:89
Buffer xs_cbuf
Definition: relscan.h:113
ItemPointerData t_self
Definition: htup.h:65
TransactionId RecentGlobalXmin
Definition: snapmgr.c:166
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
HeapTupleData xs_ctup
Definition: relscan.h:112
#define SCAN_CHECKS
Definition: indexam.c:105
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define pgstat_count_index_tuples(rel, n)
Definition: pgstat.h:1160
bool kill_prior_tuple
Definition: relscan.h:99
#define TransactionIdIsValid(xid)
Definition: transam.h:41
RegProcedure index_getprocid ( Relation  irel,
AttrNumber  attnum,
uint16  procnum 
)

Definition at line 821 of file indexam.c.

References IndexAmRoutine::amsupport, Assert, NULL, RelationData::rd_amroutine, and RelationData::rd_support.

Referenced by _hash_metapinit(), gistcanreturn(), inclusion_get_procinfo(), initGinState(), and initGISTstate().

824 {
825  RegProcedure *loc;
826  int nproc;
827  int procindex;
828 
829  nproc = irel->rd_amroutine->amsupport;
830 
831  Assert(procnum > 0 && procnum <= (uint16) nproc);
832 
833  procindex = (nproc * (attnum - 1)) + (procnum - 1);
834 
835  loc = irel->rd_support;
836 
837  Assert(loc != NULL);
838 
839  return loc[procindex];
840 }
uint16 amsupport
Definition: amapi.h:169
regproc RegProcedure
Definition: c.h:392
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
unsigned short uint16
Definition: c.h:264
RegProcedure * rd_support
Definition: rel.h:180
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
FmgrInfo* index_getprocinfo ( Relation  irel,
AttrNumber  attnum,
uint16  procnum 
)

Definition at line 855 of file indexam.c.

References IndexAmRoutine::amsupport, Assert, elog, ERROR, fmgr_info_cxt(), FmgrInfo::fn_oid, InvalidOid, NULL, RelationData::rd_amroutine, RelationData::rd_indexcxt, RelationData::rd_support, RelationData::rd_supportinfo, RegProcedureIsValid, and RelationGetRelationName.

Referenced by _bt_first(), _bt_mkscankey(), _bt_mkscankey_nodata(), _hash_datum2hashkey(), brin_build_desc(), brinbuildCallback(), bringetbitmap(), brininsert(), doPickSplit(), inclusion_get_procinfo(), initBloomState(), initGinState(), initGISTstate(), spgdoinsert(), spgGetCache(), spgLeafTest(), spgWalk(), and union_tuples().

858 {
859  FmgrInfo *locinfo;
860  int nproc;
861  int procindex;
862 
863  nproc = irel->rd_amroutine->amsupport;
864 
865  Assert(procnum > 0 && procnum <= (uint16) nproc);
866 
867  procindex = (nproc * (attnum - 1)) + (procnum - 1);
868 
869  locinfo = irel->rd_supportinfo;
870 
871  Assert(locinfo != NULL);
872 
873  locinfo += procindex;
874 
875  /* Initialize the lookup info if first time through */
876  if (locinfo->fn_oid == InvalidOid)
877  {
878  RegProcedure *loc = irel->rd_support;
879  RegProcedure procId;
880 
881  Assert(loc != NULL);
882 
883  procId = loc[procindex];
884 
885  /*
886  * Complain if function was not found during IndexSupportInitialize.
887  * This should not happen unless the system tables contain bogus
888  * entries for the index opclass. (If an AM wants to allow a support
889  * function to be optional, it can use index_getprocid.)
890  */
891  if (!RegProcedureIsValid(procId))
892  elog(ERROR, "missing support function %d for attribute %d of index \"%s\"",
893  procnum, attnum, RelationGetRelationName(irel));
894 
895  fmgr_info_cxt(procId, locinfo, irel->rd_indexcxt);
896  }
897 
898  return locinfo;
899 }
Definition: fmgr.h:53
uint16 amsupport
Definition: amapi.h:169
FmgrInfo * rd_supportinfo
Definition: rel.h:181
regproc RegProcedure
Definition: c.h:392
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
unsigned short uint16
Definition: c.h:264
#define ERROR
Definition: elog.h:43
#define RegProcedureIsValid(p)
Definition: c.h:536
#define RelationGetRelationName(relation)
Definition: rel.h:433
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:169
RegProcedure * rd_support
Definition: rel.h:180
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:56
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
MemoryContext rd_indexcxt
Definition: rel.h:175
#define elog
Definition: elog.h:219
bool index_insert ( Relation  indexRelation,
Datum values,
bool isnull,
ItemPointer  heap_t_ctid,
Relation  heapRelation,
IndexUniqueCheck  checkUnique,
IndexInfo indexInfo 
)

Definition at line 194 of file indexam.c.

References IndexAmRoutine::aminsert, IndexAmRoutine::ampredlocks, CHECK_REL_PROCEDURE, CheckForSerializableConflictIn(), InvalidBuffer, NULL, RelationData::rd_amroutine, and RELATION_CHECKS.

Referenced by CatalogIndexInsert(), ExecInsertIndexTuples(), toast_save_datum(), unique_key_recheck(), and validate_index_heapscan().

201 {
203  CHECK_REL_PROCEDURE(aminsert);
204 
205  if (!(indexRelation->rd_amroutine->ampredlocks))
206  CheckForSerializableConflictIn(indexRelation,
207  (HeapTuple) NULL,
208  InvalidBuffer);
209 
210  return indexRelation->rd_amroutine->aminsert(indexRelation, values, isnull,
211  heap_t_ctid, heapRelation,
212  checkUnique, indexInfo);
213 }
#define RELATION_CHECKS
Definition: indexam.c:98
#define InvalidBuffer
Definition: buf.h:25
bool ampredlocks
Definition: amapi.h:191
aminsert_function aminsert
Definition: amapi.h:200
void CheckForSerializableConflictIn(Relation relation, HeapTuple tuple, Buffer buffer)
Definition: predicate.c:4243
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_REL_PROCEDURE(pname)
Definition: indexam.c:112
#define NULL
Definition: c.h:226
static Datum values[MAXATTR]
Definition: bootstrap.c:162
void index_markpos ( IndexScanDesc  scan)

Definition at line 370 of file indexam.c.

References IndexAmRoutine::ammarkpos, CHECK_SCAN_PROCEDURE, IndexScanDescData::indexRelation, RelationData::rd_amroutine, and SCAN_CHECKS.

Referenced by ExecIndexMarkPos(), and ExecIndexOnlyMarkPos().

371 {
372  SCAN_CHECKS;
373  CHECK_SCAN_PROCEDURE(ammarkpos);
374 
375  scan->indexRelation->rd_amroutine->ammarkpos(scan);
376 }
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_SCAN_PROCEDURE(pname)
Definition: indexam.c:119
Relation indexRelation
Definition: relscan.h:89
#define SCAN_CHECKS
Definition: indexam.c:105
ammarkpos_function ammarkpos
Definition: amapi.h:213
Relation index_open ( Oid  relationId,
LOCKMODE  lockmode 
)

Definition at line 151 of file indexam.c.

References ereport, errcode(), errmsg(), ERROR, RelationData::rd_rel, relation_open(), RelationGetRelationName, and RELKIND_INDEX.

Referenced by ATExecAddIndex(), ATExecAddIndexConstraint(), ATExecReplicaIdentity(), brin_page_items(), brin_summarize_new_values(), build_indices(), BuildEventTriggerCache(), check_index_is_clusterable(), CheckIndexCompatible(), copy_heap_data(), DefineIndex(), enum_endpoint(), enum_range_internal(), ExecInitBitmapIndexScan(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecOpenIndices(), ExecRefreshMatView(), get_actual_variable_range(), get_relation_info(), gin_clean_pending_list(), gincostestimate(), hash_bitmap_info(), index_drop(), indexam_property(), infer_arbiter_indexes(), InitCatCachePhase2(), lookup_ts_config_cache(), open_lo_relation(), pgstathashindex(), refresh_by_match_merge(), reindex_index(), ReindexIndex(), RelationFindReplTupleByIndex(), RelationGetIndexAttrBitmap(), RelationTruncateIndexes(), systable_beginscan(), toast_open_indexes(), transformIndexConstraint(), transformTableLikeClause(), TryReuseIndex(), unique_key_recheck(), vac_open_indexes(), and validate_index().

152 {
153  Relation r;
154 
155  r = relation_open(relationId, lockmode);
156 
157  if (r->rd_rel->relkind != RELKIND_INDEX)
158  ereport(ERROR,
159  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
160  errmsg("\"%s\" is not an index",
162 
163  return r;
164 }
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:113
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_INDEX
Definition: pg_class.h:161
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
void index_parallelrescan ( IndexScanDesc  scan)

Definition at line 481 of file indexam.c.

References IndexAmRoutine::amparallelrescan, IndexScanDescData::indexRelation, NULL, RelationData::rd_amroutine, and SCAN_CHECKS.

Referenced by ExecReScanIndexOnlyScan(), and ExecReScanIndexScan().

482 {
483  SCAN_CHECKS;
484 
485  /* amparallelrescan is optional; assume no-op if not provided by AM */
488 }
amparallelrescan_function amparallelrescan
Definition: amapi.h:219
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
Relation indexRelation
Definition: relscan.h:89
#define NULL
Definition: c.h:226
#define SCAN_CHECKS
Definition: indexam.c:105
Size index_parallelscan_estimate ( Relation  indexRelation,
Snapshot  snapshot 
)

Definition at line 417 of file indexam.c.

References add_size(), IndexAmRoutine::amestimateparallelscan, EstimateSnapshotSpace(), MAXALIGN, NULL, offsetof, RelationData::rd_amroutine, and RELATION_CHECKS.

Referenced by ExecIndexOnlyScanEstimate(), and ExecIndexScanEstimate().

418 {
419  Size nbytes;
420 
422 
423  nbytes = offsetof(ParallelIndexScanDescData, ps_snapshot_data);
424  nbytes = add_size(nbytes, EstimateSnapshotSpace(snapshot));
425  nbytes = MAXALIGN(nbytes);
426 
427  /*
428  * If amestimateparallelscan is not provided, assume there is no
429  * AM-specific data needed. (It's hard to believe that could work, but
430  * it's easy enough to cater to it here.)
431  */
432  if (indexRelation->rd_amroutine->amestimateparallelscan != NULL)
433  nbytes = add_size(nbytes,
434  indexRelation->rd_amroutine->amestimateparallelscan());
435 
436  return nbytes;
437 }
#define RELATION_CHECKS
Definition: indexam.c:98
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
Size EstimateSnapshotSpace(Snapshot snap)
Definition: snapmgr.c:1992
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
#define NULL
Definition: c.h:226
size_t Size
Definition: c.h:353
#define MAXALIGN(LEN)
Definition: c.h:584
amestimateparallelscan_function amestimateparallelscan
Definition: amapi.h:217
#define offsetof(type, field)
Definition: c.h:551
void index_parallelscan_initialize ( Relation  heapRelation,
Relation  indexRelation,
Snapshot  snapshot,
ParallelIndexScanDesc  target 
)

Definition at line 450 of file indexam.c.

References add_size(), IndexAmRoutine::aminitparallelscan, EstimateSnapshotSpace(), MAXALIGN, NULL, offsetof, OffsetToPointer, ParallelIndexScanDescData::ps_indexid, ParallelIndexScanDescData::ps_offset, ParallelIndexScanDescData::ps_relid, ParallelIndexScanDescData::ps_snapshot_data, RelationData::rd_amroutine, RELATION_CHECKS, RelationGetRelid, and SerializeSnapshot().

Referenced by ExecIndexOnlyScanInitializeDSM(), and ExecIndexScanInitializeDSM().

452 {
453  Size offset;
454 
456 
457  offset = add_size(offsetof(ParallelIndexScanDescData, ps_snapshot_data),
458  EstimateSnapshotSpace(snapshot));
459  offset = MAXALIGN(offset);
460 
461  target->ps_relid = RelationGetRelid(heapRelation);
462  target->ps_indexid = RelationGetRelid(indexRelation);
463  target->ps_offset = offset;
464  SerializeSnapshot(snapshot, target->ps_snapshot_data);
465 
466  /* aminitparallelscan is optional; assume no-op if not provided by AM */
467  if (indexRelation->rd_amroutine->aminitparallelscan != NULL)
468  {
469  void *amtarget;
470 
471  amtarget = OffsetToPointer(target, offset);
472  indexRelation->rd_amroutine->aminitparallelscan(amtarget);
473  }
474 }
#define RELATION_CHECKS
Definition: indexam.c:98
char ps_snapshot_data[FLEXIBLE_ARRAY_MEMBER]
Definition: relscan.h:141
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
void SerializeSnapshot(Snapshot snapshot, char *start_address)
Definition: snapmgr.c:2016
#define OffsetToPointer(base, offset)
Definition: c.h:531
Size EstimateSnapshotSpace(Snapshot snap)
Definition: snapmgr.c:1992
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
#define NULL
Definition: c.h:226
size_t Size
Definition: c.h:353
#define MAXALIGN(LEN)
Definition: c.h:584
#define RelationGetRelid(relation)
Definition: rel.h:413
#define offsetof(type, field)
Definition: c.h:551
aminitparallelscan_function aminitparallelscan
Definition: amapi.h:218
void index_rescan ( IndexScanDesc  scan,
ScanKey  keys,
int  nkeys,
ScanKey  orderbys,
int  norderbys 
)

Definition at line 310 of file indexam.c.

References IndexAmRoutine::amrescan, Assert, BufferIsValid, CHECK_SCAN_PROCEDURE, IndexScanDescData::indexRelation, InvalidBuffer, IndexScanDescData::kill_prior_tuple, IndexScanDescData::numberOfKeys, IndexScanDescData::numberOfOrderBys, RelationData::rd_amroutine, ReleaseBuffer(), SCAN_CHECKS, IndexScanDescData::xs_cbuf, and IndexScanDescData::xs_continue_hot.

Referenced by check_exclusion_or_unique_constraint(), copy_heap_data(), ExecIndexOnlyScanInitializeDSM(), ExecIndexOnlyScanInitializeWorker(), ExecIndexScanInitializeDSM(), ExecIndexScanInitializeWorker(), ExecInitBitmapIndexScan(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecReScanBitmapIndexScan(), ExecReScanIndexOnlyScan(), ExecReScanIndexScan(), get_actual_variable_range(), MultiExecBitmapIndexScan(), RelationFindReplTupleByIndex(), systable_beginscan(), and systable_beginscan_ordered().

313 {
314  SCAN_CHECKS;
315  CHECK_SCAN_PROCEDURE(amrescan);
316 
317  Assert(nkeys == scan->numberOfKeys);
318  Assert(norderbys == scan->numberOfOrderBys);
319 
320  /* Release any held pin on a heap page */
321  if (BufferIsValid(scan->xs_cbuf))
322  {
323  ReleaseBuffer(scan->xs_cbuf);
324  scan->xs_cbuf = InvalidBuffer;
325  }
326 
327  scan->xs_continue_hot = false;
328 
329  scan->kill_prior_tuple = false; /* for safety */
330 
331  scan->indexRelation->rd_amroutine->amrescan(scan, keys, nkeys,
332  orderbys, norderbys);
333 }
#define InvalidBuffer
Definition: buf.h:25
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3292
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_SCAN_PROCEDURE(pname)
Definition: indexam.c:119
Relation indexRelation
Definition: relscan.h:89
Buffer xs_cbuf
Definition: relscan.h:113
bool xs_continue_hot
Definition: relscan.h:129
amrescan_function amrescan
Definition: amapi.h:209
#define Assert(condition)
Definition: c.h:671
#define SCAN_CHECKS
Definition: indexam.c:105
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
bool kill_prior_tuple
Definition: relscan.h:99
int numberOfOrderBys
Definition: relscan.h:92
void index_restrpos ( IndexScanDesc  scan)

Definition at line 395 of file indexam.c.

References IndexAmRoutine::amrestrpos, Assert, CHECK_SCAN_PROCEDURE, IndexScanDescData::indexRelation, IsMVCCSnapshot, IndexScanDescData::kill_prior_tuple, RelationData::rd_amroutine, SCAN_CHECKS, IndexScanDescData::xs_continue_hot, and IndexScanDescData::xs_snapshot.

Referenced by ExecIndexOnlyRestrPos(), and ExecIndexRestrPos().

396 {
398 
399  SCAN_CHECKS;
400  CHECK_SCAN_PROCEDURE(amrestrpos);
401 
402  scan->xs_continue_hot = false;
403 
404  scan->kill_prior_tuple = false; /* for safety */
405 
406  scan->indexRelation->rd_amroutine->amrestrpos(scan);
407 }
Snapshot xs_snapshot
Definition: relscan.h:90
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_SCAN_PROCEDURE(pname)
Definition: indexam.c:119
Relation indexRelation
Definition: relscan.h:89
bool xs_continue_hot
Definition: relscan.h:129
#define Assert(condition)
Definition: c.h:671
#define IsMVCCSnapshot(snapshot)
Definition: tqual.h:31
#define SCAN_CHECKS
Definition: indexam.c:105
bool kill_prior_tuple
Definition: relscan.h:99
amrestrpos_function amrestrpos
Definition: amapi.h:214
IndexBulkDeleteResult* index_vacuum_cleanup ( IndexVacuumInfo info,
IndexBulkDeleteResult stats 
)

Definition at line 764 of file indexam.c.

References IndexAmRoutine::amvacuumcleanup, CHECK_REL_PROCEDURE, IndexVacuumInfo::index, RelationData::rd_amroutine, and RELATION_CHECKS.

Referenced by do_analyze_rel(), and lazy_cleanup_index().

766 {
767  Relation indexRelation = info->index;
768 
770  CHECK_REL_PROCEDURE(amvacuumcleanup);
771 
772  return indexRelation->rd_amroutine->amvacuumcleanup(info, stats);
773 }
#define RELATION_CHECKS
Definition: indexam.c:98
Relation index
Definition: genam.h:46
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
#define CHECK_REL_PROCEDURE(pname)
Definition: indexam.c:112
amvacuumcleanup_function amvacuumcleanup
Definition: amapi.h:202