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

📄 compare.c

📁 uClinux下用的数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
	int	*offset;	mVal_t	*tmpVal;{	int	tmp = 0;	char	int8;	short	int16;	int	int32;	double	fv;	char	*cp;#ifdef HUGE_T	HUGE_T	int64;#endif	if (curCond->sysvar)	{		tmp = sysvarCompare(cacheEntry,row, curCond, value);		return(tmp);	}	/*	** Check to see if there is a type specific comparison routine	*/	switch(curCond->type)	{		case CIDR4_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			tmp = cidr4Match((data + *offset + 1), 				value->val.byteVal, curCond->op);			if (tmp < 0)				return(-2);			return(tmp);			break;	}	/*	** If not just use the base type's comparison routine	*/	switch(typeBaseType(curCond->type))	{		case INT_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, INT_LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			bcopy4((data + *offset +1), &int32);			intMatch(int32,value->val.intVal,curCond->op,tmp);			break;		case INT8_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, INT_LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			bcopy((data + *offset +1), &int8, 1);			intMatch(int8,value->val.intVal,curCond->op,tmp);			break;		case INT16_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, INT_LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			bcopy((data + *offset +1), &int16, 2);			intMatch(int16,value->val.intVal,curCond->op,tmp);			break;		case UINT_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, INT_LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			bcopy4((data + *offset +1), &int32);			uintMatch(int32,value->val.intVal,curCond->op,tmp);			break;		case UINT8_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, INT_LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			bcopy((data + *offset +1), &int8, 1);			uintMatch(int8,value->val.intVal,curCond->op,tmp);			break;		case UINT16_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, INT_LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			bcopy((data + *offset +1), &int16, 2);			uintMatch(int16,value->val.intVal,curCond->op,tmp);			break;#ifdef HUGE_T		case INT64_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, INT_LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			bcopy((data + *offset +1), &int64, sizeof(HUGE_T));			int64Match(int64,value->val.int64Val,curCond->op,tmp);			break;		case UINT64_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, INT_LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			bcopy((data + *offset +1), &int64, sizeof(HUGE_T));			uint64Match(int64,value->val.int64Val,curCond->op,tmp);			break;#endif		case CHAR_TYPE:			if (curCond->sysvar)			{				tmp = sysvarCompare(cacheEntry,row,					curCond, value);				return(tmp);			}			cp = (char *)data + *offset +1;			tmp = charMatch(cp,value->val.charVal,				curCond->op, curCond->length);			if (value == tmpVal)			{				free(tmpVal->val.charVal);				tmpVal->val.charVal = NULL;			}			if (tmp < 0)			{				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			break;		case TEXT_TYPE:			cp = (char *)data + *offset +1;			if (curCond->op == RLIKE_OP || curCond->op == SLIKE_OP)			{				strcpy(errMsg, TEXT_REGEX_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			tmp = varcharMatch(cacheEntry,cp, value->val.charVal,				curCond->length, curCond->op);			if (value == tmpVal)			{				free(tmpVal->val.charVal);				tmpVal->val.charVal = NULL;			}			if (tmp < 0)			{				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			break;		case REAL_TYPE:			if (curCond->sysvar)			{				tmp = sysvarCompare(cacheEntry,row,					curCond, value);				return(tmp);			}			bcopy8((data + *offset + 2),&fv);			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, REAL_LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			realMatch(fv,value->val.realVal, curCond->op, tmp);			break;		case BYTE_TYPE:			if (ISA_LIKE_OP(curCond->op))			{				strcpy(errMsg, LIKE_ERROR);				debugTrace(TRACE_OUT,"processCondMatch()");				return(-2);			}			tmp = byteRangeMatch((data + *offset +1),				value->val.byteVal, curCond->op,				curCond->length);			break;	}	return(tmp);}	/**************************************************************************** PUBLIC ROUTINES**************************************************************************/int compareMatchRow(cacheEntry,row,conds,query)	cache_t		*cacheEntry;	row_t		*row;	mCond_t		*conds;	mQuery_t	*query;{	mCond_t		*curCond;	int		result,			freeTmpField = 0,			tmp = 0;	int		*offset,			init=1,			res;	u_char		*data;	mVal_t		*value,			tmpVal;	mField_t	*curField,			tmpField,			*tmpFieldPtr;	int		tmpFlist[2],			foundField;	int		rhsType; /* saves rhs type prior to data fetch */	int		lhsIsNull;/* temporary that indicates nullness of lhs */	debugTrace(TRACE_IN,"compareMatchRow()");	result=0;	if (!conds)	{		debugTrace(TRACE_OUT,"compareMatchRow()");		return(1);	}	data = row->data;	curCond = conds;	offset = conds->clist;	while(curCond)	{		/*		** If this is a subcond just recurse and continue		*/		if (curCond->subCond)		{			tmp = compareMatchRow(cacheEntry,row,curCond->subCond,				query);			if (tmp < 0)				return(tmp);			if (init)			{				result = tmp;				init = 0;			}			else			{                        	switch(curCond->bool)                        	{                                	case NO_BOOL:                                        	result = tmp;                                        	break;                                	case AND_BOOL:                                        	result &= tmp;                                        	break;                                	case OR_BOOL:                                        	result |= tmp;                                        	break;                        	}			}			curCond = curCond->next;			continue;		}		/*		** OK, it wasn't a sub cond.  Proceded as normal.		**		** If we are comparing 2 fields (e.g. in a join) then		** grab the value of the second field so that we can do		** the comparison.  Watch for type mismatches!		*/		foundField = 0;		freeTmpField = 0;		tmpField.value = NULL;		rhsType = curCond->value->type;		switch(curCond->value->type)		{		    case IDENT_TYPE:			value = curCond->value;			curField = cacheEntry->def;			if (!*(value->val.identVal->seg1))			{				if (!cacheEntry->result)				{					strcpy(value->val.identVal->seg1,						cacheEntry->table);				}				else				{					strcpy(errMsg,UNQUAL_ERROR);					debugTrace(TRACE_OUT,						"compareMatchRow()");					return(-1);				}			}			while(curField)			{				if (*(curField->table) != 				    *(value->val.identVal->seg1) ||				    *(curField->name) !=				    *(value->val.identVal->seg2))				{					curField = curField->next;					continue;				}				if (strcmp(curField->table,					value->val.identVal->seg1) != 0 ||				    strcmp(curField->name,					value->val.identVal->seg2) != 0)				{					curField = curField->next;					continue;				}				tmpFieldPtr = &tmpField;				memCopyField(curField,tmpFieldPtr);				tmpField.value=NULL;				tmpField.next = NULL;				utilSetupFields(cacheEntry,tmpFlist, &tmpField);				tableExtractValues(cacheEntry,row,&tmpField,					tmpFlist, query);				bcopy(tmpField.value,&tmpVal,sizeof(mVal_t));				/* RNS				 * Character data needs to be copied, but				 * only if there is data.				 */				if (tmpVal.type == CHAR_TYPE && !tmpVal.nullVal)				{				    tmpVal.val.charVal= (u_char*)					malloc(curField->length + 1);				    bcopy(tmpField.value->val.charVal,					tmpVal.val.charVal, curField->length);				    *(tmpVal.val.charVal+curField->length) = 0;				}				parseFreeValue(tmpField.value);				tmpField.value = NULL;				value = &tmpVal;				foundField = 1;				break;			}			if (!foundField)			{				snprintf(errMsg, MAX_ERR_MSG, BAD_FIELD_ERROR,					value->val.identVal->seg1,					value->val.identVal->seg2);				msqlDebug2(MOD_ERR,"Unknown field \"%s.%s\"\n",					value->val.identVal->seg1,					value->val.identVal->seg2);				debugTrace(TRACE_OUT,"compareMatchRow()");				return(-1);			}			break;		    case SYSVAR_TYPE:			strcpy(tmpField.name,				curCond->value->val.identVal->seg2);			res = sysvarCheckVariable(cacheEntry, &tmpField);                        if (res == -2)                                return(-1);			if (res == -1)			{                        	snprintf(errMsg, MAX_ERR_MSG, SYSVAR_ERROR, 					curCond->value->val.identVal->seg2);				return(-1);			}			sysvarGetVariable(cacheEntry,row,&tmpField,query);			value = tmpField.value;			freeTmpField = 1;			break;		    default:			value = curCond->value;			break;		}		/*		** Ensure that the comparison is with the correct type.		** We do this here and in utilSetupConds() as we have to wait		** for the evaluation of field to field comparisons.  We		** also fudge it for real/int comparisons.  It's done		** in msqlutilpConds() to handle cases going to the		** index lookup code and for literal comparisons.		*/		if(utilSetCondValueType(curCond, value) < 0)		{			if (freeTmpField)				parseFreeValue(tmpField.value);			return(-1);		}		/*		** O.K. do the actual comparison		*/		if (*offset >=0)		{			lhsIsNull = (*(data + *offset) == 0);		}		else		{			/* 			** Offset of -1 indicates a sysvar we don't			** check the table data for a NULL value			*/			lhsIsNull = 0;		}				if ((rhsType == NULL_TYPE) && ISA_NULL_OP(curCond->op))		{			/* 			** An explicit comparison to NULL.  			*/			byteMatch( *(data + *offset), 0, curCond->op, tmp );		}		else if (rhsType == NULL_TYPE)		{			/* 			** SQL does not allow other operators for NULL.			*/			strcpy(errMsg, "Illegal operator applied to NULL.\n" );			debugTrace(TRACE_OUT,"compareMatchRow()");			return(-1);		}		else if (value->nullVal || lhsIsNull)		{			/* 			 * SQL says that any compare of implicit NULL values			 * should always fail (return false for now).			 */			tmp = 0;		}		else		{			if (curCond->op == BETWEEN_OP)			{				tmp = processBetweenMatch(cacheEntry,					curCond, data, offset, tmpVal);			}			else			{				tmp = processCondMatch(cacheEntry,curCond,					value,row, data, offset, &tmpVal);			}		}		if (freeTmpField)			parseFreeValue(tmpField.value);		if (tmp == -2)			return(-1);		if (init)		{			result = tmp;			init = 0;		}		else		{			switch(curCond->bool)			{				case NO_BOOL:					result = tmp;					break;					case AND_BOOL:					result &= tmp;					break;					case OR_BOOL:					result |= tmp;					break;			}		}		curCond = curCond->next;		offset++;	}	debugTrace(TRACE_OUT,"compareMatchRow()");	return(result);}int compareRows(entry,r1,r2,order,olist)	cache_t	*entry;	row_t	*r1,		*r2;	mOrder_t	*order;	int	*olist;{	mOrder_t *curOrder;	char	buf[sizeof(double)],		*cp1,		*cp2;	u_char	*data1,		*data2;	int	res = 0,		*offset,		d1IsNull,		d2IsNull;	double	fp1,		fp2;	int	int4p1, int4p2;#ifdef HUGE_T	HUGE_T	int64p1, int64p2;#endif	/*	** Allow for cases when rows are not defined	*/	debugTrace(TRACE_IN,"compareRows()");	if (r1 && !r2)	{		debugTrace(TRACE_OUT,"compareRows()");		return(-1);	}	if (!r1 && r2)	{		debugTrace(TRACE_OUT,"compareRows()");		return(1);	}	if (!r1 && !r2)	{		debugTrace(TRACE_OUT,"compareRows()");		return(0);	}	/*	** OK, we have both rows.	*/	data1 = r1->data;	data2 = r2->data;	curOrder = order;	offset = olist;	while(curOrder)	{		/* RNS		 * Allow for cases where data is not defined i.e.,		 * try to do something reasonable with null values.		 * How should we compare them?		 * For now, treat them as less than anything else.		 */		d1IsNull = (*(data1 + *offset) == 0);		d2IsNull = (*(data2 + *offset) == 0);		if (d1IsNull || d2IsNull)		{			if (d1IsNull && d2IsNull)			{				res = 0;			}			else if (d1IsNull)			{				res = -1;			}			else			{				res = 1;			}		}		else switch(typeBaseType(curOrder->type))		{			case INT_TYPE:			case UINT_TYPE:				bcopy4((data1 + *offset +1),buf);				int4p1 = (int) * (int*)buf;				bcopy4((data2 + *offset +1),buf);				int4p2 = (int) * (int*)buf;				if (int4p1 == int4p2)					res = 0;				if (int4p1 > int4p2)					res = 1;				if (int4p1 < int4p2)					res = -1;				break;#ifdef HUGE_T			case INT64_TYPE:			case UINT64_TYPE:				bcopy((data1 + *offset +1),buf, sizeof(HUGE_T));				int64p1 = (HUGE_T) * (HUGE_T*)buf;				bcopy((data2 + *offset +1),buf, sizeof(HUGE_T));				int64p2 = (HUGE_T) * (HUGE_T*)buf;				if (int64p1 == int64p2)					res = 0;				if (int64p1 > int64p2)					res = 1;				if (int64p1 < int64p2)					res = -1;				break;#endif			case CHAR_TYPE:				cp1 = (char *)data1 + *offset +1;				cp2 = (char *)data2 + *offset +1;#ifdef HAVE_STRCOLL				res = strcoll(cp1,cp2);#else				res = strncmp(cp1,cp2,curOrder->length);#endif				break;			case REAL_TYPE:				bcopy8((data1+*offset+2),buf);				fp1 = (double) * (double *)(buf);				bcopy8((data2+*offset+2),buf);				fp2 = (double) * (double *)(buf);				if (fp1 == fp2)					res = 0;				if (fp1 > fp2)					res = 1;				if (fp1 < fp2)					res = -1;				break;			case TEXT_TYPE:				cp1 = (char *)data1 + *offset +1;				cp2 = (char *)data2 + *offset +1;				res = varcharCompare(curOrder->entry, cp1, 					cp2, curOrder->length);				break;			case BYTE_TYPE:				cp1 = (char *)data1 + *offset +1;				cp2 = (char *)data2 + *offset +1;				res = localByteCmp(cp1,cp2,curOrder->length);				break;		}		if (curOrder->dir == DESC)		{			res = 0 - res;		}		if (res != 0)		{			debugTrace(TRACE_OUT,"compareRows()");			return(res);		}		curOrder = curOrder->next;		offset++;	}	debugTrace(TRACE_OUT,"compareRows()");	return(0);}

⌨️ 快捷键说明

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