MXS-2732 Add MaxScale sqlite3 changes

This commit contains all MaxScale changes that have been made
to sqlite3 version 3110100.
This commit is contained in:
Johan Wikman
2019-10-30 11:28:39 +02:00
parent d2db25073b
commit c2a601bcf5
14 changed files with 2713 additions and 24 deletions

View File

@ -72,7 +72,11 @@ static void renameTableFunc(
*/
do {
zCsr += len;
#ifdef MAXSCALE
len = sqlite3GetToken(0, zCsr, &token);
#else
len = sqlite3GetToken(zCsr, &token);
#endif
} while( token==TK_SPACE );
assert( len>0 );
} while( token!=TK_LP && token!=TK_USING );
@ -118,12 +122,20 @@ static void renameParentFunc(
UNUSED_PARAMETER(NotUsed);
if( zInput==0 || zOld==0 ) return;
for(z=zInput; *z; z=z+n){
#ifdef MAXSCALE
n = sqlite3GetToken(0, z, &token);
#else
n = sqlite3GetToken(z, &token);
#endif
if( token==TK_REFERENCES ){
char *zParent;
do {
z += n;
#ifdef MAXSCALE
n = sqlite3GetToken(0, z, &token);
#else
n = sqlite3GetToken(z, &token);
#endif
}while( token==TK_SPACE );
if( token==TK_ILLEGAL ) break;
@ -196,7 +208,11 @@ static void renameTriggerFunc(
*/
do {
zCsr += len;
#ifdef MAXSCALE
len = sqlite3GetToken(0, zCsr, &token);
#else
len = sqlite3GetToken(zCsr, &token);
#endif
}while( token==TK_SPACE );
assert( len>0 );

View File

@ -3728,6 +3728,43 @@ SrcList *sqlite3SrcListAppend(
return pList;
}
#ifdef MAXSCALE
/*
** Catenate the items of one SrcList object to the end of another
** SrcList object.
**
** If either of the provided lists is NULL, then the other list
** is returned as such. If both are NULL, then NULL is returned.
** If the operation is performed successfully, then the returned
** list will contain the items of both lists. In that case, pTail
** has been deleted.
**
** If a memory allocation fails, both lists are unchanged. The
** db->mallocFailed flag will be set to true.
*/
SrcList* sqlite3SrcListCat(sqlite3 *db, SrcList *pHead, SrcList *pTail)
{
SrcList *pNew;
if ( pTail==0 ){
return pHead;
}
if ( pHead==0 ){
return pTail;
}
pNew = sqlite3SrcListEnlarge(db, pHead, pTail->nSrc, pHead->nSrc);
if (!db->mallocFailed){
int i;
for(i=0; i<pTail->nSrc; i++){
pNew->a[pNew->nSrc - 1 + i] = pTail->a[i];
memset(&pTail->a[i], 0, sizeof(pTail->a[0]));
}
pTail->nSrc = 0;
sqlite3SrcListDelete(db, pTail);
}
return pNew;
}
#endif
/*
** Assign VdbeCursor index numbers to all tables in a SrcList
*/

View File

@ -106,8 +106,13 @@ void sqlite3MaterializeView(
assert( pFrom->a[0].pOn==0 );
assert( pFrom->a[0].pUsing==0 );
}
#ifdef MAXSCALE
pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0,
SF_IncludeHidden, 0, 0, 0);
#else
pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0,
SF_IncludeHidden, 0, 0);
#endif
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pSel, &dest);
sqlite3SelectDelete(db, pSel);
@ -178,8 +183,13 @@ Expr *sqlite3LimitWhere(
}
/* generate the SELECT expression tree. */
#ifdef MAXSCALE
pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
pOrderBy,0,pLimit,pOffset,0);
#else
pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
pOrderBy,0,pLimit,pOffset);
#endif
if( pSelect == 0 ) return 0;
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */

View File

