Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Enumerations | Functions

genam.h File Reference

#include "access/sdir.h"
#include "access/skey.h"
#include "nodes/tidbitmap.h"
#include "storage/lock.h"
#include "utils/relcache.h"
#include "utils/snapshot.h"
Include dependency graph for genam.h:

Go to the source code of this file.

Data Structures

struct  IndexBuildResult
struct  IndexVacuumInfo
struct  IndexBulkDeleteResult

Defines

#define IndexScanIsValid(scan)   PointerIsValid(scan)

Typedefs

typedef struct IndexBuildResult IndexBuildResult
typedef struct IndexVacuumInfo IndexVacuumInfo
typedef struct
IndexBulkDeleteResult 
IndexBulkDeleteResult
typedef bool(* IndexBulkDeleteCallback )(ItemPointer itemptr, void *state)
typedef struct IndexScanDescDataIndexScanDesc
typedef struct SysScanDescDataSysScanDesc
typedef enum IndexUniqueCheck IndexUniqueCheck

Enumerations

enum  IndexUniqueCheck { UNIQUE_CHECK_NO, UNIQUE_CHECK_YES, UNIQUE_CHECK_PARTIAL, UNIQUE_CHECK_EXISTING }

Functions

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)
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)
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)
RegProcedure index_getprocid (Relation irel, AttrNumber attnum, uint16 procnum)
FmgrInfoindex_getprocinfo (Relation irel, AttrNumber attnum, uint16 procnum)
IndexScanDesc RelationGetIndexScan (Relation indexRelation, int nkeys, int norderbys)
void IndexScanEnd (IndexScanDesc scan)
char * BuildIndexValueDescription (Relation indexRelation, Datum *values, bool *isnull)
SysScanDesc systable_beginscan (Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
HeapTuple systable_getnext (SysScanDesc sysscan)
bool systable_recheck_tuple (SysScanDesc sysscan, HeapTuple tup)
void systable_endscan (SysScanDesc sysscan)
SysScanDesc systable_beginscan_ordered (Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, ScanKey key)
HeapTuple systable_getnext_ordered (SysScanDesc sysscan, ScanDirection direction)
void systable_endscan_ordered (SysScanDesc sysscan)

Define Documentation

#define IndexScanIsValid (   scan  )     PointerIsValid(scan)

Definition at line 123 of file genam.h.


Typedef Documentation

typedef bool(* IndexBulkDeleteCallback)(ItemPointer itemptr, void *state)

Definition at line 80 of file genam.h.

Definition at line 83 of file genam.h.

typedef struct SysScanDescData* SysScanDesc

Definition at line 84 of file genam.h.


Enumeration Type Documentation

Enumerator:
UNIQUE_CHECK_NO 
UNIQUE_CHECK_YES 
UNIQUE_CHECK_PARTIAL 
UNIQUE_CHECK_EXISTING 

Definition at line 106 of file genam.h.

{
    UNIQUE_CHECK_NO,            /* Don't do any uniqueness checking */
    UNIQUE_CHECK_YES,           /* Enforce uniqueness at insertion time */
    UNIQUE_CHECK_PARTIAL,       /* Test uniqueness, but no error */
    UNIQUE_CHECK_EXISTING       /* Check if existing tuple is unique */
} IndexUniqueCheck;


Function Documentation

char* BuildIndexValueDescription ( Relation  indexRelation,
Datum values,
bool isnull 
)

Definition at line 161 of file genam.c.

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), buf, StringInfoData::data, getTypeOutputInfo(), i, initStringInfo(), OidOutputFunctionCall(), pg_get_indexdef_columns(), RelationData::rd_opcintype, RelationData::rd_rel, RelationGetRelid, and val.

Referenced by _bt_check_unique(), check_exclusion_constraint(), and comparetup_index_btree().

{
    StringInfoData buf;
    int         natts = indexRelation->rd_rel->relnatts;
    int         i;

    initStringInfo(&buf);
    appendStringInfo(&buf, "(%s)=(",
                     pg_get_indexdef_columns(RelationGetRelid(indexRelation),
                                             true));

    for (i = 0; i < natts; i++)
    {
        char       *val;

        if (isnull[i])
            val = "null";
        else
        {
            Oid         foutoid;
            bool        typisvarlena;

            /*
             * The provided data is not necessarily of the type stored in the
             * index; rather it is of the index opclass's input type. So look
             * at rd_opcintype not the index tupdesc.
             *
             * Note: this is a bit shaky for opclasses that have pseudotype
             * input types such as ANYARRAY or RECORD.  Currently, the
             * typoutput functions associated with the pseudotypes will work
             * okay, but we might have to try harder in future.
             */
            getTypeOutputInfo(indexRelation->rd_opcintype[i],
                              &foutoid, &typisvarlena);
            val = OidOutputFunctionCall(foutoid, values[i]);
        }

        if (i > 0)
            appendStringInfoString(&buf, ", ");
        appendStringInfoString(&buf, val);
    }

    appendStringInfoChar(&buf, ')');

    return buf.data;
}

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

Definition at line 238 of file indexam.c.

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

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

{
    IndexScanDesc scan;

    scan = index_beginscan_internal(indexRelation, nkeys, norderbys, snapshot);

    /*
     * Save additional parameters into the scandesc.  Everything else was set
     * up by RelationGetIndexScan.
     */
    scan->heapRelation = heapRelation;
    scan->xs_snapshot = snapshot;

    return scan;
}

IndexScanDesc index_beginscan_bitmap ( Relation  indexRelation,
Snapshot  snapshot,
int  nkeys 
)

Definition at line 264 of file indexam.c.

