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

📄 select.c

📁 uClinux下用的数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
				{					t2 = tail = newCond;				}				else				{					tail->next = newCond;					tail = newCond;				}			}			else			if (cur->value->type == IDENT_TYPE &&		  	strcmp(table2->table,cur->value->val.identVal->seg1)==0)			{				newCond = condDup(cur);				if (!t2)				{					t2 = tail = newCond;				}				else				{					tail->next = newCond;					tail = newCond;				}				strcpy(buf, newCond->table);				strcpy(newCond->table, 					newCond->value->val.identVal->seg1);				strcpy(newCond->value->val.identVal->seg1, buf);					strcpy(buf, newCond->name);				strcpy(newCond->name, 					newCond->value->val.identVal->seg2);				strcpy(newCond->value->val.identVal->seg2, buf);			}			cur = cur->next;		}	}	new.head = head;	new.t1 = t1;	new.t2 = t2;	return(&new);}static cache_t *joinTables(server, table1,table2, query)	msqld		*server;	cache_t		*table1,			*table2;	mQuery_t	*query;{	cache_t		*tmpTable = NULL,			*outer,			*inner;	int		outerRowNum, 	innerRowNum,			identFList[MAX_FIELDS],			t1Partial,	t2Partial,			doPartial,	res;	mCond_t		*newCondHead, 			*t1CondHead, 	*t2CondHead, 				*outerConds, 	*innerConds,			*newCond, 	*curCond;	mField_t	*curField, 	*tmpField,			*identFields;	row_t		outerRow, 	innerRow,			*row;	mCand_t		*outerCand, 	*innerCand,			*t1Cand,	*t2Cand;	mQuery_t	t1Query,	t2Query;	join_t		*joinInfo;        debugTrace(TRACE_IN,"joinTables()");	if (query->explainOnly)	{		snprintf(packet,PKT_LEN,"Joining %s and %s.\n",			table1->table, table2->table);		netWritePacket(query->clientSock);	}	/*	** Work out the conditions that apply to the join as a whole and	** the two tables individually	if (utilSetupConds(table1,query->condHead) < 0)	{		return(NULL);	}	if (utilSetupConds(table2,query->condHead) < 0)	{		return(NULL);	}	*/	joinInfo = setupJoinConditions(table1, table2, query->condHead, 		query->tableHead);	newCondHead = joinInfo->head;	t1CondHead = joinInfo->t1;	t2CondHead = joinInfo->t2;	if(utilSetupConds(table1,t1CondHead) < 0)	{		return(NULL);	}	if(utilSetupConds(table2,t2CondHead) < 0)	{		return(NULL);	}	/*	** See if we can do partial match optimisation on either table	*/	t1Partial = checkForPartialMatch(t1CondHead);	t2Partial = checkForPartialMatch(t2CondHead);	/*	** What about index based lookups?  Look for a straight literal	** index first and then an IDENT based key if we don't have	** anything.  If we end up with 2 IDENT based indices then we	** drop the first and make it sequential.	*/	bzero(&t1Query, sizeof(t1Query));	bzero(&t2Query, sizeof(t2Query));	if (query->explainOnly)	{		sprintf(packet,"Doing candidate setup for table 1 (%s)\n",			table1->table);		netWritePacket(query->clientSock);		strcpy(packet,"Check for literal based index lookups\n");		netWritePacket(query->clientSock);	}	t1Query.condHead = t1CondHead;	t1Query.explainOnly = query->explainOnly;	t1Cand = craSetupCandidate(table1, &t1Query, IGNORE_IDENT);	if (!t1Cand)		return(NULL);	if (t1Cand->type == CAND_SEQ)	{		if (query->explainOnly)		{			strcpy(packet,"Current access method is sequential.");			strcat(packet,"  Checking for ident index lookup.\n");			netWritePacket(query->clientSock);		}		craFreeCandidate(t1Cand);		t1Cand = craSetupCandidate(table1, &t1Query, KEEP_IDENT);		if (query->explainOnly)		{			if (t1Cand->type == CAND_SEQ)				strcpy(packet,"No.  Still using sequential.\n");			else				strcpy(packet,					"Using ident based index lookup.\n");			netWritePacket(query->clientSock);		}	}	if (!t1Cand)		return(NULL);	if (query->explainOnly)	{		sprintf(packet,"Doing candidate setup for table 2 (%s)\n",			table2->table);		netWritePacket(query->clientSock);		strcpy(packet,"Check for literal based index lookups\n");		netWritePacket(query->clientSock);	}	t2Query.condHead = t2CondHead;	t2Query.explainOnly = query->explainOnly;	t2Cand = craSetupCandidate(table2, &t2Query, IGNORE_IDENT);	if (!t2Cand)	{		craFreeCandidate(t1Cand);		return(NULL);	}	if (t2Cand->type == CAND_SEQ)	{		if (query->explainOnly)		{			strcpy(packet,"Current access method is sequential.");			strcat(packet,"  Checking for ident index lookup.\n");			netWritePacket(query->clientSock);		}		craFreeCandidate(t2Cand);		t2Cand=craSetupCandidate(table2,&t2Query, KEEP_IDENT);		if (query->explainOnly)		{			if (t2Cand->type == CAND_SEQ)				strcpy(packet,"No.  Still using sequential.\n");			else				strcpy(packet,					"Using ident based index lookup.\n");			netWritePacket(query->clientSock);		}	}	if (!t2Cand)	{		craFreeCandidate(t1Cand);		return(NULL);	}	if (t1Cand->type > CAND_SEQ && t2Cand->type > CAND_SEQ)	{		if (t1Cand->ident && t2Cand->ident)		{			t1Cand->type = CAND_SEQ;			t1Cand->lastPos = NO_POS;		}	}	/*	** OK, we know all there is to know.  Now what can we do with it?	*/	if (t1Cand->type > CAND_SEQ)	{		/* We've got an index on T1 */		if (t1Cand->ident == 0)		{			if (query->explainOnly)			{				strcpy(packet,"Checking ident order on table 2 and rerunning candidate setup.\n");				netWritePacket(query->clientSock);			}			if (swapIdentConds(&t1CondHead, &t2CondHead, query) > 0)			{				utilSetupConds(table1,t1CondHead);				utilSetupConds(table2,t2CondHead);			}			outer = table1;			outerConds = t1CondHead;			outerCand = t1Cand;			inner = table2;			innerConds = t2CondHead;			craFreeCandidate(t2Cand);			t2Cand=craSetupCandidate(table2, &t2Query, KEEP_IDENT);			innerCand = t2Cand;			doPartial = 0;		}		else		{			if (query->explainOnly)			{				strcpy(packet,"Checking ident order on table 2 and rerunning candidate setup.\n");				netWritePacket(query->clientSock);			}			if (swapIdentConds(&t2CondHead, &t1CondHead,query) > 0)			{				utilSetupConds(table1,t1CondHead);				utilSetupConds(table2,t2CondHead);			}			outer = table2;			outerConds = t2CondHead;			outerCand = t2Cand;			inner = table1;			innerConds = t1CondHead;			craFreeCandidate(t1Cand);			t1Cand=craSetupCandidate(table1, &t1Query, KEEP_IDENT);			innerCand = t1Cand;			doPartial = 0;		}	} else 	if (t2Cand->type > CAND_SEQ)	{		/* We've got an index on T2 */		if (t2Cand->ident == 0)		{			if (swapIdentConds(&t2CondHead, &t1CondHead,query) > 0)			{				utilSetupConds(table1,t1CondHead);				utilSetupConds(table2,t2CondHead);			}			outer = table2;			outerConds = t2CondHead;			outerCand = t2Cand;			inner = table1;			innerConds = t1CondHead;			craFreeCandidate(t1Cand);			t1Cand=craSetupCandidate(table1, &t1Query, KEEP_IDENT);			innerCand = t1Cand;			doPartial = 0;		}		else		{			if (swapIdentConds(&t1CondHead, &t2CondHead,query) > 0)			{				utilSetupConds(table1,t1CondHead);				utilSetupConds(table2,t2CondHead);			}			outer = table1;			outerConds = t1CondHead;			outerCand = t1Cand;			inner = table2;			innerConds = t2CondHead;			craFreeCandidate(t2Cand);			t2Cand=craSetupCandidate(table2, &t2Query, KEEP_IDENT);			innerCand = t2Cand;			doPartial = 0;		}	} else 	if (t1Partial)	{		/* We've got a partial match on T1 */		outer = table1;		outerConds = t1CondHead;		outerCand = t1Cand;		inner = table2;		innerConds = t2CondHead;		innerCand = t2Cand;		doPartial = 1;	} else 	if (t2Partial)	{		/* We've got a partial match on T2 */		outer = table2;		outerConds = t2CondHead;		outerCand = t2Cand;		inner = table1;		innerConds = t1CondHead;		innerCand = t1Cand;		doPartial = 1;	}	else	{		/* We've got nothing to speed this up */		outer = table1;		outerConds = t1CondHead;		outerCand = t1Cand;		inner = table2;		innerConds = t2CondHead;		innerCand = t2Cand;		doPartial = 0;	} 			/*	** Now that we know the inner table, we need to create a field	** list containing the fields from the outer table that are used	** as IDENT_TYPE conditions for the inner table.  Without this	** we can't do candidate based lookups for the inner table.	*/	identFields = buildIdentList(outer, innerConds, identFList);	/*	** Create a table definition for the join result.  We can't do	** this earlier as we must know which is the inner and outer table	*/	tmpTable = tableCreateTmpTable(server, NULL, NULL, outer,inner,		query->fieldHead,ALL_FIELDS);	if (!tmpTable)	{		craFreeCandidate(innerCand);		craFreeCandidate(outerCand);        	debugTrace(TRACE_OUT,"joinTables()");		return(NULL);	}	(void)snprintf(tmpTable->resInfo,4 * (NAME_LEN + 1),		"'%s (%s+%s)'",tmpTable->table, table1->table, table2->table);	/*	** Do the join	*/	row = &(tmpTable->row);	if (utilSetupConds(tmpTable,newCondHead) < 0)	{		craFreeCandidate(innerCand);		craFreeCandidate(outerCand);		tableFreeTmpTable(server,tmpTable);        	debugTrace(TRACE_OUT,"joinTables()");		return(NULL);	}	if (query->explainOnly)	{		strcpy(packet,"Starting join\n");		netWritePacket(query->clientSock);	}	outerRowNum = craGetCandidate(outer, outerCand);	while(outerRowNum != NO_POS)	{		tableReadRow(outer,&outerRow,outerRowNum);		/*		** Dodge holes 		*/		if (!outerRow.header->active)		{			outerRowNum = craGetCandidate(outer, outerCand);			continue;		}		/* 		** Partial match optimisation ??		*/		if(doPartial)		{			if(compareMatchRow(outer,&outerRow,outerConds,query)!=1)			{				outerRowNum = craGetCandidate(outer, outerCand);				continue;			}		}		/*		** Go ahead and join this row with the inner table		*/		tableExtractValues(outer,&outerRow,identFields,identFList,			query);		if (craSetCandidateValues(inner, innerCand, identFields, 			innerConds, &outerRow, query) < 0)		{			tableFreeTmpTable(server, tmpTable);			craFreeCandidate(innerCand);			craFreeCandidate(outerCand);			return(NULL);		}		craResetCandidate(innerCand, 0);		innerRowNum = craGetCandidate(inner, innerCand);		while(innerRowNum != NO_POS)		{			tableReadRow(inner,&innerRow,innerRowNum);			if (!innerRow.header->active)			{				innerRowNum = craGetCandidate(inner, innerCand);				continue;			}			row->header->active = 1;			mergeRows(tmpTable,row,outer,&outerRow,inner,&innerRow,				query);			res=compareMatchRow(tmpTable,row,newCondHead,query);			if (res < 0)			{				craFreeCandidate(innerCand);				craFreeCandidate(outerCand);				tableFreeTmpTable(server, tmpTable);        			debugTrace(TRACE_OUT,"joinTables()");				return(NULL);			}			if (res == 1)			{				if(tableWriteRow(tmpTable,NULL,NO_POS,query)<0)				{					tableFreeTmpTable(server, tmpTable);					craFreeCandidate(outerCand);					craFreeCandidate(innerCand);        				debugTrace(TRACE_OUT,"joinTables()");					return(NULL);				}			}			innerRowNum = craGetCandidate(inner, innerCand);		}		outerRowNum = craGetCandidate(outer, outerCand);	}	craFreeCandidate(innerCand);	craFreeCandidate(outerCand);	/*	** Free up the space allocated to the new condition list.	** We don't need to free the value structs as we just copied	** the pointers to them.  They'll be freed during msqlClen();	*/	curCond = newCondHead;	while(curCond)	{                newCond = curCond;                curCond = curCond->next;		if (newCond->value)		{			parseFreeValue(newCond->value);			newCond->value = NULL;		}                memFreeCondition(newCond);	}	curCond = t1CondHead;	while(curCond)	{                newCond = curCond;                curCond = curCond->next;		if (newCond->value)		{			parseFreeValue(newCond->value);			newCond->value = NULL;		}                memFreeCondition(newCond);	}	curCond = t2CondHead;	while(curCond)	{                newCond = curCond;                curCond = curCond->next;		if (newCond->value)		{			parseFreeValue(newCond->value);			newCond->value = NULL;		}                memFreeCondition(newCond);	}	if (identFields)	{		curField = identFields;		while(curField)		{			tmpField = curField;			curField = curField->next;			if (tmpField->value)			{				parseFreeValue(tmpField->value);					tmpField->value = NULL;			}			memFreeField(tmpField);		}	}	if (query->explainOnly)	{		sprintf(packet,"Join complete - result in %s\n",			tmpTable->table);		netWritePacket(query->clientSock);	}	debugTrace(TRACE_OUT,"joinTables()");	return(tmpTable);}static int doSelect(cacheEntry, query, dest, checkConds, tmpTable)	cache_t		*cacheEntry;	mQuery_t	*query;	int		dest,			checkConds;	cache_t		*tmpTable;{	int	flist[MAX_FIELDS],		tmpFlist[MAX_FIELDS],		rowLen,		rowNum,		numFields,		abortSelect,		count,		res;	char	outBuf[100],		outBuf2[100],		*fieldName;	row_t	row;	mCand_t	*candidate;	mField_t *identFields;	mField_t *curField;	debugTrace(TRACE_IN,"doSelect()");	identFields = NULL;		numFields = 0;	curField = query->fieldHead;	while(curField)	{		numFields++;		curField = curField->next;	}	/*	** Find the offsets of the given fields and condition	*/	if (utilSetupFields(cacheEntry,flist,query->fieldHead) < 0)	{		debugTrace(TRACE_OUT,"doSelect()");		return(-1);	}	if (checkConds)	{		if (utilSetupConds(cacheEntry,query->condHead) < 0)		{			debugTrace(TRACE_OUT,"doSelect()");			return(-1);		}	}	if (tmpTable)	{		if (utilSetupFields(tmpTable,tmpFlist,query->fieldHead) < 0)		{			debugTrace(TRACE_OUT,"doSelect()");			return(-1);		}	}	candidate = craSetupCandidate(cacheEntry, query, IGNORE_IDENT);	if (!candidate)	{		return(-1);	}	rowLen = cacheEntry->rowLen;	if (tableInitTable(cacheEntry,FULL_REMAP) < 0)	{		craFreeCandidate(candidate);		debugTrace(TRACE_OUT,"doSelect()");		return(-1);	}	if (functCheckFunctions(query) < 0)	{		craFreeCandidate(candidate);		debugTrace(TRACE_OUT,"doSelect()");		return(-1);	}	/*	** Tell the client how many fields there are in a row	*/	if (dest == DEST_CLIENT && !query->explainOnly)	{		snprintf(packet,PKT_LEN,"1:%d:\n",numFields);		netWritePacket(query->clientSock);	}	/*	** Special case for singe field sys var access.  Check the comments	** in craSetupCandidate() for info on why this is needed

⌨️ 快捷键说明

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