From 77cd733a6d79161a42c16678dd287e0e06672c58 Mon Sep 17 00:00:00 2001 From: Denis Khalikov Date: Mon, 1 Apr 2024 14:13:39 +0300 Subject: [PATCH] fix(plugin): MCOL-5236 Take `Item` from `Ref_Item` for group by list. (#3162) --- dbcon/mysql/ha_mcs_execplan.cpp | 36 ++++++++++++------- .../columnstore/bugfixes/mcol-5236.result | 22 ++++++++++++ .../columnstore/bugfixes/mcol-5236.test | 34 ++++++++++++++++++ 3 files changed, 79 insertions(+), 13 deletions(-) create mode 100644 mysql-test/columnstore/bugfixes/mcol-5236.result create mode 100644 mysql-test/columnstore/bugfixes/mcol-5236.test diff --git a/dbcon/mysql/ha_mcs_execplan.cpp b/dbcon/mysql/ha_mcs_execplan.cpp index 50ab865a8..2039e61d9 100644 --- a/dbcon/mysql/ha_mcs_execplan.cpp +++ b/dbcon/mysql/ha_mcs_execplan.cpp @@ -498,9 +498,18 @@ bool sortItemIsInGrouping(Item* sort_item, ORDER* groupcol) // is either Field or Func // Consider nonConstFunc() check here if (!found && sort_item->type() == Item::FUNC_ITEM && - (group_item->type() == Item::FUNC_ITEM || group_item->type() == Item::FIELD_ITEM)) + (group_item->type() == Item::FUNC_ITEM || group_item->type() == Item::FIELD_ITEM || + group_item->type() == Item::REF_ITEM)) { - found = sortItemIsInGroupRec(sort_item, group_item); + // MCOL-5236: see @bug5993 and @bug5916. + Item* item = group_item; + while (item->type() == Item::REF_ITEM) + { + Item_ref* item_ref = static_cast(item); + item = *item_ref->ref; + } + + found = sortItemIsInGroupRec(sort_item, item); } } @@ -4387,7 +4396,8 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non // A few functions use a different collation than that found in // the base ifp class - if (funcName == "locate" || funcName == "find_in_set" || funcName == "strcmp" || funcName == "regexp_instr") + if (funcName == "locate" || funcName == "find_in_set" || funcName == "strcmp" || + funcName == "regexp_instr") { DTCollation dt; ifp->Type_std_attributes::agg_arg_charsets_for_comparison(dt, ifp->func_name_cstring(), @@ -8086,18 +8096,18 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i ReturnedColumn* rc = buildSimpleColumn(ifp, gwi); SimpleColumn* sc = dynamic_cast(rc); - if (sc) - { - bool found = false; + if (sc) + { + bool found = false; for (uint32_t j = 0; j < gwi.returnedCols.size(); j++) { if (sc->sameColumn(gwi.returnedCols[j].get())) { sc->orderPos(j); - found = true; + found = true; break; } - } + } for (uint32_t j = 0; !found && j < gwi.returnedCols.size(); j++) { if (strcasecmp(sc->alias().c_str(), gwi.returnedCols[j]->alias().c_str()) == 0) @@ -8107,9 +8117,9 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i break; } } - } - else - { + } + else + { for (uint32_t j = 0; j < gwi.returnedCols.size(); j++) { if (ifp->name.length && string(ifp->name.str) == gwi.returnedCols[j].get()->alias()) @@ -8119,7 +8129,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i break; } } - } + } if (!rc) { @@ -9841,7 +9851,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro } } - srcp->orderPos(groupcol->counter - 1); + srcp->orderPos(groupcol->counter - 1); gwi.groupByCols.push_back(srcp); continue; } diff --git a/mysql-test/columnstore/bugfixes/mcol-5236.result b/mysql-test/columnstore/bugfixes/mcol-5236.result new file mode 100644 index 000000000..491a6e850 --- /dev/null +++ b/mysql-test/columnstore/bugfixes/mcol-5236.result @@ -0,0 +1,22 @@ +DROP DATABASE IF EXISTS mcol_5236; +CREATE DATABASE mcol_5236; +USE mcol_5236; +create table test_having_columnstore (someString varchar(1000), someInt int, FK int) ENGINE=Columnstore DEFAULT CHARSET=utf8; +insert into test_having_columnstore values ('bla', 1, 17), ('xyz', 2, 17); +create table dim_having_columnstore (PK int, someString varchar(1000)) ENGINE=Columnstore DEFAULT CHARSET=utf8; +insert into dim_having_columnstore values(17, 'test'); +create view test_having_columnstore_view as +select someString as someString, someInt as someInt, FK as FK from test_having_columnstore; +create view dim_having_columnstore_view as +select * from dim_having_columnstore; +select `dim`.`someString` as `c0` +from `dim_having_columnstore_view` as `dim`, `test_having_columnstore_view` as `fact` +where `fact`.`FK` = `dim`.`PK` +group by `dim`.`someString` +having NOT((sum(`fact`.`someInt`) is null)) +order by ISNULL(`dim`.`someString`) ASC, +`dim`.`someString` ASC; +c0 +test +DROP DATABASE mcol_5236; +ok diff --git a/mysql-test/columnstore/bugfixes/mcol-5236.test b/mysql-test/columnstore/bugfixes/mcol-5236.test new file mode 100644 index 000000000..e1f79d4ee --- /dev/null +++ b/mysql-test/columnstore/bugfixes/mcol-5236.test @@ -0,0 +1,34 @@ +# +# MCOL-5236 +# + +--source ../include/have_columnstore.inc + +--disable_warnings +DROP DATABASE IF EXISTS mcol_5236; +--enable_warnings +CREATE DATABASE mcol_5236; +USE mcol_5236; + +create table test_having_columnstore (someString varchar(1000), someInt int, FK int) ENGINE=Columnstore DEFAULT CHARSET=utf8; +insert into test_having_columnstore values ('bla', 1, 17), ('xyz', 2, 17); +create table dim_having_columnstore (PK int, someString varchar(1000)) ENGINE=Columnstore DEFAULT CHARSET=utf8; +insert into dim_having_columnstore values(17, 'test'); + +create view test_having_columnstore_view as +select someString as someString, someInt as someInt, FK as FK from test_having_columnstore; + +create view dim_having_columnstore_view as +select * from dim_having_columnstore; + +select `dim`.`someString` as `c0` +from `dim_having_columnstore_view` as `dim`, `test_having_columnstore_view` as `fact` +where `fact`.`FK` = `dim`.`PK` +group by `dim`.`someString` +having NOT((sum(`fact`.`someInt`) is null)) +order by ISNULL(`dim`.`someString`) ASC, +`dim`.`someString` ASC; + +--disable_warnings +DROP DATABASE mcol_5236; +--enable_warnings