extensions/sqlite/sqlite-source/tokenize.c
author David Anderson <dvander@alliedmods.net>
Sun Jul 29 01:15:31 2007 +0000 (2007-07-29)
changeset 1203 633c25ce6405
child 1645 27307df4d711
permissions -rw-r--r--
initial import of sqlite extension
dvander@1203
     1
/*
dvander@1203
     2
** 2001 September 15
dvander@1203
     3
**
dvander@1203
     4
** The author disclaims copyright to this source code.  In place of
dvander@1203
     5
** a legal notice, here is a blessing:
dvander@1203
     6
**
dvander@1203
     7
**    May you do good and not evil.
dvander@1203
     8
**    May you find forgiveness for yourself and forgive others.
dvander@1203
     9
**    May you share freely, never taking more than you give.
dvander@1203
    10
**
dvander@1203
    11
*************************************************************************
dvander@1203
    12
** An tokenizer for SQL
dvander@1203
    13
**
dvander@1203
    14
** This file contains C code that splits an SQL input string up into
dvander@1203
    15
** individual tokens and sends those tokens one-by-one over to the
dvander@1203
    16
** parser for analysis.
dvander@1203
    17
**
dvander@1203
    18
** $Id$
dvander@1203
    19
*/
dvander@1203
    20
#include "sqliteInt.h"
dvander@1203
    21
#include "os.h"
dvander@1203
    22
#include <ctype.h>
dvander@1203
    23
#include <stdlib.h>
dvander@1203
    24
dvander@1203
    25
/*
dvander@1203
    26
** The charMap() macro maps alphabetic characters into their
dvander@1203
    27
** lower-case ASCII equivalent.  On ASCII machines, this is just
dvander@1203
    28
** an upper-to-lower case map.  On EBCDIC machines we also need
dvander@1203
    29
** to adjust the encoding.  Only alphabetic characters and underscores
dvander@1203
    30
** need to be translated.
dvander@1203
    31
*/
dvander@1203
    32
#ifdef SQLITE_ASCII
dvander@1203
    33
# define charMap(X) sqlite3UpperToLower[(unsigned char)X]
dvander@1203
    34
#endif
dvander@1203
    35
#ifdef SQLITE_EBCDIC
dvander@1203
    36
# define charMap(X) ebcdicToAscii[(unsigned char)X]
dvander@1203
    37
const unsigned char ebcdicToAscii[] = {
dvander@1203
    38
/* 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
dvander@1203
    39
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 0x */
dvander@1203
    40
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 1x */
dvander@1203
    41
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 2x */
dvander@1203
    42
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 3x */
dvander@1203
    43
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 4x */
dvander@1203
    44
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 5x */
dvander@1203
    45
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 95,  0,  0,  /* 6x */
dvander@1203
    46
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 7x */
dvander@1203
    47
   0, 97, 98, 99,100,101,102,103,104,105,  0,  0,  0,  0,  0,  0,  /* 8x */
dvander@1203
    48
   0,106,107,108,109,110,111,112,113,114,  0,  0,  0,  0,  0,  0,  /* 9x */
dvander@1203
    49
   0,  0,115,116,117,118,119,120,121,122,  0,  0,  0,  0,  0,  0,  /* Ax */
dvander@1203
    50
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* Bx */
dvander@1203
    51
   0, 97, 98, 99,100,101,102,103,104,105,  0,  0,  0,  0,  0,  0,  /* Cx */
dvander@1203
    52
   0,106,107,108,109,110,111,112,113,114,  0,  0,  0,  0,  0,  0,  /* Dx */
dvander@1203
    53
   0,  0,115,116,117,118,119,120,121,122,  0,  0,  0,  0,  0,  0,  /* Ex */
dvander@1203
    54
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* Fx */
dvander@1203
    55
};
dvander@1203
    56
#endif
dvander@1203
    57
dvander@1203
    58