References index_beginscan_internal(), and IndexScanDescData::xs_snapshot.

Referenced by ExecInitBitmapIndexScan().

{
    IndexScanDesc scan;

    scan = index_beginscan_internal(indexRelation, nkeys, 0, snapshot);

    /*
     * Save additional parameters into the scandesc.  Everything else was set
     * up by RelationGetIndexScan.
     */
    scan->xs_snapshot = snapshot;

    return scan;
}

IndexBulkDeleteResult* index_bulk_delete ( IndexVacuumInfo info,
IndexBulkDeleteResult stats,
IndexBulkDeleteCallback  callback,
void *  callback_state 
)

Definition at line 675 of file indexam.c.

References DatumGetPointer, FunctionCall4, GET_UNCACHED_REL_PROCEDURE, IndexVacuumInfo::index, and PointerGetDatum.

Referenced by lazy_vacuum_index(), and validate_index().

{
    Relation    indexRelation = info->index;
    FmgrInfo    procedure;
    IndexBulkDeleteResult *result;

    RELATION_CHECKS;
    GET_UNCACHED_REL_PROCEDURE(ambulkdelete);

    result = (IndexBulkDeleteResult *)
        DatumGetPointer(FunctionCall4(&procedure,
                                      PointerGetDatum(info),
                                      PointerGetDatum(stats),
                                      PointerGetDatum((Pointer) callback),
                                      PointerGetDatum(callback_state)));

    return result;
}

bool index_can_return ( Relation  indexRelation  ) 

Definition at line 727 of file indexam.c.

References DatumGetBool, FunctionCall1, GET_REL_PROCEDURE, PointerGetDatum, RelationData::rd_am, and RegProcedureIsValid.

Referenced by get_relation_info().

{
    FmgrInfo   *procedure;

    RELATION_CHECKS;

    /* amcanreturn is optional; assume FALSE if not provided by AM */
    if (!RegProcedureIsValid(indexRelation->rd_am->amcanreturn))
        return false;

    GET_REL_PROCEDURE(amcanreturn);

    return DatumGetBool(FunctionCall1(procedure,
                                      PointerGetDatum(indexRelation)));
}

void index_close ( Relation  relation,
LOCKMODE  lockmode 
)
void index_endscan ( IndexScanDesc  scan  ) 

Definition at line 363 of file indexam.c.

References BufferIsValid, FunctionCall1, GET_SCAN_PROCEDURE, IndexScanDescData::indexRelation, IndexScanEnd(), PointerGetDatum, RelationDecrementReferenceCount(), ReleaseBuffer(), and IndexScanDescData::xs_cbuf.

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

{
    FmgrInfo   *procedure;

    SCAN_CHECKS;
    GET_SCAN_PROCEDURE(amendscan);

    /* Release any held pin on a heap page */
    if (BufferIsValid(scan->xs_cbuf))
    {
        ReleaseBuffer(scan->xs_cbuf);
        scan->xs_cbuf = InvalidBuffer;
    }

    /* End the AM's scan */
    FunctionCall1(procedure, PointerGetDatum(scan));

    /* Release index refcount acquired by index_beginscan */
    RelationDecrementReferenceCount(scan->indexRelation);

    /* Release the scan data structure itself */
    IndexScanEnd(scan);
}

HeapTuple index_fetch_heap ( IndexScanDesc  scan  ) 

Definition at line 503 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(), pgstat_count_heap_fetch, RecentGlobalXmin, 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().

{
    ItemPointer tid = &scan->xs_ctup.t_self;
    bool        all_dead = false;
    bool        got_heap_tuple;

    /* We can skip the buffer-switching logic if we're in mid-HOT chain. */
    if (!scan->xs_continue_hot)
    {
        /* Switch to correct buffer if we don't have it already */
        Buffer      prev_buf = scan->xs_cbuf;

        scan->xs_cbuf = ReleaseAndReadBuffer(scan->xs_cbuf,
                                             scan->heapRelation,
                                             ItemPointerGetBlockNumber(tid));

        /*
         * Prune page, but only if we weren't already on this page
         */
        if (prev_buf != scan->xs_cbuf)
            heap_page_prune_opt(scan->heapRelation, scan->xs_cbuf,
                                RecentGlobalXmin);
    }

    /* Obtain share-lock on the buffer so we can examine visibility */
    LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE);
    got_heap_tuple = heap_hot_search_buffer(tid, scan->heapRelation,
                                            scan->xs_cbuf,
                                            scan->xs_snapshot,
                                            &scan->xs_ctup,
                                            &all_dead,
                                            !scan->xs_continue_hot);
    LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK);

    if (got_heap_tuple)
    {
        /*
         * Only in a non-MVCC snapshot can more than one member of the HOT
         * chain be visible.
         */
        scan->xs_continue_hot = !IsMVCCSnapshot(scan->xs_snapshot);
        pgstat_count_heap_fetch(scan->indexRelation);
        return &scan->xs_ctup;
    }

    /* We've reached the end of the HOT chain. */
    scan->xs_continue_hot = false;

    /*
     * If we scanned a whole HOT chain and found only dead tuples, tell index
     * AM to kill its entry for that TID (this will take effect in the next
     * amgettuple call, in index_getnext_tid).  We do not do this when in
     * recovery because it may violate MVCC to do so.  See comments in
     * RelationGetIndexScan().
     */
    if (!scan->xactStartedInRecovery)
        scan->kill_prior_tuple = all_dead;

    return NULL;
}

int64 index_getbitmap ( IndexScanDesc  scan,
TIDBitmap bitmap 
)

Definition at line 634 of file indexam.c.

