| OLD | NEW | 
 | (Empty) | 
|    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 implements the sqlite3_complete() API. |  | 
|   15 ** This code used to be part of the tokenizer.c source file.  But by |  | 
|   16 ** separating it out, the code will be automatically omitted from |  | 
|   17 ** static links that do not use it. |  | 
|   18 ** |  | 
|   19 ** $Id: complete.c,v 1.8 2009/04/28 04:46:42 drh Exp $ |  | 
|   20 */ |  | 
|   21 #include "sqliteInt.h" |  | 
|   22 #ifndef SQLITE_OMIT_COMPLETE |  | 
|   23  |  | 
|   24 /* |  | 
|   25 ** This is defined in tokenize.c.  We just have to import the definition. |  | 
|   26 */ |  | 
|   27 #ifndef SQLITE_AMALGAMATION |  | 
|   28 #ifdef SQLITE_ASCII |  | 
|   29 extern const char sqlite3IsAsciiIdChar[]; |  | 
|   30 #define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsAsciiIdChar[c-0x20])) |  | 
|   31 #endif |  | 
|   32 #ifdef SQLITE_EBCDIC |  | 
|   33 extern const char sqlite3IsEbcdicIdChar[]; |  | 
|   34 #define IdChar(C)  (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) |  | 
|   35 #endif |  | 
|   36 #endif /* SQLITE_AMALGAMATION */ |  | 
|   37  |  | 
|   38  |  | 
|   39 /* |  | 
|   40 ** Token types used by the sqlite3_complete() routine.  See the header |  | 
|   41 ** comments on that procedure for additional information. |  | 
|   42 */ |  | 
|   43 #define tkSEMI    0 |  | 
|   44 #define tkWS      1 |  | 
|   45 #define tkOTHER   2 |  | 
|   46 #define tkEXPLAIN 3 |  | 
|   47 #define tkCREATE  4 |  | 
|   48 #define tkTEMP    5 |  | 
|   49 #define tkTRIGGER 6 |  | 
|   50 #define tkEND     7 |  | 
|   51  |  | 
|   52 /* |  | 
|   53 ** Return TRUE if the given SQL string ends in a semicolon. |  | 
|   54 ** |  | 
|   55 ** Special handling is require for CREATE TRIGGER statements. |  | 
|   56 ** Whenever the CREATE TRIGGER keywords are seen, the statement |  | 
|   57 ** must end with ";END;". |  | 
|   58 ** |  | 
|   59 ** This implementation uses a state machine with 7 states: |  | 
|   60 ** |  | 
|   61 **   (0) START     At the beginning or end of an SQL statement.  This routine |  | 
|   62 **                 returns 1 if it ends in the START state and 0 if it ends |  | 
|   63 **                 in any other state. |  | 
|   64 ** |  | 
|   65 **   (1) NORMAL    We are in the middle of statement which ends with a single |  | 
|   66 **                 semicolon. |  | 
|   67 ** |  | 
|   68 **   (2) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of  |  | 
|   69 **                 a statement. |  | 
|   70 ** |  | 
|   71 **   (3) CREATE    The keyword CREATE has been seen at the beginning of a |  | 
|   72 **                 statement, possibly preceeded by EXPLAIN and/or followed by |  | 
|   73 **                 TEMP or TEMPORARY |  | 
|   74 ** |  | 
|   75 **   (4) TRIGGER   We are in the middle of a trigger definition that must be |  | 
|   76 **                 ended by a semicolon, the keyword END, and another semicolon. |  | 
|   77 ** |  | 
|   78 **   (5) SEMI      We've seen the first semicolon in the ";END;" that occurs at |  | 
|   79 **                 the end of a trigger definition. |  | 
|   80 ** |  | 
|   81 **   (6) END       We've seen the ";END" of the ";END;" that occurs at the end |  | 
|   82 **                 of a trigger difinition. |  | 
|   83 ** |  | 
|   84 ** Transitions between states above are determined by tokens extracted |  | 
|   85 ** from the input.  The following tokens are significant: |  | 
|   86 ** |  | 
|   87 **   (0) tkSEMI      A semicolon. |  | 
|   88 **   (1) tkWS        Whitespace |  | 
|   89 **   (2) tkOTHER     Any other SQL token. |  | 
|   90 **   (3) tkEXPLAIN   The "explain" keyword. |  | 
|   91 **   (4) tkCREATE    The "create" keyword. |  | 
|   92 **   (5) tkTEMP      The "temp" or "temporary" keyword. |  | 
|   93 **   (6) tkTRIGGER   The "trigger" keyword. |  | 
|   94 **   (7) tkEND       The "end" keyword. |  | 
|   95 ** |  | 
|   96 ** Whitespace never causes a state transition and is always ignored. |  | 
|   97 ** |  | 
|   98 ** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed |  | 
|   99 ** to recognize the end of a trigger can be omitted.  All we have to do |  | 
|  100 ** is look for a semicolon that is not part of an string or comment. |  | 
|  101 */ |  | 
|  102 int sqlite3_complete(const char *zSql){ |  | 
|  103   u8 state = 0;   /* Current state, using numbers defined in header comment */ |  | 
|  104   u8 token;       /* Value of the next token */ |  | 
|  105  |  | 
|  106 #ifndef SQLITE_OMIT_TRIGGER |  | 
|  107   /* A complex statement machine used to detect the end of a CREATE TRIGGER |  | 
|  108   ** statement.  This is the normal case. |  | 
|  109   */ |  | 
|  110   static const u8 trans[7][8] = { |  | 
|  111                      /* Token:                                                */ |  | 
|  112      /* State:       **  SEMI  WS  OTHER EXPLAIN  CREATE  TEMP  TRIGGER  END  */ |  | 
|  113      /* 0   START: */ {    0,  0,     1,      2,      3,    1,       1,   1,  }, |  | 
|  114      /* 1  NORMAL: */ {    0,  1,     1,      1,      1,    1,       1,   1,  }, |  | 
|  115      /* 2 EXPLAIN: */ {    0,  2,     2,      1,      3,    1,       1,   1,  }, |  | 
|  116      /* 3  CREATE: */ {    0,  3,     1,      1,      1,    3,       4,   1,  }, |  | 
|  117      /* 4 TRIGGER: */ {    5,  4,     4,      4,      4,    4,       4,   4,  }, |  | 
|  118      /* 5    SEMI: */ {    5,  5,     4,      4,      4,    4,       4,   6,  }, |  | 
|  119      /* 6     END: */ {    0,  6,     4,      4,      4,    4,       4,   4,  }, |  | 
|  120   }; |  | 
|  121 #else |  | 
|  122   /* If triggers are not suppored by this compile then the statement machine |  | 
|  123   ** used to detect the end of a statement is much simplier |  | 
|  124   */ |  | 
|  125   static const u8 trans[2][3] = { |  | 
|  126                      /* Token:           */ |  | 
|  127      /* State:       **  SEMI  WS  OTHER */ |  | 
|  128      /* 0   START: */ {    0,  0,     1, }, |  | 
|  129      /* 1  NORMAL: */ {    0,  1,     1, }, |  | 
|  130   }; |  | 
|  131 #endif /* SQLITE_OMIT_TRIGGER */ |  | 
|  132  |  | 
|  133   while( *zSql ){ |  | 
|  134     switch( *zSql ){ |  | 
|  135       case ';': {  /* A semicolon */ |  | 
|  136         token = tkSEMI; |  | 
|  137         break; |  | 
|  138       } |  | 
|  139       case ' ': |  | 
|  140       case '\r': |  | 
|  141       case '\t': |  | 
|  142       case '\n': |  | 
|  143       case '\f': {  /* White space is ignored */ |  | 
|  144         token = tkWS; |  | 
|  145         break; |  | 
|  146       } |  | 
|  147       case '/': {   /* C-style comments */ |  | 
|  148         if( zSql[1]!='*' ){ |  | 
|  149           token = tkOTHER; |  | 
|  150           break; |  | 
|  151         } |  | 
|  152         zSql += 2; |  | 
|  153         while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; } |  | 
|  154         if( zSql[0]==0 ) return 0; |  | 
|  155         zSql++; |  | 
|  156         token = tkWS; |  | 
|  157         break; |  | 
|  158       } |  | 
|  159       case '-': {   /* SQL-style comments from "--" to end of line */ |  | 
|  160         if( zSql[1]!='-' ){ |  | 
|  161           token = tkOTHER; |  | 
|  162           break; |  | 
|  163         } |  | 
|  164         while( *zSql && *zSql!='\n' ){ zSql++; } |  | 
|  165         if( *zSql==0 ) return state==0; |  | 
|  166         token = tkWS; |  | 
|  167         break; |  | 
|  168       } |  | 
|  169       case '[': {   /* Microsoft-style identifiers in [...] */ |  | 
|  170         zSql++; |  | 
|  171         while( *zSql && *zSql!=']' ){ zSql++; } |  | 
|  172         if( *zSql==0 ) return 0; |  | 
|  173         token = tkOTHER; |  | 
|  174         break; |  | 
|  175       } |  | 
|  176       case '`':     /* Grave-accent quoted symbols used by MySQL */ |  | 
|  177       case '"':     /* single- and double-quoted strings */ |  | 
|  178       case '\'': { |  | 
|  179         int c = *zSql; |  | 
|  180         zSql++; |  | 
|  181         while( *zSql && *zSql!=c ){ zSql++; } |  | 
|  182         if( *zSql==0 ) return 0; |  | 
|  183         token = tkOTHER; |  | 
|  184         break; |  | 
|  185       } |  | 
|  186       default: { |  | 
|  187         int c; |  | 
|  188         if( IdChar((u8)*zSql) ){ |  | 
|  189           /* Keywords and unquoted identifiers */ |  | 
|  190           int nId; |  | 
|  191           for(nId=1; IdChar(zSql[nId]); nId++){} |  | 
|  192 #ifdef SQLITE_OMIT_TRIGGER |  | 
|  193           token = tkOTHER; |  | 
|  194 #else |  | 
|  195           switch( *zSql ){ |  | 
|  196             case 'c': case 'C': { |  | 
|  197               if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ |  | 
|  198                 token = tkCREATE; |  | 
|  199               }else{ |  | 
|  200                 token = tkOTHER; |  | 
|  201               } |  | 
|  202               break; |  | 
|  203             } |  | 
|  204             case 't': case 'T': { |  | 
|  205               if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){ |  | 
|  206                 token = tkTRIGGER; |  | 
|  207               }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){ |  | 
|  208                 token = tkTEMP; |  | 
|  209               }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){ |  | 
|  210                 token = tkTEMP; |  | 
|  211               }else{ |  | 
|  212                 token = tkOTHER; |  | 
|  213               } |  | 
|  214               break; |  | 
|  215             } |  | 
|  216             case 'e':  case 'E': { |  | 
|  217               if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ |  | 
|  218                 token = tkEND; |  | 
|  219               }else |  | 
|  220 #ifndef SQLITE_OMIT_EXPLAIN |  | 
|  221               if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ |  | 
|  222                 token = tkEXPLAIN; |  | 
|  223               }else |  | 
|  224 #endif |  | 
|  225               { |  | 
|  226                 token = tkOTHER; |  | 
|  227               } |  | 
|  228               break; |  | 
|  229             } |  | 
|  230             default: { |  | 
|  231               token = tkOTHER; |  | 
|  232               break; |  | 
|  233             } |  | 
|  234           } |  | 
|  235 #endif /* SQLITE_OMIT_TRIGGER */ |  | 
|  236           zSql += nId-1; |  | 
|  237         }else{ |  | 
|  238           /* Operators and special symbols */ |  | 
|  239           token = tkOTHER; |  | 
|  240         } |  | 
|  241         break; |  | 
|  242       } |  | 
|  243     } |  | 
|  244     state = trans[state][token]; |  | 
|  245     zSql++; |  | 
|  246   } |  | 
|  247   return state==0; |  | 
|  248 } |  | 
|  249  |  | 
|  250 #ifndef SQLITE_OMIT_UTF16 |  | 
|  251 /* |  | 
|  252 ** This routine is the same as the sqlite3_complete() routine described |  | 
|  253 ** above, except that the parameter is required to be UTF-16 encoded, not |  | 
|  254 ** UTF-8. |  | 
|  255 */ |  | 
|  256 int sqlite3_complete16(const void *zSql){ |  | 
|  257   sqlite3_value *pVal; |  | 
|  258   char const *zSql8; |  | 
|  259   int rc = SQLITE_NOMEM; |  | 
|  260  |  | 
|  261 #ifndef SQLITE_OMIT_AUTOINIT |  | 
|  262   rc = sqlite3_initialize(); |  | 
|  263   if( rc ) return rc; |  | 
|  264 #endif |  | 
|  265   pVal = sqlite3ValueNew(0); |  | 
|  266   sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); |  | 
|  267   zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); |  | 
|  268   if( zSql8 ){ |  | 
|  269     rc = sqlite3_complete(zSql8); |  | 
|  270   }else{ |  | 
|  271     rc = SQLITE_NOMEM; |  | 
|  272   } |  | 
|  273   sqlite3ValueFree(pVal); |  | 
|  274   return sqlite3ApiExit(0, rc); |  | 
|  275 } |  | 
|  276 #endif /* SQLITE_OMIT_UTF16 */ |  | 
|  277 #endif /* SQLITE_OMIT_COMPLETE */ |  | 
| OLD | NEW |