From 1baaf878d006d61262962bfacb29ad6e152a167d Mon Sep 17 00:00:00 2001 From: drrtuy Date: Wed, 11 Jun 2025 21:52:23 +0000 Subject: [PATCH] feat(optimizer): basic rewrite Union unit into Sub with union --- dbcon/execplan/calpontselectexecutionplan.cpp | 8 +- dbcon/mysql/ha_mcs_execplan.cpp | 84 ++++++++++++++----- 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/dbcon/execplan/calpontselectexecutionplan.cpp b/dbcon/execplan/calpontselectexecutionplan.cpp index 25b848f00..a09aee082 100644 --- a/dbcon/execplan/calpontselectexecutionplan.cpp +++ b/dbcon/execplan/calpontselectexecutionplan.cpp @@ -282,9 +282,13 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const output << ">>Filters" << endlWithIndent(ident); if (filters() != nullptr) + { filters()->walk(ParseTree::print, output); + } else + { output << "empty filter tree" << endlWithIndent(ident); + } // Group by columns const CalpontSelectExecutionPlan::GroupByColumnList& gbc = groupByCols(); @@ -913,8 +917,8 @@ execplan::SCSEP CalpontSelectExecutionPlan::cloneWORecursiveSelects() newPlan->returnedCols(newReturnedCols); // Deep copy of filters - // if (fFilters) - // newPlan->filters(new ParseTree(*fFilters)); + if (fFilters) + newPlan->filters(new ParseTree(*fFilters)); // Deep copy of filter token list newPlan->filterTokenList(fFilterTokenList); diff --git a/dbcon/mysql/ha_mcs_execplan.cpp b/dbcon/mysql/ha_mcs_execplan.cpp index a76fd5b22..25e6ccc42 100644 --- a/dbcon/mysql/ha_mcs_execplan.cpp +++ b/dbcon/mysql/ha_mcs_execplan.cpp @@ -9210,8 +9210,8 @@ bool tableIsInUnion(const execplan::CalpontSystemCatalog::TableAliasName& table, { return std::any_of(csep.unionVec().begin(), csep.unionVec().end(), [&table](const auto& unionUnit) { - auto unionUnitLocal = *dynamic_cast(unionUnit.get()); - bool tableIsPresented = std::any_of(unionUnitLocal.tableList().begin(), unionUnitLocal.tableList().end(), + execplan::CalpontSelectExecutionPlan* unionUnitLocal = dynamic_cast(unionUnit.get()); + bool tableIsPresented = std::any_of(unionUnitLocal->tableList().begin(), unionUnitLocal->tableList().end(), [&table](const auto& unionTable) { return unionTable == table; }); @@ -9223,15 +9223,9 @@ bool matchParallelCES(CalpontSelectExecutionPlan& csep) { auto tables = csep.tableList(); // This is leaf and there are no other tables at this level. - for (auto& table : tables) - { - if (!table.isColumnstore() && !tableIsInUnion(table, csep)) - { - return true; - } - } - - return false; + // WIP filter out CSEPs with orderBy, groupBy, having + // WIP filter out CSEPs with nonSimpleColumns in projection + return tables.size() == 1 && !tables[0].isColumnstore() && !tableIsInUnion(tables[0], csep); } CalpontSelectExecutionPlan::SelectList makeUnionFromTable(const size_t numberOfLegs, @@ -9247,19 +9241,69 @@ CalpontSelectExecutionPlan::SelectList makeUnionFromTable(const size_t numberOfL return unionVec; } +// void applyParallelCES(CalpontSelectExecutionPlan& csep) +// { +// auto tables = csep.tableList(); +// for (auto it = tables.begin(); it != tables.end(); ++it) +// { +// if (!it->isColumnstore()) +// { +// size_t parallelFactor = 2; +// auto additionalUnionVec = makeUnionFromTable(parallelFactor, csep); +// csep.unionVec().insert(csep.unionVec().end(), additionalUnionVec.begin(), additionalUnionVec.end()); +// } +// } +// } + void applyParallelCES(CalpontSelectExecutionPlan& csep) { auto tables = csep.tableList(); - for (auto it = tables.begin(); it != tables.end(); ++it) + CalpontSelectExecutionPlan::TableList newTableList; + CalpontSelectExecutionPlan::SelectList newDerivedTableList; + static const std::string aliasPrefix = "subQ"; + + // ATM Must be only 1 table + for (auto& table: tables) { - if (!it->isColumnstore()) + if (!table.isColumnstore()) { + auto derivedSCEP = csep.cloneWORecursiveSelects(); + std::string alias = aliasPrefix + table.schema + "_" + table.table; + + derivedSCEP->location(CalpontSelectExecutionPlan::FROM); + derivedSCEP->subType(CalpontSelectExecutionPlan::FROM_SUBS); + derivedSCEP->derivedTbAlias(alias); + size_t parallelFactor = 2; auto additionalUnionVec = makeUnionFromTable(parallelFactor, csep); - csep.unionVec().insert(csep.unionVec().end(), additionalUnionVec.begin(), additionalUnionVec.end()); + derivedSCEP->unionVec().insert(derivedSCEP->unionVec().end(), additionalUnionVec.begin(), additionalUnionVec.end()); + + // change parent to derived table columns + for (auto& rc : csep.returnedCols()) + { + auto* sc = dynamic_cast(rc.get()); + if (sc) + { + sc->tableName(""); + sc->schemaName(""); + sc->tableAlias(alias); + } + } + + + + // WIP need to work with existing derived tables + newDerivedTableList.push_back(derivedSCEP); + // WIP + CalpontSystemCatalog::TableAliasName tn = make_aliasview("", "", alias, ""); + newTableList.push_back(tn); } } + + csep.derivedTableList(newDerivedTableList); + csep.tableList(newTableList); } + struct Rule { Rule(std::string&& name, bool (*matchRule)(CalpontSelectExecutionPlan&), @@ -9303,7 +9347,7 @@ struct Rule if (matchRule(csep)) { - apply(csep); + applyRule(csep); rewrite = true; } @@ -9333,11 +9377,11 @@ int cs_get_select_plan(ha_columnstore_select_handler* handler, THD* /*thd*/, SCS else if (status < 0) return status; -#ifdef DEBUG_WALK_COND - // cerr << "---------------- cs_get_select_plan EXECUTION PLAN ----------------" << endl; - // cerr << *csep << endl; - // cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; -#endif +// #ifdef DEBUG_WALK_COND + cerr << "---------------- cs_get_select_plan EXECUTION PLAN ----------------" << endl; + cerr << *csep << endl; + cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; +// #endif // Derived table projection and filter optimization. derivedTableOptimization(&gwi, csep);