@ -1117,6 +1117,9 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = p->nSelectRow;
pNew->pWith = withDup(db, p->pWith);
#ifdef MAXSCALE
pNew->pInto = sqlite3ExprListDup(db, p->pInto, flags);
#endif
sqlite3SelectSetName(pNew, p->zSelName);
return pNew;
}
@ -1175,6 +1178,49 @@ no_mem:
return 0;
}
#ifdef MAXSCALE
/*
** Add an expression list to the end of an expression list. If pList
** is initially NULL, then create a new expression list.
**
** If a memory allocation error occurs, the entire list is freed and
** NULL is returned. If non-NULL is returned, then it is guaranteed
** that the list was successfully appended.
*/
ExprList *sqlite3ExprListAppendList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to append. Might be NULL */
ExprList *pAppend /* List to be appended. Might be NULL */
){
sqlite3 *db = pParse->db;
int i;
assert( db!=0 );
if (!pAppend) {
return pList;
}
if (!pList) {
return pAppend;
}
for (i = 0; i < pAppend->nExpr; ++i) {
pList = sqlite3ExprListAppend(pParse, pList, pAppend->a[i].pExpr);
if (pList) {
pAppend->a[i].pExpr = NULL;
}
else {
goto no_mem;
}
}
sqlite3ExprListDelete(db, pAppend);
return pList;
no_mem:
sqlite3ExprListDelete(db, pList);
sqlite3ExprListDelete(db, pAppend);
return 0;
}
#endif
/*
** Set the sort order for the last element on the given ExprList.
*/

View File

