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

📄 select.c

📁 uClinux下用的数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
	*/	if (candidate->type == CAND_SYS_VAR)	{		tableExtractValues(cacheEntry, NULL, query->fieldHead, flist,			query);		utilFormatPacket(packet, query->fieldHead);		netWritePacket(query->clientSock);		netEndOfList(query->clientSock);		/*		** Send the field info down the line to the client		*/		snprintf(outBuf,sizeof(outBuf),"%d",query->fieldHead->length);		snprintf(outBuf2,sizeof(outBuf2),"%d",query->fieldHead->type);		snprintf(packet,PKT_LEN,"%d:%s%d:%s%d:%s%d:%s1:%s1:%s", 			(int)strlen(query->fieldHead->table),			query->fieldHead->table,			(int)strlen(query->fieldHead->name),			query->fieldHead->name, 			(int)strlen(outBuf2), outBuf2,			(int)strlen(outBuf), outBuf, 			query->fieldHead->flags & NOT_NULL_FLAG ? "Y":"N",			" ");		netWritePacket(query->clientSock);		netEndOfList(query->clientSock);		debugTrace(TRACE_OUT,"doSelect()");		craFreeCandidate(candidate);		return(0);	}	/*	** OK, no more wierd stuff.  Just do the usual.  If for some	** reason the client socket is closed during all this (e.g. it 	** gets force closed due to a SIGPIPE) then break out of the loop	*/	abortSelect = 0;	count = 0;	rowNum = craGetCandidate(cacheEntry, candidate);	while (rowNum != NO_POS && abortSelect == 0)	{		tableReadRow(cacheEntry,&row,rowNum);		if (row.header->active)		{			if (checkConds)			{				res = compareMatchRow(cacheEntry,&row,					query->condHead, query);			}			else			{				res = compareMatchRow(cacheEntry,&row,					NULL, query);			}			if (res < 0)			{				craFreeCandidate(candidate);				return(-1);			}			if (res == 1)			{				tableExtractValues(cacheEntry, 					&row,query->fieldHead,flist,query);				functProcessFunctions(cacheEntry,query);				if (dest == DEST_CLIENT)				{				    if (!query->explainOnly &&				    	 count >= query->rowOffset)				    {					utilFormatPacket(packet, 						query->fieldHead);					if(netWritePacket(query->clientSock)<0)					{						abortSelect = 1;						continue;					}				    }				}				else				{					bzero(tmpTable->row.data,						tmpTable->rowLen);					tableFillRow(cacheEntry,						&(tmpTable->row),						query->fieldHead, tmpFlist);					tableWriteRow(tmpTable,NULL,NO_POS,						query);				}				count++;			}		}		if (dest == DEST_CLIENT && query->rowLimit > 0)		{			if (count == query->rowLimit + query->rowOffset)				break;		}		rowNum = craGetCandidate(cacheEntry, candidate);	}	if (dest == DEST_CLIENT && !query->explainOnly)	{		netEndOfList(query->clientSock);		/*		** Send the field info down the line to the client		*/		curField = query->fieldHead;		while(curField)		{			if (curField->function)			{				if (*curField->function->outputName)					fieldName = 						curField->function->outputName;				else					fieldName = curField->function->name;			}			else			{				fieldName = curField->name;			}			snprintf(outBuf,sizeof(outBuf),"%d",curField->length);			snprintf(outBuf2,sizeof(outBuf2),"%d",curField->type);			snprintf(packet,PKT_LEN,"%d:%s%d:%s%d:%s%d:%s1:%s1:%s", 				(int)strlen(curField->table), curField->table,				(int)strlen(fieldName), fieldName,				(int)strlen(outBuf2), outBuf2,				(int)strlen(outBuf), outBuf, 				curField->flags & NOT_NULL_FLAG ? "Y":"N",				" ");			netWritePacket(query->clientSock);			curField = curField->next;		}		netEndOfList(query->clientSock);	}	else	{		if (query->explainOnly)		{			netEndOfList(query->clientSock);		}	}	debugTrace(TRACE_OUT,"doSelect()");	craFreeCandidate(candidate);	return(0);}static int checkConds(conds, tables)	mTable_t	*tables;	mCond_t	*conds;{	mCond_t	*curCond;	mTable_t	*curTable;		curCond = conds;	while(curCond)	{		if (curCond->subCond)		{			if (checkConds(curCond->subCond, tables) < 0)				return(-1);			curCond = curCond->next;			continue;		}		curTable = tables;		while(curTable)		{			if ( *(curCond->table) != *(curTable->name))			{				curTable = curTable->next;				continue;			}			if (strcmp(curCond->table,curTable->name) != 0)			{				curTable = curTable->next;				continue;			}			break;		}		if (!curTable)		{			snprintf(errMsg,MAX_ERR_MSG, UNSELECT_ERROR,				(char *)curCond->table);			return(-1);		}		curCond = curCond->next;	}	return(0);}/**************************************************************************** PUBLIC ROUTINES**************************************************************************/int selectProcessSelect(server, query)	msqld		*server;	mQuery_t	*query;{	cache_t		*cacheEntry,			*table1,			*table2,			*tmpTable;	mTable_t	*curTable;	mField_t	*curField;	int		join,			foundTable;	debugTrace(TRACE_IN,"selectProcessSelect()");	/*	** Check out the tables and fields specified in the query.  If	** multiple tables are specified all field specs must be	** qualified and they must reference a selected table.	*/	if (query->tableHead->next)	{		if (query->explainOnly)		{			strcpy(packet,"Query is a join.\n");			netWritePacket(query->clientSock);			strcpy(packet,"Original table order is :\n");			netWritePacket(query->clientSock);			curTable = query->tableHead;			while(curTable)			{				if (*curTable->cname)				{					snprintf(packet,PKT_LEN,"\t%s (%s)\n",						curTable->name, 						curTable->cname);				}				else				{					snprintf(packet,PKT_LEN,"\t%s\n",						curTable->name) ;				}				netWritePacket(query->clientSock);				curTable = curTable->next;			}		}		join = 1;		query->tableHead = (mTable_t *)craReorderTableList(query);		if (query->explainOnly)		{			strcpy(packet,"Table list reorder completed.\n");			netWritePacket(query->clientSock);			strcpy(packet,"New table order is :\n");			netWritePacket(query->clientSock);			curTable = query->tableHead;			while(curTable)			{				if (*curTable->cname)				{					snprintf(packet,PKT_LEN,"\t%s (%s)\n",						curTable->name, 						curTable->cname);				}				else				{					snprintf(packet,PKT_LEN,"\t%s\n",						curTable->name) ;				}				netWritePacket(query->clientSock);				curTable = curTable->next;			}		}	}	else	{		/*		** If there's no joins ensure that each condition and field		** is fully qualified with the correct table		*/		utilQualifyFields(query);		utilQualifyConds(query);		utilQualifyOrder(query);		join = 0;		if (query->explainOnly)		{			strcpy(packet,"Query is not a join.\n");			netWritePacket(query->clientSock);		}	}	curTable = query->tableHead;	tmpTable = NULL;	/*	** Ensure that any field or condition refers to fields of 	** selected tables	*/	if (checkFieldTable(query->fieldHead,query) < 0)	{		debugTrace(TRACE_OUT,"selectProcessSelect()");		return(-1);	}	if (checkConds(query->condHead,query->tableHead) < 0)	{		debugTrace(TRACE_OUT,"selectProcessSelect()");		return(-1);	}	curField = query->fieldHead;	while (curField)	{		if (strcmp(curField->name, "*") == 0)		{			curField = curField->next;			continue;		}		if (*(curField->table) == 0)		{			if (join)			{				snprintf(errMsg, MAX_ERR_MSG, 					UNQUAL_JOIN_ERROR, curField->name);				debugTrace(TRACE_OUT,"selectProcessSelect()");				return(-1);			}			curField = curField->next;			continue;		}		curTable = query->tableHead;		foundTable = 0;		while(curTable)		{			if ( *(curTable->name) != *(curField->table))			{				curTable = curTable->next;				continue;			}			if (strcmp(curTable->name,curField->table) != 0)			{				curTable = curTable->next;				continue;			}			foundTable = 1;			break;		}		if (!foundTable)		{			snprintf(errMsg,MAX_ERR_MSG,UNSELECT_ERROR, 				curField->table);			debugTrace(TRACE_OUT,"selectProcessSelect()");			return(-1);		}		curField = curField->next;	}	/*	** If there's multiple tables, join the suckers.	*/	if (join)	{		curTable = query->tableHead;		while(curTable)		{			if (curTable == query->tableHead)			{				table1 = tableLoadDefinition(server,					curTable->name, curTable->cname,					query->curDB);				if (!table1)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}				if (tableInitTable(table1,FULL_REMAP) < 0)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}				curTable = curTable->next;				table2 = tableLoadDefinition(server,					curTable->name, curTable->cname,					query->curDB);				if (!table2)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}				if (tableInitTable(table2,FULL_REMAP) < 0)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}				if (!table1 || !table2)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}				setJoinTableDone(query->tableHead,					table1->table);				setJoinTableDone(query->tableHead,					table2->table);				tmpTable=joinTables(server,table1,table2,query);				if (!tmpTable)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}			}			else			{				table1 = tmpTable;				table2 = tableLoadDefinition(server,					curTable->name, curTable->cname,					query->curDB);				if (!table2)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}				if (tableInitTable(table1,FULL_REMAP) < 0)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}				if (tableInitTable(table2,FULL_REMAP) < 0)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}				setJoinTableDone(query->tableHead,					table1->table);				setJoinTableDone(query->tableHead,					table2->table);				tmpTable=joinTables(server,table1,table2,query);				if (table1->result)				{					tableFreeTmpTable(server, table1);				}				if (!tmpTable)				{					debugTrace(TRACE_OUT,						"selectProcessSelect()");					return(-1);				}			}			curTable = curTable->next;		}	}	/*	** Perform the actual select.  If there's an order clause or	** a pending DISTINCT, send the results to a table for further 	** processing.	**	** Look for the wildcard field spec.  Must do this before we	** "setup" because it edits the field list.  selectWildcard	** is a global set from inside the yacc parser.  Wild card	** expansion is only called if this is set otherwise it will	** consume 50% of the execution time of selects!	*/	if (!tmpTable)	{		if((cacheEntry = tableLoadDefinition(server, 			query->tableHead->name, query->tableHead->cname, 			query->curDB)) == NULL)		{			debugTrace(TRACE_OUT,"selectProcessSelect()");			return(-1);		}	}	else	{		cacheEntry = tmpTable;	}	if (query->selectWildcard)	{			query->fieldHead = utilExpandFieldWildCards(cacheEntry,			query->fieldHead);	}	utilSetFieldInfo(cacheEntry, query->fieldHead);	if (!query->orderHead && !query->selectDistinct && !query->targetTable)	{		if (doSelect(cacheEntry,query, DEST_CLIENT, BOOL_TRUE, NULL)<0)		{			if(cacheEntry->result)				tableFreeTmpTable(server, cacheEntry);			debugTrace(TRACE_OUT,"selectProcessSelect()");			return(-1);		}		if (cacheEntry->result)		{			tableFreeTmpTable(server, cacheEntry);		}		debugTrace(TRACE_OUT,"selectProcessSelect()");		return(0);	}	/*	** From here on we just want a table with the required fields	** (i.e. not all the fields of a join)	*/	tmpTable = tableCreateTmpTable(server, NULL, NULL, cacheEntry,NULL,		query->fieldHead, QUERY_FIELDS_ONLY);	if (!tmpTable)	{		if (cacheEntry->result)			tableFreeTmpTable(server, cacheEntry);		return(-1);	}	(void)snprintf(tmpTable->resInfo, 4 * (NAME_LEN + 1),		"'%s (stripped %s)'", tmpTable->table,cacheEntry->table);	if (doSelect(cacheEntry,query, DEST_TABLE, BOOL_TRUE, tmpTable) < 0)	{		if (cacheEntry->result)			tableFreeTmpTable(server, cacheEntry);		tableFreeTmpTable(server, tmpTable);		debugTrace(TRACE_OUT,"selectProcessSelect()");		return(-1);	}	if (cacheEntry->result)	{		tableFreeTmpTable(server, cacheEntry);	}	cacheEntry = tmpTable;	/*	** Blow away multiples if required	*/	if (query->selectDistinct)	{		if (distinctCreateTable(server, cacheEntry) < 0)		{			if(cacheEntry->result)				tableFreeTmpTable(server, cacheEntry);			debugTrace(TRACE_OUT,"selectProcessSelect()");			return(-1);		}	}		/*	** Sort the result if required	*/	if (query->orderHead)	{		if (sortCreateSortedTable(server, cacheEntry,query) < 0)		{			if(cacheEntry->result)				tableFreeTmpTable(server, cacheEntry);			debugTrace(TRACE_OUT,"selectProcessSelect()");			return(-1);		}	}	/*	** Send the result to the client if we haven't yet.	*/	if (query->targetTable != NULL)	{		/* 		** The data is already in a tmp table.  All we have to		** do is move the existing tmp table into place and		** create the definition file.  First, ensure that what		** we have is sane from a normal tables point of view.		*/		char	oldPath[255],			newPath[255];		if (tableCheckTargetDefinition(query) < 0)		{			if(cacheEntry->result)				tableFreeTmpTable(server, cacheEntry);			debugTrace(TRACE_OUT,"selectProcessSelect()");			return(-1);		}		if (tableCreateDefinition(server,query->targetTable,query)<0)		{			if(cacheEntry->result)				tableFreeTmpTable(server, cacheEntry);			debugTrace(TRACE_OUT,"selectProcessSelect()");			return(-1);		}		snprintf(oldPath,255,"%s/.tmp/%s.dat",server->config.dbDir,			cacheEntry->table);		snprintf(newPath,255,"%s/%s/%s.dat",server->config.dbDir,			query->curDB, query->targetTable);		if (rename(oldPath, newPath) < 0)		{			if(cacheEntry->result)				tableFreeTmpTable(server, cacheEntry);			debugTrace(TRACE_OUT,"selectProcessSelect()");			return(-1);		}		strcpy(packet,"1\n");		netWritePacket(query->clientSock);	}	else	{		/* Send this to the client */		if (doSelect(cacheEntry,query,DEST_CLIENT,BOOL_FALSE,NULL)<0)		{			if(cacheEntry->result)				tableFreeTmpTable(server, cacheEntry);			debugTrace(TRACE_OUT,"selectProcessSelect()");			return(-1);		}	}	/*	** Free the result table	*/	if (cacheEntry->result)	{		tableFreeTmpTable(server, cacheEntry);	}	debugTrace(TRACE_OUT,"selectProcessSelect()");	return(0);}

⌨️ 快捷键说明

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