complete.c.svn-base
上传用户:sunhongbo
上传日期:2022-01-25
资源大小:3010k
文件大小:9k
源码类别:

数据库系统

开发平台:

C/C++

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