/*
dvander@1203
    59
** The sqlite3KeywordCode function looks up an identifier to determine if
dvander@1203
    60
** it is a keyword.  If it is a keyword, the token code of that keyword is 
dvander@1203
    61
** returned.  If the input is not a keyword, TK_ID is returned.
dvander@1203
    62
**
dvander@1203
    63
** The implementation of this routine was generated by a program,
dvander@1203
    64
** mkkeywordhash.h, located in the tool subdirectory of the distribution.
dvander@1203
    65
** The output of the mkkeywordhash.c program is written into a file
dvander@1203
    66
** named keywordhash.h and then included into this source file by
dvander@1203
    67
** the #include below.
dvander@1203
    68
*/
dvander@1203
    69
#include "keywordhash.h"
dvander@1203
    70
dvander@1203
    71
dvander@1203
    72
/*
dvander@1203
    73
** If X is a character that can be used in an identifier then
dvander@1203
    74
** IdChar(X) will be true.  Otherwise it is false.
dvander@1203
    75
**
dvander@1203
    76
** For ASCII, any character with the high-order bit set is
dvander@1203
    77
** allowed in an identifier.  For 7-bit characters, 
dvander@1203
    78
** sqlite3IsIdChar[X] must be 1.
dvander@1203
    79
**
dvander@1203
    80
** For EBCDIC, the rules are more complex but have the same
dvander@1203
    81
** end result.
dvander@1203
    82
**
dvander@1203
    83
** Ticket #1066.  the SQL standard does not allow '$' in the
dvander@1203
    84
** middle of identfiers.  But many SQL implementations do. 
dvander@1203
    85
** SQLite will allow '$' in identifiers for compatibility.
dvander@1203
    86
** But the feature is undocumented.
dvander@1203
    87
*/
dvander@1203
    88
#ifdef SQLITE_ASCII
dvander@1203
    89
const char sqlite3IsIdChar[] = {
dvander@1203
    90
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
dvander@1203
    91
    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 2x */
dvander@1203
    92
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 3x */
dvander@1203
    93
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 4x */
dvander@1203
    94
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  /* 5x */
dvander@1203
    95
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 6x */
dvander@1203
    96
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 7x */
dvander@1203
    97
};
dvander@1203
    98
#define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsIdChar[c-0x20]))
dvander@1203
    99
#endif
dvander@1203
   100
#ifdef SQLITE_EBCDIC
dvander@1203
   101
const char sqlite3IsIdChar[] = {
dvander@1203
   102
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
dvander@1203
   103
    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 4x */
dvander@1203
   104
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0,  /* 5x */
dvander@1203
   105
    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0,  /* 6x */
dvander@1203
   106
    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,  /* 7x */
dvander@1203
   107
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0,  /* 8x */
dvander@1203
   108
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0,  /* 9x */
dvander@1203
   109
    1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0,  /* Ax */
dvander@1203
   110
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* Bx */
dvander@1203
   111
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Cx */
dvander@1203
   112
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Dx */
dvander@1203
   113
    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,  /* Ex */
dvander@1203
   114
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0,  /* Fx */
dvander@1203
   115
};
dvander@1203
   116
#define IdChar(C)  (((c=C)>=0x42 && sqlite3IsIdChar[c-0x40]))
dvander@1203
   117
#endif
dvander@1203
   118
dvander@1203
   119
dvander@1203
   120
/*
dvander@1203
   121
** Return the length of the token that begins at z[0]. 
dvander@1203
   122
** Store the token type in *tokenType before returning.
dvander@1203
   123
*/
dvander@1203
   124
