dvander@1203: /* dvander@1203: ** 2001 September 15 dvander@1203: ** dvander@1203: ** The author disclaims copyright to this source code. In place of dvander@1203: ** a legal notice, here is a blessing: dvander@1203: ** dvander@1203: ** May you do good and not evil. dvander@1203: ** May you find forgiveness for yourself and forgive others. dvander@1203: ** May you share freely, never taking more than you give. dvander@1203: ** dvander@1203: ************************************************************************* dvander@1203: ** An tokenizer for SQL dvander@1203: ** dvander@1203: ** This file contains C code that splits an SQL input string up into dvander@1203: ** individual tokens and sends those tokens one-by-one over to the dvander@1203: ** parser for analysis. dvander@1203: ** dvander@1203: ** $Id$ dvander@1203: */ dvander@1203: #include "sqliteInt.h" dvander@1203: #include "os.h" dvander@1203: #include dvander@1203: #include dvander@1203: dvander@1203: /* dvander@1203: ** The charMap() macro maps alphabetic characters into their dvander@1203: ** lower-case ASCII equivalent. On ASCII machines, this is just dvander@1203: ** an upper-to-lower case map. On EBCDIC machines we also need dvander@1203: ** to adjust the encoding. Only alphabetic characters and underscores dvander@1203: ** need to be translated. dvander@1203: */ dvander@1203: #ifdef SQLITE_ASCII dvander@1203: # define charMap(X) sqlite3UpperToLower[(unsigned char)X] dvander@1203: #endif dvander@1203: #ifdef SQLITE_EBCDIC dvander@1203: # define charMap(X) ebcdicToAscii[(unsigned char)X] dvander@1203: const unsigned char ebcdicToAscii[] = { dvander@1203: /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3x */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4x */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5x */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, /* 6x */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7x */ dvander@1203: 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* 8x */ dvander@1203: 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* 9x */ dvander@1203: 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ax */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */ dvander@1203: 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* Cx */ dvander@1203: 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* Dx */ dvander@1203: 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ex */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Fx */ dvander@1203: }; dvander@1203: #endif dvander@1203: dvander@1203: /* dvander@1203: ** The sqlite3KeywordCode function looks up an identifier to determine if dvander@1203: ** it is a keyword. If it is a keyword, the token code of that keyword is dvander@1203: ** returned. If the input is not a keyword, TK_ID is returned. dvander@1203: ** dvander@1203: ** The implementation of this routine was generated by a program, dvander@1203: ** mkkeywordhash.h, located in the tool subdirectory of the distribution. dvander@1203: ** The output of the mkkeywordhash.c program is written into a file dvander@1203: ** named keywordhash.h and then included into this source file by dvander@1203: ** the #include below. dvander@1203: */ dvander@1203: #include "keywordhash.h" dvander@1203: dvander@1203: dvander@1203: /* dvander@1203: ** If X is a character that can be used in an identifier then dvander@1203: ** IdChar(X) will be true. Otherwise it is false. dvander@1203: ** dvander@1203: ** For ASCII, any character with the high-order bit set is dvander@1203: ** allowed in an identifier. For 7-bit characters, dvander@1203: ** sqlite3IsIdChar[X] must be 1. dvander@1203: ** dvander@1203: ** For EBCDIC, the rules are more complex but have the same dvander@1203: ** end result. dvander@1203: ** dvander@1203: ** Ticket #1066. the SQL standard does not allow '$' in the dvander@1203: ** middle of identfiers. But many SQL implementations do. dvander@1203: ** SQLite will allow '$' in identifiers for compatibility. dvander@1203: ** But the feature is undocumented. dvander@1203: */ dvander@1203: #ifdef SQLITE_ASCII dvander@1203: const char sqlite3IsIdChar[] = { dvander@1203: /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ dvander@1203: 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ dvander@1203: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ dvander@1203: 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ dvander@1203: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ dvander@1203: 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ dvander@1203: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ dvander@1203: }; dvander@1203: #define IdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsIdChar[c-0x20])) dvander@1203: #endif dvander@1203: #ifdef SQLITE_EBCDIC dvander@1203: const char sqlite3IsIdChar[] = { dvander@1203: /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ dvander@1203: 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 4x */ dvander@1203: 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, /* 5x */ dvander@1203: 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 6x */ dvander@1203: 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* 7x */ dvander@1203: 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, /* 8x */ dvander@1203: 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, /* 9x */ dvander@1203: 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, /* Ax */ dvander@1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */ dvander@1203: 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Cx */ dvander@1203: 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Dx */ dvander@1203: 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */ dvander@1203: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */ dvander@1203: }; dvander@1203: #define IdChar(C) (((c=C)>=0x42 && sqlite3IsIdChar[c-0x40])) dvander@1203: #endif dvander@1203: dvander@1203: dvander@1203: /* dvander@1203: ** Return the length of the token that begins at z[0]. dvander@1203: ** Store the token type in *tokenType before returning. dvander@1203: */ dvander@1203: static int getToken(const unsigned char *z, int *tokenType){ dvander@1203: int i, c; dvander@1203: switch( *z ){ dvander@1203: case ' ': case '\t': case '\n': case '\f': case '\r': { dvander@1203: for(i=1; isspace(z[i]); i++){} dvander@1203: *tokenType = TK_SPACE; dvander@1203: return i; dvander@1203: } dvander@1203: case '-': { dvander@1203: if( z[1]=='-' ){ dvander@1203: for(i=2; (c=z[i])!=0 && c!='\n'; i++){} dvander@1203: *tokenType = TK_COMMENT; dvander@1203: return i; dvander@1203: } dvander@1203: *tokenType = TK_MINUS; dvander@1203: return 1; dvander@1203: } dvander@1203: case '(': { dvander@1203: *tokenType = TK_LP; dvander@1203: return 1; dvander@1203: } dvander@1203: case ')': { dvander@1203: *tokenType = TK_RP; dvander@1203: return 1; dvander@1203: } dvander@1203: case ';': { dvander@1203: *tokenType = TK_SEMI; dvander@1203: return 1; dvander@1203: } dvander@1203: case '+': { dvander@1203: *tokenType = TK_PLUS; dvander@1203: return 1; dvander@1203: } dvander@1203: case '*': { dvander@1203: *tokenType = TK_STAR; dvander@1203: return 1; dvander@1203: } dvander@1203: case '/': { dvander@1203: if( z[1]!='*' || z[2]==0 ){ dvander@1203: *tokenType = TK_SLASH; dvander@1203: return 1; dvander@1203: } dvander@1203: for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){} dvander@1203: if( c ) i++; dvander@1203: *tokenType = TK_COMMENT; dvander@1203: return i; dvander@1203: } dvander@1203: case '%': { dvander@1203: *tokenType = TK_REM; dvander@1203: return 1; dvander@1203: } dvander@1203: case '=': { dvander@1203: *tokenType = TK_EQ; dvander@1203: return 1 + (z[1]=='='); dvander@1203: } dvander@1203: case '<': { dvander@1203: if( (c=z[1])=='=' ){ dvander@1203: *tokenType = TK_LE; dvander@1203: return 2; dvander@1203: }else if( c=='>' ){ dvander@1203: *tokenType = TK_NE; dvander@1203: return 2; dvander@1203: }else if( c=='<' ){ dvander@1203: *tokenType = TK_LSHIFT; dvander@1203: return 2; dvander@1203: }else{ dvander@1203: *tokenType = TK_LT; dvander@1203: return 1; dvander@1203: } dvander@1203: } dvander@1203: case '>': { dvander@1203: if( (c=z[1])=='=' ){ dvander@1203: *tokenType = TK_GE; dvander@1203: return 2; dvander@1203: }else if( c=='>' ){ dvander@1203: *tokenType = TK_RSHIFT; dvander@1203: return 2; dvander@1203: }else{ dvander@1203: *tokenType = TK_GT; dvander@1203: return 1; dvander@1203: } dvander@1203: } dvander@1203: case '!': { dvander@1203: if( z[1]!='=' ){ dvander@1203: *tokenType = TK_ILLEGAL; dvander@1203: return 2; dvander@1203: }else{ dvander@1203: *tokenType = TK_NE; dvander@1203: return 2; dvander@1203: } dvander@1203: } dvander@1203: case '|': { dvander@1203: if( z[1]!='|' ){ dvander@1203: *tokenType = TK_BITOR; dvander@1203: return 1; dvander@1203: }else{ dvander@1203: *tokenType = TK_CONCAT; dvander@1203: return 2; dvander@1203: } dvander@1203: } dvander@1203: case ',': { dvander@1203: *tokenType = TK_COMMA; dvander@1203: return 1; dvander@1203: } dvander@1203: case '&': { dvander@1203: *tokenType = TK_BITAND; dvander@1203: return 1; dvander@1203: } dvander@1203: case '~': { dvander@1203: *tokenType = TK_BITNOT; dvander@1203: return 1; dvander@1203: } dvander@1203: case '`': dvander@1203: case '\'': dvander@1203: case '"': { dvander@1203: int delim = z[0]; dvander@1203: for(i=1; (c=z[i])!=0; i++){ dvander@1203: if( c==delim ){ dvander@1203: if( z[i+1]==delim ){ dvander@1203: i++; dvander@1203: }else{ dvander@1203: break; dvander@1203: } dvander@1203: } dvander@1203: } dvander@1203: if( c ){ dvander@1203: *tokenType = TK_STRING; dvander@1203: return i+1; dvander@1203: }else{ dvander@1203: *tokenType = TK_ILLEGAL; dvander@1203: return i; dvander@1203: } dvander@1203: } dvander@1203: case '.': { dvander@1203: #ifndef SQLITE_OMIT_FLOATING_POINT dvander@1203: if( !isdigit(z[1]) ) dvander@1203: #endif dvander@1203: { dvander@1203: *tokenType = TK_DOT; dvander@1203: return 1; dvander@1203: } dvander@1203: /* If the next character is a digit, this is a floating point dvander@1203: ** number that begins with ".". Fall thru into the next case */ dvander@1203: } dvander@1203: case '0': case '1': case '2': case '3': case '4': dvander@1203: case '5': case '6': case '7': case '8': case '9': { dvander@1203: *tokenType = TK_INTEGER; dvander@1203: for(i=0; isdigit(z[i]); i++){} dvander@1203: #ifndef SQLITE_OMIT_FLOATING_POINT dvander@1203: if( z[i]=='.' ){ dvander@1203: i++; dvander@1203: while( isdigit(z[i]) ){ i++; } dvander@1203: *tokenType = TK_FLOAT; dvander@1203: } dvander@1203: if( (z[i]=='e' || z[i]=='E') && dvander@1203: ( isdigit(z[i+1]) dvander@1203: || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2])) dvander@1203: ) dvander@1203: ){ dvander@1203: i += 2; dvander@1203: while( isdigit(z[i]) ){ i++; } dvander@1203: *tokenType = TK_FLOAT; dvander@1203: } dvander@1203: #endif dvander@1203: while( IdChar(z[i]) ){ dvander@1203: *tokenType = TK_ILLEGAL; dvander@1203: i++; dvander@1203: } dvander@1203: return i; dvander@1203: } dvander@1203: case '[': { dvander@1203: for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} dvander@1203: *tokenType = TK_ID; dvander@1203: return i; dvander@1203: } dvander@1203: case '?': { dvander@1203: *tokenType = TK_VARIABLE; dvander@1203: for(i=1; isdigit(z[i]); i++){} dvander@1203: return i; dvander@1203: } dvander@1203: case '#': { dvander@1203: for(i=1; isdigit(z[i]); i++){} dvander@1203: if( i>1 ){ dvander@1203: /* Parameters of the form #NNN (where NNN is a number) are used dvander@1203: ** internally by sqlite3NestedParse. */ dvander@1203: *tokenType = TK_REGISTER; dvander@1203: return i; dvander@1203: } dvander@1203: /* Fall through into the next case if the '#' is not followed by dvander@1203: ** a digit. Try to match #AAAA where AAAA is a parameter name. */ dvander@1203: } dvander@1203: #ifndef SQLITE_OMIT_TCL_VARIABLE dvander@1203: case '$': dvander@1203: #endif dvander@1203: case '@': /* For compatibility with MS SQL Server */ dvander@1203: case ':': { dvander@1203: int n = 0; dvander@1203: *tokenType = TK_VARIABLE; dvander@1203: for(i=1; (c=z[i])!=0; i++){ dvander@1203: if( IdChar(c) ){ dvander@1203: n++; dvander@1203: #ifndef SQLITE_OMIT_TCL_VARIABLE dvander@1203: }else if( c=='(' && n>0 ){ dvander@1203: do{ dvander@1203: i++; dvander@1203: }while( (c=z[i])!=0 && !isspace(c) && c!=')' ); dvander@1203: if( c==')' ){ dvander@1203: i++; dvander@1203: }else{ dvander@1203: *tokenType = TK_ILLEGAL; dvander@1203: } dvander@1203: break; dvander@1203: }else if( c==':' && z[i+1]==':' ){ dvander@1203: i++; dvander@1203: #endif dvander@1203: }else{ dvander@1203: break; dvander@1203: } dvander@1203: } dvander@1203: if( n==0 ) *tokenType = TK_ILLEGAL; dvander@1203: return i; dvander@1203: } dvander@1203: #ifndef SQLITE_OMIT_BLOB_LITERAL dvander@1203: case 'x': case 'X': { dvander@1203: if( (c=z[1])=='\'' || c=='"' ){ dvander@1203: int delim = c; dvander@1203: *tokenType = TK_BLOB; dvander@1203: for(i=2; (c=z[i])!=0; i++){ dvander@1203: if( c==delim ){ dvander@1203: if( i%2 ) *tokenType = TK_ILLEGAL; dvander@1203: break; dvander@1203: } dvander@1203: if( !isxdigit(c) ){ dvander@1203: *tokenType = TK_ILLEGAL; dvander@1203: return i; dvander@1203: } dvander@1203: } dvander@1203: if( c ) i++; dvander@1203: return i; dvander@1203: } dvander@1203: /* Otherwise fall through to the next case */ dvander@1203: } dvander@1203: #endif dvander@1203: default: { dvander@1203: if( !IdChar(*z) ){ dvander@1203: break; dvander@1203: } dvander@1203: for(i=1; IdChar(z[i]); i++){} dvander@1203: *tokenType = keywordCode((char*)z, i); dvander@1203: return i; dvander@1203: } dvander@1203: } dvander@1203: *tokenType = TK_ILLEGAL; dvander@1203: return 1; dvander@1203: } dvander@1203: int sqlite3GetToken(const unsigned char *z, int *tokenType){ dvander@1203: return getToken(z, tokenType); dvander@1203: } dvander@1203: dvander@1203: /* dvander@1203: ** The interface to the LEMON-generated parser dvander@1203: */ dvander@1203: void *sqlite3ParserAlloc(void*(*)(size_t)); dvander@1203: void sqlite3ParserFree(void*, void(*)(void*)); dvander@1203: void sqlite3Parser(void*, int, Token, Parse*); dvander@1203: dvander@1203: /* dvander@1203: ** Run the parser on the given SQL string. The parser structure is dvander@1203: ** passed in. An SQLITE_ status code is returned. If an error occurs dvander@1203: ** and pzErrMsg!=NULL then an error message might be written into dvander@1203: ** memory obtained from malloc() and *pzErrMsg made to point to that dvander@1203: ** error message. Or maybe not. dvander@1203: */ dvander@1203: int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ dvander@1203: int nErr = 0; dvander@1203: int i; dvander@1203: void *pEngine; dvander@1203: int tokenType; dvander@1203: int lastTokenParsed = -1; dvander@1203: sqlite3 *db = pParse->db; dvander@1203: dvander@1203: if( db->activeVdbeCnt==0 ){ dvander@1203: db->u1.isInterrupted = 0; dvander@1203: } dvander@1203: pParse->rc = SQLITE_OK; dvander@1203: i = 0; dvander@1203: pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3MallocX); dvander@1203: if( pEngine==0 ){ dvander@1203: return SQLITE_NOMEM; dvander@1203: } dvander@1203: assert( pParse->sLastToken.dyn==0 ); dvander@1203: assert( pParse->pNewTable==0 ); dvander@1203: assert( pParse->pNewTrigger==0 ); dvander@1203: assert( pParse->nVar==0 ); dvander@1203: assert( pParse->nVarExpr==0 ); dvander@1203: assert( pParse->nVarExprAlloc==0 ); dvander@1203: assert( pParse->apVarExpr==0 ); dvander@1203: pParse->zTail = pParse->zSql = zSql; dvander@1203: while( !sqlite3MallocFailed() && zSql[i]!=0 ){ dvander@1203: assert( i>=0 ); dvander@1203: pParse->sLastToken.z = (u8*)&zSql[i]; dvander@1203: assert( pParse->sLastToken.dyn==0 ); dvander@1203: pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType); dvander@1203: i += pParse->sLastToken.n; dvander@1203: if( i>SQLITE_MAX_SQL_LENGTH ){ dvander@1203: pParse->rc = SQLITE_TOOBIG; dvander@1203: break; dvander@1203: } dvander@1203: switch( tokenType ){ dvander@1203: case TK_SPACE: dvander@1203: case TK_COMMENT: { dvander@1203: if( db->u1.isInterrupted ){ dvander@1203: pParse->rc = SQLITE_INTERRUPT; dvander@1203: sqlite3SetString(pzErrMsg, "interrupt", (char*)0); dvander@1203: goto abort_parse; dvander@1203: } dvander@1203: break; dvander@1203: } dvander@1203: case TK_ILLEGAL: { dvander@1203: if( pzErrMsg ){ dvander@1203: sqliteFree(*pzErrMsg); dvander@1203: *pzErrMsg = sqlite3MPrintf("unrecognized token: \"%T\"", dvander@1203: &pParse->sLastToken); dvander@1203: } dvander@1203: nErr++; dvander@1203: goto abort_parse; dvander@1203: } dvander@1203: case TK_SEMI: { dvander@1203: pParse->zTail = &zSql[i]; dvander@1203: /* Fall thru into the default case */ dvander@1203: } dvander@1203: default: { dvander@1203: sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse); dvander@1203: lastTokenParsed = tokenType; dvander@1203: if( pParse->rc!=SQLITE_OK ){ dvander@1203: goto abort_parse; dvander@1203: } dvander@1203: break; dvander@1203: } dvander@1203: } dvander@1203: } dvander@1203: abort_parse: dvander@1203: if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){ dvander@1203: if( lastTokenParsed!=TK_SEMI ){ dvander@1203: sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse); dvander@1203: pParse->zTail = &zSql[i]; dvander@1203: } dvander@1203: sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); dvander@1203: } dvander@1203: sqlite3ParserFree(pEngine, sqlite3FreeX); dvander@1203: if( sqlite3MallocFailed() ){ dvander@1203: pParse->rc = SQLITE_NOMEM; dvander@1203: } dvander@1203: if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ dvander@1203: sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0); dvander@1203: } dvander@1203: if( pParse->zErrMsg ){ dvander@1203: if( pzErrMsg && *pzErrMsg==0 ){ dvander@1203: *pzErrMsg = pParse->zErrMsg; dvander@1203: }else{ dvander@1203: sqliteFree(pParse->zErrMsg); dvander@1203: } dvander@1203: pParse->zErrMsg = 0; dvander@1203: if( !nErr ) nErr++; dvander@1203: } dvander@1203: if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ dvander@1203: sqlite3VdbeDelete(pParse->pVdbe); dvander@1203: pParse->pVdbe = 0; dvander@1203: } dvander@1203: #ifndef SQLITE_OMIT_SHARED_CACHE dvander@1203: if( pParse->nested==0 ){ dvander@1203: sqliteFree(pParse->aTableLock); dvander@1203: pParse->aTableLock = 0; dvander@1203: pParse->nTableLock = 0; dvander@1203: } dvander@1203: #endif dvander@1203: dvander@1203: if( !IN_DECLARE_VTAB ){ dvander@1203: /* If the pParse->declareVtab flag is set, do not delete any table dvander@1203: ** structure built up in pParse->pNewTable. The calling code (see vtab.c) dvander@1203: ** will take responsibility for freeing the Table structure. dvander@1203: */ dvander@1203: sqlite3DeleteTable(pParse->pNewTable); dvander@1203: } dvander@1203: dvander@1203: sqlite3DeleteTrigger(pParse->pNewTrigger); dvander@1203: sqliteFree(pParse->apVarExpr); dvander@1203: if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){ dvander@1203: pParse->rc = SQLITE_ERROR; dvander@1203: } dvander@1203: return nErr; dvander@1203: }