1 
2 #pragma ident	"%Z%%M%	%I%	%E% SMI"
3 
4 /*
5 ** 2001 September 15
6 **
7 ** The author disclaims copyright to this source code.  In place of
8 ** a legal notice, here is a blessing:
9 **
10 **    May you do good and not evil.
11 **    May you find forgiveness for yourself and forgive others.
12 **    May you share freely, never taking more than you give.
13 **
14 *************************************************************************
15 ** An tokenizer for SQL
16 **
17 ** This file contains C code that splits an SQL input string up into
18 ** individual tokens and sends those tokens one-by-one over to the
19 ** parser for analysis.
20 **
21 ** $Id: tokenize.c,v 1.68 2004/02/14 23:59:58 drh Exp $
22 */
23 #include "sqliteInt.h"
24 #include "os.h"
25 #include <ctype.h>
26 #include <stdlib.h>
27 
28 /*
29 ** All the keywords of the SQL language are stored as in a hash
30 ** table composed of instances of the following structure.
31 */
32 typedef struct Keyword Keyword;
33 struct Keyword {
34   char *zName;             /* The keyword name */
35   u8 tokenType;            /* Token value for this keyword */
36   u8 len;                  /* Length of this keyword */
37   u8 iNext;                /* Index in aKeywordTable[] of next with same hash */
38 };
39 
40 /*
41 ** These are the keywords
42 */
43 static Keyword aKeywordTable[] = {
44   { "ABORT",             TK_ABORT,        },
45   { "AFTER",             TK_AFTER,        },
46   { "ALL",               TK_ALL,          },
47   { "AND",               TK_AND,          },
48   { "AS",                TK_AS,           },
49   { "ASC",               TK_ASC,          },
50   { "ATTACH",            TK_ATTACH,       },
51   { "BEFORE",            TK_BEFORE,       },
52   { "BEGIN",             TK_BEGIN,        },
53   { "BETWEEN",           TK_BETWEEN,      },
54   { "BY",                TK_BY,           },
55   { "CASCADE",           TK_CASCADE,      },
56   { "CASE",              TK_CASE,         },
57   { "CHECK",             TK_CHECK,        },
58   { "CLUSTER",           TK_CLUSTER,      },
59   { "COLLATE",           TK_COLLATE,      },
60   { "COMMIT",            TK_COMMIT,       },
61   { "CONFLICT",          TK_CONFLICT,     },
62   { "CONSTRAINT",        TK_CONSTRAINT,   },
63   { "COPY",              TK_COPY,         },
64   { "CREATE",            TK_CREATE,       },
65   { "CROSS",             TK_JOIN_KW,      },
66   { "DATABASE",          TK_DATABASE,     },
67   { "DEFAULT",           TK_DEFAULT,      },
68   { "DEFERRED",          TK_DEFERRED,     },
69   { "DEFERRABLE",        TK_DEFERRABLE,   },
70   { "DELETE",            TK_DELETE,       },
71   { "DELIMITERS",        TK_DELIMITERS,   },
72   { "DESC",              TK_DESC,         },
73   { "DETACH",            TK_DETACH,       },
74   { "DISTINCT",          TK_DISTINCT,     },
75   { "DROP",              TK_DROP,         },
76   { "END",               TK_END,          },
77   { "EACH",              TK_EACH,         },
78   { "ELSE",              TK_ELSE,         },
79   { "EXCEPT",            TK_EXCEPT,       },
80   { "EXPLAIN",           TK_EXPLAIN,      },
81   { "FAIL",              TK_FAIL,         },
82   { "FOR",               TK_FOR,          },
83   { "FOREIGN",           TK_FOREIGN,      },
84   { "FROM",              TK_FROM,         },
85   { "FULL",              TK_JOIN_KW,      },
86   { "GLOB",              TK_GLOB,         },
87   { "GROUP",             TK_GROUP,        },
88   { "HAVING",            TK_HAVING,       },
89   { "IGNORE",            TK_IGNORE,       },
90   { "IMMEDIATE",         TK_IMMEDIATE,    },
91   { "IN",                TK_IN,           },
92   { "INDEX",             TK_INDEX,        },
93   { "INITIALLY",         TK_INITIALLY,    },
94   { "INNER",             TK_JOIN_KW,      },
95   { "INSERT",            TK_INSERT,       },
96   { "INSTEAD",           TK_INSTEAD,      },
97   { "INTERSECT",         TK_INTERSECT,    },
98   { "INTO",              TK_INTO,         },
99   { "IS",                TK_IS,           },
100   { "ISNULL",            TK_ISNULL,       },
101   { "JOIN",              TK_JOIN,         },
102   { "KEY",               TK_KEY,          },
103   { "LEFT",              TK_JOIN_KW,      },
104   { "LIKE",              TK_LIKE,         },
105   { "LIMIT",             TK_LIMIT,        },
106   { "MATCH",             TK_MATCH,        },
107   { "NATURAL",           TK_JOIN_KW,      },
108   { "NOT",               TK_NOT,          },
109   { "NOTNULL",           TK_NOTNULL,      },
110   { "NULL",              TK_NULL,         },
111   { "OF",                TK_OF,           },
112   { "OFFSET",            TK_OFFSET,       },
113   { "ON",                TK_ON,           },
114   { "OR",                TK_OR,           },
115   { "ORDER",             TK_ORDER,        },
116   { "OUTER",             TK_JOIN_KW,      },
117   { "PRAGMA",            TK_PRAGMA,       },
118   { "PRIMARY",           TK_PRIMARY,      },
119   { "RAISE",             TK_RAISE,        },
120   { "REFERENCES",        TK_REFERENCES,   },
121   { "REPLACE",           TK_REPLACE,      },
122   { "RESTRICT",          TK_RESTRICT,     },
123   { "RIGHT",             TK_JOIN_KW,      },
124   { "ROLLBACK",          TK_ROLLBACK,     },
125   { "ROW",               TK_ROW,          },
126   { "SELECT",            TK_SELECT,       },
127   { "SET",               TK_SET,          },
128   { "STATEMENT",         TK_STATEMENT,    },
129   { "TABLE",             TK_TABLE,        },
130   { "TEMP",              TK_TEMP,         },
131   { "TEMPORARY",         TK_TEMP,         },
132   { "THEN",              TK_THEN,         },
133   { "TRANSACTION",       TK_TRANSACTION,  },
134   { "TRIGGER",           TK_TRIGGER,      },
135   { "UNION",             TK_UNION,        },
136   { "UNIQUE",            TK_UNIQUE,       },
137   { "UPDATE",            TK_UPDATE,       },
138   { "USING",             TK_USING,        },
139   { "VACUUM",            TK_VACUUM,       },
140   { "VALUES",            TK_VALUES,       },
141   { "VIEW",              TK_VIEW,         },
142   { "WHEN",              TK_WHEN,         },
143   { "WHERE",             TK_WHERE,        },
144 };
145 
146 /*
147 ** This is the hash table
148 */
149 #define KEY_HASH_SIZE 101
150 static u8 aiHashTable[KEY_HASH_SIZE];
151 
152 
153 /*
154 ** This function looks up an identifier to determine if it is a
155 ** keyword.  If it is a keyword, the token code of that keyword is
156 ** returned.  If the input is not a keyword, TK_ID is returned.
157 */
158 int sqliteKeywordCode(const char *z, int n){
159   int h, i;
160   Keyword *p;
161   static char needInit = 1;
162   if( needInit ){
163     /* Initialize the keyword hash table */
164     sqliteOsEnterMutex();
165     if( needInit ){
166       int nk;
167       nk = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]);
168       for(i=0; i<nk; i++){
169         aKeywordTable[i].len = strlen(aKeywordTable[i].zName);
170         h = sqliteHashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len);
171         h %= KEY_HASH_SIZE;
172         aKeywordTable[i].iNext = aiHashTable[h];
173         aiHashTable[h] = i+1;
174       }
175       needInit = 0;
176     }
177     sqliteOsLeaveMutex();
178   }
179   h = sqliteHashNoCase(z, n) % KEY_HASH_SIZE;
180   for(i=aiHashTable[h]; i; i=p->iNext){
181     p = &aKeywordTable[i-1];
182     if( p->len==n && sqliteStrNICmp(p->zName, z, n)==0 ){
183       return p->tokenType;
184     }
185   }
186   return TK_ID;
187 }
188 
189 
190 /*
191 ** If X is a character that can be used in an identifier and
192 ** X&0x80==0 then isIdChar[X] will be 1.  If X&0x80==0x80 then
193 ** X is always an identifier character.  (Hence all UTF-8
194 ** characters can be part of an identifier).  isIdChar[X] will
195 ** be 0 for every character in the lower 128 ASCII characters
196 ** that cannot be used as part of an identifier.
197 **
198 ** In this implementation, an identifier can be a string of
199 ** alphabetic characters, digits, and "_" plus any character
200 ** with the high-order bit set.  The latter rule means that
201 ** any sequence of UTF-8 characters or characters taken from
202 ** an extended ISO8859 character set can form an identifier.
203 */
204 static const char isIdChar[] = {
205 /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
206     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x */
207     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 1x */
208     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 2x */
209     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 3x */
210     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 4x */
211     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  /* 5x */
212     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 6x */
213     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 7x */
214 };
215 
216 
217 /*
218 ** Return the length of the token that begins at z[0].
219 ** Store the token type in *tokenType before returning.
220 */
221 static int sqliteGetToken(const unsigned char *z, int *tokenType){
222   int i;
223   switch( *z ){
224     case ' ': case '\t': case '\n': case '\f': case '\r': {
225       for(i=1; isspace(z[i]); i++){}
226       *tokenType = TK_SPACE;
227       return i;
228     }
229     case '-': {
230       if( z[1]=='-' ){
231         for(i=2; z[i] && z[i]!='\n'; i++){}
232         *tokenType = TK_COMMENT;
233         return i;
234       }
235       *tokenType = TK_MINUS;
236       return 1;
237     }
238     case '(': {
239       *tokenType = TK_LP;
240       return 1;
241     }
242     case ')': {
243       *tokenType = TK_RP;
244       return 1;
245     }
246     case ';': {
247       *tokenType = TK_SEMI;
248       return 1;
249     }
250     case '+': {
251       *tokenType = TK_PLUS;
252       return 1;
253     }
254     case '*': {
255       *tokenType = TK_STAR;
256       return 1;
257     }
258     case '/': {
259       if( z[1]!='*' || z[2]==0 ){
260         *tokenType = TK_SLASH;
261         return 1;
262       }
263       for(i=3; z[i] && (z[i]!='/' || z[i-1]!='*'); i++){}
264       if( z[i] ) i++;
265       *tokenType = TK_COMMENT;
266       return i;
267     }
268     case '%': {
269       *tokenType = TK_REM;
270       return 1;
271     }
272     case '=': {
273       *tokenType = TK_EQ;
274       return 1 + (z[1]=='=');
275     }
276     case '<': {
277       if( z[1]=='=' ){
278         *tokenType = TK_LE;
279         return 2;
280       }else if( z[1]=='>' ){
281         *tokenType = TK_NE;
282         return 2;
283       }else if( z[1]=='<' ){
284         *tokenType = TK_LSHIFT;
285         return 2;
286       }else{
287         *tokenType = TK_LT;
288         return 1;
289       }
290     }
291     case '>': {
292       if( z[1]=='=' ){
293         *tokenType = TK_GE;
294         return 2;
295       }else if( z[1]=='>' ){
296         *tokenType = TK_RSHIFT;
297         return 2;
298       }else{
299         *tokenType = TK_GT;
300         return 1;
301       }
302     }
303     case '!': {
304       if( z[1]!='=' ){
305         *tokenType = TK_ILLEGAL;
306         return 2;
307       }else{
308         *tokenType = TK_NE;
309         return 2;
310       }
311     }
312     case '|': {
313       if( z[1]!='|' ){
314         *tokenType = TK_BITOR;
315         return 1;
316       }else{
317         *tokenType = TK_CONCAT;
318         return 2;
319       }
320     }
321     case ',': {
322       *tokenType = TK_COMMA;
323       return 1;
324     }
325     case '&': {
326       *tokenType = TK_BITAND;
327       return 1;
328     }
329     case '~': {
330       *tokenType = TK_BITNOT;
331       return 1;
332     }
333     case '\'': case '"': {
334       int delim = z[0];
335       for(i=1; z[i]; i++){
336         if( z[i]==delim ){
337           if( z[i+1]==delim ){
338             i++;
339           }else{
340             break;
341           }
342         }
343       }
344       if( z[i] ) i++;
345       *tokenType = TK_STRING;
346       return i;
347     }
348     case '.': {
349       *tokenType = TK_DOT;
350       return 1;
351     }
352     case '0': case '1': case '2': case '3': case '4':
353     case '5': case '6': case '7': case '8': case '9': {
354       *tokenType = TK_INTEGER;
355       for(i=1; isdigit(z[i]); i++){}
356       if( z[i]=='.' && isdigit(z[i+1]) ){
357         i += 2;
358         while( isdigit(z[i]) ){ i++; }
359         *tokenType = TK_FLOAT;
360       }
361       if( (z[i]=='e' || z[i]=='E') &&
362            ( isdigit(z[i+1])
363             || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
364            )
365       ){
366         i += 2;
367         while( isdigit(z[i]) ){ i++; }
368         *tokenType = TK_FLOAT;
369       }
370       return i;
371     }
372     case '[': {
373       for(i=1; z[i] && z[i-1]!=']'; i++){}
374       *tokenType = TK_ID;
375       return i;
376     }
377     case '?': {
378       *tokenType = TK_VARIABLE;
379       return 1;
380     }
381     default: {
382       if( (*z&0x80)==0 && !isIdChar[*z] ){
383         break;
384       }
385       for(i=1; (z[i]&0x80)!=0 || isIdChar[z[i]]; i++){}
386       *tokenType = sqliteKeywordCode((char*)z, i);
387       return i;
388     }
389   }
390   *tokenType = TK_ILLEGAL;
391   return 1;
392 }
393 
394 /*
395 ** Run the parser on the given SQL string.  The parser structure is
396 ** passed in.  An SQLITE_ status code is returned.  If an error occurs
397 ** and pzErrMsg!=NULL then an error message might be written into
398 ** memory obtained from malloc() and *pzErrMsg made to point to that
399 ** error message.  Or maybe not.
400 */
401 int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
402   int nErr = 0;
403   int i;
404   void *pEngine;
405   int tokenType;
406   int lastTokenParsed = -1;
407   sqlite *db = pParse->db;
408   extern void *sqliteParserAlloc(void*(*)(int));
409   extern void sqliteParserFree(void*, void(*)(void*));
410   extern int sqliteParser(void*, int, Token, Parse*);
411 
412   db->flags &= ~SQLITE_Interrupt;
413   pParse->rc = SQLITE_OK;
414   i = 0;
415   pEngine = sqliteParserAlloc((void*(*)(int))malloc);
416   if( pEngine==0 ){
417     sqliteSetString(pzErrMsg, "out of memory", (char*)0);
418     return 1;
419   }
420   pParse->sLastToken.dyn = 0;
421   pParse->zTail = zSql;
422   while( sqlite_malloc_failed==0 && zSql[i]!=0 ){
423     assert( i>=0 );
424     pParse->sLastToken.z = &zSql[i];
425     assert( pParse->sLastToken.dyn==0 );
426     pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType);
427     i += pParse->sLastToken.n;
428     switch( tokenType ){
429       case TK_SPACE:
430       case TK_COMMENT: {
431         if( (db->flags & SQLITE_Interrupt)!=0 ){
432           pParse->rc = SQLITE_INTERRUPT;
433           sqliteSetString(pzErrMsg, "interrupt", (char*)0);
434           goto abort_parse;
435         }
436         break;
437       }
438       case TK_ILLEGAL: {
439         sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1,
440            pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0);
441         nErr++;
442         goto abort_parse;
443       }
444       case TK_SEMI: {
445         pParse->zTail = &zSql[i];
446         /* Fall thru into the default case */
447       }
448       default: {
449         sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse);
450         lastTokenParsed = tokenType;
451         if( pParse->rc!=SQLITE_OK ){
452           goto abort_parse;
453         }
454         break;
455       }
456     }
457   }
458 abort_parse:
459   if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
460     if( lastTokenParsed!=TK_SEMI ){
461       sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
462       pParse->zTail = &zSql[i];
463     }
464     sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
465   }
466   sqliteParserFree(pEngine, free);
467   if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
468     sqliteSetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc),
469                     (char*)0);
470   }
471   if( pParse->zErrMsg ){
472     if( pzErrMsg && *pzErrMsg==0 ){
473       *pzErrMsg = pParse->zErrMsg;
474     }else{
475       sqliteFree(pParse->zErrMsg);
476     }
477     pParse->zErrMsg = 0;
478     if( !nErr ) nErr++;
479   }
480   if( pParse->pVdbe && pParse->nErr>0 ){
481     sqliteVdbeDelete(pParse->pVdbe);
482     pParse->pVdbe = 0;
483   }
484   if( pParse->pNewTable ){
485     sqliteDeleteTable(pParse->db, pParse->pNewTable);
486     pParse->pNewTable = 0;
487   }
488   if( pParse->pNewTrigger ){
489     sqliteDeleteTrigger(pParse->pNewTrigger);
490     pParse->pNewTrigger = 0;
491   }
492   if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
493     pParse->rc = SQLITE_ERROR;
494   }
495   return nErr;
496 }
497 
498 /*
499 ** Token types used by the sqlite_complete() routine.  See the header
500 ** comments on that procedure for additional information.
501 */
502 #define tkEXPLAIN 0
503 #define tkCREATE  1
504 #define tkTEMP    2
505 #define tkTRIGGER 3
506 #define tkEND     4
507 #define tkSEMI    5
508 #define tkWS      6
509 #define tkOTHER   7
510 
511 /*
512 ** Return TRUE if the given SQL string ends in a semicolon.
513 **
514 ** Special handling is require for CREATE TRIGGER statements.
515 ** Whenever the CREATE TRIGGER keywords are seen, the statement
516 ** must end with ";END;".
517 **
518 ** This implementation uses a state machine with 7 states:
519 **
520 **   (0) START     At the beginning or end of an SQL statement.  This routine
521 **                 returns 1 if it ends in the START state and 0 if it ends
522 **                 in any other state.
523 **
524 **   (1) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of
525 **                 a statement.
526 **
527 **   (2) CREATE    The keyword CREATE has been seen at the beginning of a
528 **                 statement, possibly preceeded by EXPLAIN and/or followed by
529 **                 TEMP or TEMPORARY
530 **
531 **   (3) NORMAL    We are in the middle of statement which ends with a single
532 **                 semicolon.
533 **
534 **   (4) TRIGGER   We are in the middle of a trigger definition that must be
535 **                 ended by a semicolon, the keyword END, and another semicolon.
536 **
537 **   (5) SEMI      We've seen the first semicolon in the ";END;" that occurs at
538 **                 the end of a trigger definition.
539 **
540 **   (6) END       We've seen the ";END" of the ";END;" that occurs at the end
541 **                 of a trigger difinition.
542 **
543 ** Transitions between states above are determined by tokens extracted
544 ** from the input.  The following tokens are significant:
545 **
546 **   (0) tkEXPLAIN   The "explain" keyword.
547 **   (1) tkCREATE    The "create" keyword.
548 **   (2) tkTEMP      The "temp" or "temporary" keyword.
549 **   (3) tkTRIGGER   The "trigger" keyword.
550 **   (4) tkEND       The "end" keyword.
551 **   (5) tkSEMI      A semicolon.
552 **   (6) tkWS        Whitespace
553 **   (7) tkOTHER     Any other SQL token.
554 **
555 ** Whitespace never causes a state transition and is always ignored.
556 */
557 int sqlite_complete(const char *zSql){
558   u8 state = 0;   /* Current state, using numbers defined in header comment */
559   u8 token;       /* Value of the next token */
560 
561   /* The following matrix defines the transition from one state to another
562   ** according to what token is seen.  trans[state][token] returns the
563   ** next state.
564   */
565   static const u8 trans[7][8] = {
566                      /* Token:                                                */
567      /* State:       **  EXPLAIN  CREATE  TEMP  TRIGGER  END  SEMI  WS  OTHER */
568      /* 0   START: */ {       1,      2,    3,       3,   3,    0,  0,     3, },
569      /* 1 EXPLAIN: */ {       3,      2,    3,       3,   3,    0,  1,     3, },
570      /* 2  CREATE: */ {       3,      3,    2,       4,   3,    0,  2,     3, },
571      /* 3  NORMAL: */ {       3,      3,    3,       3,   3,    0,  3,     3, },
572      /* 4 TRIGGER: */ {       4,      4,    4,       4,   4,    5,  4,     4, },
573      /* 5    SEMI: */ {       4,      4,    4,       4,   6,    5,  5,     4, },
574      /* 6     END: */ {       4,      4,    4,       4,   4,    0,  6,     4, },
575   };
576 
577   while( *zSql ){
578     switch( *zSql ){
579       case ';': {  /* A semicolon */
580         token = tkSEMI;
581         break;
582       }
583       case ' ':
584       case '\r':
585       case '\t':
586       case '\n':
587       case '\f': {  /* White space is ignored */
588         token = tkWS;
589         break;
590       }
591       case '/': {   /* C-style comments */
592         if( zSql[1]!='*' ){
593           token = tkOTHER;
594           break;
595         }
596         zSql += 2;
597         while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
598         if( zSql[0]==0 ) return 0;
599         zSql++;
600         token = tkWS;
601         break;
602       }
603       case '-': {   /* SQL-style comments from "--" to end of line */
604         if( zSql[1]!='-' ){
605           token = tkOTHER;
606           break;
607         }
608         while( *zSql && *zSql!='\n' ){ zSql++; }
609         if( *zSql==0 ) return state==0;
610         token = tkWS;
611         break;
612       }
613       case '[': {   /* Microsoft-style identifiers in [...] */
614         zSql++;
615         while( *zSql && *zSql!=']' ){ zSql++; }
616         if( *zSql==0 ) return 0;
617         token = tkOTHER;
618         break;
619       }
620       case '"':     /* single- and double-quoted strings */
621       case '\'': {
622         int c = *zSql;
623         zSql++;
624         while( *zSql && *zSql!=c ){ zSql++; }
625         if( *zSql==0 ) return 0;
626         token = tkOTHER;
627         break;
628       }
629       default: {
630         if( isIdChar[(u8)*zSql] ){
631           /* Keywords and unquoted identifiers */
632           int nId;
633           for(nId=1; isIdChar[(u8)zSql[nId]]; nId++){}
634           switch( *zSql ){
635             case 'c': case 'C': {
636               if( nId==6 && sqliteStrNICmp(zSql, "create", 6)==0 ){
637                 token = tkCREATE;
638               }else{
639                 token = tkOTHER;
640               }
641               break;
642             }
643             case 't': case 'T': {
644               if( nId==7 && sqliteStrNICmp(zSql, "trigger", 7)==0 ){
645                 token = tkTRIGGER;
646               }else if( nId==4 && sqliteStrNICmp(zSql, "temp", 4)==0 ){
647                 token = tkTEMP;
648               }else if( nId==9 && sqliteStrNICmp(zSql, "temporary", 9)==0 ){
649                 token = tkTEMP;
650               }else{
651                 token = tkOTHER;
652               }
653               break;
654             }
655             case 'e':  case 'E': {
656               if( nId==3 && sqliteStrNICmp(zSql, "end", 3)==0 ){
657                 token = tkEND;
658               }else if( nId==7 && sqliteStrNICmp(zSql, "explain", 7)==0 ){
659                 token = tkEXPLAIN;
660               }else{
661                 token = tkOTHER;
662               }
663               break;
664             }
665             default: {
666               token = tkOTHER;
667               break;
668             }
669           }
670           zSql += nId-1;
671         }else{
672           /* Operators and special symbols */
673           token = tkOTHER;
674         }
675         break;
676       }
677     }
678     state = trans[state][token];
679     zSql++;
680   }
681   return state==0;
682 }
683