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

📄 cra.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: cra.c,v 1.14 2002/06/29 04:08:58 bambi Exp $***//*** Module	: cra : cra** Purpose	: ** Exports	: ** Depends Upon	: *//**************************************************************************** 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/cra/cra.h>#include <msqld/cra/uidx.h>#include <common/types/types.h>#include <msqld/main/main.h>#include <msqld/main/parse.h>#include <msqld/main/sysvar.h>#include <msqld/main/net.h>#include <libmsql/msql.h>/**************************************************************************** GLOBAL VARIABLES**************************************************************************//* HACK */extern	char	*msqlHomeDir;extern	char	*packet;extern  char    errMsg[];extern	int	outSock;/**************************************************************************** PRIVATE ROUTINES**************************************************************************/static void extractCondValue(buf,cond,max)        char    *buf;        mCond_t  *cond;	int	max;{          int     length;        switch(typeBaseType(cond->value->type))        {                case INT_TYPE:                case UINT_TYPE:			if (max)                        	bcopy(&(cond->maxValue->val.intVal),buf,4);			else                        	bcopy(&(cond->value->val.intVal),buf,4);                        break;                case REAL_TYPE:			if (max)                        	bcopy(&(cond->maxValue->val.realVal),buf,8);			else                        	bcopy(&(cond->value->val.realVal),buf,8);                        break;                case CHAR_TYPE:			if (max)                        	length = strlen(cond->maxValue->val.charVal);			else                        	length = strlen(cond->value->val.charVal);                        if (length > cond->length)                                length = cond->length;			if (max)                        	bcopy((char *)cond->maxValue->val.charVal,					buf,length);			else                        	bcopy((char *)cond->value->val.charVal,					buf,length);                        break;        }}static void extractFieldValue(buf,cond)	char	*buf;	mCond_t	*cond;{	extractCondValue(buf,cond,0);}static void extractMaxFieldValue(buf,cond)	char	*buf;	mCond_t	*cond;{	if (cond->op == BETWEEN_OP) 		extractCondValue(buf,cond,1);	if (cond->op == LE_OP || cond->op == LT_OP)		extractCondValue(buf,cond,0);}#define	CACHE_LEN	5static 	int	candCount = 0;static	mCand_t	*candCache[CACHE_LEN];static mCand_t *_mallocCand(){	mCand_t	*new;	if (candCount > 0)        {                candCount--;                new = candCache[candCount];        }        else        {                new = (mCand_t *)malloc(sizeof(mCand_t));        }	new->type = new->index = new->ident = new->length = new->rowID =		new->keyType = new->nextPos = 0;	new->rangeMin = new->rangeMax = new->buf = new->maxBuf = NULL;	*new->idx_name = 0;	new->unionIndex = NULL;	return(new);}static void _freeCand(ptr)	mCand_t	*ptr;{        if (candCount >= CACHE_LEN)        {                free(ptr);        }        else        {                candCache[candCount] = ptr;                candCount++;        }}/**************************************************************************** PUBLIC ROUTINES**************************************************************************//*** This is the mSQL 2.0 Candidate Row Abstraction code.  In short, it's** the query optimsation module.*/void craFreeCandidate(cand)	mCand_t	*cand;{	if (cand)	{		if (cand->buf)		{			free(cand->buf);			cand->buf = NULL;		}		if (cand->maxBuf)		{			free(cand->maxBuf);			cand->maxBuf = NULL;		}		_freeCand(cand);	}}int craSetCandidateValues(inner, cand, fields, conds, row, query)	cache_t		*inner;	mCand_t		*cand;	mField_t	*fields;	mCond_t		*conds;	row_t		*row;	mQuery_t	*query;{	mIndex_t	*curIndex;	mField_t	*curField,			tmpField;	mCond_t		*curCond;	int		count,			fieldID;	char		*cp;	if (cand->type == CAND_SEQ)	{		return(0);	}	curIndex = inner->indices;	count = cand->index;	while(count && curIndex)	{		count--;		curIndex = curIndex->next;	}	if (!curIndex)		return(0);	/*	** We can't use fillIndexBuffer() here as some of the	** values are in the cond list and others are in the ident	** fields list.  Sigh...	*/	curIndex = inner->indices;	count = 0;	while(count < cand->index)	{		curIndex = curIndex->next;		count ++;	}	cp = cand->buf;		bzero(cp, curIndex->length + 1);	count = 0;	while(curIndex->fields[count] != -1)	{		fieldID = curIndex->fields[count];		/*		** Look for an ident value first		*/		curField = fields;		while(curField)		{			if(curField->fieldID == fieldID)			{				if (parseCopyValue(cp,curField->value,curField->type,					curField->length,0) < 0)				{					snprintf(errMsg,MAX_ERR_MSG,						NULL_JOIN_COND_ERR,						curField->name);					return(-1);				}				cp+=curField->length;				break;			}			curField = curField->next;		}		if (curField)		{			/* Found it */				count++;			continue;		}		/*		** OK, check out the normal conditions		*/		curCond = conds;		while(curCond)		{			if(curCond->fieldID == fieldID)			{				/*				** Could be a sysvar ?				*/				strcpy(tmpField.name,curCond->name);				if (sysvarCheckVariable(inner, &tmpField) == 0)				{					sysvarGetVariable(inner,row,&tmpField,						query);					if(parseCopyValue(cp,tmpField.value,					     tmpField.type,tmpField.length,0)<0)					{						snprintf(errMsg,MAX_ERR_MSG,							NULL_JOIN_COND_ERR,							curField->name);						return(-1);					}					cp += tmpField.length;				}				else				{					/*					** Nope, it's a normal field					*/					if(parseCopyValue(cp,curCond->value,					     curCond->type,curCond->length,0)<0)					{						snprintf(errMsg,MAX_ERR_MSG,							NULL_JOIN_COND_ERR,							curField->name);						return(-1);					}					cp += curCond->length;				}				break;			}			curCond = curCond->next;		}		if (curCond)		{			/* Found it */				count++;			continue;		}/***/		abort();	}	cand->lastPos = NO_POS;	return(0);}mTable_t *craReorderTableList(query)	mQuery_t	*query;{	/*	** This isn't part of the CRA but it still an important part	** of the query optimiser so it's in this module.	**	** Work out the best order for the tables of a join to be	** processed as the user may have specified them in a bad	** order (like certain benchmark suites).	*/	mCond_t		*curCond;	mTable_t	*head = NULL,			*tail = NULL,			*prevTable = NULL,			*curTable = NULL,			*pivotTable = NULL,			*pivotPrev = NULL;	int		condCount,			maxCount;	/*	** Any table with a literal condition goes to the head	** of the list	*/	curTable = query->tableHead;	prevTable = NULL;	while(curTable)	{		curCond = query->condHead;		while(curCond)		{			if (strcmp(curCond->table,curTable->name) == 0 &&				curCond->value->type != IDENT_TYPE)			{				break;			}			curCond = curCond->next;		}		if (curCond)		{			/* 			** Pull it out of the original list 			*/			if (prevTable)				prevTable->next = curTable->next;			else				query->tableHead = curTable->next;			/* 			** Add it to the new list 			*/			if (head)				tail->next = curTable;			else				head = curTable;			tail = curTable;			tail->next = NULL;			/* 			** Move on to the next 			*/			if (prevTable)				curTable = prevTable->next;			else				curTable = query->tableHead;			continue;		}		prevTable = curTable;		curTable = curTable->next;	}	/*	** Next, move the remaining tables onto the list ensuring that	** the "pivot" table of the remainder is moved first.	*/	while(query->tableHead)	{		maxCount = 0;		curTable = query->tableHead;		prevTable = NULL;		while(curTable)		{			curCond = query->condHead;			condCount = 0;			while(curCond)			{				if (curCond->subCond)				{					curCond = curCond->next;					continue;				}				if (strcmp(curCond->table, curTable->name)==0)				{					condCount++;				}				else 				if (curCond->value)				{				    if(curCond->value->type==IDENT_TYPE &&				     strcmp(curCond->value->val.identVal->seg1, 				     curTable->name)==0)				    {					condCount++;				    }				}				curCond = curCond->next;				continue;			}			if (condCount > maxCount)			{				pivotTable = curTable;				pivotPrev = prevTable;				maxCount = condCount;			}			prevTable = curTable;			curTable = curTable->next;		}		if (maxCount == 0)		{			/* 			** Not good.  Break out so we just append the 			** rest and bail 			*/			break;		}		if (pivotPrev)			pivotPrev->next = pivotTable->next;		else			query->tableHead = pivotTable->next;		if (head)			tail->next = pivotTable;		else			head = pivotTable;		tail = pivotTable;		tail->next = NULL;	}	if (head)		tail->next = query->tableHead;	else		head = query->tableHead;	return(head);}mCand_t *craSetupCandidate(entry, query, ignoreIdent)	cache_t		*entry;	mQuery_t	*query;	int		ignoreIdent;{	mCand_t		*new;	mIndex_t	*curIndex = NULL,			*candIndex = NULL;	mCond_t		*curCond,			*idxCond;	int		count,			field,			identKey,			index,			doRowID,			doRange,			haveUnique,			indexMatches,			rowID,			validIndices[NUM_INDEX],			indexWeights[NUM_INDEX],			numKeys,			numEntries;	char		*tableName,			*cp,			*cp1;#ifdef UNION_INDEX	static  	idx_hnd	tmpIdx,			prevIdx;	int 		tmpIndex,			tmpWeight, 			done;#endif	/*	** This is the query optimiser!  The conditions are checked to	** see which access mechanism is going to provide the fastest	** query result.	*/	if (query->explainOnly)	{		snprintf(packet,PKT_LEN,		"Setup Candidate called\n\tTable = %s\n\tCheck ident comparisons = %s\n", 		entry->result?entry->resInfo:entry->table, 		ignoreIdent?"No":"Yes");		netWritePacket(query->clientSock);	}	new = _mallocCand();	new->buf = NULL;	new->maxBuf = NULL;	/*	** We can't handle OR's yet so do a quick scan through the	** conditions	*/	curCond = query->condHead;	while(curCond)	{		if (curCond->bool == OR_BOOL)		{			new->type = CAND_SEQ;			new->nextPos = 0;			msqlDebug1(MOD_ACCESS,				"setupCandidate() : Using SEQ for %s\n",				entry->table);			if (query->explainOnly)			{				strcpy(packet,"\tFound OR! Using SEQ\n");				netWritePacket(query->clientSock);			}			return(new);		}		curCond = curCond->next;	}	/*	** First test is to see if we can do a row_id based access	*/	rowID = 0;	curCond = query->condHead;	doRowID = 0;	while(curCond)	{		if (strcmp(curCond->name, "_rowid")==0 && 		    curCond->op == EQ_OP)		{			doRowID++;			rowID = curCond->value->val.intVal;			break;		}		curCond = curCond->next;	}	if (doRowID == 1)

⌨️ 快捷键说明

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