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

📄 cra.c

📁 uClinux下用的数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		new->type = CAND_ROWID;		new->lastPos = NO_POS;		new->length = 4;		new->rowID = rowID;		msqlDebug1(MOD_ACCESS, 			"setupCandidate() : Using _ROWID for %s\n",			entry->table);		if (query->explainOnly)		{			strcpy(packet,"\tUsing _ROWID\n");			netWritePacket(query->clientSock);		}		return(new);	}	/*	** Look for the wierd _seq case.  We need this because it's	** possible (in fact normal) to just select the seq value.  In	** that situation we can't expect to just fill in the blanks	** for a table row access as there may not be any table data	** yet (e.g. the first insert into a table that uses the SEQ	** as a key).  Use this for everything but _rowid and _timestamp. 	** It's ugly but it works.	*/	if (query->fieldHead)	{		if (query->fieldHead->next == NULL && 			query->fieldHead->sysvar == 1)		{			if (strcmp(query->fieldHead->name, "_rowid") != 0 &&			    strcmp(query->fieldHead->name, "_timestamp") != 0)			{				new->type = CAND_SYS_VAR;				new->lastPos = NO_POS;				new->length = 0;				new->rowID = 0;				msqlDebug1(MOD_ACCESS,				"setupCandidate() : Fake sysvar for %s\n",				entry->table);				return(new);			}		}	}	/*	** Check for an  equality index condition.  Match on the longest index	** or the first unique.  Keep an eye out for index prefix	** matches that we could use	*/	new->type = CAND_SEQ;	new->nextPos = 0;	new->length = 0;	doRange = 0;	curIndex = entry->indices;	index = 0;	if (*entry->cname != 0)		tableName = entry->cname;	else		tableName = entry->table;	haveUnique = indexMatches = 0;	while(curIndex)	{		idxCond = NULL;		field = 0;		identKey = 0;		while(field < MAX_INDEX_WIDTH && curIndex->fields[field] != -1)		{			curCond = query->condHead;			while(curCond)			{				if (strcmp(curCond->table, entry->table)!=0)				{					curCond=curCond->next;					continue;				}				if (curCond->value->type == IDENT_TYPE ||				    curCond->value->type == SYSVAR_TYPE)				{					identKey |= 1;				}				if(strcmp(tableName,curIndex->table)==0 &&				   curCond->fieldID == curIndex->fields[field])				{					if( (curCond->op == EQ_OP ||					     curCond->op == BETWEEN_OP ||					     curCond->op == LT_OP ||					     curCond->op == LE_OP ||					     curCond->op == GT_OP ||					     curCond->op == GE_OP) &&					   !((curCond->value->type==IDENT_TYPE||					      curCond->value->type==SYSVAR_TYPE)					     && ignoreIdent))					{						break;					}				}				curCond = curCond->next;			}			if (!curCond)			{				break;			}			switch(curCond->op)			{				case BETWEEN_OP:					doRange = CAND_IDX_RANGE;					break;				case LE_OP:					doRange = CAND_IDX_RANGE_LE;					break;				case LT_OP:					doRange = CAND_IDX_RANGE_LT;					break;				case GE_OP:					doRange = CAND_IDX_RANGE_GE;					break;				case GT_OP:					doRange = CAND_IDX_RANGE_GT;					break;			}			field++;		}		/*		** Don't attempt to do a range match on a compound		** index.  It can't be done.		*/		if (doRange)		{			if (curIndex->fields[1] != -1)				curCond = NULL;		}		if (curCond)		{			if (identKey == 0)			{				validIndices[indexMatches] = index;				numEntries = 					idxGetNumEntries(&curIndex->handle);				numKeys = idxGetNumKeys(&curIndex->handle);				if (numKeys)				{					indexWeights[indexMatches] = 						numEntries / numKeys;				}				else				{					indexWeights[indexMatches] = 0;				}				indexMatches++;			}			if (curIndex->unique)			{				haveUnique = 1;				if (doRange)					new->type = doRange;				else					new->type = CAND_IDX_ABS;				new->index = index;				new->ident = identKey;				new->lastPos = NO_POS;				new->length = curIndex->length;				strcpy(new->idx_name, curIndex->name);				candIndex = curIndex;				if (query->explainOnly)				{					snprintf(packet,PKT_LEN,					"\tFound unique %s index (%s)\n",					new->type == CAND_IDX_RANGE?					"range" : "absolute",					curIndex->name);					netWritePacket(query->clientSock);				}				break;			}			if (curIndex->length > new->length)			{				if (doRange)					new->type = doRange;				else					new->type = CAND_IDX_ABS;				new->index = index;				new->ident = identKey;				new->lastPos = NO_POS;				new->length = curIndex->length;				strcpy(new->idx_name, curIndex->name);				if (query->explainOnly)				{					snprintf(packet,PKT_LEN,					"\tFound %s index (%s) of length %d\n",					new->type == CAND_IDX_RANGE?					"range" : "absolute",					curIndex->name, curIndex->length);					netWritePacket(query->clientSock);				}				candIndex = curIndex;			}		}		curIndex = curIndex->next;		index++;	}        /*        ** Can we do a union index?  Don't bother if we have a unique.	** If we are going to do it then make sure it's done in the most	** efficient order.        */#ifdef UNION_INDEX        prevIdx.native = NULL;        if (indexMatches > 1 && haveUnique == 0)        {                /*                ** Yup we can.  Sort those puppies based on index weight		** (i.e. num entries / num keys)		*/		while(1)		{			index = 1;			done = 1;			while(index < indexMatches)			{				if(indexWeights[index-1] > indexWeights[index])				{					tmpIndex = validIndices[index -1];					validIndices[index - 1] =						validIndices[index];					validIndices[index] = tmpIndex;					tmpWeight = indexWeights[index -1];					indexWeights[index - 1] =						indexWeights[index];					indexWeights[index] = tmpWeight;					done = 0;				}				index++;			}			if (done)				break;		}			/*		** Scan through the valid indices and                ** create an AVL tree containing just the rowid's of                ** the intersection of the indices (i.e. the union index)                */                index = 0;                tmpIdx.native = prevIdx.native = NULL;                while(index < indexMatches)                {                        curIndex = entry->indices;                        count = 0;                        while(count < validIndices[index])                        {                                curIndex = curIndex->next;                                count++;                        }                        msqlDebug3(MOD_CANDIDATE, 				"Union index on %s:%s with weight %d\n",                                curIndex->table,curIndex->name,				indexWeights[index]);                        if (unionIdxCreateTmpIndex(&tmpIdx, &prevIdx, curIndex, 				query->condHead) < 0)			{				tmpIdx.native = NULL;			}                        if (prevIdx.native)                        {                                unionIdxFree(&prevIdx);                        }                        bcopy(&tmpIdx,&prevIdx,sizeof(tmpIdx));                        curIndex = curIndex->next;                        index++;                }                new->unionIndex = &tmpIdx;                new->type = CAND_UNION;                msqlDebug1(MOD_CANDIDATE,                        "setupCandidate() : Using UNION_INDEX for %s\n",                        entry->table);                return(new);        }#endif /* UNION_INDEX */	/*	** Setup the index stuff	*/	if (new->type == CAND_IDX_ABS || new->type == CAND_IDX_RANGE || 	    new->type == CAND_IDX_RANGE_LE || new->type == CAND_IDX_RANGE_LT ||	    new->type == CAND_IDX_RANGE_GE || new->type == CAND_IDX_RANGE_GT )	{		new->handle = candIndex->handle;		new->buf = (char *)malloc(new->length + 1);		new->maxBuf = (char *)malloc(new->length + 1);		new->keyType = candIndex->keyType;		/* Setup the key buffer */		count = 0;		cp = new->buf;		bzero(new->buf,new->length + 1);		cp1 = new->maxBuf;		bzero(new->maxBuf,new->length + 1);		while(candIndex->fields[count] != -1)		{			curCond = query->condHead;			while(curCond)			{				if (curCond->subCond)				{					curCond = curCond->next;					continue;				}				if(curCond->fieldID==candIndex->fields[count]				  && curCond->value->type != IDENT_TYPE)				{					if (curCond->value->nullVal)					{                				snprintf(errMsg,MAX_ERR_MSG,							NULL_COND_ERR, 							curCond->name);               					return(NULL);					}					extractFieldValue(cp,curCond);					extractMaxFieldValue(cp1,curCond);					cp += curCond->length;					cp1 += curCond->length;					break;				}				curCond = curCond->next;			}			count++;		}		msqlDebug2(MOD_ACCESS, 			"setupCandidate() : Using IDX %d for %s\n",			new->index, entry->table);		return(new);	}	if (query->explainOnly)	{		strcpy(packet,"\tDidn't find anything of use. Using SEQ\n");		netWritePacket(query->clientSock);	}	msqlDebug1(MOD_ACCESS, 		"setupCandidate() : Using SEQ for %s\n",		entry->table);	return(new);}void craResetCandidate(cand, deleteFlag)	mCand_t	*cand;	int	deleteFlag;{	/*	** If it's a SEQ search candidate then just start at the top	** again.  We need to reset it in this way when the candidate	** is the inner loop of a join.  If this is from a delete only	** reset index based candidates	*/	if (cand->type == CAND_SEQ && deleteFlag == 0)		cand->nextPos = 0;	else		cand->lastPos = NO_POS;}u_int craGetCandidate(entry, cand)	cache_t	*entry;	mCand_t	*cand;{	int	length,		rangeEnd,		res = 0;	u_int	pos;	idx_nod	node;	switch(cand->type)	{	    case CAND_SEQ:		cand->nextPos++;		if (cand->nextPos > entry->sblk->numRows)		{			msqlDebug1(MOD_ACCESS, 				"getCandidate() : SEQ on %s => NO_POS\n",				entry->table);			return(NO_POS);		}		else		{			msqlDebug2(MOD_ACCESS, 				"getCandidate() : SEQ on %s => %d\n",				entry->table, cand->nextPos -1);			return(cand->nextPos -1);		}		break;	    case CAND_IDX_ABS:		msqlDebug2(MOD_ACCESS, 			"getCandidate() : using IDX '%s' on %s\n",			cand->idx_name, entry->table);		msqlDebug3(MOD_ACCESS, 			"getCandidate() : IDX key on %s = '%s','%d'\n",			entry->table, cand->buf, (int) *(int*)cand->buf);		length = cand->length;		if (cand->lastPos == NO_POS)		{			res = idxLookup(&cand->handle, cand->buf,				cand->length, IDX_EXACT, &node);			idxSetCursor(&cand->handle, &cand->cursor);		}		else		{			res = idxGetNext(&cand->handle, &cand->cursor,&node);		}		if (res != IDX_OK)		{			idxCloseCursor(&cand->handle, &cand->cursor);			msqlDebug1(MOD_ACCESS, 				"getCandidate() : IDX on %s => NO_POS\n",				entry->table);			return(NO_POS);		}		if (cand->keyType == IDX_CHAR)		{			if (strcmp(node.key, cand->buf) != 0)			{				msqlDebug1(MOD_ACCESS, 				    "getCandidate() : IDX on %s => NO_POS\n",				    entry->table);				return(NO_POS);			}		}		else		{			if (bcmp(node.key, cand->buf, length) != 0)			{				msqlDebug1(MOD_ACCESS, 				    "getCandidate() : IDX on %s => NO_POS\n",				    entry->table);				return(NO_POS);			}		}		pos = node.data;		if (cand->lastPos == NO_POS)		{			cand->lastPos = pos;		}		msqlDebug2(MOD_ACCESS, 			"getCandidate() : IDX on %s => %d\n", 			entry->table, pos);		return(pos);            case CAND_IDX_RANGE:            case CAND_IDX_RANGE_LE:            case CAND_IDX_RANGE_LT:            case CAND_IDX_RANGE_GE:            case CAND_IDX_RANGE_GT:                msqlDebug2(MOD_ACCESS,                        "getCandidate() : using RANGE IDX '%s' on %s\n",                        cand->idx_name, entry->table);                msqlDebug3(MOD_ACCESS,                        "getCandidate() : IDX key on %s = '%s','%d'\n",                        entry->table, cand->buf, (int) *(int*)cand->buf);                length = cand->length;                if (cand->lastPos == NO_POS)                {		    switch(cand->type)		    {			case CAND_IDX_RANGE:			case CAND_IDX_RANGE_GE:			case CAND_IDX_RANGE_GT:				res = idxLookup(&cand->handle, cand->buf,					cand->length, IDX_CLOSEST, &node);				idxSetCursor(&cand->handle, &cand->cursor);				break;			case CAND_IDX_RANGE_LE:			case CAND_IDX_RANGE_LT:				res = idxGetFirst(&cand->handle,&node);				idxSetCursor(&cand->handle, &cand->cursor);				break;		    }                }                else                {			res = idxGetNext(&cand->handle, &cand->cursor,&node);		}		if (res != IDX_OK)		{			idxCloseCursor(&cand->handle, &cand->cursor);                        msqlDebug1(MOD_ACCESS,                                "getCandidate() : RANGE IDX on %s => NO_POS\n",                                entry->table);                        return(NO_POS);                }                rangeEnd = 0;		if (cand->type != CAND_IDX_RANGE_GT && 		    cand->type != CAND_IDX_RANGE_GE)		{                	switch(cand->keyType)                	{                    	case IDX_CHAR:                        	if (strcmp(node.key, cand->maxBuf) > 0)                                	rangeEnd = 1;                        	break;                    	case IDX_INT:                        	if (idxIntCompare(node.key, cand->maxBuf) > 0)                                	rangeEnd = 1;                        	break;                    	case IDX_UINT:                        	if (idxUIntCompare(node.key, cand->maxBuf) > 0)                               		rangeEnd = 1;                        	break;                    	case IDX_REAL:                        	if (idxRealCompare(node.key, cand->maxBuf) > 0)                                	rangeEnd = 1;				break;                    	default:                        	if(idxByteCompare(node.key,cand->maxBuf,					length)>0)				{                                	rangeEnd = 1;				}			}                }                if (rangeEnd)                {			idxCloseCursor(&cand->handle, &cand->cursor);                        msqlDebug1(MOD_ACCESS,                                "getCandidate() : RANGE IDX on %s => NO_POS\n",                                entry->table);                        return(NO_POS);                }                pos = node.data;                if (cand->lastPos == NO_POS)                {                        cand->lastPos = pos;                }                msqlDebug2(MOD_ACCESS,			"getCandidate() : RANGE IDX on %s => %d\n",                        entry->table, pos);                return(pos);            case CAND_UNION:                if (cand->lastPos == NO_POS)                {                        cand->lastPos = 0;                }                cand->lastPos++;                return(unionIdxGet(cand->unionIndex,cand->lastPos-1));	    case CAND_ROWID:		msqlDebug2(MOD_ACCESS, 			"getCandidate() : using ROW ID '%d' on %s\n",			cand->rowID, entry->table);		if (cand->lastPos == NO_POS)		{			if (entry->sblk->numRows < cand->rowID)			{				cand->rowID = 0;				return(NO_POS);			}			cand->lastPos = cand->rowID;			return(cand->rowID);		}			else		{			return(NO_POS);		}	}	return(NO_POS);}

⌨️ 快捷键说明

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