References DatumGetInt64, DatumGetPointer, FunctionCall2, GET_SCAN_PROCEDURE, IndexScanDescData::indexRelation, IndexScanDescData::kill_prior_tuple, pfree(), pgstat_count_index_tuples, and PointerGetDatum.

Referenced by MultiExecBitmapIndexScan().

{
    FmgrInfo   *procedure;
    int64       ntids;
    Datum       d;

    SCAN_CHECKS;
    GET_SCAN_PROCEDURE(amgetbitmap);

    /* just make sure this is false... */
    scan->kill_prior_tuple = false;

    /*
     * have the am's getbitmap proc do all the work.
     */
    d = FunctionCall2(procedure,
                      PointerGetDatum(scan),
                      PointerGetDatum(bitmap));

    ntids = DatumGetInt64(d);

    /* If int8 is pass-by-ref, must free the result to avoid memory leak */
#ifndef USE_FLOAT8_BYVAL
    pfree(DatumGetPointer(d));
#endif

    pgstat_count_index_tuples(scan->indexRelation, ntids);

    return ntids;
}

HeapTuple index_getnext ( IndexScanDesc  scan,
ScanDirection  direction 
)

Definition at line 580 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_constraint(), copy_heap_data(), get_actual_variable_range(), IndexNext(), systable_getnext(), and systable_getnext_ordered().

{
    HeapTuple   heapTuple;
    ItemPointer tid;

    for (;;)
    {
        if (scan->xs_continue_hot)
        {
            /*
             * We are resuming scan of a HOT chain after having returned an
             * earlier member.  Must still hold pin on current heap page.
             */
            Assert(BufferIsValid(scan->xs_cbuf));
            Assert(ItemPointerGetBlockNumber(&scan->xs_ctup.t_self) ==
                   BufferGetBlockNumber(scan->xs_cbuf));
        }
        else
        {
            /* Time to fetch the next TID from the index */
            tid = index_getnext_tid(scan, direction);

            /* If we're out of index entries, we're done */
            if (tid == NULL)
                break;
        }

        /*
         * Fetch the next (or only) visible heap tuple for this index entry.
         * If we don't find anything, loop around and grab the next TID from
         * the index.
         */
        heapTuple = index_fetch_heap(scan);
        if (heapTuple != NULL)
            return heapTuple;
    }

    return NULL;                /* failure exit */
}

ItemPointer index_getnext_tid ( IndexScanDesc  scan,
ScanDirection  direction 
)

Definition at line 443 of file indexam.c.

References Assert, BufferIsValid, DatumGetBool, FunctionCall2, GET_SCAN_PROCEDURE, IndexScanDescData::indexRelation, Int32GetDatum, IndexScanDescData::kill_prior_tuple, pgstat_count_index_tuples, PointerGetDatum, RecentGlobalXmin, ReleaseBuffer(), HeapTupleData::t_self, TransactionIdIsValid, IndexScanDescData::xs_cbuf, and IndexScanDescData::xs_ctup.

Referenced by index_getnext(), and IndexOnlyNext().

{
    FmgrInfo   *procedure;
    bool        found;

    SCAN_CHECKS;
    GET_SCAN_PROCEDURE(amgettuple);

    Assert(TransactionIdIsValid(RecentGlobalXmin));

    /*
     * The AM's amgettuple proc finds the next index entry matching the scan
     * keys, and puts the TID into scan->xs_ctup.t_self.  It should also set
     * scan->xs_recheck and possibly scan->xs_itup, though we pay no attention
     * to those fields here.
     */
    found = DatumGetBool(FunctionCall2(procedure,
                                       PointerGetDatum(scan),
                                       Int32GetDatum(direction)));

    /* Reset kill flag immediately for safety */
    scan->kill_prior_tuple = false;

    /* If we're out of index entries, we're done */
    if (!found)
    {
        /* ... but first, release any held pin on a heap page */
        if (BufferIsValid(scan->xs_cbuf))
        {
            ReleaseBuffer(scan->xs_cbuf);
            scan->xs_cbuf = InvalidBuffer;
        }
        return NULL;
    }

    pgstat_count_index_tuples(scan->indexRelation, 1);

    /* Return the TID of the tuple we found. */
    return &scan->xs_ctup.t_self;
}

RegProcedure index_getprocid ( Relation  irel,
AttrNumber  attnum,
uint16  procnum 
)

Definition at line 770 of file indexam.c.

References Assert, NULL, RelationData::rd_am, and RelationData::rd_support.

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

{
    RegProcedure *loc;
    int         nproc;
    int         procindex;

    nproc = irel->rd_am->amsupport;

    Assert(procnum > 0 && procnum <= (uint16) nproc);

    procindex = (nproc * (attnum - 1)) + (procnum - 1);

    loc = irel->rd_support;

    Assert(loc != NULL);

    return loc[procindex];
}

FmgrInfo* index_getprocinfo ( Relation  irel,
AttrNumber  attnum,
uint16  procnum 
)

Definition at line 804 of file indexam.c.

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

Referenced by _bt_first(), _bt_mkscankey(), _bt_mkscankey_nodata(), _hash_datum2hashkey(), doPickSplit(), initGinState(), initGISTstate(), spgdoinsert(), spgGetCache(), spgLeafTest(), and spgWalk().

