From dfa9657f2e22c61a643c4b2a75f510d2bc6cc1d5 Mon Sep 17 00:00:00 2001 From: Gagan Goel Date: Mon, 8 Mar 2021 07:23:51 -0500 Subject: [PATCH] MCOL-4589 Follow up on MCOL-4543 to optimize out non-referenced columns from a subquery involving UNIONs. --- dbcon/mysql/ha_from_sub.cpp | 63 +++++++++++++++++++++++++----------- mtr/basic/r/mcol-4543.result | 51 ++++++++++++++++++++++++++++- mtr/basic/t/mcol-4543.test | 7 +++- 3 files changed, 100 insertions(+), 21 deletions(-) diff --git a/dbcon/mysql/ha_from_sub.cpp b/dbcon/mysql/ha_from_sub.cpp index 1a183c456..c95bbe96c 100644 --- a/dbcon/mysql/ha_from_sub.cpp +++ b/dbcon/mysql/ha_from_sub.cpp @@ -57,7 +57,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) for (uint i = 0; i < derivedTbList.size(); i++) { - CalpontSelectExecutionPlan* plan = dynamic_cast(derivedTbList[i].get()); + CalpontSelectExecutionPlan* plan = reinterpret_cast(derivedTbList[i].get()); CalpontSelectExecutionPlan::ReturnedColumnList cols = plan->returnedCols(); vector unionColVec; @@ -73,7 +73,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) for (uint j = 0; j < plan->unionVec().size(); j++) { unionColVec.push_back( - dynamic_cast(plan->unionVec()[j].get())->returnedCols()); + reinterpret_cast(plan->unionVec()[j].get())->returnedCols()); } } @@ -82,7 +82,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) for (uint j = 0; j < plan->unionVec().size(); j++) { - if (dynamic_cast(plan->unionVec()[j].get())->tableList().empty()) + if (reinterpret_cast(plan->unionVec()[j].get())->tableList().empty()) { horizontalOptimization = false; break; @@ -111,6 +111,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) // of the subquery in ExeMgr. // This will be addressed in future. CalpontSelectExecutionPlan::ReturnedColumnList nonConstCols; + vector nonConstUnionColVec(unionColVec.size()); int64_t lastNonConstIndex = -1; @@ -122,7 +123,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) if (cols[i]->derivedRefCol()) cols[i]->derivedRefCol()->decRefCount(); - if ((lastNonConstIndex == -1) && unionColVec.empty()) + if (lastNonConstIndex == -1) { SimpleColumn* sc = dynamic_cast(cols[i].get()); @@ -134,13 +135,28 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) else { cols[i].reset(new ConstantColumn(val)); - (dynamic_cast(cols[i].get()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (reinterpret_cast(cols[i].get()))->timeZone(thd->variables.time_zone->get_name()->ptr()); } for (uint j = 0; j < unionColVec.size(); j++) { - unionColVec[j][i].reset(new ConstantColumn(val)); - (dynamic_cast(unionColVec[j][i].get()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + if (lastNonConstIndex == -1) + { + CalpontSelectExecutionPlan* unionSubPlan = + reinterpret_cast(plan->unionVec()[j].get()); + + SimpleColumn* sc = dynamic_cast(unionSubPlan->returnedCols()[i].get()); + + if (sc && (unionSubPlan->columnMap().count(sc->columnName()) == 1)) + { + unionSubPlan->columnMap().erase(sc->columnName()); + } + } + else + { + unionColVec[j][i].reset(new ConstantColumn(val)); + (reinterpret_cast(unionColVec[j][i].get()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + } } } else if (lastNonConstIndex == -1) @@ -155,27 +171,36 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) if (!cols.empty()) { cols[0].reset(new ConstantColumn(val)); - (dynamic_cast(cols[0].get()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (reinterpret_cast(cols[0].get()))->timeZone(thd->variables.time_zone->get_name()->ptr()); nonConstCols.push_back(cols[0]); + + for (uint j = 0; j < unionColVec.size(); j++) + { + unionColVec[j][0].reset(new ConstantColumn(val)); + (reinterpret_cast(unionColVec[j][0].get()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + nonConstUnionColVec[j].push_back(unionColVec[j][0]); + } } } else { nonConstCols.assign(cols.begin(), cols.begin() + lastNonConstIndex + 1); + + for (uint j = 0; j < unionColVec.size(); j++) + { + nonConstUnionColVec[j].assign(unionColVec[j].begin(), unionColVec[j].begin() + lastNonConstIndex + 1); + } } // set back - if (unionColVec.empty()) - { - plan->returnedCols(nonConstCols); - } - else - { - plan->returnedCols(cols); - } + plan->returnedCols(nonConstCols); for (uint j = 0; j < unionColVec.size(); j++) - dynamic_cast(plan->unionVec()[j].get())->returnedCols(unionColVec[j]); + { + CalpontSelectExecutionPlan* unionSubPlan = + reinterpret_cast(plan->unionVec()[j].get()); + unionSubPlan->returnedCols(nonConstUnionColVec[j]); + } } } @@ -210,7 +235,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) for (uint i = 0; i < derivedTbList.size(); i++) { - CalpontSelectExecutionPlan* plan = dynamic_cast(derivedTbList[i].get()); + CalpontSelectExecutionPlan* plan = reinterpret_cast(derivedTbList[i].get()); CalpontSelectExecutionPlan::ReturnedColumnList derivedColList = plan->returnedCols(); mapIt = derivedTbFilterMap.find(plan->derivedTbAlias()); @@ -240,7 +265,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) for (uint j = 0; j < plan->unionVec().size(); j++) { CalpontSelectExecutionPlan* unionPlan = - dynamic_cast(plan->unionVec()[j].get()); + reinterpret_cast(plan->unionVec()[j].get()); CalpontSelectExecutionPlan::ReturnedColumnList unionColList = unionPlan->returnedCols(); ParseTree* mainFilterForUnion = new ParseTree(); mainFilterForUnion->copyTree(*(mapIt->second)); diff --git a/mtr/basic/r/mcol-4543.result b/mtr/basic/r/mcol-4543.result index f0557638b..2ba78a8bd 100644 --- a/mtr/basic/r/mcol-4543.result +++ b/mtr/basic/r/mcol-4543.result @@ -176,10 +176,59 @@ COUNT(a) SELECT COUNT(b) FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q; COUNT(b) 10 +SELECT COUNT(b), COUNT(a) FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q; +COUNT(b) COUNT(a) +10 10 SELECT COUNT(a) FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q GROUP BY b ORDER BY b; COUNT(a) 4 6 +SELECT q1.a FROM (SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q1_1) q1 JOIN +(SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q2_1) q2 ON q1.a=q2.a ORDER BY 1; +a +1 +1 +1 +1 +2 +2 +2 +2 +3 +3 +3 +3 +4 +4 +4 +4 +5 +5 +5 +5 +SELECT q1.a, q2.b FROM (SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q1_1) q1 JOIN +(SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q2_1) q2 ON q1.a=q2.a ORDER BY 2 desc, 1 asc; +a b +3 2 +3 2 +3 2 +3 2 +4 2 +4 2 +4 2 +4 2 +5 2 +5 2 +5 2 +5 2 +1 1 +1 1 +1 1 +1 1 +2 1 +2 1 +2 1 +2 1 SELECT "123" FROM (SELECT * FROM t1) q GROUP BY b ORDER BY b; 123 123 @@ -188,4 +237,4 @@ SELECT "123" FROM (SELECT * FROM t1) q GROUP BY b; 123 123 123 -DROP DATABASE IF EXISTS mcol4543; +DROP DATABASE mcol4543; diff --git a/mtr/basic/t/mcol-4543.test b/mtr/basic/t/mcol-4543.test index 427c7a803..d92b399b9 100644 --- a/mtr/basic/t/mcol-4543.test +++ b/mtr/basic/t/mcol-4543.test @@ -51,7 +51,12 @@ SELECT tab1.a, tab2.b FROM t1 tab1 JOIN (SELECT * FROM t1) tab2 ON tab1.a=tab2.a # Test subquery columns referenced/not-referenced when subqueries contain unions SELECT COUNT(a) FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q; SELECT COUNT(b) FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q; +SELECT COUNT(b), COUNT(a) FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q; SELECT COUNT(a) FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q GROUP BY b ORDER BY b; +SELECT q1.a FROM (SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q1_1) q1 JOIN +(SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q2_1) q2 ON q1.a=q2.a ORDER BY 1; +SELECT q1.a, q2.b FROM (SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q1_1) q1 JOIN +(SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q2_1) q2 ON q1.a=q2.a ORDER BY 2 desc, 1 asc; # Patch for MCOL-4543 also optimizes out an unnecessary BPS projection in PrimProc # that was happening earlier. The following 2 queries trigger this optimization. @@ -59,4 +64,4 @@ SELECT COUNT(a) FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) q GROUP BY b SELECT "123" FROM (SELECT * FROM t1) q GROUP BY b ORDER BY b; SELECT "123" FROM (SELECT * FROM t1) q GROUP BY b; -DROP DATABASE IF EXISTS mcol4543; +DROP DATABASE mcol4543;