From 49ab5797a26ae283b6257041a5c9e9f456fa0c3a Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 12 Sep 2017 15:38:25 +0300 Subject: [PATCH] MXS-1406 Report CALL operation Basically it would be trivial to report far more operations explicitly, but for the fact that the values in qc_query_op_t currently, quite unnecessarily, form a bitmask. In 2.2 that is no longer the case, so other operations will be added there. --- include/maxscale/query_classifier.h | 3 ++- .../qc_mysqlembedded/qc_mysqlembedded.cc | 4 ++++ query_classifier/qc_sqlite/qc_sqlite.c | 9 +++++++- .../qc_sqlite/sqlite-src-3110100/src/parse.y | 21 ++++++------------- query_classifier/test/maxscale.test | 5 ++++- server/core/query_classifier.cc | 3 +++ 6 files changed, 27 insertions(+), 18 deletions(-) diff --git a/include/maxscale/query_classifier.h b/include/maxscale/query_classifier.h index d886208d5..50ac81083 100644 --- a/include/maxscale/query_classifier.h +++ b/include/maxscale/query_classifier.h @@ -94,7 +94,8 @@ typedef enum qc_query_op QUERY_OP_CHANGE_DB = (1 << 8), QUERY_OP_LOAD = (1 << 9), QUERY_OP_GRANT = (1 << 10), - QUERY_OP_REVOKE = (1 << 11) + QUERY_OP_REVOKE = (1 << 11), + QUERY_OP_CALL = (1 << 12), } qc_query_op_t; /** diff --git a/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc b/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc index ee7dd83bb..a180fb072 100644 --- a/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc +++ b/query_classifier/qc_mysqlembedded/qc_mysqlembedded.cc @@ -1737,6 +1737,10 @@ int32_t qc_mysql_get_operation(GWBUF* querybuf, int32_t* operation) *operation = QUERY_OP_REVOKE; break; + case SQLCOM_CALL: + *operation = QUERY_OP_CALL; + break; + default: *operation = QUERY_OP_UNDEFINED; } diff --git a/query_classifier/qc_sqlite/qc_sqlite.c b/query_classifier/qc_sqlite/qc_sqlite.c index ab9e84fc5..438fb1489 100644 --- a/query_classifier/qc_sqlite/qc_sqlite.c +++ b/query_classifier/qc_sqlite/qc_sqlite.c @@ -1946,7 +1946,7 @@ void maxscaleAlterTable(Parse *pParse, /* Parser context. */ exposed_sqlite3SrcListDelete(pParse->db, pSrc); } -void maxscaleCall(Parse* pParse, SrcList* pName) +void maxscaleCall(Parse* pParse, SrcList* pName, ExprList* pExprList) { QC_TRACE(); @@ -1955,8 +1955,15 @@ void maxscaleCall(Parse* pParse, SrcList* pName) info->status = QC_QUERY_PARSED; info->type_mask = QUERY_TYPE_WRITE; + info->operation = QUERY_OP_CALL; + + if (pExprList) + { + update_field_infos_from_exprlist(info, pExprList, 0, NULL); + } exposed_sqlite3SrcListDelete(pParse->db, pName); + exposed_sqlite3ExprListDelete(pParse->db, pExprList); } void maxscaleCheckTable(Parse* pParse, SrcList* pTables) 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 62a95357b..f3f7e0007 100644 --- a/query_classifier/qc_sqlite/sqlite-src-3110100/src/parse.y +++ b/query_classifier/qc_sqlite/sqlite-src-3110100/src/parse.y @@ -107,7 +107,7 @@ extern void mxs_sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); extern void maxscaleCollectInfoFromSelect(Parse*, Select*, int); extern void maxscaleAlterTable(Parse*, mxs_alter_t command, SrcList*, Token*); -extern void maxscaleCall(Parse*, SrcList* pName); +extern void maxscaleCall(Parse*, SrcList* pName, ExprList* pExprList); extern void maxscaleCheckTable(Parse*, SrcList* pTables); extern void maxscaleDeallocate(Parse*, Token* pName); extern void maxscaleDo(Parse*, ExprList* pEList); @@ -2691,21 +2691,12 @@ default_opt ::= DEFAULT. // cmd ::= call. -call_arg ::= INTEGER. -call_arg ::= FLOAT. -call_arg ::= STRING. -call_arg ::= id. -call_arg ::= VARIABLE. +%type call_args_opt {ExprList*} +call_args_opt(A) ::= . {A=0;} +call_args_opt(A) ::= LP exprlist(X) RP. {A=X;} -call_args ::= call_arg. -call_args ::= call_args COMMA call_arg. - -call_args_opt ::= . -call_args_opt ::= LP RP. -call_args_opt ::= LP call_args RP. - -call ::= CALL fullname(X) call_args_opt. { - maxscaleCall(pParse, X); +call ::= CALL fullname(X) call_args_opt(Y). { + maxscaleCall(pParse, X, Y); } //////////////////////// DROP FUNCTION statement //////////////////////////////////// diff --git a/query_classifier/test/maxscale.test b/query_classifier/test/maxscale.test index 64f5050bc..6b9b59449 100644 --- a/query_classifier/test/maxscale.test +++ b/query_classifier/test/maxscale.test @@ -83,4 +83,7 @@ SELECT her FROM (SELECT @@server_id as her) as t WHERE her REGEXP '.*'; select * from db1.t1 union select * from db2.t2; # Names is a keyword as well -select names from t; \ No newline at end of file +select names from t; + +call p1(); +call p1(@var); \ No newline at end of file diff --git a/server/core/query_classifier.cc b/server/core/query_classifier.cc index 17b8c41fa..73b73fb8c 100644 --- a/server/core/query_classifier.cc +++ b/server/core/query_classifier.cc @@ -530,6 +530,9 @@ const char* qc_op_to_string(qc_query_op_t op) case QUERY_OP_REVOKE: return "QUERY_OP_REVOKE"; + case QUERY_OP_CALL: + return "QUERY_OP_CALL"; + default: return "UNKNOWN_QUERY_OP"; }