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

📄 indexam.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * indexam.c *	  general index access method routines * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.71 2003/09/25 06:57:57 petere Exp $ * * INTERFACE ROUTINES *		index_open		- open an index relation by relation OID *		index_openrv	- open an index relation specified by a RangeVar *		index_openr		- open a system index relation by name *		index_close		- close an index relation *		index_beginscan - start a scan of an index *		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_bulk_delete	- bulk deletion of index tuples *		index_vacuum_cleanup	- post-deletion cleanup of an index *		index_cost_estimator	- fetch amcostestimate procedure OID *		index_getprocid - get a support procedure OID * * 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 "utils/relcache.h"#include "pgstat.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(x,y) \( \	procedure = indexRelation->rd_am->y, \	(!RegProcedureIsValid(procedure)) ? \		elog(ERROR, "index_%s: invalid %s regproc", \			 CppAsString(x), CppAsString(y)) \	: (void)NULL \)#define GET_SCAN_PROCEDURE(x,y) \( \	procedure = scan->indexRelation->rd_am->y, \	(!RegProcedureIsValid(procedure)) ? \		elog(ERROR, "index_%s: invalid %s regproc", \			 CppAsString(x), CppAsString(y)) \	: (void)NULL \)/* ---------------------------------------------------------------- *				   index_ interface functions * ---------------------------------------------------------------- *//* ---------------- *		index_open - open an index relation by relation OID * *		Note: we acquire no lock on the index.	An AccessShareLock is *		acquired by index_beginscan (and released by index_endscan). *		Generally, the caller should already hold some type of lock on *		the parent relation to ensure that the index doesn't disappear. * *		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_openr - open a system index relation specified by name. * *		As above, but the relation is specified by an unqualified name; *		it is assumed to live in the system catalog namespace. * ---------------- */Relationindex_openr(const char *sysRelationName){	Relation	r;	r = relation_openr(sysRelationName, 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 * ---------------- */InsertIndexResultindex_insert(Relation indexRelation,			 Datum *datums,			 char *nulls,			 ItemPointer heap_t_ctid,			 Relation heapRelation,			 bool check_uniqueness){	RegProcedure procedure;	InsertIndexResult specificResult;	RELATION_CHECKS;	GET_REL_PROCEDURE(insert, aminsert);	/*	 * have the am's insert proc do all the work.	 */	specificResult = (InsertIndexResult)		DatumGetPointer(OidFunctionCall6(procedure,										 PointerGetDatum(indexRelation),										 PointerGetDatum(datums),										 PointerGetDatum(nulls),										 PointerGetDatum(heap_t_ctid),										 PointerGetDatum(heapRelation),										 BoolGetDatum(check_uniqueness)));	/* must be pfree'ed */	return specificResult;}/* ---------------- *		index_beginscan - start a scan of an index * * 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;	RegProcedure procedure;	RELATION_CHECKS;	GET_REL_PROCEDURE(beginscan, ambeginscan);	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);	/*	 * Tell the AM to open a scan.	 */	scan = (IndexScanDesc)		DatumGetPointer(OidFunctionCall3(procedure,										 PointerGetDatum(indexRelation),										 Int32GetDatum(nkeys),										 PointerGetDatum(key)));	/*	 * Save additional parameters into the scandesc.  Everything else was	 * set up by RelationGetIndexScan.	 */	scan->heapRelation = heapRelation;	scan->xs_snapshot = snapshot;	/*	 * We want to look up the amgettuple procedure just once per scan, not	 * once per index_getnext call.  So do it here and save the fmgr info	 * result in the scan descriptor.	 */	GET_SCAN_PROCEDURE(beginscan, amgettuple);	fmgr_info(procedure, &scan->fn_getnext);	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){	RegProcedure procedure;	SCAN_CHECKS;	GET_SCAN_PROCEDURE(rescan, amrescan);	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;	OidFunctionCall2(procedure,					 PointerGetDatum(scan),					 PointerGetDatum(key));	pgstat_reset_index_scan(&scan->xs_pgstat_info);}/* ---------------- *		index_endscan - end a scan * ---------------- */voidindex_endscan(IndexScanDesc scan){	RegProcedure procedure;	SCAN_CHECKS;	GET_SCAN_PROCEDURE(endscan, 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 */	OidFunctionCall1(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){	RegProcedure procedure;	SCAN_CHECKS;	GET_SCAN_PROCEDURE(markpos, ammarkpos);	scan->unique_tuple_mark = scan->unique_tuple_pos;	OidFunctionCall1(procedure, PointerGetDatum(scan));}/* ---------------- *		index_restrpos	- restore a scan position * ---------------- */voidindex_restrpos(IndexScanDesc scan)

⌨️ 快捷键说明

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