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

📄 nbtree.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * btree.c *	  Implementation of Lehman and Yao's btree management algorithm for *	  Postgres. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.41.2.1 1999/08/02 05:24:41 scrappy Exp $ * * NOTES *	  This file contains only the public interface routines. * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/genam.h"#include "access/heapam.h"#include "access/nbtree.h"#include "catalog/index.h"#include "executor/executor.h"#include "miscadmin.h"#ifdef BTREE_BUILD_STATS#define ShowExecutorStats pg_options[TRACE_EXECUTORSTATS]#endifbool		BuildingBtree = false;		/* see comment in btbuild() */bool		FastBuild = true;	/* use sort/build instead of insertion								 * build */static void _bt_restscan(IndexScanDesc scan);/* *	btbuild() -- build a new btree index. * *		We use a global variable to record the fact that we're creating *		a new index.  This is used to avoid high-concurrency locking, *		since the index won't be visible until this transaction commits *		and since building is guaranteed to be single-threaded. */voidbtbuild(Relation heap,		Relation index,		int natts,		AttrNumber *attnum,		IndexStrategy istrat,		uint16 pcount,		Datum *params,		FuncIndexInfo *finfo,		PredInfo *predInfo){	HeapScanDesc hscan;	HeapTuple	htup;	IndexTuple	itup;	TupleDesc	htupdesc,				itupdesc;	Datum	   *attdata;	bool	   *nulls;	InsertIndexResult res = 0;	int			nhtups,				nitups;	int			i;	BTItem		btitem;#ifndef OMIT_PARTIAL_INDEX	ExprContext *econtext = (ExprContext *) NULL;	TupleTable	tupleTable = (TupleTable) NULL;	TupleTableSlot *slot = (TupleTableSlot *) NULL;#endif	Oid			hrelid,				irelid;	Node	   *pred,			   *oldPred;	void	   *spool = (void *) NULL;	bool		isunique;	bool		usefast;	/* note that this is a new btree */	BuildingBtree = true;	pred = predInfo->pred;	oldPred = predInfo->oldPred;	/*	 * bootstrap processing does something strange, so don't use	 * sort/build for initial catalog indices.	at some point i need to	 * look harder at this.  (there is some kind of incremental processing	 * going on there.) -- pma 08/29/95	 */	usefast = (FastBuild && IsNormalProcessingMode());#ifdef BTREE_BUILD_STATS	if (ShowExecutorStats)		ResetUsage();#endif	/* see if index is unique */	isunique = IndexIsUniqueNoCache(RelationGetRelid(index));	/* initialize the btree index metadata page (if this is a new index) */	if (oldPred == NULL)		_bt_metapinit(index);	/* get tuple descriptors for heap and index relations */	htupdesc = RelationGetDescr(heap);	itupdesc = RelationGetDescr(index);	/* get space for data items that'll appear in the index tuple */	attdata = (Datum *) palloc(natts * sizeof(Datum));	nulls = (bool *) palloc(natts * sizeof(bool));	/*	 * If this is a predicate (partial) index, we will need to evaluate	 * the predicate using ExecQual, which requires the current tuple to	 * be in a slot of a TupleTable.  In addition, ExecQual must have an	 * ExprContext referring to that slot.	Here, we initialize dummy	 * TupleTable and ExprContext objects for this purpose. --Nels, Feb	 * '92	 */#ifndef OMIT_PARTIAL_INDEX	if (pred != NULL || oldPred != NULL)	{		tupleTable = ExecCreateTupleTable(1);		slot = ExecAllocTableSlot(tupleTable);		econtext = makeNode(ExprContext);		FillDummyExprContext(econtext, slot, htupdesc, InvalidBuffer);		/*		 * we never want to use sort/build if we are extending an existing		 * partial index -- it works by inserting the newly-qualifying		 * tuples into the existing index. (sort/build would overwrite the		 * existing index with one consisting of the newly-qualifying		 * tuples.)		 */		usefast = false;	}#endif	 /* OMIT_PARTIAL_INDEX */	/* start a heap scan */	/* build the index */	nhtups = nitups = 0;	if (usefast)	{		spool = _bt_spoolinit(index, 7, isunique);		res = (InsertIndexResult) NULL;	}	hscan = heap_beginscan(heap, 0, SnapshotNow, 0, (ScanKey) NULL);	while (HeapTupleIsValid(htup = heap_getnext(hscan, 0)))	{		nhtups++;		/*		 * If oldPred != NULL, this is an EXTEND INDEX command, so skip		 * this tuple if it was already in the existing partial index		 */		if (oldPred != NULL)		{#ifndef OMIT_PARTIAL_INDEX			/* SetSlotContents(slot, htup); */			slot->val = htup;			if (ExecQual((List *) oldPred, econtext) == true)			{				nitups++;				continue;			}#endif	 /* OMIT_PARTIAL_INDEX */		}		/*		 * Skip this tuple if it doesn't satisfy the partial-index		 * predicate		 */		if (pred != NULL)		{#ifndef OMIT_PARTIAL_INDEX			/* SetSlotContents(slot, htup); */			slot->val = htup;			if (ExecQual((List *) pred, econtext) == false)				continue;#endif	 /* OMIT_PARTIAL_INDEX */		}		nitups++;		/*		 * For the current heap tuple, extract all the attributes we use		 * in this index, and note which are null.		 */		for (i = 1; i <= natts; i++)		{			int			attoff;			bool		attnull;			/*			 * Offsets are from the start of the tuple, and are			 * zero-based; indices are one-based.  The next call returns i			 * - 1.  That's data hiding for you.			 */			attoff = AttrNumberGetAttrOffset(i);			attdata[attoff] = GetIndexValue(htup,											htupdesc,											attoff,											attnum,											finfo,											&attnull);			nulls[attoff] = (attnull ? 'n' : ' ');		}		/* form an index tuple and point it at the heap tuple */		itup = index_formtuple(itupdesc, attdata, nulls);		/*		 * If the single index key is null, we don't insert it into the		 * index.  Btrees support scans on <, <=, =, >=, and >. Relational		 * algebra says that A op B (where op is one of the operators		 * above) returns null if either A or B is null.  This means that		 * no qualification used in an index scan could ever return true		 * on a null attribute.  It also means that indices can't be used		 * by ISNULL or NOTNULL scans, but that's an artifact of the		 * strategy map architecture chosen in 1986, not of the way nulls		 * are handled here.		 */		/*		 * New comments: NULLs handling. While we can't do NULL		 * comparison, we can follow simple rule for ordering items on		 * btree pages - NULLs greater NOT_NULLs and NULL = NULL is TRUE.		 * Sure, it's just rule for placing/finding items and no more -		 * keytest'll return FALSE for a = 5 for items having 'a' isNULL.		 * Look at _bt_skeycmp, _bt_compare and _bt_itemcmp for how it		 * works.				 - vadim 03/23/97		 *		 * if (itup->t_info & INDEX_NULL_MASK) { pfree(itup); continue; }		 */		itup->t_tid = htup->t_self;		btitem = _bt_formitem(itup);		/*		 * if we are doing bottom-up btree build, we insert the index into		 * a spool page for subsequent processing.	otherwise, we insert		 * into the btree.		 */		if (usefast)			_bt_spool(index, btitem, spool);		else			res = _bt_doinsert(index, btitem, isunique, heap);		pfree(btitem);		pfree(itup);		if (res)			pfree(res);	}	/* okay, all heap tuples are indexed */	heap_endscan(hscan);	if (pred != NULL || oldPred != NULL)	{#ifndef OMIT_PARTIAL_INDEX		ExecDestroyTupleTable(tupleTable, true);		pfree(econtext);#endif	 /* OMIT_PARTIAL_INDEX */	}	/*	 * if we are doing bottom-up btree build, we now have a bunch of	 * sorted runs in the spool pages.	finish the build by (1) merging	 * the runs, (2) inserting the sorted tuples into btree pages and (3)	 * building the upper levels.	 */	if (usefast)	{		_bt_spool(index, (BTItem) NULL, spool); /* flush the spool */		_bt_leafbuild(index, spool);		_bt_spooldestroy(spool);	}#ifdef BTREE_BUILD_STATS	if (ShowExecutorStats)	{		fprintf(stderr, "! BtreeBuild Stats:\n");		ShowUsage();		ResetUsage();	}#endif	/*	 * Since we just counted the tuples in the heap, we update its stats	 * in pg_class to guarantee that the planner takes advantage of the	 * index we just created. Finally, only update statistics during	 * normal index definitions, not for indices on system catalogs	 * created during bootstrap processing.  We must close the relations	 * before updatings statistics to guarantee that the relcache entries	 * are flushed when we increment the command counter in UpdateStats().	 */	if (IsNormalProcessingMode())	{		hrelid = RelationGetRelid(heap);		irelid = RelationGetRelid(index);		heap_close(heap);		index_close(index);		UpdateStats(hrelid, nhtups, true);		UpdateStats(irelid, nitups, false);		if (oldPred != NULL)		{			if (nitups == nhtups)				pred = NULL;			UpdateIndexPredicate(irelid, oldPred, pred);		}	}	pfree(nulls);	pfree(attdata);	/* all done */	BuildingBtree = false;}/* *	btinsert() -- insert an index tuple into a btree. * *		Descend the tree recursively, find the appropriate location for our *		new tuple, put it there, set its unique OID as appropriate, and *		return an InsertIndexResult to the caller. */InsertIndexResultbtinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation heapRel){	BTItem		btitem;	IndexTuple	itup;	InsertIndexResult res;	/* generate an index tuple */	itup = index_formtuple(RelationGetDescr(rel), datum, nulls);

⌨️ 快捷键说明

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