{
    FmgrInfo   *locinfo;
    int         nproc;
    int         procindex;

    nproc = irel->rd_am->amsupport;

    Assert(procnum > 0 && procnum <= (uint16) nproc);

    procindex = (nproc * (attnum - 1)) + (procnum - 1);

    locinfo = irel->rd_supportinfo;

    Assert(locinfo != NULL);

    locinfo += procindex;

    /* Initialize the lookup info if first time through */
    if (locinfo->fn_oid == InvalidOid)
    {
        RegProcedure *loc = irel->rd_support;
        RegProcedure procId;

        Assert(loc != NULL);

        procId = loc[procindex];

        /*
         * Complain if function was not found during IndexSupportInitialize.
         * This should not happen unless the system tables contain bogus
         * entries for the index opclass.  (If an AM wants to allow a support
         * function to be optional, it can use index_getprocid.)
         */
        if (!RegProcedureIsValid(procId))
            elog(ERROR, "missing support function %d for attribute %d of index \"%s\"",
                 procnum, attnum, RelationGetRelationName(irel));

        fmgr_info_cxt(procId, locinfo, irel->rd_indexcxt);
    }

    return locinfo;
}

bool index_insert ( Relation  indexRelation,
Datum values,
bool isnull,
ItemPointer  heap_t_ctid,
Relation  heapRelation,
IndexUniqueCheck  checkUnique 
)

Definition at line 203 of file indexam.c.

References CheckForSerializableConflictIn(), DatumGetBool, FunctionCall6, GET_REL_PROCEDURE, Int32GetDatum, InvalidBuffer, NULL, PointerGetDatum, and RelationData::rd_am.

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

{
    FmgrInfo   *procedure;

    RELATION_CHECKS;
    GET_REL_PROCEDURE(aminsert);

    if (!(indexRelation->rd_am->ampredlocks))
        CheckForSerializableConflictIn(indexRelation,
                                       (HeapTuple) NULL,
                                       InvalidBuffer);

    /*
     * have the am's insert proc do all the work.
     */
    return DatumGetBool(FunctionCall6(procedure,
                                      PointerGetDatum(indexRelation),
                                      PointerGetDatum(values),
                                      PointerGetDatum(isnull),
                                      PointerGetDatum(heap_t_ctid),
                                      PointerGetDatum(heapRelation),
                                      Int32GetDatum((int32) checkUnique)));
}

void index_markpos ( IndexScanDesc  scan  ) 

Definition at line 392 of file indexam.c.

References FunctionCall1, GET_SCAN_PROCEDURE, and PointerGetDatum.

Referenced by ExecIndexMarkPos(), and ExecIndexOnlyMarkPos().

{
    FmgrInfo   *procedure;

    SCAN_CHECKS;
    GET_SCAN_PROCEDURE(ammarkpos);

    FunctionCall1(procedure, PointerGetDatum(scan));
}

Relation index_open ( Oid  relationId,
LOCKMODE  lockmode 
)
void index_rescan ( IndexScanDesc  scan,
ScanKey  keys,
int  nkeys,
ScanKey  orderbys,
int  norderbys 
)
void index_restrpos ( IndexScanDesc  scan  ) 
IndexBulkDeleteResult* index_vacuum_cleanup ( IndexVacuumInfo info,
IndexBulkDeleteResult stats 
)

Definition at line 704 of file indexam.c.

References DatumGetPointer, FunctionCall2, GET_UNCACHED_REL_PROCEDURE, IndexVacuumInfo::index, and PointerGetDatum.

Referenced by do_analyze_rel(), and lazy_cleanup_index().

{
    Relation    indexRelation = info->index;
    FmgrInfo    procedure;
    IndexBulkDeleteResult *result;

    RELATION_CHECKS;
    GET_UNCACHED_REL_PROCEDURE(amvacuumcleanup);

    result = (IndexBulkDeleteResult *)
        DatumGetPointer(FunctionCall2(&procedure,
                                      PointerGetDatum(info),
                                      PointerGetDatum(stats)));

    return result;
}

void IndexScanEnd ( IndexScanDesc  scan  ) 

Definition at line 139 of file genam.c.

References IndexScanDescData::keyData, NULL, IndexScanDescData::orderByData, and pfree().

Referenced by index_endscan().

{
    if (scan->keyData != NULL)
        pfree(scan->keyData);
    if (scan->orderByData != NULL)
        pfree(scan->orderByData);

    pfree(scan);
}

IndexScanDesc RelationGetIndexScan ( Relation  indexRelation,
int  nkeys,
int  norderbys 
)

Definition at line 73 of file genam.c.

References IndexScanDescData::heapRelation, IndexScanDescData::ignore_killed_tuples, IndexScanDescData::indexRelation, ItemPointerSetInvalid, IndexScanDescData::keyData, IndexScanDescData::kill_prior_tuple, IndexScanDescData::numberOfKeys, IndexScanDescData::numberOfOrderBys, IndexScanDescData::opaque, IndexScanDescData::orderByData, palloc(), HeapTupleData::t_data, HeapTupleData::t_self, TransactionStartedDuringRecovery(), IndexScanDescData::xactStartedInRecovery, IndexScanDescData::xs_cbuf, IndexScanDescData::xs_continue_hot, IndexScanDescData::xs_ctup, IndexScanDescData::xs_itup, IndexScanDescData::xs_itupdesc, IndexScanDescData::xs_snapshot, and IndexScanDescData::xs_want_itup.

Referenced by btbeginscan(), ginbeginscan(), gistbeginscan(), hashbeginscan(), and spgbeginscan().