@ -1268,6 +1268,9 @@ static Trigger *fkActionTrigger(
sqlite3SrcListAppend(db, 0, &tFrom, 0),
pWhere,
0, 0, 0, 0, 0, 0
#ifdef MAXSCALE
, 0
#endif
);
pWhere = 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -75,6 +75,9 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
sqlite3ExprDelete(db, p->pLimit);
sqlite3ExprDelete(db, p->pOffset);
sqlite3WithDelete(db, p->pWith);
#ifdef MAXSCALE
sqlite3ExprListDelete(db, p->pInto);
#endif
if( bFree ) sqlite3DbFree(db, p);
p = pPrior;
bFree = 1;
@ -108,6 +111,10 @@ Select *sqlite3SelectNew(
u16 selFlags, /* Flag parameters, such as SF_Distinct */
Expr *pLimit, /* LIMIT value. NULL means not used */
Expr *pOffset /* OFFSET value. NULL means no offset */
#ifdef MAXSCALE
,
ExprList *pInto /* the INTO clause */
#endif
){
Select *pNew;
Select standin;
@ -118,7 +125,9 @@ Select *sqlite3SelectNew(
pNew = &standin;
}
if( pEList==0 ){
#ifndef MAXSCALE
pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
#endif
}
pNew->pEList = pEList;
pNew->op = TK_SELECT;
@ -142,6 +151,9 @@ Select *sqlite3SelectNew(
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
pNew->pWith = 0;
#ifdef MAXSCALE
pNew->pInto = pInto;
#endif
assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
if( db->mallocFailed ) {
clearSelect(db, pNew, pNew!=&standin);
@ -247,8 +259,10 @@ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
jointype = JT_INNER;
}else if( (jointype & JT_OUTER)!=0
&& (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
#ifndef MAXSCALE
sqlite3ErrorMsg(pParse,
"RIGHT and FULL OUTER JOINs are not currently supported");
#endif
jointype = JT_INNER;
}
return jointype;

View File

@ -2517,6 +2517,9 @@ struct Select {
Expr *pLimit; /* LIMIT expression. NULL means not used. */
Expr *pOffset; /* OFFSET expression. NULL means not used. */
With *pWith; /* WITH clause attached to this select. Or NULL. */
#ifdef MAXSCALE
ExprList* pInto; /* The INTO clause */
#endif
};
/*
@ -3358,6 +3361,9 @@ Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
void sqlite3ExprDelete(sqlite3*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
#ifdef MAXSCALE
ExprList *sqlite3ExprListAppendList(Parse*,ExprList*,ExprList*);
#endif
void sqlite3ExprListSetSortOrder(ExprList*,int);
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
@ -3445,6 +3451,9 @@ IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
int sqlite3IdListIndex(IdList*,const char*);
SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
#ifdef MAXSCALE
SrcList* sqlite3SrcListCat(sqlite3*, SrcList*, SrcList*);
#endif
SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
Token*, Select*, Expr*, IdList*);
void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
@ -3459,8 +3468,13 @@ Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
Expr*, int, int);
void sqlite3DropIndex(Parse*, SrcList*, int);
int sqlite3Select(Parse*, Select*, SelectDest*);
#ifdef MAXSCALE
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
Expr*,ExprList*,u16,Expr*,Expr*,ExprList*);
#else
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
Expr*,ExprList*,u16,Expr*,Expr*);
#endif
void sqlite3SelectDelete(sqlite3*, Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);
@ -3746,7 +3760,11 @@ void sqlite3RootPageMoved(sqlite3*, int, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
#ifdef MAXSCALE
int sqlite3GetToken(Parse*, const unsigned char *, int *);
#else
int sqlite3GetToken(const unsigned char *, int *);
#endif
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
int sqlite3CodeSubselect(Parse *, Expr *, int, int);
@ -4072,4 +4090,78 @@ int sqlite3ThreadJoin(SQLiteThread*, void**);
int sqlite3DbstatRegister(sqlite3*);
#endif
#ifdef MAXSCALE
typedef enum mxs_drop
{
MXS_DROP_DATABASE,
MXS_DROP_FUNCTION,
MXS_DROP_SEQUENCE,
} mxs_drop_t;
typedef enum mxs_set
{
MXS_SET_VARIABLES,
MXS_SET_TRANSACTION
} mxs_set_t;
typedef enum mxs_show
{
MXS_SHOW_COLUMNS,
MXS_SHOW_CREATE_SEQUENCE,
MXS_SHOW_CREATE_TABLE,
MXS_SHOW_CREATE_VIEW,
MXS_SHOW_DATABASES,
MXS_SHOW_INDEX,
MXS_SHOW_INDEXES,
MXS_SHOW_KEYS,
MXS_SHOW_STATUS,
MXS_SHOW_TABLE_STATUS,
MXS_SHOW_TABLES,
MXS_SHOW_VARIABLES,
MXS_SHOW_WARNINGS,
} mxs_show_t;
enum mxs_show_data
{
MXS_SHOW_COLUMNS_FULL = 1,
// NOTE: The following are used both in MXS_SHOW_VARIABLES and MXS_SHOW_STATUS
MXS_SHOW_VARIABLES_GLOBAL,
MXS_SHOW_VARIABLES_SESSION,
MXS_SHOW_VARIABLES_UNSPECIFIED,
MXS_SHOW_STATUS_MASTER,
MXS_SHOW_STATUS_SLAVE,
MXS_SHOW_STATUS_ALL_SLAVES,
};
typedef struct MxsShow
{
mxs_show_t what;
u32 data;
Token* pName;
Token* pDatabase;
} MxsShow;
typedef enum mxs_alter
{
MXS_ALTER_DISABLE_KEYS,
MXS_ALTER_ENABLE_KEYS,
MXS_ALTER_RENAME,
} mxs_alter_t;
typedef enum mxs_lock
{
MXS_LOCK_LOCK,
MXS_LOCK_UNLOCK,
} mxs_lock_t;
typedef enum mxs_handler
{
MXS_HANDLER_OPEN,
MXS_HANDLER_CLOSE
} mxs_handler_t;
#endif /* MAXSCALE */
#endif /* _SQLITEINT_H_ */

View File

@ -60,7 +60,11 @@ static const unsigned char aiClass[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */
/* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27,
/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
#ifdef MAXSCALE
/* 2x */ 7, 15, 8, 5, 2, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16,
#else
/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16,
#endif
/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6,
/* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 9, 27, 27, 27, 1,
@ -193,7 +197,12 @@ int sqlite3IsIdChar(u8 c){ return IdChar(c); }
** Return the length (in bytes) of the token that begins at z[0].
** Store the token type in *tokenType before returning.
*/
#ifdef MAXSCALE
extern int maxscaleComment();
int sqlite3GetToken(Parse* pParse, const unsigned char *z, int *tokenType){
#else
int sqlite3GetToken(const unsigned char *z, int *tokenType){
#endif
int i, c;
switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
** of the token. See the comment on the CC_ defines
@ -210,6 +219,9 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
}
case CC_MINUS: {
if( z[1]=='-' ){
#ifdef MAXSCALE
maxscaleComment();
#endif
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
return i;
@ -242,8 +254,39 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
*tokenType = TK_SLASH;
return 1;
}
#ifdef MAXSCALE
if ( z[2]=='!' || (z[2]=='M' && z[3]=='!')){
int j = (z[2]=='M' ? 4 : 3);
// MySQL-specific code
for (i=j, c=z[j-1]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if (c=='*' && z[i]=='/'){
if (sqlite3Isdigit(z[j])) {
// A version specific executable comment,
// e.g. "/*!99999 ..." or "/*M!99999 ..." => never parsed.
extern void maxscaleSetStatusCap(int);
maxscaleSetStatusCap(2); // QC_QUERY_PARTIALLY_PARSED, see query_classifier.h:qc_parse_result
++i; // Next after the trailing '/'
}
else {
// A non-version specific executable comment,
// e.g."/*! select 1 */ or "/*M! select 1 */ => always parsed.
char* znc = (char*) z;
znc[0]=znc[1]=znc[2]=znc[i-1]=znc[i]=' '; // Remove comment chars, i.e. "/*!" and "*/".
if (j==4){
znc[3]=0; // It wasn't "/*!" but "/*M!".
}
for (i=j; sqlite3Isspace(z[i]); ++i){} // Jump over any space.
}
}
} else {
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if( c ) i++;
}
#else
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if( c ) i++;
#endif
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
return i;
}
@ -257,6 +300,13 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
}
case CC_LT: {
if( (c=z[1])=='=' ){
#ifdef MAXSCALE
if ( z[2]=='>' ){
// "<=>"
*tokenType = TK_EQ;
return 3;
}
#endif
*tokenType = TK_LE;
return 2;
}else if( c=='>' ){
@ -324,9 +374,19 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
}else{
break;
}
#ifdef MAXSCALE
}else if (c == '\\' ){
if ( z[i+1] ){
i++;
}
#endif
}
}
#ifdef MAXSCALE
if( c=='\'' || c=='"' ){
#else
if( c=='\'' ){
#endif
*tokenType = TK_STRING;
return i+1;
}else if( c!=0 ){
@ -345,6 +405,23 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
*tokenType = TK_DOT;
return 1;
}
#ifdef MAXSCALE
/* Next char is a digit, we need to sniff further to find out whether it
** is an identifer that starts with a digit.
*/
int j=1;
int nondigitChars=0;
while ( IdChar(z[j]) ){
if ( !sqlite3Isdigit(z[j++]) ){
++nondigitChars;
}
}
if ( nondigitChars ){
// At least one char that is not a digit => an id (and not a float) coming.
*tokenType = TK_DOT;
return 1;
}
#endif
/* If the next character is a digit, this is a floating point
** number that begins with ".". Fall thru into the next case */
}
@ -378,7 +455,11 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
}
#endif
while( IdChar(z[i]) ){
#ifdef MAXSCALE
*tokenType = TK_ID;
#else
*tokenType = TK_ILLEGAL;
#endif
i++;
}
return i;
@ -398,9 +479,30 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
int n = 0;
testcase( z[0]=='$' ); testcase( z[0]=='@' );
testcase( z[0]==':' ); testcase( z[0]=='#' );
#ifdef MAXSCALE
if (z[0]=='#') {
if (maxscaleComment()) {
for(i=1; (c=z[i])!=0 && c!='\n'; i++){}
*tokenType = TK_SPACE;
return i;
}
}
if (z[0]==':' && z[1]=='=') {
*tokenType = TK_EQ;
return 2;
}
#endif
*tokenType = TK_VARIABLE;
for(i=1; (c=z[i])!=0; i++){
#ifdef MAXSCALE
if ( (i == 1) && (z[0] == '@') && (c == '@') ) {
// If the first char is '@' then if the second char is a '@'
// it is a system variable (@@xyz).
continue;
}else if( IdChar(c) ){
#else
if( IdChar(c) ){
#endif
n++;
#ifndef SQLITE_OMIT_TCL_VARIABLE
}else if( c=='(' && n>0 ){
@ -415,6 +517,20 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
break;
}else if( c==':' && z[i+1]==':' ){
i++;
#endif
#ifdef MAXSCALE
}else if ( c=='\'' || c=='"' || c=='`' ){
int q=c;
++i;
while ( IdChar(z[i]) ) {
++i;
++n;
}
if ( z[i]==q )
{
++i;
break;
}
#endif
}else{
break;
@ -424,6 +540,23 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
return i;
}
case CC_KYWD: {
#ifdef MAXSCALE
// This is for bit fields, e.g. b'10110111'.
if ( z[0]=='b' || z[0]=='B' ) {
if ( z[1]=='\'' ){
// We return it as an integer. We are not interested in the value
*tokenType = TK_INTEGER;
for(i=2; (z[i]=='0'||z[i]=='1'); i++){}
if ( z[i]!='\'' ){
*tokenType = TK_ILLEGAL;
while ( z[i] && z[i]!='\'' ){ i++; }
}
if ( z[i] ) i++;
return i;
}
}
/* Not a bit field. It may be a keyword so we flow through */
#endif
for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
if( IdChar(z[i]) ){
/* This token started out using characters that can appear in keywords,
@ -433,7 +566,49 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
break;
}
*tokenType = TK_ID;
#ifdef MAXSCALE
i = keywordCode((char*)z, i, tokenType);
if (*tokenType != TK_ID)
{
if (pParse) {
if (z != (const unsigned char *)pParse->zTail) {
const char *p = (const char*)z - 1;
while ((p != pParse->zTail) && sqlite3Isspace(*p)) {
--p;
}
if (*p == '.') {
/* If the last character before the keyword is '.' then
** we assume this token is the second part of a qualified
** name, e.g. "tbl1.index" in which case we return the
** keyword as an id.
*/
*tokenType = TK_ID;
}
}
}
if (*tokenType != TK_ID) {
extern int maxscaleKeyword(int);
extern int maxscaleTranslateKeyword(int);
*tokenType = maxscaleTranslateKeyword(*tokenType);
if (*tokenType != TK_ID) {
if (maxscaleKeyword(*tokenType) != 0)
{
/* Consume the entire string. */
while ( z[i] ) {
++i;
}
}
}
}
}
return i;
#else
return keywordCode((char*)z, i, tokenType);
#endif
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case CC_X: {
@ -451,6 +626,22 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
/* If it is not a BLOB literal, then it must be an ID, since no
** SQL keywords start with the letter 'x'. Fall through */
}
#endif
#ifdef MAXSCALE
// It may be the "XA" keyword.
// If the next character is 'a' or 'A', followed by whitespace or a
// comment, then we are indeed dealing with the "XA" keyword.
if (( z[1]=='a' || z[1]=='A' ) &&
(sqlite3Isspace(z[2]) || // Whitespace
(z[2]=='/' && z[3]=='*') || // Beginning of /* comment
(z[2]=='#') || // # eol comment
(z[2]=='-' && z[3]=='-' && sqlite3Isspace(z[4])))) { // -- eol comment
extern int maxscaleKeyword(int);
*tokenType = TK_XA;
maxscaleKeyword(*tokenType);
return 2;
}
#endif
case CC_ID: {
i = 1;
@ -505,7 +696,11 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
while( zSql[i]!=0 ){
assert( i>=0 );
pParse->sLastToken.z = &zSql[i];
#ifdef MAXSCALE
pParse->sLastToken.n = sqlite3GetToken(pParse,(unsigned char*)&zSql[i],&tokenType);
#else
pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
#endif
i += pParse->sLastToken.n;
if( i>mxSqlLen ){
pParse->rc = SQLITE_TOOBIG;

View File

@ -219,6 +219,23 @@ int sqlite3Dequote(char *z){
}
for(i=1, j=0;; i++){
assert( z[i] );
#ifdef MAXSCALE
if ( z[i]==0 ){
// TODO: This is needed only because exposed_sqlite3Dequote() is called
// TODO: in qc_sqlite.c:update_names(). That call probably is not needed
// TODO: and should be removed, in which case this check could also be
// TODO: removed.
break;
}else if ( z[i]=='\\' ){
// If we want to dequote properly, a few more characters would have to be
// handled explicitly. That would not affect the classification, however,
// so we won't do that.
if ( z[i+1]==quote || z[i+1]=='\\' ){
z[j++] = z[i+1];
i++;
}
} else
#endif
if( z[i]==quote ){
if( z[i+1]==quote ){
z[j++] = quote;

View File

@ -33,7 +33,11 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
*pnToken = 0;
while( zSql[0] ){
#ifdef MAXSCALE
n = sqlite3GetToken(0, (u8*)zSql, &tokenType);
#else
n = sqlite3GetToken((u8*)zSql, &tokenType);
#endif
assert( n>0 && tokenType!=TK_ILLEGAL );
if( tokenType==TK_VARIABLE ){
*pnToken = n;