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

📄 nbtutils.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * "break" statement below.	 */	for (i = 0;; cur++, i++)	{		if (i < numberOfKeys)		{			/* See comments above: any NULL implies cannot match qual */			if (cur->sk_flags & SK_ISNULL)			{				so->qual_ok = false;				/*				 * Quit processing so we don't try to invoke comparison				 * routines on NULLs.				 */				return;			}		}		/*		 * If we are at the end of the keys for a particular attr, finish up		 * processing and emit the cleaned-up keys.		 */		if (i == numberOfKeys || cur->sk_attno != attno)		{			int			priorNumberOfEqualCols = numberOfEqualCols;			/* check input keys are correctly ordered */			if (i < numberOfKeys && cur->sk_attno < attno)				elog(ERROR, "btree index keys must be ordered by attribute");			/*			 * If = has been specified, no other key will be used. In case of			 * key > 2 && key == 1 and so on we have to set qual_ok to false			 * before discarding the other keys.			 */			if (xform[BTEqualStrategyNumber - 1])			{				ScanKey		eq = xform[BTEqualStrategyNumber - 1];				for (j = BTMaxStrategyNumber; --j >= 0;)				{					ScanKey		chk = xform[j];					if (!chk || j == (BTEqualStrategyNumber - 1))						continue;					test = FunctionCall2(&chk->sk_func,										 eq->sk_argument,										 chk->sk_argument);					if (!DatumGetBool(test))					{						so->qual_ok = false;						break;					}				}				xform[BTLessStrategyNumber - 1] = NULL;				xform[BTLessEqualStrategyNumber - 1] = NULL;				xform[BTGreaterEqualStrategyNumber - 1] = NULL;				xform[BTGreaterStrategyNumber - 1] = NULL;				/* track number of attrs for which we have "=" keys */				numberOfEqualCols++;			}			else			{				/* track number of attrs for which we have "=" keys */				if (hasOtherTypeEqual)					numberOfEqualCols++;			}			/* keep only one of <, <= */			if (xform[BTLessStrategyNumber - 1]				&& xform[BTLessEqualStrategyNumber - 1])			{				ScanKey		lt = xform[BTLessStrategyNumber - 1];				ScanKey		le = xform[BTLessEqualStrategyNumber - 1];				test = FunctionCall2(&le->sk_func,									 lt->sk_argument,									 le->sk_argument);				if (DatumGetBool(test))					xform[BTLessEqualStrategyNumber - 1] = NULL;				else					xform[BTLessStrategyNumber - 1] = NULL;			}			/* keep only one of >, >= */			if (xform[BTGreaterStrategyNumber - 1]				&& xform[BTGreaterEqualStrategyNumber - 1])			{				ScanKey		gt = xform[BTGreaterStrategyNumber - 1];				ScanKey		ge = xform[BTGreaterEqualStrategyNumber - 1];				test = FunctionCall2(&ge->sk_func,									 gt->sk_argument,									 ge->sk_argument);				if (DatumGetBool(test))					xform[BTGreaterEqualStrategyNumber - 1] = NULL;				else					xform[BTGreaterStrategyNumber - 1] = NULL;			}			/*			 * Emit the cleaned-up keys into the outkeys[] array.			 */			for (j = BTMaxStrategyNumber; --j >= 0;)			{				if (xform[j])					memcpy(&outkeys[new_numberOfKeys++], xform[j],						   sizeof(ScanKeyData));			}			/*			 * If all attrs before this one had "=", include these keys into			 * the required-keys count.			 */			if (priorNumberOfEqualCols == attno - 1)				so->numberOfRequiredKeys = new_numberOfKeys;			/*			 * Exit loop here if done.			 */			if (i == numberOfKeys)				break;			/* Re-initialize for new attno */			attno = cur->sk_attno;			memset(xform, 0, sizeof(xform));			hasOtherTypeEqual = false;		}		/* check strategy this key's operator corresponds to */		j = cur->sk_strategy - 1;		/* if wrong RHS data type, punt */		if (cur->sk_subtype != InvalidOid)		{			memcpy(&outkeys[new_numberOfKeys++], cur,				   sizeof(ScanKeyData));			if (j == (BTEqualStrategyNumber - 1))				hasOtherTypeEqual = true;			continue;		}		/* have we seen one of these before? */		if (xform[j])		{			/* yup, keep the more restrictive key */			test = FunctionCall2(&cur->sk_func,								 cur->sk_argument,								 xform[j]->sk_argument);			if (DatumGetBool(test))				xform[j] = cur;			else if (j == (BTEqualStrategyNumber - 1))			{				/* key == a && key == b, but a != b */				so->qual_ok = false;				return;			}		}		else		{			/* nope, so remember this scankey */			xform[j] = cur;		}	}	so->numberOfKeys = new_numberOfKeys;	/*	 * If unique index and we have equality keys for all columns, set	 * keys_are_unique flag for higher levels.	 */	if (relation->rd_index->indisunique &&		relation->rd_rel->relnatts == numberOfEqualCols)		scan->keys_are_unique = true;}/* * Test whether an indextuple satisfies all the scankey conditions. * * If the tuple fails to pass the qual, we also determine whether there's * any need to continue the scan beyond this tuple, and set *continuescan * accordingly.  See comments for _bt_preprocess_keys(), above, about how * this is done. */bool_bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,			  ScanDirection dir, bool *continuescan){	BTScanOpaque so = (BTScanOpaque) scan->opaque;	int			keysz = so->numberOfKeys;	int			ikey;	TupleDesc	tupdesc;	ScanKey		key;	*continuescan = true;	/* If no keys, always scan the whole index */	if (keysz == 0)		return true;	IncrIndexProcessed();	tupdesc = RelationGetDescr(scan->indexRelation);	for (key = so->keyData, ikey = 0; ikey < keysz; key++, ikey++)	{		Datum		datum;		bool		isNull;		Datum		test;		datum = index_getattr(tuple,							  key->sk_attno,							  tupdesc,							  &isNull);		/* btree doesn't support 'A is null' clauses, yet */		if (key->sk_flags & SK_ISNULL)		{			/* we shouldn't get here, really; see _bt_preprocess_keys() */			*continuescan = false;			return false;		}		if (isNull)		{			/*			 * Since NULLs are sorted after non-NULLs, we know we have reached			 * the upper limit of the range of values for this index attr.	On			 * a forward scan, we can stop if this qual is one of the "must			 * match" subset.  On a backward scan, however, we should keep			 * going.			 */			if (ikey < so->numberOfRequiredKeys &&				ScanDirectionIsForward(dir))				*continuescan = false;			/*			 * In any case, this indextuple doesn't match the qual.			 */			return false;		}		test = FunctionCall2(&key->sk_func, datum, key->sk_argument);		if (!DatumGetBool(test))		{			/*			 * Tuple fails this qual.  If it's a required qual, then we may be			 * able to conclude no further tuples will pass, either. We have			 * to look at the scan direction and the qual type.			 *			 * Note: the only case in which we would keep going after failing			 * a required qual is if there are partially-redundant quals that			 * _bt_preprocess_keys() was unable to eliminate.  For example,			 * given "x > 4 AND x > 10" where both are cross-type comparisons			 * and so not removable, we might start the scan at the x = 4			 * boundary point.	The "x > 10" condition will fail until we pass			 * x = 10, but we must not stop the scan on its account.			 *			 * Note: because we stop the scan as soon as any required equality			 * qual fails, it is critical that equality quals be used for the			 * initial positioning in _bt_first() when they are available. See			 * comments in _bt_first().			 */			if (ikey < so->numberOfRequiredKeys)			{				switch (key->sk_strategy)				{					case BTLessStrategyNumber:					case BTLessEqualStrategyNumber:						if (ScanDirectionIsForward(dir))							*continuescan = false;						break;					case BTEqualStrategyNumber:						*continuescan = false;						break;					case BTGreaterEqualStrategyNumber:					case BTGreaterStrategyNumber:						if (ScanDirectionIsBackward(dir))							*continuescan = false;						break;					default:						elog(ERROR, "unrecognized StrategyNumber: %d",							 key->sk_strategy);				}			}			/*			 * In any case, this indextuple doesn't match the qual.			 */			return false;		}	}	/* If we get here, the tuple passes all quals. */	return true;}

⌨️ 快捷键说明

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