You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
feat(optimizer): basic rewrite Union unit into Sub with union
This commit is contained in:
@ -282,9 +282,13 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const
|
|||||||
output << ">>Filters" << endlWithIndent(ident);
|
output << ">>Filters" << endlWithIndent(ident);
|
||||||
|
|
||||||
if (filters() != nullptr)
|
if (filters() != nullptr)
|
||||||
|
{
|
||||||
filters()->walk(ParseTree::print, output);
|
filters()->walk(ParseTree::print, output);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
output << "empty filter tree" << endlWithIndent(ident);
|
output << "empty filter tree" << endlWithIndent(ident);
|
||||||
|
}
|
||||||
|
|
||||||
// Group by columns
|
// Group by columns
|
||||||
const CalpontSelectExecutionPlan::GroupByColumnList& gbc = groupByCols();
|
const CalpontSelectExecutionPlan::GroupByColumnList& gbc = groupByCols();
|
||||||
@ -913,8 +917,8 @@ execplan::SCSEP CalpontSelectExecutionPlan::cloneWORecursiveSelects()
|
|||||||
newPlan->returnedCols(newReturnedCols);
|
newPlan->returnedCols(newReturnedCols);
|
||||||
|
|
||||||
// Deep copy of filters
|
// Deep copy of filters
|
||||||
// if (fFilters)
|
if (fFilters)
|
||||||
// newPlan->filters(new ParseTree(*fFilters));
|
newPlan->filters(new ParseTree(*fFilters));
|
||||||
|
|
||||||
// Deep copy of filter token list
|
// Deep copy of filter token list
|
||||||
newPlan->filterTokenList(fFilterTokenList);
|
newPlan->filterTokenList(fFilterTokenList);
|
||||||
|
@ -9210,8 +9210,8 @@ bool tableIsInUnion(const execplan::CalpontSystemCatalog::TableAliasName& table,
|
|||||||
{
|
{
|
||||||
return std::any_of(csep.unionVec().begin(), csep.unionVec().end(),
|
return std::any_of(csep.unionVec().begin(), csep.unionVec().end(),
|
||||||
[&table](const auto& unionUnit) {
|
[&table](const auto& unionUnit) {
|
||||||
auto unionUnitLocal = *dynamic_cast<execplan::CalpontSelectExecutionPlan*>(unionUnit.get());
|
execplan::CalpontSelectExecutionPlan* unionUnitLocal = dynamic_cast<execplan::CalpontSelectExecutionPlan*>(unionUnit.get());
|
||||||
bool tableIsPresented = std::any_of(unionUnitLocal.tableList().begin(), unionUnitLocal.tableList().end(),
|
bool tableIsPresented = std::any_of(unionUnitLocal->tableList().begin(), unionUnitLocal->tableList().end(),
|
||||||
[&table](const auto& unionTable) {
|
[&table](const auto& unionTable) {
|
||||||
return unionTable == table;
|
return unionTable == table;
|
||||||
});
|
});
|
||||||
@ -9223,15 +9223,9 @@ bool matchParallelCES(CalpontSelectExecutionPlan& csep)
|
|||||||
{
|
{
|
||||||
auto tables = csep.tableList();
|
auto tables = csep.tableList();
|
||||||
// This is leaf and there are no other tables at this level.
|
// This is leaf and there are no other tables at this level.
|
||||||
for (auto& table : tables)
|
// WIP filter out CSEPs with orderBy, groupBy, having
|
||||||
{
|
// WIP filter out CSEPs with nonSimpleColumns in projection
|
||||||
if (!table.isColumnstore() && !tableIsInUnion(table, csep))
|
return tables.size() == 1 && !tables[0].isColumnstore() && !tableIsInUnion(tables[0], csep);
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CalpontSelectExecutionPlan::SelectList makeUnionFromTable(const size_t numberOfLegs,
|
CalpontSelectExecutionPlan::SelectList makeUnionFromTable(const size_t numberOfLegs,
|
||||||
@ -9247,19 +9241,69 @@ CalpontSelectExecutionPlan::SelectList makeUnionFromTable(const size_t numberOfL
|
|||||||
return unionVec;
|
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)
|
void applyParallelCES(CalpontSelectExecutionPlan& csep)
|
||||||
{
|
{
|
||||||
auto tables = csep.tableList();
|
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;
|
size_t parallelFactor = 2;
|
||||||
auto additionalUnionVec = makeUnionFromTable(parallelFactor, csep);
|
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<execplan::SimpleColumn*>(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
|
struct Rule
|
||||||
{
|
{
|
||||||
Rule(std::string&& name, bool (*matchRule)(CalpontSelectExecutionPlan&),
|
Rule(std::string&& name, bool (*matchRule)(CalpontSelectExecutionPlan&),
|
||||||
@ -9303,7 +9347,7 @@ struct Rule
|
|||||||
|
|
||||||
if (matchRule(csep))
|
if (matchRule(csep))
|
||||||
{
|
{
|
||||||
apply(csep);
|
applyRule(csep);
|
||||||
rewrite = true;
|
rewrite = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9333,11 +9377,11 @@ int cs_get_select_plan(ha_columnstore_select_handler* handler, THD* /*thd*/, SCS
|
|||||||
else if (status < 0)
|
else if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
#ifdef DEBUG_WALK_COND
|
// #ifdef DEBUG_WALK_COND
|
||||||
// cerr << "---------------- cs_get_select_plan EXECUTION PLAN ----------------" << endl;
|
cerr << "---------------- cs_get_select_plan EXECUTION PLAN ----------------" << endl;
|
||||||
// cerr << *csep << endl;
|
cerr << *csep << endl;
|
||||||
// cerr << "-------------- EXECUTION PLAN END --------------\n" << endl;
|
cerr << "-------------- EXECUTION PLAN END --------------\n" << endl;
|
||||||
#endif
|
// #endif
|
||||||
// Derived table projection and filter optimization.
|
// Derived table projection and filter optimization.
|
||||||
derivedTableOptimization(&gwi, csep);
|
derivedTableOptimization(&gwi, csep);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user