static int getToken(const unsigned char *z, int *tokenType){
dvander@1203
   125
  int i, c;
dvander@1203
   126
  switch( *z ){
dvander@1203
   127
    case ' ': case '\t': case '\n': case '\f': case '\r': {
dvander@1203
   128
      for(i=1; isspace(z[i]); i++){}
dvander@1203
   129
      *tokenType = TK_SPACE;
dvander@1203
   130
      return i;
dvander@1203
   131
    }
dvander@1203
   132
    case '-': {
dvander@1203
   133
      if( z[1]=='-' ){
dvander@1203
   134
        for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
dvander@1203
   135
        *tokenType = TK_COMMENT;
dvander@1203
   136
        return i;
dvander@1203
   137
      }
dvander@1203
   138
      *tokenType = TK_MINUS;
dvander@1203
   139
      return 1;
dvander@1203
   140
    }
dvander@1203
   141
    case '(': {
dvander@1203
   142
      *tokenType = TK_LP;
dvander@1203
   143
      return 1;
dvander@1203
   144
    }
dvander@1203
   145
    case ')': {
dvander@1203
   146
      *tokenType = TK_RP;
dvander@1203
   147
      return 1;
dvander@1203
   148
    }
dvander@1203
   149
    case ';': {
dvander@1203
   150
      *tokenType = TK_SEMI;
dvander@1203
   151
      return 1;
dvander@1203
   152
    }
dvander@1203
   153
    case '+': {
dvander@1203
   154
      *tokenType = TK_PLUS;
dvander@1203
   155
      return 1;
dvander@1203
   156
    }
dvander@1203
   157
    case '*': {
dvander@1203
   158
      *tokenType = TK_STAR;
dvander@1203
   159
      return 1;
dvander@1203
   160
    }
dvander@1203
   161
    case '/': {
dvander@1203
   162
      if( z[1]!='*' || z[2]==0 ){
dvander@1203
   163
        *tokenType = TK_SLASH;
dvander@1203
   164
        return 1;
dvander@1203
   165
      }
dvander@1203
   166
      for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
dvander@1203
   167
      if( c ) i++;
dvander@1203
   168
      *tokenType = TK_COMMENT;
dvander@1203
   169
      return i;
dvander@1203
   170
    }
dvander@1203
   171
    case '%': {
dvander@1203
   172
      *tokenType = TK_REM;
dvander@1203
   173
      return 1;
dvander@1203
   174
    }
dvander@1203
   175
    case '=': {
dvander@1203
   176
      *tokenType = TK_EQ;
dvander@1203
   177
      return 1 + (z[1]=='=');
dvander@1203
   178
    }
dvander@1203
   179
    case '<': {
dvander@1203
   180
      if( (c=z[1])=='=' ){
dvander@1203
   181
        *tokenType = TK_LE;
dvander@1203
   182
        return 2;
dvander@1203
   183
      }else if( c=='>' ){
dvander@1203
   184
        *tokenType = TK_NE;
dvander@1203
   185
        return 2;
dvander@1203
   186
      }else if( c=='<' ){
dvander@1203
   187
        *tokenType = TK_LSHIFT;
dvander@1203
   188
        return 2;
dvander@1203
   189
      }else{
dvander@1203
   190
        *tokenType = TK_LT;
dvander@1203
   191
        return 1;
dvander@1203
   192
      }
dvander@1203
   193
    }
dvander@1203
   194
    case '>': {
dvander@1203
   195
      if( (c=z[1])=='=' ){
dvander@1203
   196
        *tokenType = TK_GE;
dvander@1203
   197
        return 2;
dvander@1203
   198
      }else if( c=='>' ){
dvander@1203
   199
        *tokenType = TK_RSHIFT;
dvander@1203
   200
        return 2;
dvander@1203
   201
      }else{
dvander@1203
   202
        *tokenType = TK_GT;
dvander@1203
   203
        return 1;
dvander@1203
   204
      }
dvander@1203
   205
    }
dvander@1203
   206
    case '!': {
dvander@1203
   207
      if( z[1]!='=' ){
dvander@1203
   208
        *tokenType = TK_ILLEGAL;
dvander@1203
   209
        return 2;
dvander@1203
   210
      }else{
dvander@1203
   211
        *tokenType = TK_NE;
dvander@1203
   212
        return 2;
dvander@1203
   213
      }
dvander@1203
   214
    }
dvander@1203
   215
    case '|': {
dvander@1203
   216
      if( z[1]!='|' ){
dvander@1203
   217
        *tokenType = TK_BITOR;
dvander@1203
   218
        return 1;
dvander@1203
   219
      }else{
dvander@1203
   220
        *tokenType = TK_CONCAT;
dvander@1203
   221
        return 2;
dvander@1203
   222
      }
dvander@1203
   223
    }
dvander@1203
   224
    case ',': {
dvander@1203
   225
      *tokenType = TK_COMMA;
dvander@1203
   226
      return 1;
dvander@1203
   227
    }
dvander@1203
   228
    case '&': {
dvander@1203
   229
      *tokenType = TK_BITAND;
dvander@1203
   230
      return 1;
dvander@1203
   231
    }
dvander@1203
   232
    case '~': {
dvander@1203
   233
      *tokenType = TK_BITNOT;
dvander@1203
   234
      return 1;
dvander@1203
   235
    }
dvander@1203
   236
    case '`':
dvander@1203
   237
    case '\'':
dvander@1203
   238
    case '"': {
dvander@1203
   239
      int delim = z[0];
dvander@1203
   240
      for(i=1; (c=z[i])!=0; i++){
dvander@1203
   241
        if( c==delim ){
dvander@1203
   242
          if( z[i+1]==delim ){
dvander@1203
   243
            i++;
dvander@1203
   244
          }else{
dvander@1203
   245
            break;
dvander@1203
   246
          }
dvander@1203
   247
        }
dvander@1203
   248
      }
dvander@1203
   249
      if( c ){
dvander@1203
   250
        *tokenType = TK_STRING;
dvander@1203
   251
        return i+1;
dvander@1203
   252
      }else{
dvander@1203
   253
        *tokenType = TK_ILLEGAL;
dvander@1203
   254
        return i;
dvander@1203
   255
      }
dvander@1203
   256
    }
dvander@1203
   257
    case '.': {
dvander@1203
   258
#ifndef SQLITE_OMIT_FLOATING_POINT
dvander@1203
   259
      if( !isdigit(z[1]) )
dvander@1203
   260
#endif
dvander@1203
   261
      {
dvander@1203
   262
        *tokenType = TK_DOT;
dvander@1203
   263
        return 1;
dvander@1203
   264
      }
dvander@1203
   265
      /* If the next character is a digit, this is a floating point
dvander@1203
   266
      ** number that begins with ".".  Fall thru into the next case */
dvander@1203
   267
    }
dvander@1203
   268
    case '0': case '1': case '2': case '3': case '4':
dvander@1203
   269
    case '5': case '6': case '7': case '8': case '9': {
dvander@1203
   270
      *tokenType = TK_INTEGER;
dvander@1203
   271
      for(i=0; isdigit(z[i]); i++){}
dvander@1203
   272
#ifndef SQLITE_OMIT_FLOATING_POINT
dvander@1203
   273
      if( z[i]=='.' ){
dvander@1203
   274
        i++;
dvander@1203
   275
        while( isdigit(z[i]) ){ i++; }
dvander@1203
   276
        *tokenType = TK_FLOAT;
dvander@1203
   277
      }
dvander@1203
   278
      if( (z[i]=='e' || z[i]=='E') &&
dvander@1203
   279
           ( isdigit(z[i+1]) 
dvander@1203
   280
            || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
dvander@1203
   281
           )
dvander@1203
   282
      ){
dvander@1203
   283
        i += 2;
dvander@1203
   284
        while( isdigit(z[i]) ){ i++; }
dvander@1203
   285
        *tokenType = TK_FLOAT;
dvander@1203
   286
      }
dvander@1203
   287
#endif
dvander@1203
   288
      while( IdChar(z[i]) ){
dvander@1203
   289
        *tokenType = TK_ILLEGAL;
dvander@1203
   290
        i++;
dvander@1203
   291
      }
dvander@1203
   292
      return i;
dvander@1203
   293
    }
dvander@1203
   294
    case '[': {
dvander@1203
   295
      for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
dvander@1203
   296
      *tokenType = TK_ID;
dvander@1203
   297
      return i;
dvander@1203
   298
    }
dvander@1203
   299
    case '?': {
dvander@1203
   300
      *tokenType = TK_VARIABLE;
dvander@1203
   301
      for(i=1; isdigit(z[i]); i++){}
dvander@1203
   302
      return i;
dvander@1203
   303
    }
dvander@1203
   304
    case '#': {
dvander@1203
   305
      for(i=1; isdigit(z[i]); i++){}
dvander@1203
   306
      if( i>1 ){
dvander@1203
   307
        /* Parameters of the form #NNN (where NNN is a number) are used
dvander@1203
   308
        ** internally by sqlite3NestedParse.  */
dvander@1203
   309
        *tokenType = TK_REGISTER;
dvander@1203
   310
        return i;
dvander@1203
   311
      }
dvander@1203
   312
      /* Fall through into the next case if the '#' is not followed by
dvander@1203
   313
      ** a digit. Try to match #AAAA where AAAA is a parameter name. */
dvander@1203
   314
    }
dvander@1203
   315
#ifndef SQLITE_OMIT_TCL_VARIABLE
dvander@1203
   316
    case '$':
dvander@1203
   317
#endif
dvander@1203
   318
    case '@':  /* For compatibility with MS SQL Server */
dvander@1203
   319
    case ':': {
dvander@1203
   320
      int n = 0;
dvander@1203
   321
      *tokenType = TK_VARIABLE;
dvander@1203
   322
      for(i=1; (c=z[i])!=0; i++){
dvander@1203
   323
        if( IdChar(c) ){
dvander@1203
   324
          n++;
dvander@1203
   325
#ifndef SQLITE_OMIT_TCL_VARIABLE
dvander@1203
   326
        }else if( c=='(' && n>0 ){
dvander@1203
   327
          do{
dvander@1203
   328
            i++;
dvander@1203
   329
          }while( (c=z[i])!=0 && !isspace(c) && c!=')' );
dvander@1203
   330
          if( c==')' ){
dvander@1203
   331
            i++;
dvander@1203
   332
          }else{
dvander@1203
   333
            *tokenType = TK_ILLEGAL;
dvander@1203
   334
          }
dvander@1203
   335
          break;
dvander@1203
   336
        }else if( c==':' && z[i+1]==':' ){
dvander@1203
   337
          i++;
dvander@1203
   338
#endif
dvander@1203
   339
        }else{
dvander@1203
   340
          break;
dvander@1203
   341
        }
dvander@1203
   342
      }
dvander@1203
   343
      if( n==0 ) *tokenType = TK_ILLEGAL;
dvander@1203
   344
      return i;
dvander@1203
   345
    }
dvander@1203
   346
#ifndef SQLITE_OMIT_BLOB_LITERAL
dvander@1203
   347
    case 'x': case 'X': {
dvander@1203
   348
      if( (c=z[1])=='\'' || c=='"' ){
dvander@1203
   349
        int delim = c;
dvander@1203
   350
        *tokenType = TK_BLOB;
dvander@1203
   351
        for(i=2; (c=z[i])!=0; i++){
dvander@1203
   352
          if( c==delim ){
dvander@1203
   353
            if( i%2 ) *tokenType = TK_ILLEGAL;
dvander@1203
   354
            break;
dvander@1203
   355
          }
dvander@1203
   356
          if( !isxdigit(c) ){
dvander@1203
   357
            *tokenType = TK_ILLEGAL;
dvander@1203
   358
            return i;
dvander@1203
   359
          }
dvander@1203
   360
        }
dvander@1203
   361
        if( c ) i++;
dvander@1203
   362
        return i;
dvander@1203
   363
      }
dvander@1203
   364
      /* Otherwise fall through to the next case */
dvander@1203
   365
    }
dvander@1203
   366
#endif
dvander@1203
   367
    default: {
dvander@1203
   368
      if( !IdChar(*z) ){
dvander@1203
   369
        break;
dvander@1203
   370
      }
dvander@1203
   371
      for(i=1; IdChar(z[i]); i++){}
dvander@1203
   372
      *tokenType = keywordCode((char*)z, i);
dvander@1203
   373
      return i;
dvander@1203
   374
    }
dvander@1203
   375
  }
dvander@1203
   376
  *tokenType = TK_ILLEGAL;
dvander@1203
   377
  return 1;
dvander@1203
   378
}
dvander@1203
   379