{
    IndexScanDesc scan;

    scan = (IndexScanDesc) palloc(sizeof(IndexScanDescData));

    scan->heapRelation = NULL;  /* may be set later */
    scan->indexRelation = indexRelation;
    scan->xs_snapshot = SnapshotNow;    /* may be set later */
    scan->numberOfKeys = nkeys;
    scan->numberOfOrderBys = norderbys;

    /*
     * We allocate key workspace here, but it won't get filled until amrescan.
     */
    if (nkeys > 0)
        scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys);
    else
        scan->keyData = NULL;
    if (norderbys > 0)
        scan->orderByData = (ScanKey) palloc(sizeof(ScanKeyData) * norderbys);
    else
        scan->orderByData = NULL;

    scan->xs_want_itup = false; /* may be set later */

    /*
     * During recovery we ignore killed tuples and don't bother to kill them
     * either. We do this because the xmin on the primary node could easily be
     * later than the xmin on the standby node, so that what the primary
     * thinks is killed is supposed to be visible on standby. So for correct
     * MVCC for queries during recovery we must ignore these hints and check
     * all tuples. Do *not* set ignore_killed_tuples to true when running in a
     * transaction that was started during recovery. xactStartedInRecovery
     * should not be altered by index AMs.
     */
    scan->kill_prior_tuple = false;
    scan->xactStartedInRecovery = TransactionStartedDuringRecovery();
    scan->ignore_killed_tuples = !scan->xactStartedInRecovery;

    scan->opaque = NULL;

    scan->xs_itup = NULL;
    scan->xs_itupdesc = NULL;

    ItemPointerSetInvalid(&scan->xs_ctup.t_self);
    scan->xs_ctup.t_data = NULL;
    scan->xs_cbuf = InvalidBuffer;
    scan->xs_continue_hot = false;

    return scan;
}

SysScanDesc systable_beginscan ( Relation  heapRelation,
Oid  indexId,
bool  indexOK,
Snapshot  snapshot,
int  nkeys,
ScanKey  key 
)

Definition at line 248 of file genam.c.

References AccessShareLock, elog, ERROR, heap_beginscan_strat(), SysScanDescData::heap_rel, i, IgnoreSystemIndexes, index_beginscan(), index_open(), index_rescan(), SysScanDescData::irel, SysScanDescData::iscan, NULL, palloc(), RelationData::rd_index, ReindexIsProcessingIndex(), SysScanDescData::scan, and ScanKeyData::sk_attno.

Referenced by AfterTriggerSetState(), AlterConstraintNamespaces(), AlterDatabase(), AlterDatabaseOwner(), AlterDomainDropConstraint(), AlterDomainValidateConstraint(), AlterExtensionNamespace(), AlterSeqNamespaces(), AlterSetting(), ApplyExtensionUpdates(), ApplySetting(), ATExecAddInherit(), ATExecAddOf(), ATExecAlterColumnType(), ATExecDropConstraint(), ATExecDropInherit(), ATExecValidateConstraint(), AttrDefaultFetch(), change_owner_fix_column_acls(), change_owner_recurse_to_sequences(), changeDependencyFor(), check_functional_grouping(), CheckConstraintFetch(), checkSharedDependencies(), ChooseConstraintName(), ConstraintNameIsUsed(), copyTemplateDependencies(), CreateComments(), CreateSharedComments(), CreateTrigger(), DefineOpClass(), DefineTSConfiguration(), DeleteAttributeTuples(), DeleteComments(), deleteDependencyRecordsFor(), deleteDependencyRecordsForClass(), deleteOneObject(), DeleteSecurityLabel(), DeleteSharedComments(), DeleteSharedSecurityLabel(), DeleteSystemAttributeTuples(), drop_parent_dependency(), DropCastById(), DropConfigurationMapping(), dropDatabaseDependencies(), DropRole(), EnableDisableTrigger(), EnumValuesDelete(), exec_object_restorecon(), ExecAlterExtensionStmt(), ExecGrant_Largeobject(), extension_config_remove(), find_composite_type_dependencies(), find_inheritance_children(), find_language_template(), findDependentObjects(), get_catalog_object_by_oid(), get_constraint_index(), get_database_oid(), get_db_info(), get_domain_constraint_oid(), get_extension_name(), get_extension_oid(), get_extension_schema(), get_index_constraint(), get_pkey_attnames(), get_relation_constraint_oid(), get_rels_with_domain(), get_trigger_oid(), GetComment(), GetDatabaseTuple(), GetDatabaseTupleByOid(), GetDefaultOpClass(), GetDomainConstraints(), getExtensionOfObject(), GetNewOidWithIndex(), getObjectDescription(), getObjectIdentity(), getOwnedSequences(), GetSecurityLabel(), GetSharedSecurityLabel(), heap_truncate_find_FKs(), isObjectPinned(), isSharedObjectPinned(), LargeObjectDrop(), LargeObjectExists(), load_enum_cache_data(), LookupOpclassInfo(), makeConfigurationDependencies(), MakeConfigurationMapping(), MergeConstraintsIntoExisting(), MergeWithExistingConstraint(), movedb(), myLargeObjectExists(), pg_extension_config_dump(), pg_extension_ownercheck(), pg_get_serial_sequence(), pg_get_triggerdef_worker(), pg_largeobject_aclmask_snapshot(), pg_largeobject_ownercheck(), RangeDelete(), regclassin(), regoperin(), regprocin(), regtypein(), RelationBuildRuleLock(), RelationBuildTriggers(), RelationBuildTupleDesc(), RelationGetExclusionInfo(), RelationGetIndexList(), RelationRemoveInheritance(), RemoveAmOpEntryById(), RemoveAmProcEntryById(), RemoveAttrDefault(), RemoveAttrDefaultById(), RemoveCollationById(), RemoveDefaultACLById(), RemoveExtensionById(), RemoveRewriteRuleById(), RemoveRoleFromObjectACL(), RemoveStatistics(), RemoveTriggerById(), RemoveTSConfigurationById(), renametrig(), ScanPgRelation(), SearchCatCache(), SearchCatCacheList(), sepgsql_attribute_post_create(), sepgsql_database_post_create(), sepgsql_proc_post_create(), sepgsql_proc_setattr(), sepgsql_relation_post_create(), sepgsql_relation_setattr(), sepgsql_relation_setattr_extra(), sepgsql_schema_post_create(), sequenceIsOwned(), SetSecurityLabel(), SetSharedSecurityLabel(), shdepChangeDep(), shdepDropDependency(), shdepDropOwned(), shdepReassignOwned(), toastrel_valueid_exists(), typeInheritsFrom(), and vac_update_datfrozenxid().

