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

📄 compare.c

📁 uClinux下用的数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Copyright (c) 1995-2001  Hughes Technologies Pty Ltd.  All rights** reserved.  **** Terms under which this software may be used or copied are** provided in the  specific license associated with this product.**** Hughes Technologies disclaims all warranties with regard to this ** software, including all implied warranties of merchantability and ** fitness, in no event shall Hughes Technologies be liable for any ** special, indirect or consequential damages or any damages whatsoever ** resulting from loss of use, data or profits, whether in an action of ** contract, negligence or other tortious action, arising out of or in ** connection with the use or performance of this software.****** $Id: compare.c,v 1.20 2002/12/13 04:03:35 bambi Exp $***//*** Module	: main : compare** Purpose	: ** Exports	: ** Depends Upon	: */#define HAVE_STRCOLL/**************************************************************************** STANDARD INCLUDES**************************************************************************/#include <common/config.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#ifdef HAVE_UNISTD_H#  include <unistd.h>#endif#ifdef HAVE_STRING_H#  include <string.h>#endif#ifdef HAVE_STRINGS_H#  include <strings.h>#endif#include <common/portability.h>/**************************************************************************** MODULE SPECIFIC INCLUDES**************************************************************************/#include <common/msql_defs.h>#include <common/debug/debug.h>#include <msqld/index/index.h>#include <msqld/includes/errmsg.h>#include <msqld/includes/msqld.h>#include <msqld/main/main.h>#include <msqld/main/yaccer.h>#include <msqld/main/varchar.h>#include <msqld/main/sysvar.h>#include <msqld/main/util.h>#include <msqld/main/table.h>#include <msqld/main/compare.h>#include <msqld/main/parse.h>#include <msqld/main/regex.h>#include <msqld/main/memory.h>#include <common/types/types.h>#include <libmsql/msql.h>/**************************************************************************** GLOBAL VARIABLES**************************************************************************//* HACK*/extern	char    errMsg[];/**************************************************************************** PRIVATE ROUTINES**************************************************************************//*** Operator class macros*/#define ISA_NULL_OP(op) ((op == EQ_OP) || (op == NE_OP))#define ISA_LIKE_OP(op) ((op >= LIKE_OP) && (op <= NOT_SLIKE_OP))int localByteCmp(b1, b2, len)        void 	*b1, 		*b2;        int	len;{        register char *p1, *p2;        if (len == 0)                return(0);        p1 = (char *)b1;        p2 = (char *)b2;        while (len)	{                if (*p1 != *p2)                        break;		p1++;		p2++;		len--;	}	if (len == 0)		return(0);	if (*p1 > *p2)		return(1);        return(-1);}/******************************************************************************      _byteMatch****      Purpose : comparison suite for single bytes.**      Args    :**      Returns :**      Notes   : in-lined for performance***/#define byteMatch(v1,v2,op, result)				\{								\        switch(op)						\        {							\                case EQ_OP:					\                        result = ((char)v1 == (char)v2);	\                        break;					\                case NE_OP:					\                        result = ((char)v1 != (char)v2);	\                        break;					\                case LT_OP:					\                        result = ((char)v1 < (char)v2);		\                        break;					\                case LE_OP:					\                        result = ((char)v1 <= (char)v2);	\                        break;					\                case GT_OP:					\                        result = ((char)v1 > (char)v2);		\                        break;					\                case GE_OP:					\                        result = ((char)v1 >= (char)v2);	\                        break;					\        }							\}/****************************************************************************** 	_intMatch****	Purpose	: comparison suite for integer fields.**	Args	: **	Returns	: **	Notes	: in-lined for performance*/#define intMatch(v1,v2,op,result)			\{							\	switch(op)					\	{						\		case EQ_OP:				\			result = (v1 == v2); 		\			break;				\		case NE_OP:				\			result = (v1 != v2);		\			break;				\		case LT_OP:				\			result = (v1 < v2);		\			break;				\		case LE_OP:				\			result = (v1 <= v2);		\			break;				\		case GT_OP:				\			result = (v1 > v2);		\			break;				\		case GE_OP:				\			result = (v1 >= v2);		\			break;				\	}						\}/****************************************************************************** 	_uintMatch****	Purpose	: comparison suite for unsigned integer fields.**	Args	: **	Returns	: **	Notes	: in-lined for performance*/#define uintMatch(v1,v2,op,result)			\{							\	switch(op)					\	{						\		case EQ_OP:				\			result = ((u_int)v1 == (u_int)v2); \			break;				\		case NE_OP:				\			result = ((u_int)v1 != (u_int)v2);\			break;				\		case LT_OP:				\			result = ((u_int)v1 < (u_int)v2);\			break;				\		case LE_OP:				\			result = ((u_int)v1 <= (u_int)v2);\			break;				\		case GT_OP:				\			result = ((u_int)v1 > (u_int)v2);\			break;				\		case GE_OP:				\			result = ((u_int)v1 >= (u_int)v2);\			break;				\	}						\}#define int64Match	intMatch#define uint64Match	uintMatch/****************************************************************************** 	_charMatch****	Purpose	: Comparison suite for text fields**	Args	: **	Returns	: **	Notes	: */static int charMatch(v1,v2,op,maxLen)	char	*v1,		*v2;	int	op,		maxLen;{	int	v1Len, v2Len; /* actual length of input data */	int	result = 0,		cmp = 0;	/* needed for both ordinary and *LIKE operators */	v1Len = regexStringLength( v1, maxLen ); 	v2Len = strlen( v2 );	/* common stuff for ordinary operators (=, <, ...) */	if (!ISA_LIKE_OP(op))	{#ifdef HAVE_STRCOLL		{			/*			** Sadly there isn't an strncoll so we must			** ensure the data from the row is NULL			** terminated.			*/			char tmp;			tmp = *(v1+v1Len);			*(v1+v1Len) = 0;			cmp = strcoll( v1, v2);			*(v1+v1Len) = tmp;		}#else		cmp = strncmp( v1, v2, (v1Len < v2Len) ? v1Len : v2Len );#endif		if (cmp == 0)		{			cmp = v1Len - v2Len;		}	}	switch(op)	{		case EQ_OP:			result = (cmp == 0);			break;					case NE_OP:			result = (cmp != 0);			break;					case LT_OP:			result = (cmp < 0);			break;					case LE_OP:			result = (cmp <= 0);			break;					case GT_OP:			result = (cmp > 0);			break;					case GE_OP:			result = (cmp >= 0);			break;		case RLIKE_OP:			result = rLikeTest(v1,v2,v1Len);			break;		case LIKE_OP:			result = likeTest(v1,v2,v1Len, 0, CHAR_TYPE);			break;		case CLIKE_OP:			result = likeTest(v1,v2,v1Len, 1, CHAR_TYPE);			break;		case SLIKE_OP:			result = sLikeTest(v1,v2,v1Len);			break;		case NOT_RLIKE_OP:			result = !(rLikeTest(v1,v2,v1Len));			break;		case NOT_LIKE_OP:			result = !(likeTest(v1,v2,v1Len, 0, CHAR_TYPE));			break;		case NOT_CLIKE_OP:			result = !(likeTest(v1,v2,v1Len, 1, CHAR_TYPE));			break;		case NOT_SLIKE_OP:			result = !(sLikeTest(v1,v2,v1Len));			break;	}	return(result);}/****************************************************************************** 	_byteRangeMatch****	Purpose	: Comparison suite for byte ranges (i.e. basetype = BYTE)**	Args	: **	Returns	: **	Notes	: */static int byteRangeMatch(v1,v2,op,len)	void	*v1,		*v2;	int	op,		len;{	int	result = 0,		cmp = 0;	cmp = localByteCmp( v1, v2, len);	switch(op)	{		case EQ_OP:			result = (cmp == 0);			break;					case NE_OP:			result = (cmp != 0);			break;					case LT_OP:			result = (cmp < 0);			break;					case LE_OP:			result = (cmp <= 0);			break;					case GT_OP:			result = (cmp > 0);			break;					case GE_OP:			result = (cmp >= 0);			break;	}	return(result);}/****************************************************************************** 	_cidr4Match****	Purpose	: Comparison suite for cidr4 fields**	Args	: **	Returns	: **	Notes	: */int cidr4Match(p1, p2, op)	void	*p1,		*p2;	int	op;{	u_char	byte1, byte2, byte3, byte4, byte5;	u_int	addr1, addr2,		len, len1, len2,		mask;	int	result;	byte1 = (u_char)*(u_char*)(p1);	byte2 = (u_char)*(u_char*)(p1 + 1);	byte3 = (u_char)*(u_char*)(p1 + 2);	byte4 = (u_char)*(u_char*)(p1 + 3);	byte5 = (u_char)*(u_char*)(p1 + 4);	addr1 = ( byte1 << 24) + (byte2 << 16) + (byte3 << 8) + byte4;	len1 = byte5;	byte1 = (u_char)*(u_char*)(p2);	byte2 = (u_char)*(u_char*)(p2 + 1);	byte3 = (u_char)*(u_char*)(p2 + 2);	byte4 = (u_char)*(u_char*)(p2 + 3);	byte5 = (u_char)*(u_char*)(p2 + 4);	addr2 = ( byte1 << 24) + (byte2 << 16) + (byte3 << 8) + byte4;	len2 = byte5;	len = (len1 < len2 ? len1 : len2);	switch(len)	{		case 0 : mask = 0; break;		case 1 : mask = 2147483648u; break;		case 2 : mask = 3221225472u; break;		case 3 : mask = 3758096384u; break;		case 4 : mask = 4026531840u; break;		case 5 : mask = 4160749568u; break;		case 6 : mask = 4227858432u; break;		case 7 : mask = 4261412864u; break;		case 8 : mask = 4278190080u; break;		case 9 : mask = 4286578688u; break;		case 10 : mask = 4290772992u; break;		case 11 : mask = 4292870144u; break;		case 12 : mask = 4293918720u; break;		case 13 : mask = 4294443008u; break;		case 14 : mask = 4294705152u; break;		case 15 : mask = 4294836224u; break;		case 16 : mask = 4294901760u; break;		case 17 : mask = 4294934528u; break;		case 18 : mask = 4294950912u; break;		case 19 : mask = 4294959104u; break;		case 20 : mask = 4294963200u; break;		case 21 : mask = 4294965248u; break;		case 22 : mask = 4294966272u; break;		case 23 : mask = 4294966784u; break;		case 24 : mask = 4294967040u; break;		case 25 : mask = 4294967168u; break;		case 26 : mask = 4294967232u; break;		case 27 : mask = 4294967264u; break;		case 28 : mask = 4294967280u; break;		case 29 : mask = 4294967288u; break;		case 30 : mask = 4294967292u; break;		case 31 : mask = 4294967294u; break;		case 32 : mask = 4294967295u; break;	}	/*	** The manual (and slow) way of working out a mask	**	while(count <  len)        {                mask = (mask << 1) + 1;                count++;        }        mask = mask << (32 - len);	**	*/	switch(op)	{		case EQ_OP:			result = (addr1 == addr2) && (len1 == len2);			break;		case NE_OP:			result = (addr1 != addr2) || (len1 != len2);			break;		case LT_OP:			result = ((addr1 & mask) == (addr2 & mask)) &&				(len1 < len2);			break;		case LE_OP:			result = ((addr1 & mask) == (addr2 & mask)) &&				(len1 <= len2);			break;		case GT_OP:			result = ((addr1 & mask) == (addr2 & mask)) &&				(len1 > len2);			break;		case GE_OP:			result = ((addr1 & mask) == (addr2 & mask)) &&				(len1 >= len2);			break;		default:			strcpy(errMsg, "Invalid cidr4 comparison");			return(-1);	}	return(result);}/****************************************************************************** 	_realMatch****	Purpose	: Comparison suite for real fields**	Args	: **	Returns	: **	Notes	: in-lined for performance*/#define realMatch(v1,v2,op, result)			\{							\	switch(op)					\	{						\		case EQ_OP:				\			result = (v1 == v2);		\			break;				\		case NE_OP:				\			result = (v1 != v2);		\			break;				\		case LT_OP:				\			result = (v1 < v2);		\			break;				\		case LE_OP:				\			result = (v1 <= v2);		\			break;				\		case GT_OP:				\			result = (v1 > v2);		\			break;				\		case GE_OP:				\			result = (v1 >= v2);		\			break;				\	}						\}/****************************************************************************** Row comparison routines*/static int processBetweenMatch(cacheEntry,curCond,data, offset, tmpVal)	cache_t	*cacheEntry;	mCond_t	*curCond;	u_char	*data;	int	*offset;	mVal_t	*tmpVal;{	int	tmp = 0;	int	iv;	double	fv;	char	*cp;#ifdef HUGE_T	HUGE_T	hv;#endif	switch(typeBaseType(curCond->type))	{		case INT_TYPE:			bcopy4((data + *offset +1),&iv);			intMatch(iv,curCond->value->val.intVal,GE_OP,tmp);			if (tmp == 1)			{				intMatch(iv,curCond->maxValue->val.intVal,					LE_OP,tmp);			}			break;		case UINT_TYPE:			bcopy4((data + *offset +1),&iv);			uintMatch(iv,curCond->value->val.intVal,GE_OP,tmp);			if (tmp == 1)			{				uintMatch(iv,curCond->maxValue->val.intVal,					LE_OP, tmp);			}			break;#ifdef HUGE_T		case INT64_TYPE:			bcopy((data + *offset +1),&hv, sizeof(HUGE_T));			int64Match(hv,curCond->value->val.int64Val,GE_OP,tmp);			if (tmp == 1)			{				int64Match(hv,curCond->maxValue->val.int64Val,					LE_OP,tmp);			}			break;		case UINT64_TYPE:			bcopy((data + *offset +1),&hv, sizeof(HUGE_T));			uint64Match(hv,curCond->value->val.int64Val,GE_OP,tmp);			if (tmp == 1)			{				uint64Match(hv,curCond->maxValue->val.int64Val,					LE_OP, tmp);			}			break;#endif		case CHAR_TYPE:			cp = (char *)data + *offset +1;			tmp = charMatch(cp,curCond->value->val.charVal,				GE_OP, curCond->length);			if (tmp == 1)			{				tmp = charMatch(cp,					curCond->maxValue->val.charVal,					LE_OP, curCond->length);			}			break;		case TEXT_TYPE:			cp = (char *)data + *offset +1;			tmp = varcharMatch(cacheEntry,cp, 				curCond->value->val.charVal,				curCond->length, GE_OP);			if (tmp == 1)			{				tmp = varcharMatch(cacheEntry,cp, 					curCond->maxValue->val.charVal,					curCond->length, LE_OP);			}			break;		case REAL_TYPE:			bcopy8((data + *offset + 2),&fv);			realMatch(fv,curCond->value->val.realVal,GE_OP, tmp);			if (tmp == 1)			{				realMatch(fv,curCond->maxValue->val.realVal,					LE_OP, tmp);			}			break;		case BYTE_TYPE:			cp = (char *)data + *offset +1;			tmp = byteRangeMatch(cp,curCond->value->val.byteVal,				GE_OP, curCond->length);			if (tmp == 1)			{				tmp = byteRangeMatch(cp,					curCond->maxValue->val.byteVal,					LE_OP, curCond->length);			}			break;	}	return(tmp);}	static int processCondMatch(cacheEntry,curCond,value,row, data, offset,		tmpVal)	cache_t	*cacheEntry;	mCond_t	*curCond;	mVal_t	*value;	row_t	*row;	u_char	*data;

⌨️ 快捷键说明

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