int sqlite3GetToken(const unsigned char *z, int *tokenType){
dvander@1203
   380
  return getToken(z, tokenType);
dvander@1203
   381
}
dvander@1203
   382
dvander@1203
   383
/*
dvander@1203
   384
** The interface to the LEMON-generated parser
dvander@1203
   385
*/
dvander@1203
   386
void *sqlite3ParserAlloc(void*(*)(size_t));
dvander@1203
   387
void sqlite3ParserFree(void*, void(*)(void*));
dvander@1203
   388
void sqlite3Parser(void*, int, Token, Parse*);
dvander@1203
   389
dvander@1203
   390
/*
dvander@1203
   391
** Run the parser on the given SQL string.  The parser structure is
dvander@1203
   392
** passed in.  An SQLITE_ status code is returned.  If an error occurs
dvander@1203
   393
** and pzErrMsg!=NULL then an error message might be written into 
dvander@1203
   394
** memory obtained from malloc() and *pzErrMsg made to point to that
dvander@1203
   395
** error message.  Or maybe not.
dvander@1203
   396
*/
dvander@1203
   397
int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
dvander@1203
   398
  int nErr = 0;
dvander@1203
   399
  int i;
dvander@1203
   400
  void *pEngine;
dvander@1203
   401
  int tokenType;