{
    SysScanDesc sysscan;
    Relation    irel;

    if (indexOK &&
        !IgnoreSystemIndexes &&
        !ReindexIsProcessingIndex(indexId))
        irel = index_open(indexId, AccessShareLock);
    else
        irel = NULL;

    sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData));

    sysscan->heap_rel = heapRelation;
    sysscan->irel = irel;

    if (irel)
    {
        int         i;

        /* Change attribute numbers to be index column numbers. */
        for (i = 0; i < nkeys; i++)
        {
            int         j;

            for (j = 0; j < irel->rd_index->indnatts; j++)
            {
                if (key[i].sk_attno == irel->rd_index->indkey.values[j])
                {
                    key[i].sk_attno = j + 1;
                    break;
                }
            }
            if (j == irel->rd_index->indnatts)
                elog(ERROR, "column is not in index");
        }

        sysscan->iscan = index_beginscan(heapRelation, irel,
                                         snapshot, nkeys, 0);
        index_rescan(sysscan->iscan, key, nkeys, NULL, 0);
        sysscan->scan = NULL;
    }
    else
    {
        /*
         * We disallow synchronized scans when forced to use a heapscan on a
         * catalog.  In most cases the desired rows are near the front, so
         * that the unpredictable start point of a syncscan is a serious
         * disadvantage; and there are no compensating advantages, because
         * it's unlikely that such scans will occur in parallel.
         */
        sysscan->scan = heap_beginscan_strat(heapRelation, snapshot,
                                             nkeys, key,
                                             true, false);
        sysscan->iscan = NULL;
    }

    return sysscan;
}

SysScanDesc systable_beginscan_ordered ( Relation  heapRelation,
Relation  indexRelation,
Snapshot  snapshot,
int  nkeys,
ScanKey  key 
)

Definition at line 425 of file genam.c.

References elog, ERROR, SysScanDescData::heap_rel, i, IgnoreSystemIndexes, index_beginscan(), index_rescan(), SysScanDescData::irel, SysScanDescData::iscan, NULL, palloc(), RelationData::rd_index, ReindexIsProcessingIndex(), RelationGetRelationName, RelationGetRelid, SysScanDescData::scan, ScanKeyData::sk_attno, and WARNING.

Referenced by BuildEventTriggerCache(), enum_endpoint(), enum_range_internal(), inv_getsize(), inv_read(), inv_truncate(), inv_write(), lookup_ts_config_cache(), toast_delete_datum(), toast_fetch_datum(), and toast_fetch_datum_slice().

{
    SysScanDesc sysscan;
    int         i;

    /* REINDEX can probably be a hard error here ... */
    if (ReindexIsProcessingIndex(RelationGetRelid(indexRelation)))
        elog(ERROR, "cannot do ordered scan on index \"%s\", because it is being reindexed",
             RelationGetRelationName(indexRelation));
    /* ... but we only throw a warning about violating IgnoreSystemIndexes */
    if (IgnoreSystemIndexes)
        elog(WARNING, "using index \"%s\" despite IgnoreSystemIndexes",
             RelationGetRelationName(indexRelation));

    sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData));

    sysscan->heap_rel = heapRelation;
    sysscan->irel = indexRelation;

    /* Change attribute numbers to be index column numbers. */
    for (i = 0; i < nkeys; i++)
    {
        int         j;

        for (j = 0; j < indexRelation->rd_index->indnatts; j++)
        {
            if (key[i].sk_attno == indexRelation->rd_index->indkey.values[j])
            {
                key[i].sk_attno = j + 1;
                break;
            }
        }
        if (j == indexRelation->rd_index->indnatts)
            elog(ERROR, "column is not in index");
    }

    sysscan->iscan = index_beginscan(heapRelation, indexRelation,
                                     snapshot, nkeys, 0);
    index_rescan(sysscan->iscan, key, nkeys, NULL, 0);
    sysscan->scan = NULL;

    return sysscan;
}

void systable_endscan ( SysScanDesc  sysscan  ) 

Definition at line 394 of file genam.c.

References AccessShareLock, heap_endscan(), index_close(), index_endscan(), SysScanDescData::irel, SysScanDescData::iscan, pfree(), and SysScanDescData::scan.

