MXS-1196: Handle anonymous blocks
In PL/SQL BEGIN starts a block (i.e. not a transaction). Whenever we see that, we assume it is such a block, consume all input and set the type to QUERY_TYPE_WRITE to ensure it goes to master.
This commit is contained in:
@ -1536,15 +1536,18 @@ void mxs_sqlite3Analyze(Parse* pParse, SrcList* pSrcList)
|
|||||||
exposed_sqlite3SrcListDelete(pParse->db, pSrcList);
|
exposed_sqlite3SrcListDelete(pParse->db, pSrcList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mxs_sqlite3BeginTransaction(Parse* pParse, int type)
|
void mxs_sqlite3BeginTransaction(Parse* pParse, int token, int type)
|
||||||
{
|
{
|
||||||
QC_TRACE();
|
QC_TRACE();
|
||||||
|
|
||||||
QC_SQLITE_INFO* info = this_thread.info;
|
QC_SQLITE_INFO* info = this_thread.info;
|
||||||
ss_dassert(info);
|
ss_dassert(info);
|
||||||
|
|
||||||
info->status = QC_QUERY_PARSED;
|
if ((this_unit.sql_mode != QC_SQL_MODE_ORACLE) || (token == TK_START))
|
||||||
info->type_mask = QUERY_TYPE_BEGIN_TRX | type;
|
{
|
||||||
|
info->status = QC_QUERY_PARSED;
|
||||||
|
info->type_mask = QUERY_TYPE_BEGIN_TRX | type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mxs_sqlite3BeginTrigger(Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
|
void mxs_sqlite3BeginTrigger(Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
|
||||||
@ -2465,10 +2468,19 @@ void maxscaleLock(Parse* pParse, mxs_lock_t type, SrcList* pTables)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void maxscaleKeyword(int token)
|
/**
|
||||||
|
* Register the tokenization of a keyword.
|
||||||
|
*
|
||||||
|
* @param token A keyword code (check generated parse.h)
|
||||||
|
*
|
||||||
|
* @return Non-zero if all input should be consumed, 0 otherwise.
|
||||||
|
*/
|
||||||
|
int maxscaleKeyword(int token)
|
||||||
{
|
{
|
||||||
QC_TRACE();
|
QC_TRACE();
|
||||||
|
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
QC_SQLITE_INFO* info = this_thread.info;
|
QC_SQLITE_INFO* info = this_thread.info;
|
||||||
ss_dassert(info);
|
ss_dassert(info);
|
||||||
|
|
||||||
@ -2493,6 +2505,18 @@ void maxscaleKeyword(int token)
|
|||||||
info->operation = QUERY_OP_ALTER;
|
info->operation = QUERY_OP_ALTER;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TK_BEGIN:
|
||||||
|
if (this_unit.sql_mode == QC_SQL_MODE_ORACLE)
|
||||||
|
{
|
||||||
|
// The beginning of a BLOCK. We'll assume it is in a single
|
||||||
|
// COM_QUERY packet and hence one GWBUF.
|
||||||
|
info->status = QC_QUERY_TOKENIZED;
|
||||||
|
info->type_mask = QUERY_TYPE_WRITE;
|
||||||
|
// Return non-0 to cause the entire input to be consumed.
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case TK_CALL:
|
case TK_CALL:
|
||||||
info->status = QC_QUERY_TOKENIZED;
|
info->status = QC_QUERY_TOKENIZED;
|
||||||
info->type_mask = QUERY_TYPE_WRITE;
|
info->type_mask = QUERY_TYPE_WRITE;
|
||||||
@ -2683,6 +2707,8 @@ void maxscaleKeyword(int token)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void maxscaleRenameTable(Parse* pParse, SrcList* pTables)
|
void maxscaleRenameTable(Parse* pParse, SrcList* pTables)
|
||||||
|
@ -86,7 +86,7 @@ typedef enum qc_field_usage
|
|||||||
extern void mxs_sqlite3AlterFinishAddColumn(Parse *, Token *);
|
extern void mxs_sqlite3AlterFinishAddColumn(Parse *, Token *);
|
||||||
extern void mxs_sqlite3AlterBeginAddColumn(Parse *, SrcList *);
|
extern void mxs_sqlite3AlterBeginAddColumn(Parse *, SrcList *);
|
||||||
extern void mxs_sqlite3Analyze(Parse *, SrcList *);
|
extern void mxs_sqlite3Analyze(Parse *, SrcList *);
|
||||||
extern void mxs_sqlite3BeginTransaction(Parse*, int);
|
extern void mxs_sqlite3BeginTransaction(Parse*, int token, int type);
|
||||||
extern void mxs_sqlite3CommitTransaction(Parse*);
|
extern void mxs_sqlite3CommitTransaction(Parse*);
|
||||||
extern void mxs_sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
|
extern void mxs_sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
|
||||||
Expr*, int, int);
|
Expr*, int, int);
|
||||||
@ -308,7 +308,7 @@ cmdx ::= cmd. { sqlite3FinishCoding(pParse); }
|
|||||||
%ifdef MAXSCALE
|
%ifdef MAXSCALE
|
||||||
work_opt ::= WORK.
|
work_opt ::= WORK.
|
||||||
work_opt ::= .
|
work_opt ::= .
|
||||||
cmd ::= BEGIN work_opt. {mxs_sqlite3BeginTransaction(pParse, 0);} // BEGIN [WORK]
|
cmd ::= BEGIN work_opt. {mxs_sqlite3BeginTransaction(pParse, TK_BEGIN, 0);} // BEGIN [WORK]
|
||||||
%endif
|
%endif
|
||||||
%ifndef MAXSCALE
|
%ifndef MAXSCALE
|
||||||
cmd ::= BEGIN transtype(Y) trans_opt. {sqlite3BeginTransaction(pParse, Y);}
|
cmd ::= BEGIN transtype(Y) trans_opt. {sqlite3BeginTransaction(pParse, Y);}
|
||||||
@ -3256,7 +3256,7 @@ start_transaction_characteristics(A) ::=
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd ::= START TRANSACTION start_transaction_characteristics(X). {
|
cmd ::= START TRANSACTION start_transaction_characteristics(X). {
|
||||||
mxs_sqlite3BeginTransaction(pParse, X);
|
mxs_sqlite3BeginTransaction(pParse, TK_START, X);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////// The TRUNCATE statement ////////////////////////////////////
|
//////////////////////// The TRUNCATE statement ////////////////////////////////////
|
||||||
|
@ -568,8 +568,14 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*tokenType != TK_ID) {
|
if (*tokenType != TK_ID) {
|
||||||
extern void maxscaleKeyword(int);
|
extern int maxscaleKeyword(int);
|
||||||
maxscaleKeyword(*tokenType);
|
if (maxscaleKeyword(*tokenType) != 0)
|
||||||
|
{
|
||||||
|
/* Consume the entire string. */
|
||||||
|
while ( z[i] ) {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
|
Reference in New Issue
Block a user