#include <ctype.h>
#include <stdlib.h>
#include "db_sql_codegen.h"
#ifdef SQLITE_ASCII
# define charMap(X) sqlite3UpperToLower[(unsigned char)X]
#endif
#ifdef SQLITE_EBCDIC
# define charMap(X) ebcdicToAscii[(unsigned char)X]
const unsigned char ebcdicToAscii[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0,
0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0,
0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0,
0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0,
0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
#endif
#include "sqlite/keywordhash.h"
#ifdef SQLITE_ASCII
const char sqlite3IsAsciiIdChar[] = {
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
};
#define IdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsAsciiIdChar[c-0x20]))
#endif
#ifdef SQLITE_EBCDIC
const char sqlite3IsEbcdicIdChar[] = {
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0,
1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0,
};
#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
#endif
static int getToken(const unsigned char *z, int *tokenType) {
int i, c;
switch ( *z ) {
case ' ': case '\t': case '\n': case '\f': case '\r': {
for (i=1; isspace(z[i]); i++) {}
*tokenType = TK_SPACE;
return i;
}
case '-': {
if ( z[1]=='-' ) {
for (i=2; (c=z[i])!=0 && c!='\n'; i++) {}
*tokenType = TK_COMMENT;
return i;
}
*tokenType = TK_MINUS;
return 1;
}
case '(': {
*tokenType = TK_LP;
return 1;
}
case ')': {
*tokenType = TK_RP;
return 1;
}
case ';': {
*tokenType = TK_SEMI;
return 1;
}
case '+': {
*tokenType = TK_PLUS;
return 1;
}
case '*': {
*tokenType = TK_STAR;
return 1;
}
case '/': {
if ( z[1]!='*' || z[2]==0 ) {
*tokenType = TK_SLASH;
return 1;
}
for (i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++) {}
if ( c ) i++;
*tokenType = TK_COMMENT;
return i;
}
case '%': {
*tokenType = TK_REM;
return 1;
}
case '=': {
*tokenType = TK_EQ;
return 1 + (z[1]=='=');
}
case '<': {
if ( (c=z[1])=='=' ) {
*tokenType = TK_LE;
return 2;
}else if ( c=='>' ) {
*tokenType = TK_NE;
return 2;
}else if ( c=='<' ) {
*tokenType = TK_LSHIFT;
return 2;
}else{
*tokenType = TK_LT;
return 1;
}
}
case '>': {
if ( (c=z[1])=='=' ) {
*tokenType = TK_GE;
return 2;
}else if ( c=='>' ) {
*tokenType = TK_RSHIFT;
return 2;
}else{
*tokenType = TK_GT;
return 1;
}
}
case '!': {
if ( z[1]!='=' ) {
*tokenType = TK_ILLEGAL;
return 2;
}else{
*tokenType = TK_NE;
return 2;
}
}
case '|': {
if ( z[1]!='|' ) {
*tokenType = TK_BITOR;
return 1;
}else{
*tokenType = TK_CONCAT;
return 2;
}
}
case ',': {
*tokenType = TK_COMMA;
return 1;
}
case '&': {
*tokenType = TK_BITAND;
return 1;
}
case '~': {
*tokenType = TK_BITNOT;
return 1;
}
case '`':
case '\'':
case '"': {
int delim = z[0];
for (i=1; (c=z[i])!=0; i++) {
if ( c==delim ) {
if ( z[i+1]==delim ) {
i++;
}else{
break;
}
}
}
if ( c ) {
*tokenType = TK_STRING;
return i+1;
}else{
*tokenType = TK_ILLEGAL;
return i;
}
}
case '.': {
#ifndef SQLITE_OMIT_FLOATING_POINT
if ( !isdigit(z[1]) )
#endif
{
*tokenType = TK_DOT;
return 1;
}
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
*tokenType = TK_INTEGER;
for (i=0; isdigit(z[i]); i++) {}
#ifndef SQLITE_OMIT_FLOATING_POINT
if ( z[i]=='.' ) {
i++;
while ( isdigit(z[i]) ) { i++; }
*tokenType = TK_FLOAT;
}
if ( (z[i]=='e' || z[i]=='E') &&
( isdigit(z[i+1])
|| ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
)
) {
i += 2;
while ( isdigit(z[i]) ) { i++; }
*tokenType = TK_FLOAT;
}
#endif
while ( IdChar(z[i]) ) {
*tokenType = TK_ILLEGAL;
i++;
}
return i;
}
case '[': {
for (i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++) {}
*tokenType = c==']' ? TK_ID : TK_ILLEGAL;
return i;
}
case '?': {
*tokenType = TK_VARIABLE;
for (i=1; isdigit(z[i]); i++) {}
return i;
}
case '#': {
for (i=1; isdigit(z[i]); i++) {}
if ( i>1 ) {
*tokenType = TK_REGISTER;
return i;
}
}
#ifndef SQLITE_OMIT_TCL_VARIABLE
case '$':
#endif
case '@':
case ':': {
int n = 0;
*tokenType = TK_VARIABLE;
for (i=1; (c=z[i])!=0; i++) {
if ( IdChar(c) ) {
n++;
#ifndef SQLITE_OMIT_TCL_VARIABLE
}else if ( c=='(' && n>0 ) {
do{
i++;
}while( (c=z[i])!=0 && !isspace(c) && c!=')' );
if ( c==')' ) {
i++;
}else{
*tokenType = TK_ILLEGAL;
}
break;
}else if ( c==':' && z[i+1]==':' ) {
i++;
#endif
}else{
break;
}
}
if ( n==0 ) *tokenType = TK_ILLEGAL;
return i;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case 'x': case 'X': {
if ( z[1]=='\'' ) {
*tokenType = TK_BLOB;
for (i=2; (c=z[i])!=0 && c!='\''; i++) {
if ( !isxdigit(c) ) {
*tokenType = TK_ILLEGAL;
}
}
if ( i%2 || !c ) *tokenType = TK_ILLEGAL;
if ( c ) i++;
return i;
}
}
#endif
default: {
if ( !IdChar(*z) ) {
break;
}
for (i=1; IdChar(z[i]); i++) {}
*tokenType = keywordCode((char*)z, i);
return i;
}
}
*tokenType = TK_ILLEGAL;
return 1;
}
static int
bdb_run_parser(Parse *pParse, const char *zSql, char **pzErrMsg) {
int nErr = 0;
int i;
void *pEngine;
int tokenType;
int lastTokenParsed = -1;
pParse->rc = SQLITE_OK;
pParse->zTail = pParse->zSql = zSql;
i = 0;
pEngine = sqlite3ParserAlloc((void*(*)(size_t))malloc);
if ( pEngine==0 ) {
return SQLITE_NOMEM;
}
while (zSql[i]!=0 ) {
assert( i>=0 );
pParse->sLastToken.z = (u8*)&zSql[i];
assert( pParse->sLastToken.dyn==0 );
pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType);
i += pParse->sLastToken.n;
if ( i>SQLITE_MAX_SQL_LENGTH ) {
pParse->rc = SQLITE_TOOBIG;
break;
}
switch ( tokenType ) {
case TK_SPACE: {
break;
}
case TK_COMMENT: {
parse_hint_comment(&pParse->sLastToken);
break;
}
case TK_ILLEGAL: {
if ( pzErrMsg ) {
free(*pzErrMsg);
*pzErrMsg = sqlite3MPrintf(0, "unrecognized token: \"%T\"",
&pParse->sLastToken);
}
nErr++;
goto abort_parse;
}
case TK_SEMI: {
pParse->zTail = &zSql[i];
}
default: {
preparser(pEngine, tokenType, pParse->sLastToken, pParse);
lastTokenParsed = tokenType;
if ( pParse->rc!=SQLITE_OK ) {
goto abort_parse;
}
break;
}
}
}
abort_parse:
if ( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ) {
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
pParse->zTail = &zSql[i];
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
}
sqlite3ParserFree(pEngine,free);
if ( 0 ) {
pParse->rc = SQLITE_NOMEM;
}
if ( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ) {
setString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);
}
if ( pParse->zErrMsg ) {
if ( pzErrMsg && *pzErrMsg==0 ) {
*pzErrMsg = pParse->zErrMsg;
}else{
free(pParse->zErrMsg);
}
pParse->zErrMsg = 0;
nErr++;
}
if ( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ) {
pParse->rc = SQLITE_ERROR;
}
return nErr;
}
int do_parse(const char *zSql, char **pzErrMsg) {
Parse sParse;
memset(&sParse, 0, sizeof(sParse));
return bdb_run_parser(&sParse, zSql, pzErrMsg);
}