Referenced by AfterTriggerSetState(), AlterConstraintNamespaces(), AlterDatabase(), AlterDatabaseOwner(), AlterDomainDropConstraint(), AlterDomainValidateConstraint(), AlterExtensionNamespace(), AlterSeqNamespaces(), AlterSetting(), ApplyExtensionUpdates(), ApplySetting(), ATExecAddInherit(), ATExecAddOf(), ATExecAlterColumnType(), ATExecDropConstraint(), ATExecDropInherit(), ATExecValidateConstraint(), AttrDefaultFetch(), change_owner_fix_column_acls(), change_owner_recurse_to_sequences(), changeDependencyFor(), check_functional_grouping(), CheckConstraintFetch(), checkSharedDependencies(), ChooseConstraintName(), ConstraintNameIsUsed(), copyTemplateDependencies(), CreateComments(), CreateSharedComments(), CreateTrigger(), DefineOpClass(), DefineTSConfiguration(), DeleteAttributeTuples(), DeleteComments(), deleteDependencyRecordsFor(), deleteDependencyRecordsForClass(), deleteOneObject(), DeleteSecurityLabel(), DeleteSharedComments(), DeleteSharedSecurityLabel(), DeleteSystemAttributeTuples(), drop_parent_dependency(), DropCastById(), DropConfigurationMapping(), dropDatabaseDependencies(), DropRole(), EnableDisableTrigger(), EnumValuesDelete(), exec_object_restorecon(), ExecAlterExtensionStmt(), ExecGrant_Largeobject(), extension_config_remove(), find_composite_type_dependencies(), find_inheritance_children(), find_language_template(), findDependentObjects(), get_catalog_object_by_oid(), get_constraint_index(), get_database_oid(), get_db_info(), get_domain_constraint_oid(), get_extension_name(), get_extension_oid(), get_extension_schema(), get_index_constraint(), get_pkey_attnames(), get_relation_constraint_oid(), get_rels_with_domain(), get_trigger_oid(), GetComment(), GetDatabaseTuple(), GetDatabaseTupleByOid(), GetDefaultOpClass(), GetDomainConstraints(), getExtensionOfObject(), GetNewOidWithIndex(), getObjectDescription(), getObjectIdentity(), getOwnedSequences(), GetSecurityLabel(), GetSharedSecurityLabel(), heap_truncate_find_FKs(), isObjectPinned(), isSharedObjectPinned(), LargeObjectDrop(), LargeObjectExists(), load_enum_cache_data(), LookupOpclassInfo(), makeConfigurationDependencies(), MakeConfigurationMapping(), MergeConstraintsIntoExisting(), MergeWithExistingConstraint(), movedb(), myLargeObjectExists(), pg_extension_config_dump(), pg_extension_ownercheck(), pg_get_serial_sequence(), pg_get_triggerdef_worker(), pg_largeobject_aclmask_snapshot(), pg_largeobject_ownercheck(), RangeDelete(), regclassin(), regoperin(), regprocin(), regtypein(), RelationBuildRuleLock(), RelationBuildTriggers(), RelationBuildTupleDesc(), RelationGetExclusionInfo(), RelationGetIndexList(), RelationRemoveInheritance(), RemoveAmOpEntryById(), RemoveAmProcEntryById(), RemoveAttrDefault(), RemoveAttrDefaultById(), RemoveCollationById(), RemoveDefaultACLById(), RemoveExtensionById(), RemoveRewriteRuleById(), RemoveRoleFromObjectACL(), RemoveStatistics(), RemoveTriggerById(), RemoveTSConfigurationById(), renametrig(), ScanPgRelation(), SearchCatCache(), SearchCatCacheList(), sepgsql_attribute_post_create(), sepgsql_database_post_create(), sepgsql_proc_post_create(), sepgsql_proc_setattr(), sepgsql_relation_post_create(), sepgsql_relation_setattr(), sepgsql_relation_setattr_extra(), sepgsql_schema_post_create(), sequenceIsOwned(), SetSecurityLabel(), SetSharedSecurityLabel(), shdepChangeDep(), shdepDropDependency(), shdepDropOwned(), shdepReassignOwned(), toastrel_valueid_exists(), typeInheritsFrom(), and vac_update_datfrozenxid().

{
    if (sysscan->irel)
    {
        index_endscan(sysscan->iscan);
        index_close(sysscan->irel, AccessShareLock);
    }
    else
        heap_endscan(sysscan->scan);

    pfree(sysscan);
}

void systable_endscan_ordered ( SysScanDesc  sysscan  ) 
HeapTuple systable_getnext ( SysScanDesc  sysscan  ) 

Definition at line 323 of file genam.c.

References elog, ERROR, ForwardScanDirection, heap_getnext(), index_getnext(), SysScanDescData::irel, SysScanDescData::iscan, SysScanDescData::scan, and IndexScanDescData::xs_recheck.

