#include "access/sdir.h"#include "access/skey.h"#include "nodes/tidbitmap.h"#include "storage/lock.h"#include "utils/relcache.h"#include "utils/snapshot.h"
Go to the source code of this file.
| typedef struct IndexBuildResult IndexBuildResult |
| typedef bool(* IndexBulkDeleteCallback)(ItemPointer itemptr, void *state) |
| typedef struct IndexBulkDeleteResult IndexBulkDeleteResult |
| typedef struct IndexScanDescData* IndexScanDesc |
| typedef enum IndexUniqueCheck IndexUniqueCheck |
| typedef struct IndexVacuumInfo IndexVacuumInfo |
| typedef struct SysScanDescData* SysScanDesc |
| enum IndexUniqueCheck |
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;
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;
}
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)));
}
Definition at line 185 of file indexam.c.
References Assert, LockInfoData::lockRelId, MAX_LOCKMODES, NoLock, RelationData::rd_lockInfo, RelationClose(), and UnlockRelationId().
Referenced by ATExecAddIndex(), ATExecAddIndexConstraint(), build_indices(), BuildEventTriggerCache(), check_index_is_clusterable(), CheckIndexCompatible(), close_lo_relation(), copy_heap_data(), DefineIndex(), enum_endpoint(), enum_range_internal(), ExecCloseIndices(), ExecEndBitmapIndexScan(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), get_actual_variable_range(), get_relation_info(), gincostestimate(), index_create(), index_drop(), InitCatCachePhase2(), lookup_ts_config_cache(), reindex_index(), RelationGetIndexAttrBitmap(), RelationTruncateIndexes(), systable_endscan(), toast_delete_datum(), toast_fetch_datum(), toast_fetch_datum_slice(), toast_save_datum(), transformTableLikeClause(), TryReuseIndex(), vac_close_indexes(), vac_open_indexes(), and validate_index().
{
LockRelId relid = relation->rd_lockInfo.lockRelId;
Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
/* The relcache does the real work... */
RelationClose(relation);
if (lockmode != NoLock)
UnlockRelationId(&relid, 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));
}
Definition at line 160 of file indexam.c.
References ereport, errcode(), errmsg(), ERROR, RelationData::rd_rel, relation_open(), RelationGetRelationName, and RELKIND_INDEX.
Referenced by ATExecAddIndex(), ATExecAddIndexConstraint(), build_indices(), BuildEventTriggerCache(), check_index_is_clusterable(), CheckIndexCompatible(), copy_heap_data(), DefineIndex(), enum_endpoint(), enum_range_internal(), ExecInitBitmapIndexScan(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecOpenIndices(), get_actual_variable_range(), get_relation_info(), gincostestimate(), index_drop(), InitCatCachePhase2(), lookup_ts_config_cache(), open_lo_relation(), reindex_index(), RelationGetIndexAttrBitmap(), RelationTruncateIndexes(), systable_beginscan(), toast_delete_datum(), toast_fetch_datum(), toast_fetch_datum_slice(), toast_save_datum(), transformIndexConstraint(), transformTableLikeClause(), TryReuseIndex(), vac_open_indexes(), and validate_index().
{
Relation r;
r = relation_open(relationId, lockmode);
if (r->rd_rel->relkind != RELKIND_INDEX)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not an index",
RelationGetRelationName(r))));
return r;
}
| void index_rescan | ( | IndexScanDesc | scan, | |
| ScanKey | keys, | |||
| int | nkeys, | |||
| ScanKey | orderbys, | |||
| int | norderbys | |||
| ) |
Definition at line 327 of file indexam.c.
References Assert, BufferIsValid, FunctionCall5, GET_SCAN_PROCEDURE, Int32GetDatum, IndexScanDescData::kill_prior_tuple, IndexScanDescData::numberOfKeys, IndexScanDescData::numberOfOrderBys, PointerGetDatum, ReleaseBuffer(), IndexScanDescData::xs_cbuf, and IndexScanDescData::xs_continue_hot.
Referenced by check_exclusion_constraint(), copy_heap_data(), ExecInitBitmapIndexScan(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecReScanBitmapIndexScan(), ExecReScanIndexOnlyScan(), ExecReScanIndexScan(), get_actual_variable_range(), MultiExecBitmapIndexScan(), systable_beginscan(), and systable_beginscan_ordered().
{
FmgrInfo *procedure;
SCAN_CHECKS;
GET_SCAN_PROCEDURE(amrescan);
Assert(nkeys == scan->numberOfKeys);
Assert(norderbys == scan->numberOfOrderBys);
/* Release any held pin on a heap page */
if (BufferIsValid(scan->xs_cbuf))
{
ReleaseBuffer(scan->xs_cbuf);
scan->xs_cbuf = InvalidBuffer;
}
scan->xs_continue_hot = false;
scan->kill_prior_tuple = false; /* for safety */
FunctionCall5(procedure,
PointerGetDatum(scan),
PointerGetDatum(keys),
Int32GetDatum(nkeys),
PointerGetDatum(orderbys),
Int32GetDatum(norderbys));
}
| void index_restrpos | ( | IndexScanDesc | scan | ) |
Definition at line 419 of file indexam.c.
References Assert, FunctionCall1, GET_SCAN_PROCEDURE, IsMVCCSnapshot, IndexScanDescData::kill_prior_tuple, PointerGetDatum, IndexScanDescData::xs_continue_hot, and IndexScanDescData::xs_snapshot.
Referenced by ExecIndexOnlyRestrPos(), and ExecIndexRestrPos().
{
FmgrInfo *procedure;
Assert(IsMVCCSnapshot(scan->xs_snapshot));
SCAN_CHECKS;
GET_SCAN_PROCEDURE(amrestrpos);
scan->xs_continue_hot = false;
scan->kill_prior_tuple = false; /* for safety */
FunctionCall1(procedure, PointerGetDatum(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 | ) |
Definition at line 493 of file genam.c.
References Assert, index_endscan(), SysScanDescData::irel, SysScanDescData::iscan, and pfree().
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().
{
Assert(sysscan->irel);
index_endscan(sysscan->iscan);
pfree(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;
}
1.7.1