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

📄 nbtutils.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		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)		{			bool		priorAllEqualSoFar = allEqualSoFar;			/* check input keys are correctly ordered */			if (i < numberOfKeys && cur->sk_attno != attno + 1)				elog(ERROR, "key(s) for attribute %d missed", attno + 1);			/*			 * 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 (init[BTEqualStrategyNumber - 1])			{				ScanKeyData *eq,						   *chk;				eq = &xform[BTEqualStrategyNumber - 1];				for (j = BTMaxStrategyNumber; --j >= 0;)				{					if (!init[j] ||						j == (BTEqualStrategyNumber - 1))						continue;					chk = &xform[j];					test = OidFunctionCall2(chk->sk_procedure,											eq->sk_argument,											chk->sk_argument);					if (!DatumGetBool(test))						so->qual_ok = false;				}				init[BTLessStrategyNumber - 1] = false;				init[BTLessEqualStrategyNumber - 1] = false;				init[BTGreaterEqualStrategyNumber - 1] = false;				init[BTGreaterStrategyNumber - 1] = false;			}			else			{				/*				 * No "=" for this key, so we're done with required keys				 */				allEqualSoFar = false;			}			/* keep only one of <, <= */			if (init[BTLessStrategyNumber - 1]				&& init[BTLessEqualStrategyNumber - 1])			{				ScanKeyData *lt = &xform[BTLessStrategyNumber - 1];				ScanKeyData *le = &xform[BTLessEqualStrategyNumber - 1];				test = OidFunctionCall2(le->sk_procedure,										lt->sk_argument,										le->sk_argument);				if (DatumGetBool(test))					init[BTLessEqualStrategyNumber - 1] = false;				else					init[BTLessStrategyNumber - 1] = false;			}			/* keep only one of >, >= */			if (init[BTGreaterStrategyNumber - 1]				&& init[BTGreaterEqualStrategyNumber - 1])			{				ScanKeyData *gt = &xform[BTGreaterStrategyNumber - 1];				ScanKeyData *ge = &xform[BTGreaterEqualStrategyNumber - 1];				test = OidFunctionCall2(ge->sk_procedure,										gt->sk_argument,										ge->sk_argument);				if (DatumGetBool(test))					init[BTGreaterEqualStrategyNumber - 1] = false;				else					init[BTGreaterStrategyNumber - 1] = false;			}			/*			 * Emit the cleaned-up keys back into the key[] array in the			 * correct order.  Note we are overwriting our input here!			 * It's OK because (a) xform[] is a physical copy of the keys			 * we want, (b) we cannot emit more keys than we input, so we			 * won't overwrite as-yet-unprocessed keys.			 */			for (j = BTMaxStrategyNumber; --j >= 0;)			{				if (init[j])					memcpy(&key[new_numberOfKeys++], &xform[j],						   sizeof(ScanKeyData));			}			/*			 * If all attrs before this one had "=", include these keys			 * into the required-keys count.			 */			if (priorAllEqualSoFar)				so->numberOfRequiredKeys = new_numberOfKeys;			/*			 * Exit loop here if done.			 */			if (i == numberOfKeys)				break;			/* Re-initialize for new attno */			attno = cur->sk_attno;			map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),											  BTMaxStrategyNumber,											  attno);			MemSet(xform, 0, sizeof(xform));	/* not really necessary */			MemSet(init, 0, sizeof(init));		}		/* figure out which strategy this key's operator corresponds to */		j = _bt_getstrategynumber(cur->sk_procedure, map);		/* have we seen one of these before? */		if (init[j])		{			/* yup, keep the more restrictive value */			test = FunctionCall2(&cur->sk_func,								 cur->sk_argument,								 xform[j].sk_argument);			if (DatumGetBool(test))				xform[j].sk_argument = cur->sk_argument;			else if (j == (BTEqualStrategyNumber - 1))				so->qual_ok = false;			/* key == a && key == b, but a != b */		}		else		{			/* nope, so remember this scankey */			memcpy(&xform[j], cur, sizeof(ScanKeyData));			init[j] = true;		}	}	so->numberOfKeys = new_numberOfKeys;	/*	 * If unique index and we have equality keys for all columns, set	 * keys_are_unique flag for higher levels.	 */	if (allEqualSoFar && relation->rd_index->indisunique &&		relation->rd_rel->relnatts == new_numberOfKeys)		scan->keys_are_unique = true;}/* * Determine which btree strategy an operator procedure matches. * * Result is strategy number minus 1. */static int_bt_getstrategynumber(RegProcedure sk_procedure, StrategyMap map){	int			j;	for (j = BTMaxStrategyNumber; --j >= 0;)	{		if (sk_procedure == map->entry[j].sk_procedure)			return j;	}	elog(ERROR, "could not identify operator %u", sk_procedure);	return -1;					/* keep compiler quiet */}/* * 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_orderkeys(), 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			keysok;	TupleDesc	tupdesc;	ScanKey		key;	*continuescan = true;	/* If no keys, always scan the whole index */	if (keysz == 0)		return true;	tupdesc = RelationGetDescr(scan->indexRelation);	key = so->keyData;	keysok = 0;	IncrIndexProcessed();	while (keysz > 0)	{		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_orderkeys() */			*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 (keysok < so->numberOfRequiredKeys &&				ScanDirectionIsForward(dir))				*continuescan = false;			/*			 * In any case, this indextuple doesn't match the qual.			 */			return false;		}		if (key->sk_flags & SK_COMMUTE)			test = FunctionCall2(&key->sk_func,								 key->sk_argument, datum);		else			test = FunctionCall2(&key->sk_func,								 datum, key->sk_argument);		if (DatumGetBool(test) == !!(key->sk_flags & SK_NEGATE))		{			/*			 * Tuple fails this qual.  If it's a required qual, then we			 * can conclude no further tuples will pass, either.			 */			if (keysok < so->numberOfRequiredKeys)				*continuescan = false;			return false;		}		keysok++;		key++;		keysz--;	}	/* If we get here, the tuple passes all quals. */	return true;}

⌨️ 快捷键说明

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