📄 parse.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: parse.c,v 1.23 2003/01/13 21:21:38 bambi Exp $***//*** Module : main : parse** 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#include <common/portability.h>#include <common/libc_stuff/c_stuff.h>/**************************************************************************** MODULE SPECIFIC INCLUDES**************************************************************************/#include <common/msql_defs.h>#include <common/debug/debug.h>#include <msqld/index/index.h>#include <msqld/includes/msqld.h>#include <msqld/includes/errmsg.h>#include <msqld/main/main.h>#include <msqld/main/yaccer.h>#include <msqld/main/lexer.h>#include <msqld/main/sysvar.h>#include <msqld/main/util.h>#include <msqld/main/net.h>#include <msqld/main/parse.h>#include <msqld/main/memory.h>#include <common/types/types.h>#include <libmsql/msql.h>/**************************************************************************** GLOBAL VARIABLES**************************************************************************/static cstk_t *condStack = NULL;static int insertOffset = 0;int yyparse();unsigned long local_strtoul();/**************************************************************************** PRIVATE ROUTINES**************************************************************************/static void _cleanCond(curCond) mCond_t *curCond;{ mCond_t *tmpCond; while(curCond) { if (curCond->subCond != NULL) { _cleanCond(curCond->subCond); curCond->subCond = NULL; } parseFreeValue(curCond->value); curCond->value = NULL; curCond->op = curCond->bool = 0; tmpCond = curCond; curCond = curCond->next; tmpCond->next = NULL; memFreeCondition(tmpCond); }}static void _cleanFields(curField) mField_t *curField;{ mField_t *tmpField; while(curField) { parseFreeValue(curField->value); if (curField->function) { _cleanFields(curField->function->paramHead); free(curField->function); curField->function = NULL; } curField->value = NULL; tmpField = curField; curField = curField->next; tmpField->next = NULL; memFreeField(tmpField); }}static u_char expandEscape(c,remain) u_char *c; int remain;{ u_char ret; switch(*c) { case 'n': ret = '\n'; break; case 't': ret = '\t'; break; case 'r': ret = '\r'; break; case 'b': ret = '\b'; break; default: ret = *c; break; } return(ret);}/**************************************************************************** PUBLIC ROUTINES**************************************************************************//****************************************************************************** parseCleanQuery - clean out the internal structures**** Purpose : Free all space and reset structures after a query** Args : None** Returns : Nothing** Notes : Updates all public data structures*/void parseCleanQuery(query) mQuery_t *query;{ register mTable_t *curTable, *tmpTable; register mOrder_t *curOrder, *tmpOrder; register mValList_t *curValue, *tmpValue; register mField_t *curField; extern u_char *yyprev, *yytext; debugTrace(TRACE_IN,"parseCleanQuery()"); if (yyprev) { free(yyprev); yyprev = NULL; } yytext = NULL; /* ** blow away the table list from the query */ curTable = query->tableHead; while(curTable) { tmpTable = curTable; curTable = curTable->next; tmpTable->next = NULL; memFreeTable(tmpTable); } /* ** Blow away the insert value list */ if (query->insertValHead) { /* ** Ensure that none of these value pointers ** are referenced from the field list so that ** we don't double free them */ curField = query->fieldHead; while(curField) { curField->value = NULL; curField = curField->next; } } curValue = query->insertValHead; while(curValue) { tmpValue = curValue; curValue = curValue->next; parseFreeValue(tmpValue->value); tmpValue->next = NULL; memFreeValList(tmpValue); } /* ** blow away the field list from the query */ _cleanFields(query->fieldHead); /* ** Blow away the condition list from the query (recurse for ** subconds) */ _cleanCond(query->condHead); /* ** Blow away the order list from the query */ curOrder = query->orderHead; while(curOrder) { curOrder->dir = 0; tmpOrder = curOrder; curOrder = curOrder->next; tmpOrder->next = NULL; memFreeOrder(tmpOrder); } /* ** Reset the list pointers */ sysvarResetVariables(); query->fieldHead = NULL; query->condHead = NULL; query->tableHead = NULL; query->orderHead = NULL; query->insertValHead = NULL; memFreeQuery(query); debugTrace(TRACE_OUT,"parseClean()");}mIdent_t *parseCreateIdent(seg1,seg2,query) char *seg1, *seg2; mQuery_t *query;{ mIdent_t *new; debugTrace(TRACE_IN,"parseCreateIdent()"); if (seg1) { if ((int)strlen(seg1) > NAME_LEN) { netError(query->clientSock, "Identifier name '%s' too long\n",seg1); debugTrace(TRACE_OUT,"parseCreateIdent()"); return(NULL); } } if (seg2) { if ((int)strlen(seg2) > NAME_LEN) { netError(query->clientSock, "Identifier name '%s' too long\n",seg2); debugTrace(TRACE_OUT,"parseCreateIdent()"); return(NULL); } } new = memMallocIdent(); if (seg1) { (void)strncpy(new->seg1,seg1,NAME_LEN); } else { *(new->seg1) = 0; } if (seg2) { (void)strncpy(new->seg2,seg2, NAME_LEN); } else { *(new->seg1) = 0; } debugTrace(TRACE_OUT,"parseCreateIdent()"); return(new);}mVal_t *parseCreateValue(textRep,type,tokLen) u_char *textRep; int type, tokLen;{ mVal_t *new; int length, remain, escCount, res; register u_char *cp, *cp2; char *cp3; debugTrace(TRACE_IN,"parseCreateValue()"); new = memMallocValue(); new->type = type; new->dataLen = tokLen; new->nullVal = 0; new->precision = 0; new->val.charVal = NULL; switch(type) { case NULL_TYPE: new->nullVal = 1; break; case IDENT_TYPE: case SYSVAR_TYPE: new->val.identVal = (mIdent_t *)textRep; break; case CHAR_TYPE: remain = length = tokLen - 2; escCount = 0; new->val.charVal = (u_char *)malloc(length+1); cp = textRep+1; cp2 = new->val.charVal; while(remain) { if (*cp == '\\') { escCount ++; remain--; *cp2 = expandEscape(++cp,remain); if (*cp2) { cp2++; cp++; remain--; } } else { *cp2++ = *cp++; remain--; } } *cp2 = 0; new->dataLen = tokLen - 2 - escCount; break; case INT_TYPE: case INT64_TYPE: new->type = INT_TYPE; new->val.intVal=local_strtoul((char *)textRep,NULL,10, &res);#ifdef HUGE_T if (res < 0) { new->val.intVal = 0; new->type = INT64_TYPE; strtohuge((char *)textRep, &new->val.int64Val); }#endif break; case UINT_TYPE: case UINT64_TYPE: new->type = UINT_TYPE; new->val.intVal=local_strtoul((char *)textRep,NULL,10, &res);#ifdef HUGE_T if (res < 0) { new->val.intVal = 0; new->type = UINT64_TYPE; strtohuge((char *)textRep, &new->val.int64Val); }#endif break; case REAL_TYPE: sscanf((char *)textRep ,"%lg",&new->val.realVal); cp3 = (char *)index(textRep,'.'); if (cp3) { new->precision = strlen(textRep) - (cp3 - (char *)textRep) - 1; if (new->precision < 0) new->precision = 0; } break; } debugTrace(TRACE_OUT,"parseCreateValue()"); return(new);}mVal_t *parseFillValue(val,type,length) char *val; int type, length;{ mVal_t *new; char int8Val; short int16Val; debugTrace(TRACE_IN,"parseFillValue()"); new = memMallocValue(); new->type = type; new->nullVal = 0; switch(typeBaseType(type)) { case CHAR_TYPE: new->val.charVal = (u_char *)malloc(length+1); bcopy(val,new->val.charVal,length); *(new->val.charVal + length) = 0; new->dataLen = strlen(new->val.charVal); break; case INT8_TYPE: case UINT8_TYPE: int8Val = *val; new->val.intVal = int8Val; new->dataLen = length; break; case INT16_TYPE: case UINT16_TYPE: bcopy((char *)val, &int16Val, 2); new->val.intVal = int16Val; new->dataLen = length; break; case INT_TYPE: case UINT_TYPE: new->val.intVal = (int) * (int *)val; new->dataLen = length; break;#ifdef HUGE_T case INT64_TYPE: case UINT64_TYPE: new->val.int64Val = (HUGE_T) * (HUGE_T *)val; new->dataLen = length; break;#endif case REAL_TYPE: new->val.realVal = (double) * (double *)val; new->dataLen = length; break; case BYTE_TYPE: if (length != typeFieldSize(type)) { fprintf(stderr, "parseFillValue : Size mismatch\n"); exit(1); } new->dataLen = length; new->val.byteVal = (void*)malloc(length); bcopy((char *)val, (char *)new->val.byteVal, length); break; default: fprintf(stderr,"parseFillValue : Unknown type %d\n", typeBaseType(type)); exit(1); } debugTrace(TRACE_OUT,"parseFillValue()"); return(new);}int parseCopyValue(cp,value,type,length,nullOK) char *cp; mVal_t *value; int type, length, nullOK;{ int strLen; if (value->nullVal) { if (!nullOK) { return(-1); } else { bzero(cp,length); return(0); } } switch(typeBaseType(type)) { case INT_TYPE: case UINT_TYPE: bcopy(&(value->val.intVal),cp,4); break;#ifdef HUGE_T case INT64_TYPE: case UINT64_TYPE: bcopy(&(value->val.int64Val),cp,sizeof(HUGE_T)); break;#endif case REAL_TYPE: bcopy(&(value->val.realVal),cp,8); break; case CHAR_TYPE: value->val.charVal[value->dataLen]=0; strLen = strlen((char *)value->val.charVal); if (strLen > length) strLen = length; else strLen++; bcopy((char *)value->val.charVal,cp, strLen); break; case BYTE_TYPE: strLen = typeFieldSize(type); if (strLen != length) { fprintf(stderr, "parseFillValue : Size mismatch\n"); exit(1); } bcopy((char *)value->val.charVal,cp, strLen); break; } return(0);}mVal_t *parseCreateNullValue(){ mVal_t *new; new = memMallocValue(); new->nullVal = 1; return(new);}void parseFreeValue(val) mVal_t *val;{ debugTrace(TRACE_IN,"parseFreeValue()"); if (!val) { debugTrace(TRACE_OUT,"parseFreeValue()"); return; } if (!val->nullVal) { switch(val->type) { case IDENT_TYPE: case SYSVAR_TYPE: if (val->val.identVal) { memFreeIdent(val->val.identVal); val->val.identVal = NULL; } break; case CHAR_TYPE: case TEXT_TYPE: if (val->val.charVal) { (void)free(val->val.charVal); val->val.charVal = NULL; } break; } } memFreeValue(val); debugTrace(TRACE_OUT,"parseFreeValue()");}void parseAddSequence(table, step, val, query) char *table; int step, val; mQuery_t *query;{ debugTrace(TRACE_IN,"parseAddSequence()"); strcpy(query->sequenceDef.table,table); query->sequenceDef.step = step; query->sequenceDef.value = val; debugTrace(TRACE_OUT,"parseAddSequence()");}/****************************************************************************** _msqlAddField - add a field definition to the list**** Purpose : store field details from the query for later use** Args : field name, field type, field length, value** Returns : Nothing** Notes : Depending on the query in process, only some of the** args will be supplied. eg. a SELECT doesn't use the** type arg. The length arg is only used during a create** if the field is of type CHAR*/int parseAddField(ident,type,length,notNull,priKey,query) mIdent_t *ident; int type; char *length; int notNull, priKey; mQuery_t *query;{ mField_t *new; char *name, *table; debugTrace(TRACE_IN,"ParseAddField()"); name = ident->seg2; table = ident->seg1; /* ** Look for duplicate field names on a table create. If the ** type is set then we know this is a table creation. */ if (type != 0) { new = query->fieldHead; while(new) { if (strcmp(new->name,name) == 0) { netError(query->clientSock, "Duplicate field name '%s'\n", name); debugTrace(TRACE_OUT,"parseAddField()"); memFreeIdent(ident); return(-1); } new = new->next; } } /* ** Look for the obsolete prinary key construct */ if (priKey) { netError(query->clientSock, "Primary keys are obsolete. Use CREATE INDEX\n"); memFreeIdent(ident); debugTrace(TRACE_OUT,"parseAddField()"); return(-1); } /* ** Create the new field definition */ new = memMallocField(); if (table)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -