175897234Sdrh /* 275897234Sdrh ** Copyright (c) 1999, 2000 D. Richard Hipp 375897234Sdrh ** 475897234Sdrh ** This program is free software; you can redistribute it and/or 575897234Sdrh ** modify it under the terms of the GNU General Public 675897234Sdrh ** License as published by the Free Software Foundation; either 775897234Sdrh ** version 2 of the License, or (at your option) any later version. 875897234Sdrh ** 975897234Sdrh ** This program is distributed in the hope that it will be useful, 1075897234Sdrh ** but WITHOUT ANY WARRANTY; without even the implied warranty of 1175897234Sdrh ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1275897234Sdrh ** General Public License for more details. 1375897234Sdrh ** 1475897234Sdrh ** You should have received a copy of the GNU General Public 1575897234Sdrh ** License along with this library; if not, write to the 1675897234Sdrh ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, 1775897234Sdrh ** Boston, MA 02111-1307, USA. 1875897234Sdrh ** 1975897234Sdrh ** Author contact information: 2075897234Sdrh ** [email protected] 2175897234Sdrh ** http://www.hwaci.com/drh/ 2275897234Sdrh ** 2375897234Sdrh ************************************************************************* 2475897234Sdrh ** An tokenizer for SQL 2575897234Sdrh ** 2675897234Sdrh ** This file contains C code that splits an SQL input string up into 2775897234Sdrh ** individual tokens and sends those tokens one-by-one over to the 2875897234Sdrh ** parser for analysis. 2975897234Sdrh ** 30*c4a3c779Sdrh ** $Id: tokenize.c,v 1.18 2001/04/04 11:48:58 drh Exp $ 3175897234Sdrh */ 3275897234Sdrh #include "sqliteInt.h" 3375897234Sdrh #include <ctype.h> 34dcc581ccSdrh #include <stdlib.h> 3575897234Sdrh 3675897234Sdrh /* 3775897234Sdrh ** All the keywords of the SQL language are stored as in a hash 3875897234Sdrh ** table composed of instances of the following structure. 3975897234Sdrh */ 4075897234Sdrh typedef struct Keyword Keyword; 4175897234Sdrh struct Keyword { 4275897234Sdrh char *zName; /* The keyword name */ 4375897234Sdrh int len; /* Number of characters in the keyword */ 4475897234Sdrh int tokenType; /* The token value for this keyword */ 4575897234Sdrh Keyword *pNext; /* Next keyword with the same hash */ 4675897234Sdrh }; 4775897234Sdrh 4875897234Sdrh /* 4975897234Sdrh ** These are the keywords 5075897234Sdrh */ 5175897234Sdrh static Keyword aKeywordTable[] = { 52fef5208cSdrh { "ALL", 0, TK_ALL, 0 }, 5375897234Sdrh { "AND", 0, TK_AND, 0 }, 5475897234Sdrh { "AS", 0, TK_AS, 0 }, 5575897234Sdrh { "ASC", 0, TK_ASC, 0 }, 56*c4a3c779Sdrh { "BEGIN", 0, TK_BEGIN, 0 }, 57fef5208cSdrh { "BETWEEN", 0, TK_BETWEEN, 0 }, 5875897234Sdrh { "BY", 0, TK_BY, 0 }, 5975897234Sdrh { "CHECK", 0, TK_CHECK, 0 }, 60*c4a3c779Sdrh { "COMMIT", 0, TK_COMMIT, 0 }, 6175897234Sdrh { "CONSTRAINT", 0, TK_CONSTRAINT, 0 }, 62982cef7eSdrh { "COPY", 0, TK_COPY, 0 }, 6375897234Sdrh { "CREATE", 0, TK_CREATE, 0 }, 6475897234Sdrh { "DEFAULT", 0, TK_DEFAULT, 0 }, 6575897234Sdrh { "DELETE", 0, TK_DELETE, 0 }, 66982cef7eSdrh { "DELIMITERS", 0, TK_DELIMITERS, 0 }, 6775897234Sdrh { "DESC", 0, TK_DESC, 0 }, 68efb7251dSdrh { "DISTINCT", 0, TK_DISTINCT, 0 }, 6975897234Sdrh { "DROP", 0, TK_DROP, 0 }, 70*c4a3c779Sdrh { "END", 0, TK_END, 0 }, 7182c3d636Sdrh { "EXCEPT", 0, TK_EXCEPT, 0 }, 7275897234Sdrh { "EXPLAIN", 0, TK_EXPLAIN, 0 }, 7375897234Sdrh { "FROM", 0, TK_FROM, 0 }, 74dce2cbe6Sdrh { "GLOB", 0, TK_GLOB, 0 }, 752282792aSdrh { "GROUP", 0, TK_GROUP, 0 }, 762282792aSdrh { "HAVING", 0, TK_HAVING, 0 }, 77fef5208cSdrh { "IN", 0, TK_IN, 0 }, 7875897234Sdrh { "INDEX", 0, TK_INDEX, 0 }, 7975897234Sdrh { "INSERT", 0, TK_INSERT, 0 }, 8082c3d636Sdrh { "INTERSECT", 0, TK_INTERSECT, 0 }, 8175897234Sdrh { "INTO", 0, TK_INTO, 0 }, 8275897234Sdrh { "IS", 0, TK_IS, 0 }, 8375897234Sdrh { "ISNULL", 0, TK_ISNULL, 0 }, 8475897234Sdrh { "KEY", 0, TK_KEY, 0 }, 85dce2cbe6Sdrh { "LIKE", 0, TK_LIKE, 0 }, 8675897234Sdrh { "NOT", 0, TK_NOT, 0 }, 8775897234Sdrh { "NOTNULL", 0, TK_NOTNULL, 0 }, 8875897234Sdrh { "NULL", 0, TK_NULL, 0 }, 8975897234Sdrh { "ON", 0, TK_ON, 0 }, 9075897234Sdrh { "OR", 0, TK_OR, 0 }, 9175897234Sdrh { "ORDER", 0, TK_ORDER, 0 }, 9275897234Sdrh { "PRIMARY", 0, TK_PRIMARY, 0 }, 93*c4a3c779Sdrh { "ROLLBACK", 0, TK_ROLLBACK, 0 }, 9475897234Sdrh { "SELECT", 0, TK_SELECT, 0 }, 9575897234Sdrh { "SET", 0, TK_SET, 0 }, 9675897234Sdrh { "TABLE", 0, TK_TABLE, 0 }, 97*c4a3c779Sdrh { "TRANSACTION", 0, TK_TRANSACTION, 0 }, 9882c3d636Sdrh { "UNION", 0, TK_UNION, 0 }, 9975897234Sdrh { "UNIQUE", 0, TK_UNIQUE, 0 }, 10075897234Sdrh { "UPDATE", 0, TK_UPDATE, 0 }, 101982cef7eSdrh { "USING", 0, TK_USING, 0 }, 102dce2cbe6Sdrh { "VACUUM", 0, TK_VACUUM, 0 }, 10375897234Sdrh { "VALUES", 0, TK_VALUES, 0 }, 10475897234Sdrh { "WHERE", 0, TK_WHERE, 0 }, 10575897234Sdrh }; 10675897234Sdrh 10775897234Sdrh /* 10875897234Sdrh ** This is the hash table 10975897234Sdrh */ 1108c82b350Sdrh #define KEY_HASH_SIZE 69 11175897234Sdrh static Keyword *apHashTable[KEY_HASH_SIZE]; 11275897234Sdrh 11375897234Sdrh 11475897234Sdrh /* 11575897234Sdrh ** This function looks up an identifier to determine if it is a 11675897234Sdrh ** keyword. If it is a keyword, the token code of that keyword is 11775897234Sdrh ** returned. If the input is not a keyword, TK_ID is returned. 11875897234Sdrh */ 11975897234Sdrh static int sqliteKeywordCode(const char *z, int n){ 12075897234Sdrh int h; 12175897234Sdrh Keyword *p; 12275897234Sdrh if( aKeywordTable[0].len==0 ){ 12375897234Sdrh /* Initialize the keyword hash table */ 12475897234Sdrh int i; 12575897234Sdrh int n; 12675897234Sdrh n = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]); 12775897234Sdrh for(i=0; i<n; i++){ 12875897234Sdrh aKeywordTable[i].len = strlen(aKeywordTable[i].zName); 12975897234Sdrh h = sqliteHashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len); 13075897234Sdrh h %= KEY_HASH_SIZE; 13175897234Sdrh aKeywordTable[i].pNext = apHashTable[h]; 13275897234Sdrh apHashTable[h] = &aKeywordTable[i]; 13375897234Sdrh } 13475897234Sdrh } 13575897234Sdrh h = sqliteHashNoCase(z, n) % KEY_HASH_SIZE; 13675897234Sdrh for(p=apHashTable[h]; p; p=p->pNext){ 13775897234Sdrh if( p->len==n && sqliteStrNICmp(p->zName, z, n)==0 ){ 13875897234Sdrh return p->tokenType; 13975897234Sdrh } 14075897234Sdrh } 14175897234Sdrh return TK_ID; 14275897234Sdrh } 14375897234Sdrh 14475897234Sdrh /* 14575897234Sdrh ** Return the length of the token that begins at z[0]. Return 14675897234Sdrh ** -1 if the token is (or might be) incomplete. Store the token 14775897234Sdrh ** type in *tokenType before returning. 14875897234Sdrh */ 14975897234Sdrh int sqliteGetToken(const char *z, int *tokenType){ 15075897234Sdrh int i; 15175897234Sdrh switch( *z ){ 15230cab809Sdrh case ' ': case '\t': case '\n': case '\f': case '\r': { 15375897234Sdrh for(i=1; z[i] && isspace(z[i]); i++){} 15475897234Sdrh *tokenType = TK_SPACE; 15575897234Sdrh return i; 15675897234Sdrh } 15775897234Sdrh case '-': { 15875897234Sdrh if( z[1]==0 ) return -1; 15975897234Sdrh if( z[1]=='-' ){ 16075897234Sdrh for(i=2; z[i] && z[i]!='\n'; i++){} 16175897234Sdrh *tokenType = TK_COMMENT; 16275897234Sdrh return i; 16375897234Sdrh } 16475897234Sdrh *tokenType = TK_MINUS; 16575897234Sdrh return 1; 16675897234Sdrh } 16775897234Sdrh case '(': { 16875897234Sdrh *tokenType = TK_LP; 16975897234Sdrh return 1; 17075897234Sdrh } 17175897234Sdrh case ')': { 17275897234Sdrh *tokenType = TK_RP; 17375897234Sdrh return 1; 17475897234Sdrh } 17575897234Sdrh case ';': { 17675897234Sdrh *tokenType = TK_SEMI; 17775897234Sdrh return 1; 17875897234Sdrh } 17975897234Sdrh case '+': { 18075897234Sdrh *tokenType = TK_PLUS; 18175897234Sdrh return 1; 18275897234Sdrh } 18375897234Sdrh case '*': { 18475897234Sdrh *tokenType = TK_STAR; 18575897234Sdrh return 1; 18675897234Sdrh } 18775897234Sdrh case '/': { 18875897234Sdrh *tokenType = TK_SLASH; 18975897234Sdrh return 1; 19075897234Sdrh } 19175897234Sdrh case '=': { 19275897234Sdrh *tokenType = TK_EQ; 19375897234Sdrh return 1 + (z[1]=='='); 19475897234Sdrh } 19575897234Sdrh case '<': { 19675897234Sdrh if( z[1]=='=' ){ 19775897234Sdrh *tokenType = TK_LE; 19875897234Sdrh return 2; 19975897234Sdrh }else if( z[1]=='>' ){ 20075897234Sdrh *tokenType = TK_NE; 20175897234Sdrh return 2; 20275897234Sdrh }else{ 20375897234Sdrh *tokenType = TK_LT; 20475897234Sdrh return 1; 20575897234Sdrh } 20675897234Sdrh } 20775897234Sdrh case '>': { 20875897234Sdrh if( z[1]=='=' ){ 20975897234Sdrh *tokenType = TK_GE; 21075897234Sdrh return 2; 21175897234Sdrh }else{ 21275897234Sdrh *tokenType = TK_GT; 21375897234Sdrh return 1; 21475897234Sdrh } 21575897234Sdrh } 21675897234Sdrh case '!': { 21775897234Sdrh if( z[1]!='=' ){ 21875897234Sdrh *tokenType = TK_ILLEGAL; 219c837e709Sdrh return 2; 22075897234Sdrh }else{ 22175897234Sdrh *tokenType = TK_NE; 22275897234Sdrh return 2; 22375897234Sdrh } 22475897234Sdrh } 2250040077dSdrh case '|': { 2260040077dSdrh if( z[1]!='|' ){ 2270040077dSdrh *tokenType = TK_ILLEGAL; 2280040077dSdrh return 1; 2290040077dSdrh }else{ 2300040077dSdrh *tokenType = TK_CONCAT; 2310040077dSdrh return 2; 2320040077dSdrh } 2330040077dSdrh } 23475897234Sdrh case ',': { 23575897234Sdrh *tokenType = TK_COMMA; 23675897234Sdrh return 1; 23775897234Sdrh } 23875897234Sdrh case '\'': case '"': { 23975897234Sdrh int delim = z[0]; 24075897234Sdrh for(i=1; z[i]; i++){ 24175897234Sdrh if( z[i]==delim ){ 24275897234Sdrh if( z[i+1]==delim ){ 24375897234Sdrh i++; 24475897234Sdrh }else{ 24575897234Sdrh break; 24675897234Sdrh } 24775897234Sdrh } 24875897234Sdrh } 24975897234Sdrh if( z[i] ) i++; 25075897234Sdrh *tokenType = TK_STRING; 25175897234Sdrh return i; 25275897234Sdrh } 25375897234Sdrh case '.': { 25475897234Sdrh if( !isdigit(z[1]) ){ 25575897234Sdrh *tokenType = TK_DOT; 25675897234Sdrh return 1; 25775897234Sdrh } 25875897234Sdrh /* Fall thru into the next case */ 25975897234Sdrh } 26075897234Sdrh case '0': case '1': case '2': case '3': case '4': 26175897234Sdrh case '5': case '6': case '7': case '8': case '9': { 262c837e709Sdrh *tokenType = TK_INTEGER; 26375897234Sdrh for(i=1; z[i] && isdigit(z[i]); i++){} 26475897234Sdrh if( z[i]=='.' ){ 26575897234Sdrh i++; 26675897234Sdrh while( z[i] && isdigit(z[i]) ){ i++; } 267c837e709Sdrh *tokenType = TK_FLOAT; 268c837e709Sdrh } 26975897234Sdrh if( (z[i]=='e' || z[i]=='E') && 27075897234Sdrh ( isdigit(z[i+1]) 27175897234Sdrh || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2])) 27275897234Sdrh ) 27375897234Sdrh ){ 27475897234Sdrh i += 2; 27575897234Sdrh while( z[i] && isdigit(z[i]) ){ i++; } 27675897234Sdrh *tokenType = TK_FLOAT; 27775897234Sdrh }else if( z[0]=='.' ){ 27875897234Sdrh *tokenType = TK_FLOAT; 27975897234Sdrh } 28075897234Sdrh return i; 28175897234Sdrh } 28275897234Sdrh case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 28375897234Sdrh case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': 28475897234Sdrh case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': 28575897234Sdrh case 's': case 't': case 'u': case 'v': case 'w': case 'x': 28675897234Sdrh case 'y': case 'z': case '_': 28775897234Sdrh case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 28875897234Sdrh case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': 28975897234Sdrh case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 29075897234Sdrh case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': 29175897234Sdrh case 'Y': case 'Z': { 29275897234Sdrh for(i=1; z[i] && (isalnum(z[i]) || z[i]=='_'); i++){} 29375897234Sdrh *tokenType = sqliteKeywordCode(z, i); 29475897234Sdrh return i; 29575897234Sdrh } 29675897234Sdrh default: { 29775897234Sdrh break; 29875897234Sdrh } 29975897234Sdrh } 30075897234Sdrh *tokenType = TK_ILLEGAL; 30175897234Sdrh return 1; 30275897234Sdrh } 30375897234Sdrh 30475897234Sdrh /* 30575897234Sdrh ** Run the parser on the given SQL string. The parser structure is 3064c504391Sdrh ** passed in. An SQLITE_ status code. 30775897234Sdrh */ 30875897234Sdrh int sqliteRunParser(Parse *pParse, char *zSql, char **pzErrMsg){ 30975897234Sdrh int nErr = 0; 31075897234Sdrh int i; 31175897234Sdrh void *pEngine; 31275897234Sdrh int once = 1; 31375897234Sdrh static FILE *trace = 0; 31475897234Sdrh extern void *sqliteParserAlloc(void*(*)(int)); 31575897234Sdrh extern void sqliteParserFree(void*, void(*)(void*)); 316338ea13cSdrh extern int sqliteParser(void*, int, Token, Parse*); 31775897234Sdrh extern void sqliteParserTrace(FILE*, char *); 31875897234Sdrh 3194c504391Sdrh pParse->db->flags &= ~SQLITE_Interrupt; 3204c504391Sdrh pParse->rc = SQLITE_OK; 32175897234Sdrh i = 0; 3222282792aSdrh sqliteParseInfoReset(pParse); 323982cef7eSdrh pEngine = sqliteParserAlloc((void*(*)(int))malloc); 32475897234Sdrh if( pEngine==0 ){ 32575897234Sdrh sqliteSetString(pzErrMsg, "out of memory", 0); 32675897234Sdrh return 1; 32775897234Sdrh } 328ccb2a3daSdrh #ifndef NDEBUG 32975897234Sdrh sqliteParserTrace(trace, "parser: "); 330ccb2a3daSdrh #endif 33175897234Sdrh while( nErr==0 && i>=0 && zSql[i]!=0 ){ 33275897234Sdrh int tokenType; 33375897234Sdrh 3344c504391Sdrh if( (pParse->db->flags & SQLITE_Interrupt)!=0 ){ 3354c504391Sdrh pParse->rc = SQLITE_INTERRUPT; 3364c504391Sdrh sqliteSetString(pzErrMsg, "interrupt", 0); 3374c504391Sdrh break; 3384c504391Sdrh } 33975897234Sdrh pParse->sLastToken.z = &zSql[i]; 34075897234Sdrh pParse->sLastToken.n = sqliteGetToken(&zSql[i], &tokenType); 34175897234Sdrh i += pParse->sLastToken.n; 34275897234Sdrh if( once ){ 34375897234Sdrh pParse->sFirstToken = pParse->sLastToken; 34475897234Sdrh once = 0; 34575897234Sdrh } 34675897234Sdrh switch( tokenType ){ 34775897234Sdrh case TK_SPACE: 34875897234Sdrh break; 34975897234Sdrh case TK_COMMENT: { 35075897234Sdrh /* Various debugging modes can be turned on and off using 35175897234Sdrh ** special SQL comments. Check for the special comments 35275897234Sdrh ** here and take approriate action if found. 35375897234Sdrh */ 3546e142f54Sdrh #ifndef NDEBUG 35575897234Sdrh char *z = pParse->sLastToken.z; 35675897234Sdrh if( sqliteStrNICmp(z,"--parser-trace-on--",19)==0 ){ 35775897234Sdrh trace = stderr; 35875897234Sdrh sqliteParserTrace(trace, "parser: "); 35975897234Sdrh }else if( sqliteStrNICmp(z,"--parser-trace-off--", 20)==0 ){ 36075897234Sdrh trace = 0; 36175897234Sdrh sqliteParserTrace(trace, "parser: "); 36275897234Sdrh }else if( sqliteStrNICmp(z,"--vdbe-trace-on--",17)==0 ){ 36375897234Sdrh pParse->db->flags |= SQLITE_VdbeTrace; 364670f74f5Sdrh }else if( sqliteStrNICmp(z,"--vdbe-trace-off--", 18)==0 ){ 36575897234Sdrh pParse->db->flags &= ~SQLITE_VdbeTrace; 3666e142f54Sdrh #ifdef MEMORY_DEBUG 36730cab809Sdrh }else if( sqliteStrNICmp(z,"--malloc-fail=",14)==0 ){ 3686e142f54Sdrh sqlite_iMallocFail = atoi(&z[14]); 3696e142f54Sdrh }else if( sqliteStrNICmp(z,"--malloc-stats--", 16)==0 ){ 3706e142f54Sdrh if( pParse->xCallback ){ 3716e142f54Sdrh static char *azName[4] = {"malloc", "free", "to_fail", 0 }; 3726e142f54Sdrh char *azArg[4]; 3736e142f54Sdrh char zVal[3][30]; 3746e142f54Sdrh sprintf(zVal[0],"%d", sqlite_nMalloc); 3756e142f54Sdrh sprintf(zVal[1],"%d", sqlite_nFree); 3766e142f54Sdrh sprintf(zVal[2],"%d", sqlite_iMallocFail); 3776e142f54Sdrh azArg[0] = zVal[0]; 3786e142f54Sdrh azArg[1] = zVal[1]; 3796e142f54Sdrh azArg[2] = zVal[2]; 3806e142f54Sdrh azArg[3] = 0; 3816e142f54Sdrh pParse->xCallback(pParse->pArg, 3, azArg, azName); 38275897234Sdrh } 3836e142f54Sdrh #endif 3846e142f54Sdrh } 3856e142f54Sdrh #endif 38675897234Sdrh break; 38775897234Sdrh } 38875897234Sdrh case TK_ILLEGAL: 389c837e709Sdrh sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1, 390c837e709Sdrh pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0); 39175897234Sdrh nErr++; 39275897234Sdrh break; 39375897234Sdrh default: 39475897234Sdrh sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse); 3956e142f54Sdrh if( pParse->zErrMsg && pParse->sErrToken.z ){ 39675897234Sdrh sqliteSetNString(pzErrMsg, "near \"", -1, 39775897234Sdrh pParse->sErrToken.z, pParse->sErrToken.n, 39875897234Sdrh "\": ", -1, 39975897234Sdrh pParse->zErrMsg, -1, 40075897234Sdrh 0); 40175897234Sdrh nErr++; 4026e142f54Sdrh sqliteFree(pParse->zErrMsg); 4036e142f54Sdrh pParse->zErrMsg = 0; 40475897234Sdrh } 40575897234Sdrh break; 40675897234Sdrh } 40775897234Sdrh } 4084c504391Sdrh if( nErr==0 && (pParse->db->flags & SQLITE_Interrupt)==0 ){ 40975897234Sdrh sqliteParser(pEngine, 0, pParse->sLastToken, pParse); 4106e142f54Sdrh if( pParse->zErrMsg && pParse->sErrToken.z ){ 41175897234Sdrh sqliteSetNString(pzErrMsg, "near \"", -1, 41275897234Sdrh pParse->sErrToken.z, pParse->sErrToken.n, 41375897234Sdrh "\": ", -1, 41475897234Sdrh pParse->zErrMsg, -1, 41575897234Sdrh 0); 41675897234Sdrh nErr++; 4176e142f54Sdrh sqliteFree(pParse->zErrMsg); 4186e142f54Sdrh pParse->zErrMsg = 0; 41975897234Sdrh } 42075897234Sdrh } 421dcc581ccSdrh sqliteParserFree(pEngine, free); 42275897234Sdrh if( pParse->zErrMsg ){ 42375897234Sdrh if( pzErrMsg ){ 4246e142f54Sdrh sqliteFree(*pzErrMsg); 42575897234Sdrh *pzErrMsg = pParse->zErrMsg; 42675897234Sdrh }else{ 42775897234Sdrh sqliteFree(pParse->zErrMsg); 42875897234Sdrh } 42975897234Sdrh if( !nErr ) nErr++; 43075897234Sdrh } 43175897234Sdrh if( pParse->pVdbe ){ 43275897234Sdrh sqliteVdbeDelete(pParse->pVdbe); 43375897234Sdrh pParse->pVdbe = 0; 43475897234Sdrh } 43575897234Sdrh if( pParse->pNewTable ){ 43675897234Sdrh sqliteDeleteTable(pParse->db, pParse->pNewTable); 43775897234Sdrh pParse->pNewTable = 0; 43875897234Sdrh } 4392282792aSdrh sqliteParseInfoReset(pParse); 4404c504391Sdrh sqliteStrRealloc(pzErrMsg); 4414c504391Sdrh if( nErr>0 && pParse->rc==SQLITE_OK ){ 4424c504391Sdrh pParse->rc = SQLITE_ERROR; 4434c504391Sdrh } 44475897234Sdrh return nErr; 44575897234Sdrh } 446