dvander@1203
   402
  int lastTokenParsed = -1;
dvander@1203
   403
  sqlite3 *db = pParse->db;
dvander@1203
   404
dvander@1203
   405
  if( db->activeVdbeCnt==0 ){
dvander@1203
   406
    db->u1.isInterrupted = 0;
dvander@1203
   407
  }
dvander@1203
   408
  pParse->rc = SQLITE_OK;
dvander@1203
   409
  i = 0;
dvander@1203
   410
  pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3MallocX);
dvander@1203
   411
  if( pEngine==0 ){
dvander@1203
   412
    return SQLITE_NOMEM;
dvander@1203
   413
  }
dvander@1203
   414
  assert( pParse->sLastToken.dyn==0 );
dvander@1203
   415
  assert( pParse->pNewTable==0 );
dvander@1203
   416
  assert( pParse->pNewTrigger==0 );
dvander@1203
   417
  assert( pParse->nVar==0 );
dvander@1203
   418
  assert( pParse->nVarExpr==0 );
dvander@1203
   419
  assert( pParse->nVarExprAlloc==0 );
dvander@1203
   420
  assert( pParse->apVarExpr==0 );
dvander@1203
   421
  pParse->zTail = pParse->zSql = zSql;
dvander@1203
   422
  while( !sqlite3MallocFailed() && zSql[i]!=0 ){
dvander@1203
   423
    assert( i>=0 );
dvander@1203
   424
    pParse->sLastToken.z = (u8*)&zSql[i];
dvander@1203
   425
    assert( pParse->sLastToken.dyn==0 );
dvander@1203
   426
    pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType);
