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