diff options
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/tokenize.c')
-rw-r--r-- | ext/pdo_sqlite/sqlite/src/tokenize.c | 229 |
1 files changed, 93 insertions, 136 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/tokenize.c b/ext/pdo_sqlite/sqlite/src/tokenize.c index 061e5b9a45..fb1f6674df 100644 --- a/ext/pdo_sqlite/sqlite/src/tokenize.c +++ b/ext/pdo_sqlite/sqlite/src/tokenize.c @@ -23,106 +23,18 @@ #include <stdlib.h> /* -** This function looks up an identifier to determine if it is a -** keyword. If it is a keyword, the token code of that keyword is +** The sqlite3KeywordCode function looks up an identifier to determine if +** it is a keyword. If it is a keyword, the token code of that keyword is ** returned. If the input is not a keyword, TK_ID is returned. ** ** The implementation of this routine was generated by a program, -** mkkeywordhash.c, located in the tool subdirectory of the distribution. -** The output of the mkkeywordhash.c program was manually cut and pasted -** into this file. When the set of keywords for SQLite changes, you -** must modify the mkkeywordhash.c program (to add or remove keywords from -** the data tables) then rerun that program to regenerate this function. +** mkkeywordhash.h, located in the tool subdirectory of the distribution. +** The output of the mkkeywordhash.c program is written into a file +** named keywordhash.h and then included into this source file by +** the #include below. */ -int sqlite3KeywordCode(const char *z, int n){ - static const char zText[519] = - "ABORTAFTERALLANDASCATTACHBEFOREBEGINBETWEENBYCASCADECASECHECK" - "COLLATECOMMITCONFLICTCONSTRAINTCREATECROSSDATABASEDEFAULTDEFERRABLE" - "DEFERREDDELETEDESCDETACHDISTINCTDROPEACHELSEENDEXCEPTEXCLUSIVE" - "EXPLAINFAILFOREIGNFROMFULLGLOBGROUPHAVINGIGNOREIMMEDIATEINDEX" - "INITIALLYINNERINSERTINSTEADINTERSECTINTOISNULLJOINKEYLEFTLIKE" - "LIMITMATCHNATURALNOTNULLNULLOFFSETONORDEROUTERPRAGMAPRIMARYRAISE" - "REFERENCESREPLACERESTRICTRIGHTROLLBACKROWSELECTSETSTATEMENTTABLE" - "TEMPORARYTHENTRANSACTIONTRIGGERUNIONUNIQUEUPDATEUSINGVACUUMVALUES" - "VIEWWHENWHERE"; - static const unsigned char aHash[154] = { - 0, 75, 82, 0, 0, 97, 80, 0, 83, 0, 0, 0, 0, - 0, 0, 6, 0, 95, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 86, 8, 0, 26, 13, 7, 19, 15, 0, 0, 32, - 25, 0, 21, 31, 41, 0, 0, 0, 34, 27, 0, 0, 30, - 0, 0, 0, 9, 0, 10, 0, 0, 0, 0, 51, 0, 44, - 43, 0, 45, 40, 0, 29, 39, 35, 0, 0, 20, 0, 59, - 0, 16, 0, 17, 0, 18, 0, 55, 42, 72, 0, 33, 0, - 0, 61, 66, 56, 0, 0, 0, 0, 0, 0, 0, 54, 0, - 0, 0, 0, 0, 74, 50, 76, 64, 52, 0, 0, 0, 0, - 68, 84, 0, 47, 0, 58, 60, 92, 0, 0, 48, 0, 93, - 0, 63, 71, 98, 0, 0, 0, 0, 0, 67, 0, 0, 0, - 0, 87, 0, 0, 0, 0, 0, 90, 88, 0, 94, - }; - static const unsigned char aNext[98] = { - 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 12, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, - 0, 0, 0, 14, 3, 24, 0, 0, 0, 1, 22, 0, 0, - 36, 23, 28, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, - 0, 49, 37, 0, 0, 0, 38, 0, 53, 0, 57, 62, 0, - 0, 0, 0, 0, 0, 70, 46, 0, 65, 0, 0, 0, 0, - 69, 73, 0, 77, 0, 0, 0, 0, 0, 0, 81, 85, 0, - 91, 79, 78, 0, 0, 89, 0, - }; - static const unsigned char aLen[98] = { - 5, 5, 3, 3, 2, 3, 6, 6, 5, 7, 2, 7, 4, - 5, 7, 6, 8, 10, 6, 5, 8, 7, 10, 8, 6, 4, - 6, 8, 4, 4, 4, 3, 6, 9, 7, 4, 3, 7, 4, - 4, 4, 5, 6, 6, 9, 2, 5, 9, 5, 6, 7, 9, - 4, 2, 6, 4, 3, 4, 4, 5, 5, 7, 3, 7, 4, - 2, 6, 2, 2, 5, 5, 6, 7, 5, 10, 7, 8, 5, - 8, 3, 6, 3, 9, 5, 4, 9, 4, 11, 7, 5, 6, - 6, 5, 6, 6, 4, 4, 5, - }; - static const unsigned short int aOffset[98] = { - 0, 5, 10, 13, 16, 16, 19, 25, 31, 36, 43, 45, 52, - 56, 61, 68, 74, 82, 92, 98, 103, 111, 118, 128, 136, 142, - 146, 152, 160, 164, 168, 172, 175, 181, 190, 197, 201, 201, 208, - 212, 216, 220, 225, 231, 237, 246, 246, 251, 260, 265, 271, 278, - 287, 291, 291, 297, 301, 304, 308, 312, 317, 322, 329, 329, 336, - 340, 340, 346, 348, 348, 353, 358, 364, 371, 376, 386, 393, 401, - 406, 414, 417, 423, 426, 435, 440, 440, 449, 453, 464, 471, 476, - 482, 488, 493, 499, 505, 509, 513, - }; - static const unsigned char aCode[98] = { - TK_ABORT, TK_AFTER, TK_ALL, TK_AND, TK_AS, - TK_ASC, TK_ATTACH, TK_BEFORE, TK_BEGIN, TK_BETWEEN, - TK_BY, TK_CASCADE, TK_CASE, TK_CHECK, TK_COLLATE, - TK_COMMIT, TK_CONFLICT, TK_CONSTRAINT, TK_CREATE, TK_JOIN_KW, - TK_DATABASE, TK_DEFAULT, TK_DEFERRABLE, TK_DEFERRED, TK_DELETE, - TK_DESC, TK_DETACH, TK_DISTINCT, TK_DROP, TK_EACH, - TK_ELSE, TK_END, TK_EXCEPT, TK_EXCLUSIVE, TK_EXPLAIN, - TK_FAIL, TK_FOR, TK_FOREIGN, TK_FROM, TK_JOIN_KW, - TK_GLOB, TK_GROUP, TK_HAVING, TK_IGNORE, TK_IMMEDIATE, - TK_IN, TK_INDEX, TK_INITIALLY, TK_JOIN_KW, TK_INSERT, - TK_INSTEAD, TK_INTERSECT, TK_INTO, TK_IS, TK_ISNULL, - TK_JOIN, TK_KEY, TK_JOIN_KW, TK_LIKE, TK_LIMIT, - TK_MATCH, TK_JOIN_KW, TK_NOT, TK_NOTNULL, TK_NULL, - TK_OF, TK_OFFSET, TK_ON, TK_OR, TK_ORDER, - TK_JOIN_KW, TK_PRAGMA, TK_PRIMARY, TK_RAISE, TK_REFERENCES, - TK_REPLACE, TK_RESTRICT, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, - TK_SELECT, TK_SET, TK_STATEMENT, TK_TABLE, TK_TEMP, - TK_TEMP, TK_THEN, TK_TRANSACTION,TK_TRIGGER, TK_UNION, - TK_UNIQUE, TK_UPDATE, TK_USING, TK_VACUUM, TK_VALUES, - TK_VIEW, TK_WHEN, TK_WHERE, - }; - int h, i; - if( n<2 ) return TK_ID; - h = (sqlite3UpperToLower[((unsigned char*)z)[0]]*5 + - sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3 + - n) % 154; - for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){ - if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){ - return aCode[i]; - } - } - return TK_ID; -} +#include "keywordhash.h" + /* ** If X is a character that can be used in an identifier and @@ -137,9 +49,15 @@ int sqlite3KeywordCode(const char *z, int n){ ** with the high-order bit set. The latter rule means that ** any sequence of UTF-8 characters or characters taken from ** an extended ISO8859 character set can form an identifier. +** +** Ticket #1066. the SQL standard does not allow '$' in the +** middle of identfiers. But many SQL implementations do. +** SQLite will allow '$' in identifiers for compatibility. +** But the feature is undocumented. */ static const char isIdChar[] = { /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ @@ -147,13 +65,13 @@ static const char isIdChar[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ }; -#define IdChar(C) (((c=C)&0x80)!=0 || (c>0x2f && isIdChar[c-0x30])) +#define IdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && isIdChar[c-0x20])) /* ** Return the length of the token that begins at z[0]. ** Store the token type in *tokenType before returning. */ -static int sqliteGetToken(const unsigned char *z, int *tokenType){ +static int getToken(const unsigned char *z, int *tokenType){ int i, c; switch( *z ){ case ' ': case '\t': case '\n': case '\f': case '\r': { @@ -265,6 +183,11 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_BITNOT; return 1; } + case '#': { + for(i=1; isdigit(z[i]) || (i==1 && z[1]=='-'); i++){} + *tokenType = TK_REGISTER; + return i; + } case '\'': case '"': { int delim = z[0]; for(i=1; (c=z[i])!=0; i++){ @@ -288,6 +211,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ case '5': case '6': case '7': case '8': case '9': { *tokenType = TK_INTEGER; for(i=1; isdigit(z[i]); i++){} +#ifndef SQLITE_OMIT_FLOATING_POINT if( z[i]=='.' && isdigit(z[i+1]) ){ i += 2; while( isdigit(z[i]) ){ i++; } @@ -302,6 +226,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ while( isdigit(z[i]) ){ i++; } *tokenType = TK_FLOAT; } +#endif return i; } case '[': { @@ -319,6 +244,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ *tokenType = i>1 ? TK_VARIABLE : TK_ILLEGAL; return i; } +#ifndef SQLITE_OMIT_TCL_VARIABLE case '$': { *tokenType = TK_VARIABLE; if( z[1]=='{' ){ @@ -355,7 +281,9 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ if( n==0 ) *tokenType = TK_ILLEGAL; } return i; - } + } +#endif +#ifndef SQLITE_OMIT_BLOB_LITERAL case 'x': case 'X': { if( (c=z[1])=='\'' || c=='"' ){ int delim = c; @@ -375,18 +303,22 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ } /* Otherwise fall through to the next case */ } +#endif default: { if( !IdChar(*z) ){ break; } for(i=1; IdChar(z[i]); i++){} - *tokenType = sqlite3KeywordCode((char*)z, i); + *tokenType = keywordCode((char*)z, i); return i; } } *tokenType = TK_ILLEGAL; return 1; } +int sqlite3GetToken(const unsigned char *z, int *tokenType){ + return getToken(z, tokenType); +} /* ** Run the parser on the given SQL string. The parser structure is @@ -426,7 +358,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( i>=0 ); pParse->sLastToken.z = &zSql[i]; assert( pParse->sLastToken.dyn==0 ); - pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType); + pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType); i += pParse->sLastToken.n; switch( tokenType ){ case TK_SPACE: @@ -486,7 +418,7 @@ abort_parse: pParse->zErrMsg = 0; if( !nErr ) nErr++; } - if( pParse->pVdbe && pParse->nErr>0 ){ + if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ sqlite3VdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; } @@ -503,14 +435,14 @@ abort_parse: ** Token types used by the sqlite3_complete() routine. See the header ** comments on that procedure for additional information. */ -#define tkEXPLAIN 0 -#define tkCREATE 1 -#define tkTEMP 2 -#define tkTRIGGER 3 -#define tkEND 4 -#define tkSEMI 5 -#define tkWS 6 -#define tkOTHER 7 +#define tkSEMI 0 +#define tkWS 1 +#define tkOTHER 2 +#define tkEXPLAIN 3 +#define tkCREATE 4 +#define tkTEMP 5 +#define tkTRIGGER 6 +#define tkEND 7 /* ** Return TRUE if the given SQL string ends in a semicolon. @@ -525,16 +457,16 @@ abort_parse: ** returns 1 if it ends in the START state and 0 if it ends ** in any other state. ** -** (1) EXPLAIN The keyword EXPLAIN has been seen at the beginning of +** (1) NORMAL We are in the middle of statement which ends with a single +** semicolon. +** +** (2) EXPLAIN The keyword EXPLAIN has been seen at the beginning of ** a statement. ** -** (2) CREATE The keyword CREATE has been seen at the beginning of a +** (3) CREATE The keyword CREATE has been seen at the beginning of a ** statement, possibly preceeded by EXPLAIN and/or followed by ** TEMP or TEMPORARY ** -** (3) NORMAL We are in the middle of statement which ends with a single -** semicolon. -** ** (4) TRIGGER We are in the middle of a trigger definition that must be ** ended by a semicolon, the keyword END, and another semicolon. ** @@ -547,36 +479,51 @@ abort_parse: ** Transitions between states above are determined by tokens extracted ** from the input. The following tokens are significant: ** -** (0) tkEXPLAIN The "explain" keyword. -** (1) tkCREATE The "create" keyword. -** (2) tkTEMP The "temp" or "temporary" keyword. -** (3) tkTRIGGER The "trigger" keyword. -** (4) tkEND The "end" keyword. -** (5) tkSEMI A semicolon. -** (6) tkWS Whitespace -** (7) tkOTHER Any other SQL token. +** (0) tkSEMI A semicolon. +** (1) tkWS Whitespace +** (2) tkOTHER Any other SQL token. +** (3) tkEXPLAIN The "explain" keyword. +** (4) tkCREATE The "create" keyword. +** (5) tkTEMP The "temp" or "temporary" keyword. +** (6) tkTRIGGER The "trigger" keyword. +** (7) tkEND The "end" keyword. ** ** Whitespace never causes a state transition and is always ignored. +** +** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed +** to recognize the end of a trigger can be omitted. All we have to do +** is look for a semicolon that is not part of an string or comment. */ int sqlite3_complete(const char *zSql){ u8 state = 0; /* Current state, using numbers defined in header comment */ u8 token; /* Value of the next token */ - /* The following matrix defines the transition from one state to another - ** according to what token is seen. trans[state][token] returns the - ** next state. +#ifndef SQLITE_OMIT_TRIGGER + /* A complex statement machine used to detect the end of a CREATE TRIGGER + ** statement. This is the normal case. */ static const u8 trans[7][8] = { /* Token: */ - /* State: ** EXPLAIN CREATE TEMP TRIGGER END SEMI WS OTHER */ - /* 0 START: */ { 1, 2, 3, 3, 3, 0, 0, 3, }, - /* 1 EXPLAIN: */ { 3, 2, 3, 3, 3, 0, 1, 3, }, - /* 2 CREATE: */ { 3, 3, 2, 4, 3, 0, 2, 3, }, - /* 3 NORMAL: */ { 3, 3, 3, 3, 3, 0, 3, 3, }, - /* 4 TRIGGER: */ { 4, 4, 4, 4, 4, 5, 4, 4, }, - /* 5 SEMI: */ { 4, 4, 4, 4, 6, 5, 5, 4, }, - /* 6 END: */ { 4, 4, 4, 4, 4, 0, 6, 4, }, + /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ + /* 0 START: */ { 0, 0, 1, 2, 3, 1, 1, 1, }, + /* 1 NORMAL: */ { 0, 1, 1, 1, 1, 1, 1, 1, }, + /* 2 EXPLAIN: */ { 0, 2, 1, 1, 3, 1, 1, 1, }, + /* 3 CREATE: */ { 0, 3, 1, 1, 1, 3, 4, 1, }, + /* 4 TRIGGER: */ { 5, 4, 4, 4, 4, 4, 4, 4, }, + /* 5 SEMI: */ { 5, 5, 4, 4, 4, 4, 4, 6, }, + /* 6 END: */ { 0, 6, 4, 4, 4, 4, 4, 4, }, + }; +#else + /* If triggers are not suppored by this compile then the statement machine + ** used to detect the end of a statement is much simplier + */ + static const u8 trans[2][3] = { + /* Token: */ + /* State: ** SEMI WS OTHER */ + /* 0 START: */ { 0, 0, 1, }, + /* 1 NORMAL: */ { 0, 1, 1, }, }; +#endif /* SQLITE_OMIT_TRIGGER */ while( *zSql ){ switch( *zSql ){ @@ -636,6 +583,9 @@ int sqlite3_complete(const char *zSql){ /* Keywords and unquoted identifiers */ int nId; for(nId=1; IdChar(zSql[nId]); nId++){} +#ifdef SQLITE_OMIT_TRIGGER + token = tkOTHER; +#else switch( *zSql ){ case 'c': case 'C': { if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ @@ -660,9 +610,13 @@ int sqlite3_complete(const char *zSql){ case 'e': case 'E': { if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ token = tkEND; - }else if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ + }else +#ifndef SQLITE_OMIT_EXPLAIN + if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ token = tkEXPLAIN; - }else{ + }else +#endif + { token = tkOTHER; } break; @@ -672,6 +626,7 @@ int sqlite3_complete(const char *zSql){ break; } } +#endif /* SQLITE_OMIT_TRIGGER */ zSql += nId-1; }else{ /* Operators and special symbols */ @@ -686,6 +641,7 @@ int sqlite3_complete(const char *zSql){ return state==0; } +#ifndef SQLITE_OMIT_UTF16 /* ** This routine is the same as the sqlite3_complete() routine described ** above, except that the parameter is required to be UTF-16 encoded, not @@ -705,3 +661,4 @@ int sqlite3_complete16(const void *zSql){ sqlite3ValueFree(pVal); return rc; } +#endif /* SQLITE_OMIT_UTF16 */ |