Referenced by AfterTriggerSetState(), AlterConstraintNamespaces(), AlterDatabase(), AlterDatabaseOwner(), AlterDomainDropConstraint(), AlterDomainValidateConstraint(), AlterExtensionNamespace(), AlterSeqNamespaces(), AlterSetting(), ApplyExtensionUpdates(), ApplySetting(), ATExecAddInherit(), ATExecAddOf(), ATExecAlterColumnType(), ATExecDropConstraint(), ATExecDropInherit(), ATExecValidateConstraint(), AttrDefaultFetch(), change_owner_fix_column_acls(), change_owner_recurse_to_sequences(), changeDependencyFor(), check_functional_grouping(), CheckConstraintFetch(), checkSharedDependencies(), ChooseConstraintName(), ConstraintNameIsUsed(), copyTemplateDependencies(), CreateComments(), CreateSharedComments(), CreateTrigger(), DefineOpClass(), DefineTSConfiguration(), DeleteAttributeTuples(), DeleteComments(), deleteDependencyRecordsFor(), deleteDependencyRecordsForClass(), deleteOneObject(), DeleteSecurityLabel(), DeleteSharedComments(), DeleteSharedSecurityLabel(), DeleteSystemAttributeTuples(), drop_parent_dependency(), DropCastById(), DropConfigurationMapping(), dropDatabaseDependencies(), DropRole(), EnableDisableTrigger(), EnumValuesDelete(), exec_object_restorecon(), ExecAlterExtensionStmt(), ExecGrant_Largeobject(), extension_config_remove(), find_composite_type_dependencies(), find_inheritance_children(), find_language_template(), findDependentObjects(), get_catalog_object_by_oid(), get_constraint_index(), get_database_oid(), get_db_info(), get_domain_constraint_oid(), get_extension_name(), get_extension_oid(), get_extension_schema(), get_index_constraint(), get_pkey_attnames(), get_relation_constraint_oid(), get_rels_with_domain(), get_trigger_oid(), GetComment(), GetDatabaseTuple(), GetDatabaseTupleByOid(), GetDefaultOpClass(), GetDomainConstraints(), getExtensionOfObject(), GetNewOidWithIndex(), getObjectDescription(), getObjectIdentity(), getOwnedSequences(), GetSecurityLabel(), GetSharedSecurityLabel(), heap_truncate_find_FKs(), isObjectPinned(), isSharedObjectPinned(), LargeObjectDrop(), LargeObjectExists(), load_enum_cache_data(), LookupOpclassInfo(), makeConfigurationDependencies(), MakeConfigurationMapping(), MergeConstraintsIntoExisting(), MergeWithExistingConstraint(), movedb(), myLargeObjectExists(), pg_extension_config_dump(), pg_extension_ownercheck(), pg_get_serial_sequence(), pg_get_triggerdef_worker(), pg_largeobject_aclmask_snapshot(), pg_largeobject_ownercheck(), RangeDelete(), regclassin(), regoperin(), regprocin(), regtypein(), RelationBuildRuleLock(), RelationBuildTriggers(), RelationBuildTupleDesc(), RelationGetExclusionInfo(), RelationGetIndexList(), RelationRemoveInheritance(), RemoveAmOpEntryById(), RemoveAmProcEntryById(), RemoveAttrDefault(), RemoveAttrDefaultById(), RemoveCollationById(), RemoveDefaultACLById(), RemoveExtensionById(), RemoveRewriteRuleById(), RemoveRoleFromObjectACL(), RemoveStatistics(), RemoveTriggerById(), RemoveTSConfigurationById(), renametrig(), ScanPgRelation(), SearchCatCache(), SearchCatCacheList(), sepgsql_attribute_post_create(), sepgsql_database_post_create(), sepgsql_proc_post_create(), sepgsql_proc_setattr(), sepgsql_relation_post_create(), sepgsql_relation_setattr(), sepgsql_relation_setattr_extra(), sepgsql_schema_post_create(), sequenceIsOwned(), SetSecurityLabel(), SetSharedSecurityLabel(), shdepChangeDep(), shdepDropDependency(), shdepDropOwned(), shdepReassignOwned(), toastrel_valueid_exists(), typeInheritsFrom(), and vac_update_datfrozenxid().

{
    HeapTuple   htup;

    if (sysscan->irel)
    {
        htup = index_getnext(sysscan->iscan, ForwardScanDirection);

        /*
         * We currently don't need to support lossy index operators for any
         * system catalog scan.  It could be done here, using the scan keys to
         * drive the operator calls, if we arranged to save the heap attnums
         * during systable_beginscan(); this is practical because we still
         * wouldn't need to support indexes on expressions.
         */
        if (htup && sysscan->iscan->xs_recheck)
            elog(ERROR, "system catalog scans with lossy index conditions are not implemented");
    }
    else
        htup = heap_getnext(sysscan->scan, ForwardScanDirection);

    return htup;
}

HeapTuple systable_getnext_ordered ( SysScanDesc  sysscan,
ScanDirection  direction 
)

Definition at line 476 of file genam.c.

References Assert, elog, ERROR, index_getnext(), SysScanDescData::irel, SysScanDescData::iscan, and IndexScanDescData::xs_recheck.

Referenced by BuildEventTriggerCache(), enum_endpoint(), enum_range_internal(), inv_getsize(), inv_read(), inv_truncate(), inv_write(), lookup_ts_config_cache(), toast_delete_datum(), toast_fetch_datum(), and toast_fetch_datum_slice().

{
    HeapTuple   htup;

    Assert(sysscan->irel);
    htup = index_getnext(sysscan->iscan, direction);
    /* See notes in systable_getnext */
    if (htup && sysscan->iscan->xs_recheck)
        elog(ERROR, "system catalog scans with lossy index conditions are not implemented");

    return htup;
}

bool systable_recheck_tuple ( SysScanDesc  sysscan,
HeapTuple  tup 
)

Definition at line 357 of file genam.c.

References Assert, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferIsValid, HeapTupleSatisfiesVisibility, SysScanDescData::irel, SysScanDescData::iscan, LockBuffer(), HeapScanDescData::rs_cbuf, HeapScanDescData::rs_ctup, HeapScanDescData::rs_snapshot, SysScanDescData::scan, IndexScanDescData::xs_cbuf, IndexScanDescData::xs_ctup, and IndexScanDescData::xs_snapshot.

Referenced by findDependentObjects().

{
    bool        result;

    if (sysscan->irel)
    {
        IndexScanDesc scan = sysscan->iscan;

        Assert(tup == &scan->xs_ctup);
        Assert(BufferIsValid(scan->xs_cbuf));
        /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
        LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE);
        result = HeapTupleSatisfiesVisibility(tup, scan->xs_snapshot,
                                              scan->xs_cbuf);
        LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK);
    }
    else
    {
        HeapScanDesc scan = sysscan->scan;

        Assert(tup == &scan->rs_ctup);
        Assert(BufferIsValid(scan->rs_cbuf));
        /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
        LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
        result = HeapTupleSatisfiesVisibility(tup, scan->rs_snapshot,
                                              scan->rs_cbuf);
        LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
    }
    return result;
}