dvander@1203
   427
    i += pParse->sLastToken.n;
dvander@1203
   428
    if( i>SQLITE_MAX_SQL_LENGTH ){
dvander@1203
   429
      pParse->rc = SQLITE_TOOBIG;
dvander@1203
   430
      break;
dvander@1203
   431
    }
dvander@1203
   432
    switch( tokenType ){
dvander@1203
   433
      case TK_SPACE:
dvander@1203
   434
      case TK_COMMENT: {
dvander@1203
   435
        if( db->u1.isInterrupted ){
dvander@1203
   436
          pParse->rc = SQLITE_INTERRUPT;
dvander@1203
   437
          sqlite3SetString(pzErrMsg, "interrupt", (char*)0);
dvander@1203
   438
          goto abort_parse;
dvander@1203
   439
        }
dvander@1203
   440
        break;
dvander@1203
   441
      }
dvander@1203
   442
      case TK_ILLEGAL: {
dvander@1203
   443
        if( pzErrMsg ){
dvander@1203
   444
          sqliteFree(*pzErrMsg);
dvander@1203
   445
          *pzErrMsg = sqlite3MPrintf("unrecognized token: \"%T\"",
dvander@1203
   446
                          &pParse->sLastToken);
dvander@1203
   447
        }
dvander@1203
   448
        nErr++;
dvander@1203
   449
        goto abort_parse;
dvander@1203
   450
      }
dvander@1203
   451
      case TK_SEMI: {
dvander@1203
   452
        pParse->zTail = &zSql[i];
dvander@1203
   453
        /* Fall thru into the default case */
dvander@1203
   454
      }
dvander@1203
   455
      default: {
dvander@1203
   456
        sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
dvander@1203
   457
        lastTokenParsed = tokenType;
dvander@1203
   458
        if( pParse->rc!=SQLITE_OK ){
dvander@1203
   459
          goto abort_parse;
dvander@1203
   460
        }
dvander@1203
   461
        break;
dvander@1203
   462
      }
dvander@1203
   463
    }
