📄 select.c
字号:
*/ 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 + -