⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 indexam.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * indexam.c *	  general index access method routines * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.86 2005/10/15 02:49:09 momjian Exp $ * * INTERFACE ROUTINES *		index_open		- open an index relation by relation OID *		index_openrv	- open an index relation specified by a RangeVar *		index_close		- close an index relation *		index_beginscan - start a scan of an index with amgettuple *		index_beginscan_multi - start a scan of an index with amgetmulti *		index_rescan	- restart a scan of an index *		index_endscan	- end a scan *		index_insert	- insert an index tuple into a relation *		index_markpos	- mark a scan position *		index_restrpos	- restore a scan position *		index_getnext	- get the next tuple from a scan *		index_getmulti	- get multiple tuples from a scan *		index_bulk_delete	- bulk deletion of index tuples *		index_vacuum_cleanup	- post-deletion cleanup of an index *		index_getprocid - get a support procedure OID *		index_getprocinfo - get a support procedure's lookup info * * NOTES *		This file contains the index_ routines which used *		to be a scattered collection of stuff in access/genam. * * * old comments *		Scans are implemented as follows: * *		`0' represents an invalid item pointer. *		`-' represents an unknown item pointer. *		`X' represents a known item pointers. *		`+' represents known or invalid item pointers. *		`*' represents any item pointers. * *		State is represented by a triple of these symbols in the order of *		previous, current, next.  Note that the case of reverse scans works *		identically. * *				State	Result *		(1)		+ + -	+ 0 0			(if the next item pointer is invalid) *		(2)				+ X -			(otherwise) *		(3)		* 0 0	* 0 0			(no change) *		(4)		+ X 0	X 0 0			(shift) *		(5)		* + X	+ X -			(shift, add unknown) * *		All other states cannot occur. * *		Note: It would be possible to cache the status of the previous and *			  next item pointer using the flags. * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/genam.h"#include "access/heapam.h"#include "pgstat.h"#include "utils/relcache.h"/* ---------------------------------------------------------------- *					macros used in index_ routines * ---------------------------------------------------------------- */#define RELATION_CHECKS \( \	AssertMacro(RelationIsValid(indexRelation)), \	AssertMacro(PointerIsValid(indexRelation->rd_am)) \)#define SCAN_CHECKS \( \	AssertMacro(IndexScanIsValid(scan)), \	AssertMacro(RelationIsValid(scan->indexRelation)), \	AssertMacro(PointerIsValid(scan->indexRelation->rd_am)) \)#define GET_REL_PROCEDURE(pname) \do { \	procedure = &indexRelation->rd_aminfo->pname; \	if (!OidIsValid(procedure->fn_oid)) \	{ \		RegProcedure	procOid = indexRelation->rd_am->pname; \		if (!RegProcedureIsValid(procOid)) \			elog(ERROR, "invalid %s regproc", CppAsString(pname)); \		fmgr_info_cxt(procOid, procedure, indexRelation->rd_indexcxt); \	} \} while(0)#define GET_SCAN_PROCEDURE(pname) \do { \	procedure = &scan->indexRelation->rd_aminfo->pname; \	if (!OidIsValid(procedure->fn_oid)) \	{ \		RegProcedure	procOid = scan->indexRelation->rd_am->pname; \		if (!RegProcedureIsValid(procOid)) \			elog(ERROR, "invalid %s regproc", CppAsString(pname)); \		fmgr_info_cxt(procOid, procedure, scan->indexRelation->rd_indexcxt); \	} \} while(0)static IndexScanDesc index_beginscan_internal(Relation indexRelation,						 int nkeys, ScanKey key);/* ---------------------------------------------------------------- *				   index_ interface functions * ---------------------------------------------------------------- *//* ---------------- *		index_open - open an index relation by relation OID * *		Note: we acquire no lock on the index.	A lock is not needed when *		simply examining the index reldesc; the index's schema information *		is considered to be protected by the lock that the caller had better *		be holding on the parent relation.	Some type of lock should be *		obtained on the index before physically accessing it, however. *		This is handled automatically for most uses by index_beginscan *		and index_endscan for scan cases, or by ExecOpenIndices and *		ExecCloseIndices for update cases.	Other callers will need to *		obtain their own locks. * *		This is a convenience routine adapted for indexscan use. *		Some callers may prefer to use relation_open directly. * ---------------- */Relationindex_open(Oid relationId){	Relation	r;	r = relation_open(relationId, NoLock);	if (r->rd_rel->relkind != RELKIND_INDEX)		ereport(ERROR,				(errcode(ERRCODE_WRONG_OBJECT_TYPE),				 errmsg("\"%s\" is not an index",						RelationGetRelationName(r))));	pgstat_initstats(&r->pgstat_info, r);	return r;}/* ---------------- *		index_openrv - open an index relation specified *		by a RangeVar node * *		As above, but relation is specified by a RangeVar. * ---------------- */Relationindex_openrv(const RangeVar *relation){	Relation	r;	r = relation_openrv(relation, NoLock);	if (r->rd_rel->relkind != RELKIND_INDEX)		ereport(ERROR,				(errcode(ERRCODE_WRONG_OBJECT_TYPE),				 errmsg("\"%s\" is not an index",						RelationGetRelationName(r))));	pgstat_initstats(&r->pgstat_info, r);	return r;}/* ---------------- *		index_close - close a index relation * *		presently the relcache routines do all the work we need *		to open/close index relations. * ---------------- */voidindex_close(Relation relation){	RelationClose(relation);}/* ---------------- *		index_insert - insert an index tuple into a relation * ---------------- */boolindex_insert(Relation indexRelation,			 Datum *values,			 bool *isnull,			 ItemPointer heap_t_ctid,			 Relation heapRelation,			 bool check_uniqueness){	FmgrInfo   *procedure;	RELATION_CHECKS;	GET_REL_PROCEDURE(aminsert);	/*	 * 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),									  BoolGetDatum(check_uniqueness)));}/* * index_beginscan - start a scan of an index with amgettuple * * Note: heapRelation may be NULL if there is no intention of calling * index_getnext on this scan; index_getnext_indexitem will not use the * heapRelation link (nor the snapshot).  However, the caller had better * be holding some kind of lock on the heap relation in any case, to ensure * no one deletes it (or the index) out from under us. */IndexScanDescindex_beginscan(Relation heapRelation,				Relation indexRelation,				Snapshot snapshot,				int nkeys, ScanKey key){	IndexScanDesc scan;	scan = index_beginscan_internal(indexRelation, nkeys, key);	/*	 * Save additional parameters into the scandesc.  Everything else was set	 * up by RelationGetIndexScan.	 */	scan->is_multiscan = false;	scan->heapRelation = heapRelation;	scan->xs_snapshot = snapshot;	return scan;}/* * index_beginscan_multi - start a scan of an index with amgetmulti * * As above, caller had better be holding some lock on the parent heap * relation, even though it's not explicitly mentioned here. */IndexScanDescindex_beginscan_multi(Relation indexRelation,					  Snapshot snapshot,					  int nkeys, ScanKey key){	IndexScanDesc scan;	scan = index_beginscan_internal(indexRelation, nkeys, key);	/*	 * Save additional parameters into the scandesc.  Everything else was set	 * up by RelationGetIndexScan.	 */	scan->is_multiscan = true;	scan->xs_snapshot = snapshot;	return scan;}/* * index_beginscan_internal --- common code for index_beginscan variants */static IndexScanDescindex_beginscan_internal(Relation indexRelation,						 int nkeys, ScanKey key){	IndexScanDesc scan;	FmgrInfo   *procedure;	RELATION_CHECKS;	RelationIncrementReferenceCount(indexRelation);	/*	 * Acquire AccessShareLock for the duration of the scan	 *	 * Note: we could get an SI inval message here and consequently have to	 * rebuild the relcache entry.	The refcount increment above ensures that	 * we will rebuild it and not just flush it...	 */	LockRelation(indexRelation, AccessShareLock);	/*	 * LockRelation can clean rd_aminfo structure, so fill procedure after	 * LockRelation	 */	GET_REL_PROCEDURE(ambeginscan);	/*	 * Tell the AM to open a scan.	 */	scan = (IndexScanDesc)		DatumGetPointer(FunctionCall3(procedure,									  PointerGetDatum(indexRelation),									  Int32GetDatum(nkeys),									  PointerGetDatum(key)));	return scan;}/* ---------------- *		index_rescan  - (re)start a scan of an index * * The caller may specify a new set of scankeys (but the number of keys * cannot change).	To restart the scan without changing keys, pass NULL * for the key array. * * Note that this is also called when first starting an indexscan; * see RelationGetIndexScan.  Keys *must* be passed in that case, * unless scan->numberOfKeys is zero. * ---------------- */voidindex_rescan(IndexScanDesc scan, ScanKey key){	FmgrInfo   *procedure;	SCAN_CHECKS;	GET_SCAN_PROCEDURE(amrescan);	/* Release any held pin on a heap page */	if (BufferIsValid(scan->xs_cbuf))	{		ReleaseBuffer(scan->xs_cbuf);		scan->xs_cbuf = InvalidBuffer;	}	scan->kill_prior_tuple = false;		/* for safety */	scan->keys_are_unique = false;		/* may be set by index AM */	scan->got_tuple = false;	scan->unique_tuple_pos = 0;	scan->unique_tuple_mark = 0;	FunctionCall2(procedure,				  PointerGetDatum(scan),				  PointerGetDatum(key));}/* ---------------- *		index_endscan - end a scan * ---------------- */voidindex_endscan(IndexScanDesc scan){	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 lock and refcount acquired by index_beginscan */	UnlockRelation(scan->indexRelation, AccessShareLock);	RelationDecrementReferenceCount(scan->indexRelation);	/* Release the scan data structure itself */	IndexScanEnd(scan);}/* ---------------- *		index_markpos  - mark a scan position * ---------------- */voidindex_markpos(IndexScanDesc scan){	FmgrInfo   *procedure;	SCAN_CHECKS;	GET_SCAN_PROCEDURE(ammarkpos);	scan->unique_tuple_mark = scan->unique_tuple_pos;	FunctionCall1(procedure, PointerGetDatum(scan));}/* ---------------- *		index_restrpos	- restore a scan position *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -