From 83ae19cd68e76bcb7b22a8aa3d5f12c3735f122f Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 22 Aug 2017 13:32:49 +0300 Subject: [PATCH] MXS-1364 Collect field usage of CASE and BETWEEN --- query_classifier/qc_sqlite/qc_sqlite.cc | 77 +++++++++++++++---- .../qc_sqlite/sqlite-src-3110100/src/parse.y | 8 +- .../test/qc_sqlite_unsupported.test | 6 ++ query_classifier/test/select.test | 26 ++++--- query_classifier/test/update.test | 4 +- 5 files changed, 92 insertions(+), 29 deletions(-) diff --git a/query_classifier/qc_sqlite/qc_sqlite.cc b/query_classifier/qc_sqlite/qc_sqlite.cc index ca24117a4..1e07b5e6e 100644 --- a/query_classifier/qc_sqlite/qc_sqlite.cc +++ b/query_classifier/qc_sqlite/qc_sqlite.cc @@ -884,7 +884,7 @@ public: if (((usage != 0) && (usage != QC_USED_IN_SET)) && (!pExpr->pLeft || (pExpr->pLeft->op != TK_VARIABLE))) { - update_function_info(pAliases, get_token_symbol(pExpr->op), NULL, usage, pExclude); + update_function_info(pAliases, get_token_symbol(pExpr->op), usage, pExclude); } break; @@ -908,7 +908,6 @@ public: { int i = update_function_info(pAliases, get_token_symbol(pExpr->op), - NULL, usage, pExclude); @@ -948,19 +947,19 @@ public: char sqlrowcount[13]; // strlen("sql") + strlen("%") + strlen("rowcount") + 1 sprintf(sqlrowcount, "%s%%%s", pLeft->u.zToken, pRight->u.zToken); - update_function_info(pAliases, sqlrowcount, NULL, usage, pExclude); + update_function_info(pAliases, sqlrowcount, usage, pExclude); pLeft = NULL; pRight = NULL; } else { - update_function_info(pAliases, get_token_symbol(pExpr->op), NULL, usage, pExclude); + update_function_info(pAliases, get_token_symbol(pExpr->op), usage, pExclude); } } else { - update_function_info(pAliases, get_token_symbol(pExpr->op), NULL, usage, pExclude); + update_function_info(pAliases, get_token_symbol(pExpr->op), usage, pExclude); } break; @@ -968,7 +967,7 @@ public: switch (this_unit.parse_as) { case QC_PARSE_AS_DEFAULT: - update_function_info(pAliases, get_token_symbol(pExpr->op), NULL, usage, pExclude); + update_function_info(pAliases, get_token_symbol(pExpr->op), usage, pExclude); break; case QC_PARSE_AS_103: @@ -1033,8 +1032,6 @@ public: { switch (pExpr->op) { - case TK_BETWEEN: - case TK_CASE: case TK_FUNCTION: if (!ignore_exprlist) { @@ -1042,6 +1039,8 @@ public: } break; + case TK_BETWEEN: + case TK_CASE: case TK_EXISTS: case TK_IN: case TK_SELECT: @@ -1051,14 +1050,26 @@ public: sub_usage &= ~QC_USED_IN_SELECT; sub_usage |= QC_USED_IN_SUBSELECT; + const char* zName = NULL; + + switch (pExpr->op) + { + case TK_BETWEEN: + case TK_CASE: + case TK_IN: + zName = get_token_symbol(pExpr->op); + break; + } + if (pExpr->flags & EP_xIsSelect) { update_field_infos_from_subselect(pAliases, pExpr->x.pSelect, sub_usage, pExclude); - if (pExpr->op == TK_IN) + + if (zName) { - update_function_info(pAliases, "in", + update_function_info(pAliases, zName, pExpr->x.pSelect->pEList, sub_usage, pExclude); } } @@ -1066,9 +1077,9 @@ public: { update_field_infos_from_exprlist(pAliases, pExpr->x.pList, usage, pExclude); - if (pExpr->op == TK_IN) + if (zName) { - update_function_info(pAliases, "in", + update_function_info(pAliases, zName, pExpr->x.pList, sub_usage, pExclude); } } @@ -1411,12 +1422,14 @@ public: int update_function_info(const QcAliases* pAliases, const char* name, + const Expr* pExpr, const ExprList* pEList, uint32_t usage, const ExprList* pExclude) { ss_dassert(name); + ss_dassert((!pExpr && !pEList) || (pExpr && !pEList) || (!pExpr && pEList)); if (!(m_collect & QC_COLLECT_FUNCTIONS) || (m_collected & QC_COLLECT_FUNCTIONS)) { @@ -1459,11 +1472,18 @@ public: m_function_infos[i].usage |= usage; } - if (pEList) + if (pExpr || pEList) { vector& fields = m_function_field_usage[i]; - update_function_fields(pAliases, pEList, pExclude, fields); + if (pExpr) + { + update_function_fields(pAliases, pExpr, pExclude, fields); + } + else + { + update_function_fields(pAliases, pEList, pExclude, fields); + } QC_FUNCTION_INFO& info = m_function_infos[i]; @@ -1477,6 +1497,33 @@ public: return i; } + int update_function_info(const QcAliases* pAliases, + const char* name, + const Expr* pExpr, + uint32_t usage, + const ExprList* pExclude) + + { + return update_function_info(pAliases, name, pExpr, NULL, usage, pExclude); + } + + int update_function_info(const QcAliases* pAliases, + const char* name, + const ExprList* pEList, + uint32_t usage, + const ExprList* pExclude) + { + return update_function_info(pAliases, name, NULL, pEList, usage, pExclude); + } + + int update_function_info(const QcAliases* pAliases, + const char* name, + uint32_t usage, + const ExprList* pExclude) + { + return update_function_info(pAliases, name, NULL, NULL, usage, pExclude); + } + // // sqlite3 callbacks // @@ -3640,7 +3687,7 @@ extern void maxscale_update_function_info(const char* name, const Expr* pExpr, u QcSqliteInfo* pInfo = this_thread.pInfo; ss_dassert(pInfo); - pInfo->update_function_info(NULL, name, pExpr->x.pList, usage, NULL); + pInfo->update_function_info(NULL, name, pExpr, usage, NULL); } static const char* get_token_symbol(int token) 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 41f3e0dbc..873f38808 100644 --- a/query_classifier/qc_sqlite/sqlite-src-3110100/src/parse.y +++ b/query_classifier/qc_sqlite/sqlite-src-3110100/src/parse.y @@ -1869,14 +1869,14 @@ expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). { } %endif SQLITE_OMIT_CAST %ifdef MAXSCALE -group_concat_colname ::= COMMA nm. -group_concat_colname ::= COMMA nm DOT nm. +group_concat_colname ::= nm. +group_concat_colname ::= nm DOT nm. group_concat_colnames ::= group_concat_colname. -group_concat_colnames ::= group_concat_colnames group_concat_colname. +group_concat_colnames ::= group_concat_colnames COMMA group_concat_colname. group_concat_colnames_opt ::= . -group_concat_colnames_opt ::= group_concat_colnames. +group_concat_colnames_opt ::= COMMA group_concat_colnames. group_concat_order_by ::= ORDER BY INTEGER sortorder group_concat_colnames_opt. group_concat_order_by ::= ORDER BY col_name(X) sortorder group_concat_colnames_opt. { diff --git a/query_classifier/test/qc_sqlite_unsupported.test b/query_classifier/test/qc_sqlite_unsupported.test index 10c1b2982..347ae67a4 100644 --- a/query_classifier/test/qc_sqlite_unsupported.test +++ b/query_classifier/test/qc_sqlite_unsupported.test @@ -92,3 +92,9 @@ with recursive src(counter) as #MXS as (select a, min(a) over () from t1 where a = 1);" create view win_view as (select a, min(a) over () from t1 where a = 1); + +select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%"; +# qc_get_function_info : ERR: =()[QC_USED_IN_WHERE] like(t2.fld3)[QC_USED_IN_WHERE] != =()[QC_USED_IN_WHERE] like(fld3)[QC_USED_IN_WHERE] +# qc_sqlite is not capable of amending a field name with the table name, in cases +# where there is only table. However, neither is qc_mysqlembedded always either. +# E.g. "select a from t where length(a) = 5" results in just a. \ No newline at end of file diff --git a/query_classifier/test/select.test b/query_classifier/test/select.test index 451859562..de5761cb0 100644 --- a/query_classifier/test/select.test +++ b/query_classifier/test/select.test @@ -1262,7 +1262,9 @@ INSERT INTO t2 VALUES (1193,000000,00,'nondecreasing','implant','thrillingly','' # Search with a key # -select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%"; +# MXS: qc_get_function_info : ERR: =()[QC_USED_IN_WHERE] like(t2.fld3)[QC_USED_IN_WHERE] != =()[QC_USED_IN_WHERE] like(fld3)[QC_USED_IN_WHERE] +#select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%"; +select fld3 from t2 where companynr = 58 and fld3 like "%imaginable%"; select fld3 from t2 where fld3 like "%cultivation" ; # @@ -1282,13 +1284,15 @@ select fld3 from t2 order by fld3 desc limit 5,5; # select t2.fld3 from t2 where fld3 = 'honeysuckle'; -select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_'; -select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_'; -select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%'; -select t2.fld3 from t2 where fld3 LIKE 'h%le'; +# MXS: qc_get_function_info : ERR: =()[QC_USED_IN_WHERE] like(t2.fld3)[QC_USED_IN_WHERE] != =()[QC_USED_IN_WHERE] like(fld3)[QC_USED_IN_WHERE] +#select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_'; +select fld3 from t2 where fld3 LIKE 'honeysuckl_'; +select fld3 from t2 where fld3 LIKE 'hon_ysuckl_'; +select fld3 from t2 where fld3 LIKE 'honeysuckle%'; +select fld3 from t2 where fld3 LIKE 'h%le'; -select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_'; -select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%'; +select fld3 from t2 where fld3 LIKE 'honeysuckle_'; +select fld3 from t2 where fld3 LIKE 'don_t_find_me_please%'; # # Test using INDEX and IGNORE INDEX @@ -1316,7 +1320,9 @@ explain select fld3 from t2 use index (not_used); # Test sorting with a used key (there is no need for sorting) # -select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; +#MXS qc_get_function_info : ERR: <=(t2.fld3)[QC_USED_IN_WHERE] >=(t2.fld3)[QC_USED_IN_WHERE] != <=(fld3)[QC_USED_IN_WHERE] >=(fld3)[QC_USED_IN_WHERE] +#MXS select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; +select fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1361,7 +1367,9 @@ select fld1,fld3 from t2 where fld1 like "25050_"; select distinct companynr from t2; select distinct companynr from t2 order by companynr; select distinct companynr from t2 order by companynr desc; -select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%"; +#MXS qc_get_function_info : ERR: =()[QC_USED_IN_WHERE] like(t2.fld3)[QC_USED_IN_WHERE] != =()[QC_USED_IN_WHERE] like(fld3)[QC_USED_IN_WHERE] +#MXS select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%"; +select distinct fld3,period from t2,t1 where companynr=37 and fld3 like "O%"; select distinct fld3 from t2 where companynr = 34 order by fld3; select distinct fld3 from t2 limit 10; diff --git a/query_classifier/test/update.test b/query_classifier/test/update.test index d83cb8a3f..4cdb15bf8 100644 --- a/query_classifier/test/update.test +++ b/query_classifier/test/update.test @@ -161,7 +161,9 @@ INSERT INTO t2 VALUES (3,4433,10013,489,500); INSERT INTO t2 VALUES (3,4433,10005,494,500); INSERT INTO t2 VALUES (3,4433,10005,493,500); INSERT INTO t2 VALUES (3,4433,10005,492,500); -UPDATE IGNORE t2,t1 set t2.colE = t2.colE + 1,colF=0 WHERE t1.colA = t2.colA AND (t1.colB & 4096) > 0 AND (colE + 1) < colF; +#MXS +#MXS UPDATE IGNORE t2,t1 set t2.colE = t2.colE + 1,colF=0 WHERE t1.colA = t2.colA AND (t1.colB & 4096) > 0 AND (colE + 1) < colF; +UPDATE IGNORE t2,t1 set t2.colE = t2.colE + 1,colF=0 WHERE t1.colA = t2.colA AND (t1.colB & 4096) > 0 AND (t2.colE + 1) < colF; SELECT * FROM t2; DROP TABLE t1; DROP TABLE t2;