From 4c2909e86ca9cfe2df201ec65e081e69eb58818a Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Mar 2020 13:06:30 +0200 Subject: [PATCH] MXS-2227 Fix problem, parse OPTIMIZE statements OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ... [WAIT n | NOWAIT] --- query_classifier/qc_sqlite/qc_sqlite.cc | 31 +++++++++++++++++++ .../qc_sqlite/sqlite-src-3110100/src/parse.y | 24 ++++++++++++++ .../sqlite-src-3110100/tool/mkkeywordhash.c | 3 ++ 3 files changed, 58 insertions(+) diff --git a/query_classifier/qc_sqlite/qc_sqlite.cc b/query_classifier/qc_sqlite/qc_sqlite.cc index 8903de849..0d9aebd31 100644 --- a/query_classifier/qc_sqlite/qc_sqlite.cc +++ b/query_classifier/qc_sqlite/qc_sqlite.cc @@ -2508,6 +2508,21 @@ public: } } + void maxscaleOptimize(Parse* pParse, SrcList* pTables) + { + mxb_assert(this_thread.initialized); + + m_status = QC_QUERY_PARSED; + m_type_mask = QUERY_TYPE_WRITE; + + if (pTables) + { + update_names_from_srclist(NULL, pTables); + + exposed_sqlite3SrcListDelete(pParse->db, pTables); + } + } + int maxscaleTranslateKeyword(int token) { switch (token) @@ -2641,6 +2656,11 @@ public: m_type_mask = QUERY_TYPE_WRITE; break; + case TK_OPTIMIZE: + m_status = QC_QUERY_TOKENIZED; + m_type_mask = QUERY_TYPE_WRITE; + break; + case TK_PREPARE: m_status = QC_QUERY_TOKENIZED; m_type_mask = QUERY_TYPE_PREPARE_NAMED_STMT; @@ -3563,6 +3583,7 @@ extern void maxscaleFlush(Parse*, Token* pWhat); extern void maxscaleHandler(Parse*, mxs_handler_t, SrcList* pFullName, Token* pName); extern void maxscaleLoadData(Parse*, SrcList* pFullName, int local); extern void maxscaleLock(Parse*, mxs_lock_t, SrcList*); +extern void maxscaleOptimize(Parse* pParse, SrcList*); extern void maxscalePrepare(Parse*, Token* pName, Expr* pStmt); extern void maxscalePrivileges(Parse*, int kind); extern void maxscaleRenameTable(Parse*, SrcList* pTables); @@ -4543,6 +4564,16 @@ void maxscaleLoadData(Parse* pParse, SrcList* pFullName, int local) QC_EXCEPTION_GUARD(pInfo->maxscaleLoadData(pParse, pFullName, local)); } +void maxscaleOptimize(Parse* pParse, SrcList* pTables) +{ + QC_TRACE(); + + QcSqliteInfo* pInfo = this_thread.pInfo; + mxb_assert(pInfo); + + QC_EXCEPTION_GUARD(pInfo->maxscaleOptimize(pParse, pTables)); +} + void maxscaleLock(Parse* pParse, mxs_lock_t type, SrcList* pTables) { QC_TRACE(); diff --git a/query_classifier/qc_sqlite/sqlite-src-3110100/src/parse.y b/query_classifier/qc_sqlite/sqlite-src-3110100/src/parse.y index 19e5f7d21..c084b1983 100644 --- a/query_classifier/qc_sqlite/sqlite-src-3110100/src/parse.y +++ b/query_classifier/qc_sqlite/sqlite-src-3110100/src/parse.y @@ -123,6 +123,7 @@ extern void maxscaleFlush(Parse*, Token* pWhat); extern void maxscaleHandler(Parse*, mxs_handler_t, SrcList* pFullName, Token* pName); extern void maxscaleLoadData(Parse*, SrcList* pFullName, int local); extern void maxscaleLock(Parse*, mxs_lock_t, SrcList*); +extern void maxscaleOptimize(Parse*, SrcList*); extern void maxscalePrepare(Parse*, Token* pName, Expr* pStmt); extern void maxscalePrivileges(Parse*, int kind); extern void maxscaleRenameTable(Parse*, SrcList* pTables); @@ -630,6 +631,7 @@ columnid(A) ::= nm(X). { IF IMMEDIATE INITIALLY INSTEAD /*KEY*/ /*LIKE_KW*/ + LOCAL MASTER /*MATCH*/ MERGE // TODO: MOD is a keyword that should not decay into an id. However, now that is does, // TODO: also "mod(a, 2)" kind of usage will be accepted. Incorrect use will anyway be @@ -637,6 +639,7 @@ columnid(A) ::= nm(X). { MOD NAMES NEXT NO + NOWAIT OF OFFSET OPEN PARTITIONS PASSWORD PREVIOUS QUERY QUICK @@ -648,6 +651,7 @@ columnid(A) ::= nm(X). { // TODO: However, if not here then rules such as CAST need to be modified. UNSIGNED VALUE VIEW /*VIRTUAL*/ + WAIT /*WITH*/ WORK XA @@ -3497,6 +3501,26 @@ cmd ::= TRUNCATE table_opt nm(X) dbnm(Y). { maxscaleTruncate(pParse, pDatabase, pName); } +//////////////////////// OPTIMIZE statement //////////////////////////////////// +// +cmd ::= optimize(X). { + maxscaleOptimize(pParse, X); +} + +%type optimize {SrcList*} + +optimize_arg1_opt ::= . +optimize_arg1_opt ::= LOCAL. +optimize_arg1_opt ::= NO_WRITE_TO_BINLOG. + +optimize_arg2_opt ::= . +optimize_arg2_opt ::= NOWAIT. +optimize_arg2_opt ::= WAIT INTEGER. + +optimize(A) ::= OPTIMIZE optimize_arg1_opt TABLE fullnames(X) optimize_arg2_opt. { + A = X; +} + //////////////////////// ORACLE Assignment //////////////////////////////////// // oracle_assignment ::= id(X) EQ expr(Y). { diff --git a/query_classifier/qc_sqlite/sqlite-src-3110100/tool/mkkeywordhash.c b/query_classifier/qc_sqlite/sqlite-src-3110100/tool/mkkeywordhash.c index 42c8c088c..c31357797 100644 --- a/query_classifier/qc_sqlite/sqlite-src-3110100/tool/mkkeywordhash.c +++ b/query_classifier/qc_sqlite/sqlite-src-3110100/tool/mkkeywordhash.c @@ -361,6 +361,7 @@ static Keyword aKeywordTable[] = { { "NOT", "TK_NOT", ALWAYS }, { "NOTNULL", "TK_NOTNULL", ALWAYS }, #ifdef MAXSCALE + { "NOWAIT", "TK_NOWAIT", ALWAYS }, { "NO_WRITE_TO_BINLOG","TK_NO_WRITE_TO_BINLOG",ALWAYS }, #endif { "NULL", "TK_NULL", ALWAYS }, @@ -400,6 +401,7 @@ static Keyword aKeywordTable[] = { { "PROCEDURE", "TK_FUNCTION_KW", ALWAYS }, #endif #ifdef MAXSCALE + { "OPTIMIZE", "TK_OPTIMIZE", ALWAYS }, { "QUERY", "TK_QUERY", ALWAYS }, #else { "QUERY", "TK_QUERY", EXPLAIN }, @@ -501,6 +503,7 @@ static Keyword aKeywordTable[] = { { "VIEW", "TK_VIEW", VIEW }, { "VIRTUAL", "TK_VIRTUAL", VTAB }, #ifdef MAXSCALE + { "WAIT", "TK_WAIT", ALWAYS }, { "WARNINGS", "TK_WARNINGS", ALWAYS }, { "WINDOW", "TK_WINDOW", ALWAYS }, #endif