dvander@1203
   464
  }
dvander@1203
   465
abort_parse:
dvander@1203
   466
  if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
dvander@1203
   467
    if( lastTokenParsed!=TK_SEMI ){
dvander@1203
   468
      sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
dvander@1203
   469
      pParse->zTail = &zSql[i];
dvander@1203
   470
    }
dvander@1203
   471
    sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
dvander@1203
   472
  }
dvander@1203
   473
  sqlite3ParserFree(pEngine, sqlite3FreeX);
dvander@1203
   474
  if( sqlite3MallocFailed() ){
dvander@1203
   475
    pParse->rc = SQLITE_NOMEM;
dvander@1203
   476
  }
dvander@1203
   477
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
dvander@1203
   478
    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);
dvander@1203
   479
  }
dvander@1203
   480
  if( pParse->zErrMsg ){
dvander@1203
   481
    if( pzErrMsg && *pzErrMsg==0 ){
dvander@1203
   482
      *pzErrMsg = pParse->zErrMsg;
dvander@1203
   483
    }else{
dvander@1203
   484
      sqliteFree(pParse->zErrMsg);
dvander@1203
   485
    }
dvander@1203
   486
    pParse->zErrMsg = 0;
dvander@1203
   487
    if( !nErr ) nErr++;
dvander@1203
   488
  }
dvander@1203
   489
  if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
dvander@1203
   490
    sqlite3VdbeDelete(pParse->pVdbe);
dvander@1203
   491
    pParse->pVdbe = 0;
dvander@1203
   492
  }
dvander@1203
   493
#ifndef SQLITE_OMIT_SHARED_CACHE
dvander@1203
   494
  if( pParse->nested==0 ){
dvander@1203
   495
    sqliteFree(pParse->aTableLock);
dvander@1203
   496
    pParse->aTableLock = 0;
dvander@1203
   497
    pParse->nTableLock = 0;
dvander@1203
   498
  }
dvander@1203
   499
#endif
dvander@1203
   500
dvander@1203
   501
  if( !IN_DECLARE_VTAB ){
dvander@1203
   502
    /* If the pParse->declareVtab flag is set, do not delete any table 
dvander@1203
   503
    ** structure built up in pParse->pNewTable. The calling code (see vtab.c)
dvander@1203
   504
    ** will take responsibility for freeing the Table structure.
dvander@1203
   505
    */
dvander@1203
   506
    sqlite3DeleteTable(pParse->pNewTable);
dvander@1203
   507
  }
dvander@1203
   508
dvander@1203
   509
  sqlite3DeleteTrigger(pParse->pNewTrigger);
dvander@1203
   510
  sqliteFree(pParse->apVarExpr);
dvander@1203
   511
  if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
dvander@1203
   512
    pParse->rc = SQLITE_ERROR;
dvander@1203
   513
  }
dvander@1203
   514
  return nErr;
dvander@1203
   515
}