📄 select.c
字号:
/*** 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: select.c,v 1.18 2003/02/26 03:11:16 bambi Exp $***//*** Module : main : select** 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/**************************************************************************** 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/main/main.h>#include <msqld/main/yaccer.h>#include <msqld/main/table.h>#include <msqld/main/net.h>#include <msqld/main/util.h>#include <msqld/main/sysvar.h>#include <msqld/main/compare.h>#include <msqld/main/select.h>#include <msqld/main/parse.h>#include <msqld/main/funct.h>#include <msqld/main/distinct.h>#include <msqld/main/sort.h>#include <msqld/main/memory.h>#include <libmsql/msql.h>/**************************************************************************** GLOBAL VARIABLES**************************************************************************//**************************************************************************** PRIVATE ROUTINES**************************************************************************/typedef struct { mCond_t *head, *t1, *t2;} join_t;extern char *packet, errMsg[];static void mergeRows(result,row,table1,t1Row,table2,t2Row,query) cache_t *result; row_t *row, *t1Row, *t2Row; cache_t *table1, *table2; mQuery_t *query;{ mField_t *curField; char *cp; int sysvarRow; /* ** Drag the 2 rows over */ bcopy(t1Row->data,row->data,table1->rowDataLen); bcopy(t2Row->data,row->data+table1->rowDataLen, table2->rowDataLen); cp = (char *)row->data + table1->rowDataLen + table2->rowDataLen; /* ** If there are any system variables in the join result we ** have to manaully add them. tableCreateTmpTable() forces them ** to be at the end of the table row so we just need to append ** to correct values to the newly created row. */ curField = result->def; while(curField) { if (*curField->name == '_') { sysvarRow = 0; if (strcmp(curField->table,table1->table)==0) sysvarRow = 1; if (strcmp(curField->table,table2->table)==0) sysvarRow = 2; if (sysvarRow == 0) { curField = curField->next; continue; } if (sysvarRow == 1) sysvarGetVariable(table1,t1Row,curField,query); else sysvarGetVariable(table2,t2Row,curField,query); *cp = 1; cp++; parseCopyValue(cp,curField->value,curField->type, curField->length,1); cp += curField->length; } curField = curField->next; }}static int checkForPartialMatch(conds) mCond_t *conds;{ mCond_t *curCond; int res; if (!conds) return(0); res = 1; curCond = conds; while(curCond) { if (curCond->value->type == IDENT_TYPE) { return(0); } if (curCond->bool == OR_BOOL) { return(0); } curCond=curCond->next; } return(res);}static mField_t *buildIdentList(entry, conds, flist) cache_t *entry; mCond_t *conds; int *flist;{ mField_t *identFields, *tail, *curField; mCond_t *curCond; int *curOffset; tail = identFields = NULL; curCond = conds; curOffset = flist; while(curCond) { /* ** Find an IDENT cond and setup the field struct */ if (curCond->value->type != IDENT_TYPE) { curCond = curCond->next; continue; } curField = memMallocField(); strcpy(curField->name, curCond->name); strcpy(curField->table, curCond->table); if (tail) { tail->next = curField; } else { identFields = curField; } tail = curField; curField->next = NULL; /* ** Fill in the blanks */ curField = entry->def; *curOffset = 0; while(curField) { if (strcmp(curField->name, curCond->value->val.identVal->seg2)!=0 || strcmp(curField->table, curCond->value->val.identVal->seg1)!=0) { *curOffset += curField->dataLength + 1; curField = curField->next; continue; } tail->dataLength = curField->dataLength; tail->length = curField->length; tail->type = curField->type; tail->offset = *curOffset; tail->fieldID = curCond->fieldID; curOffset++; break; } curCond = curCond->next; } *curOffset = -1; return(identFields);}static int invertOp(op) int op;{ switch(op) { case GT_OP: return(LT_OP); case LT_OP: return(GT_OP); case GE_OP: return(LE_OP); case LE_OP: return(GE_OP); } return(op);}static int swapIdentConds(cond1, cond2, query) mCond_t **cond1, **cond2; mQuery_t *query;{ mCond_t *tail, *cur, *tmp, *prev; mIdent_t *newIdent, *curIdent; int count; tail = prev = NULL; count = 0; cur = *cond2; while (cur) { tail = cur; cur = cur->next; } cur = *cond1; while (cur) { if (cur->value->type == IDENT_TYPE) { /* ** ensure we don't have this already */ tmp = *cond2; while(tmp) { if (tmp->value->type != IDENT_TYPE) { tmp = tmp->next; continue; } curIdent = cur->value->val.identVal; if(*tmp->table != *curIdent->seg1 || *tmp->name != *curIdent->seg2) { tmp=tmp->next; continue; } if(strcmp(tmp->table,curIdent->seg1)!=0 || strcmp(tmp->name,curIdent->seg2)!=0) { tmp = tmp->next; continue; } curIdent = tmp->value->val.identVal; if(strcmp(cur->table,curIdent->seg1)!=0 || strcmp(cur->name,curIdent->seg2)!=0) { tmp = tmp->next; continue; } break; } if (tmp) { /* Dodge it. It's already there! */ cur = cur->next; continue; } count++; newIdent = (mIdent_t *)parseCreateIdent(cur->table, cur->name, query); strcpy(cur->table,cur->value->val.identVal->seg1); strcpy(cur->name,cur->value->val.identVal->seg2); memFreeIdent(cur->value->val.identVal); cur->value->val.identVal = newIdent; cur->op = invertOp(cur->op); if (prev) { prev->next = cur->next; } else { *cond1 = cur->next; } if (tail) { tail->next = cur; } else { *cond2 = cur; } cur->next = NULL; tail = cur; } cur = cur->next; } return(count);}static mCond_t *condDup(cond) mCond_t *cond;{ mCond_t *new; new = memMallocCondition(); bcopy(cond,new,sizeof(mCond_t)); new->value = memMallocValue(); bcopy(cond->value,new->value,sizeof(mVal_t)); new->next = NULL; switch(new->value->type) { case CHAR_TYPE: new->value->val.charVal = (u_char *)strdup( cond->value->val.charVal); break; case IDENT_TYPE: new->value->val.identVal = memMallocIdent(); bcopy(cond->value->val.identVal, new->value->val.identVal, sizeof(mIdent_t)); break; } return(new);}static int checkFieldTable(fields,query) mField_t *fields; mQuery_t *query;{ mField_t *curField; mTable_t *curTable; curField = fields; while(curField) { if (curField->function) { if (checkFieldTable(curField->function->paramHead, query) < 0) { return(-1); } curField = curField->next; continue; } if (strcmp(curField->name, "*") == 0) { curField = curField->next; continue; } curTable = query->tableHead; while(curTable) { if ( *(curField->table) != *(curTable->name)) { curTable = curTable->next; continue; } if (strcmp(curField->table,curTable->name) != 0) { curTable = curTable->next; continue; } break; } if (!curTable) { snprintf(errMsg,MAX_ERR_MSG, UNSELECT_ERROR, curField->table); debugTrace(TRACE_OUT,"checkFieldTable()"); return(-1); } curField = curField->next; } return(0);}static void setJoinTableDone(tables,name) mTable_t *tables; char *name;{ mTable_t *cur; cur = tables; while(cur) { if (strcmp(cur->name, name) == 0) { cur->done = 1; return; } cur = cur->next; } return;}static int checkJoinTableDone(tables,name) mTable_t *tables; char *name;{ mTable_t *cur; cur = tables; while(cur) { if (strcmp(cur->name, name) == 0) { return(cur->done); } cur = cur->next; } return(0);}static join_t *setupJoinConditions(table1, table2, conds, tables) cache_t *table1, *table2; mCond_t *conds; mTable_t *tables;{ mCond_t *head, *tail, *t1, *t2, *cur, *newCond; char buf[NAME_LEN + 1]; static join_t new; /* ** Build a list of all conditions related to the join as a whole */ head = tail = NULL; cur = conds; while(cur) { if (cur->subCond) { cur = cur->next; continue; } if (strcmp(table1->table,cur->table) == 0 || strcmp(table2->table,cur->table) == 0) { if (cur->value->type == IDENT_TYPE) { if (checkJoinTableDone(tables, cur->value->val.identVal->seg1) == 0) { cur = cur->next; continue; } } newCond = condDup(cur); if (!head) { tail = head = newCond; } else { tail->next = newCond; tail = newCond; } cur = cur->next; continue; } if (cur->value->type == IDENT_TYPE && (strcmp(table1->table,cur->value->val.identVal->seg1)==0|| strcmp(table2->table,cur->value->val.identVal->seg1)==0)) { if (checkJoinTableDone(tables,cur->table) == 0) { cur = cur->next; continue; } newCond = condDup(cur); if (!head) { tail = head = newCond; } else { tail->next = newCond; tail = newCond; } cur = cur->next; continue; } cur = cur->next; } /* ** Build a list for T1 if it isn't a result table. */ t1 = tail = NULL; if (table1->result == 0) { cur = head; while(cur) { if (strcmp(table1->table, cur->table) == 0) { newCond = condDup(cur); if (!t1) { t1 = tail = newCond; } else { tail->next = newCond; tail = newCond; } } else if (cur->value->type == IDENT_TYPE && strcmp(table1->table,cur->value->val.identVal->seg1)==0) { newCond = condDup(cur); if (!t1) { t1 = 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; } } /* ** Build a list for T2 if it isn't a result table */ t2 = tail = NULL; if (table2->result == 0) { cur = head; while(cur) { if (strcmp(table2->table, cur->table) == 0) { newCond = condDup(cur); if (!t2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -