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

📄 nbtutils.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * btutils.c *	  Utility code for Postgres btree implementation. * * 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/nbtree/nbtutils.c,v 1.54 2003/08/04 02:39:57 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/genam.h"#include "access/istrat.h"#include "access/nbtree.h"#include "catalog/catalog.h"#include "executor/execdebug.h"static int	_bt_getstrategynumber(RegProcedure sk_procedure, StrategyMap map);/* * _bt_mkscankey *		Build a scan key that contains comparison data from itup *		as well as comparator routines appropriate to the key datatypes. * *		The result is intended for use with _bt_compare(). */ScanKey_bt_mkscankey(Relation rel, IndexTuple itup){	ScanKey		skey;	TupleDesc	itupdesc;	int			natts;	int			i;	FmgrInfo   *procinfo;	Datum		arg;	bool		null;	bits16		flag;	itupdesc = RelationGetDescr(rel);	natts = RelationGetNumberOfAttributes(rel);	skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));	for (i = 0; i < natts; i++)	{		procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);		arg = index_getattr(itup, i + 1, itupdesc, &null);		flag = null ? SK_ISNULL : 0x0;		ScanKeyEntryInitializeWithInfo(&skey[i],									   flag,									   (AttrNumber) (i + 1),									   procinfo,									   CurrentMemoryContext,									   arg);	}	return skey;}/* * _bt_mkscankey_nodata *		Build a scan key that contains comparator routines appropriate to *		the key datatypes, but no comparison data. * *		The result cannot be used with _bt_compare().  Currently this *		routine is only called by utils/sort/tuplesort.c, which has its *		own comparison routine. */ScanKey_bt_mkscankey_nodata(Relation rel){	ScanKey		skey;	int			natts;	int			i;	FmgrInfo   *procinfo;	natts = RelationGetNumberOfAttributes(rel);	skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));	for (i = 0; i < natts; i++)	{		procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);		ScanKeyEntryInitializeWithInfo(&skey[i],									   SK_ISNULL,									   (AttrNumber) (i + 1),									   procinfo,									   CurrentMemoryContext,									   (Datum) 0);	}	return skey;}/* * free a scan key made by either _bt_mkscankey or _bt_mkscankey_nodata. */void_bt_freeskey(ScanKey skey){	pfree(skey);}/* * free a retracement stack made by _bt_search. */void_bt_freestack(BTStack stack){	BTStack		ostack;	while (stack != (BTStack) NULL)	{		ostack = stack;		stack = stack->bts_parent;		pfree(ostack);	}}/* * Construct a BTItem from a plain IndexTuple. * * This is now useless code, since a BTItem *is* an index tuple with * no extra stuff.	We hang onto it for the moment to preserve the * notational distinction, in case we want to add some extra stuff * again someday. */BTItem_bt_formitem(IndexTuple itup){	int			nbytes_btitem;	BTItem		btitem;	Size		tuplen;	/* make a copy of the index tuple with room for extra stuff */	tuplen = IndexTupleSize(itup);	nbytes_btitem = tuplen + (sizeof(BTItemData) - sizeof(IndexTupleData));	btitem = (BTItem) palloc(nbytes_btitem);	memcpy((char *) &(btitem->bti_itup), (char *) itup, tuplen);	return btitem;}/*---------- *	_bt_orderkeys() -- Put keys in a sensible order for conjunctive quals. * * After this routine runs, the scan keys are ordered by index attribute * (all quals for attr 1, then all for attr 2, etc) and within each attr * the keys are ordered by constraint type: ">", ">=", "=", "<=", "<". * Furthermore, redundant keys are eliminated: we keep only the tightest * >/>= bound and the tightest </<= bound, and if there's an = key then * that's the only one returned.  (So, we return either a single = key, * or one or two boundary-condition keys for each attr.) * * As a byproduct of this work, we can detect contradictory quals such * as "x = 1 AND x > 2".  If we see that, we return so->quals_ok = FALSE, * indicating the scan need not be run at all since no tuples can match. * * Another byproduct is to determine how many quals must be satisfied to * continue the scan.  _bt_checkkeys uses this.  For example, if the quals * are "x = 1 AND y < 4 AND z < 5", then _bt_checkkeys will reject a tuple * (1,2,7), but we must continue the scan in case there are tuples (1,3,z). * But once we reach tuples like (1,4,z) we can stop scanning because no * later tuples could match.  This is reflected by setting * so->numberOfRequiredKeys to the number of leading keys that must be * matched to continue the scan.  numberOfRequiredKeys is equal to the * number of leading "=" keys plus the key(s) for the first non "=" * attribute, which can be seen to be correct by considering the above * example. * * Furthermore, we detect the case where the index is unique and we have * equality quals for all columns.	In this case there can be at most one * (visible) matching tuple.  index_getnext uses this to avoid uselessly * continuing the scan after finding one match. * * The initial ordering of the keys is expected to be by attribute already * (see group_clauses_by_indexkey() in indxpath.c).  The task here is to * standardize the appearance of multiple keys for the same attribute. * * XXX this routine is one of many places that fail to handle SK_COMMUTE * scankeys properly.  Currently, the planner is careful never to generate * any indexquals that would require SK_COMMUTE to be set.	Someday we ought * to try to fix this, though it's not real critical as long as indexable * operators all have commutators... * * Note: this routine invokes comparison operators via OidFunctionCallN, * ie, without caching function lookups.  No point in trying to be smarter, * since these comparisons are executed only when the user expresses a * hokey qualification, and happen only once per scan anyway. *---------- */void_bt_orderkeys(IndexScanDesc scan){	Relation	relation = scan->indexRelation;	BTScanOpaque so = (BTScanOpaque) scan->opaque;	ScanKeyData xform[BTMaxStrategyNumber];	bool		init[BTMaxStrategyNumber];	int			numberOfKeys = so->numberOfKeys;	ScanKey		key;	ScanKey		cur;	StrategyMap map;	Datum		test;	int			i,				j;	AttrNumber	attno;	int			new_numberOfKeys;	bool		allEqualSoFar;	so->qual_ok = true;	so->numberOfRequiredKeys = 0;	scan->keys_are_unique = false;	if (numberOfKeys < 1)		return;					/* done if qual-less scan */	key = so->keyData;	cur = &key[0];	/* check input keys are correctly ordered */	if (cur->sk_attno != 1)		elog(ERROR, "key(s) for attribute 1 missed");	/* We can short-circuit most of the work if there's just one key */	if (numberOfKeys == 1)	{		/*		 * We don't use indices for 'A is null' and 'A is not null'		 * currently and 'A < = > <> NULL' will always fail - so qual is		 * not Ok if comparison value is NULL.		- vadim 03/21/97		 */		if (cur->sk_flags & SK_ISNULL)			so->qual_ok = false;		else if (relation->rd_index->indisunique &&				 relation->rd_rel->relnatts == 1)		{			/* it's a unique index, do we have an equality qual? */			map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),											  BTMaxStrategyNumber,											  1);			j = _bt_getstrategynumber(cur->sk_procedure, map);			if (j == (BTEqualStrategyNumber - 1))				scan->keys_are_unique = true;		}		so->numberOfRequiredKeys = 1;		return;	}	/*	 * Otherwise, do the full set of pushups.	 */	new_numberOfKeys = 0;	allEqualSoFar = true;	/*	 * Initialize for processing of keys for attr 1.	 *	 * xform[i] holds a copy of the current scan key of strategy type i+1, if	 * any; init[i] is TRUE if we have found such a key for this attr.	 */	attno = 1;	map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),									  BTMaxStrategyNumber,									  attno);	MemSet(xform, 0, sizeof(xform));	/* not really necessary */	MemSet(init, 0, sizeof(init));	/*	 * Loop iterates from 0 to numberOfKeys inclusive; we use the last	 * pass to handle after-last-key processing.  Actual exit from the	 * loop is at the "break" statement below.	 */	for (i = 0;; cur++, i++)

⌨️ 快捷键说明

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