You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-01 06:46:55 +03:00
feat(optimizer): rewrite rule does not descent into a freshly created UNION unit.
This commit is contained in:
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
namespace optimizer {
|
namespace optimizer {
|
||||||
|
|
||||||
|
static const std::string RewrittenSubTableAliasPrefix = "$added_sub_";
|
||||||
|
|
||||||
// Apply a list of rules to a CSEP
|
// Apply a list of rules to a CSEP
|
||||||
bool optimizeCSEPWithRules(execplan::CalpontSelectExecutionPlan& root, const std::vector<Rule>& rules) {
|
bool optimizeCSEPWithRules(execplan::CalpontSelectExecutionPlan& root, const std::vector<Rule>& rules) {
|
||||||
|
|
||||||
@ -47,9 +49,9 @@ bool Rule::apply(execplan::CalpontSelectExecutionPlan& root) const
|
|||||||
{
|
{
|
||||||
bool changedThisRound = false;
|
bool changedThisRound = false;
|
||||||
bool hasBeenApplied = false;
|
bool hasBeenApplied = false;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
changedThisRound = walk(root);
|
changedThisRound = walk(root) && !applyOnlyOnce;
|
||||||
hasBeenApplied = changedThisRound;
|
hasBeenApplied = changedThisRound;
|
||||||
} while (changedThisRound);
|
} while (changedThisRound);
|
||||||
|
|
||||||
@ -70,7 +72,7 @@ bool Rule::walk(execplan::CalpontSelectExecutionPlan& csep) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto& csepLocal = *csepPtr;
|
auto& csepLocal = *csepPtr;
|
||||||
rewrite |= apply(csepLocal);
|
rewrite |= walk(csepLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& unionUnit : csep.unionVec())
|
for (auto& unionUnit : csep.unionVec())
|
||||||
@ -82,7 +84,7 @@ bool Rule::walk(execplan::CalpontSelectExecutionPlan& csep) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto& unionUnitLocal = *unionUnitPtr;
|
auto& unionUnitLocal = *unionUnitPtr;
|
||||||
rewrite |= apply(unionUnitLocal);
|
rewrite |= walk(unionUnitLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchRule(csep))
|
if (matchRule(csep))
|
||||||
@ -112,7 +114,7 @@ bool matchParallelCES(execplan::CalpontSelectExecutionPlan& csep)
|
|||||||
auto tables = csep.tableList();
|
auto tables = csep.tableList();
|
||||||
// This is leaf and there are no other tables at this level in neither UNION, nor derived table.
|
// This is leaf and there are no other tables at this level in neither UNION, nor derived table.
|
||||||
// WIP filter out CSEPs with orderBy, groupBy, having
|
// WIP filter out CSEPs with orderBy, groupBy, having
|
||||||
// WIP filter out CSEPs with nonSimpleColumns in projection
|
// Filter out tables that were re-written.
|
||||||
return tables.size() == 1 && !tables[0].isColumnstore() && !tableIsInUnion(tables[0], csep);
|
return tables.size() == 1 && !tables[0].isColumnstore() && !tableIsInUnion(tables[0], csep);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +136,7 @@ void applyParallelCES(execplan::CalpontSelectExecutionPlan& csep)
|
|||||||
auto tables = csep.tableList();
|
auto tables = csep.tableList();
|
||||||
execplan::CalpontSelectExecutionPlan::TableList newTableList;
|
execplan::CalpontSelectExecutionPlan::TableList newTableList;
|
||||||
execplan::CalpontSelectExecutionPlan::SelectList newDerivedTableList;
|
execplan::CalpontSelectExecutionPlan::SelectList newDerivedTableList;
|
||||||
static const std::string aliasPrefix = "$sub_";
|
execplan::CalpontSelectExecutionPlan::ReturnedColumnList newReturnedColumns;
|
||||||
|
|
||||||
// ATM Must be only 1 table
|
// ATM Must be only 1 table
|
||||||
for (auto& table: tables)
|
for (auto& table: tables)
|
||||||
@ -143,32 +145,35 @@ void applyParallelCES(execplan::CalpontSelectExecutionPlan& csep)
|
|||||||
{
|
{
|
||||||
auto derivedSCEP = csep.cloneWORecursiveSelects();
|
auto derivedSCEP = csep.cloneWORecursiveSelects();
|
||||||
// need to add a level here
|
// need to add a level here
|
||||||
std::string alias = aliasPrefix + table.schema + "_" + table.table;
|
std::string tableAlias = RewrittenSubTableAliasPrefix + table.schema + "_" + table.table;
|
||||||
|
|
||||||
derivedSCEP->location(execplan::CalpontSelectExecutionPlan::FROM);
|
derivedSCEP->location(execplan::CalpontSelectExecutionPlan::FROM);
|
||||||
derivedSCEP->subType(execplan::CalpontSelectExecutionPlan::FROM_SUBS);
|
derivedSCEP->subType(execplan::CalpontSelectExecutionPlan::FROM_SUBS);
|
||||||
derivedSCEP->derivedTbAlias(alias);
|
derivedSCEP->derivedTbAlias(tableAlias);
|
||||||
|
|
||||||
// TODO: hardcoded for now
|
// TODO: hardcoded for now
|
||||||
size_t parallelFactor = 2;
|
size_t parallelFactor = 2;
|
||||||
auto additionalUnionVec = makeUnionFromTable(parallelFactor, csep);
|
auto additionalUnionVec = makeUnionFromTable(parallelFactor, csep);
|
||||||
derivedSCEP->unionVec().insert(derivedSCEP->unionVec().end(), additionalUnionVec.begin(), additionalUnionVec.end());
|
derivedSCEP->unionVec().insert(derivedSCEP->unionVec().end(), additionalUnionVec.begin(), additionalUnionVec.end());
|
||||||
|
|
||||||
|
size_t colPosition = 0;
|
||||||
// change parent to derived table columns
|
// change parent to derived table columns
|
||||||
for (auto& rc : csep.returnedCols())
|
for (auto& rc : csep.returnedCols())
|
||||||
{
|
{
|
||||||
auto* sc = dynamic_cast<execplan::SimpleColumn*>(rc.get());
|
auto rc_ = boost::make_shared<execplan::SimpleColumn>(*rc);
|
||||||
if (sc)
|
// TODO timezone and result type are not copied
|
||||||
{
|
// TODO add specific ctor for this functionality
|
||||||
sc->tableName("");
|
rc_->tableName("");
|
||||||
sc->schemaName("");
|
rc_->schemaName("");
|
||||||
sc->tableAlias(alias);
|
rc_->tableAlias(tableAlias);
|
||||||
sc->colPosition(0);
|
rc_->colPosition(colPosition++);
|
||||||
}
|
rc_->resultType(rc->resultType());
|
||||||
|
|
||||||
|
newReturnedColumns.push_back(rc_);
|
||||||
}
|
}
|
||||||
|
|
||||||
newDerivedTableList.push_back(derivedSCEP);
|
newDerivedTableList.push_back(derivedSCEP);
|
||||||
execplan::CalpontSystemCatalog::TableAliasName tn = execplan::make_aliasview("", "", alias, "");
|
execplan::CalpontSystemCatalog::TableAliasName tn = execplan::make_aliasview("", "", tableAlias, "");
|
||||||
newTableList.push_back(tn);
|
newTableList.push_back(tn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,6 +182,8 @@ void applyParallelCES(execplan::CalpontSelectExecutionPlan& csep)
|
|||||||
csep.derivedTableList(newDerivedTableList);
|
csep.derivedTableList(newDerivedTableList);
|
||||||
// Replace table list with new table list populated with union units
|
// Replace table list with new table list populated with union units
|
||||||
csep.tableList(newTableList);
|
csep.tableList(newTableList);
|
||||||
}
|
csep.returnedCols(newReturnedColumns);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,13 +24,24 @@ namespace optimizer {
|
|||||||
|
|
||||||
struct Rule
|
struct Rule
|
||||||
{
|
{
|
||||||
Rule(std::string&& name, bool (*matchRule)(execplan::CalpontSelectExecutionPlan&),
|
using RuleMatcher = bool (*)(execplan::CalpontSelectExecutionPlan&);
|
||||||
void (*applyRule)(execplan::CalpontSelectExecutionPlan&))
|
using RuleApplier = void (*)(execplan::CalpontSelectExecutionPlan&);
|
||||||
|
|
||||||
|
Rule(std::string&& name, RuleMatcher matchRule, RuleApplier applyRule)
|
||||||
: name(name), matchRule(matchRule), applyRule(applyRule) {};
|
: name(name), matchRule(matchRule), applyRule(applyRule) {};
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
bool (*matchRule)(execplan::CalpontSelectExecutionPlan&);
|
RuleMatcher matchRule;
|
||||||
void (*applyRule)(execplan::CalpontSelectExecutionPlan&);
|
RuleApplier applyRule;
|
||||||
|
// TODO Wrap CSEP into Nodes to be able to navigate up and down the tree and remove this flag
|
||||||
|
bool applyOnlyOnce = true;
|
||||||
|
|
||||||
|
Rule() = default;
|
||||||
|
Rule(const Rule&) = default;
|
||||||
|
Rule(Rule&&) = default;
|
||||||
|
Rule& operator=(const Rule&) = default;
|
||||||
|
Rule& operator=(Rule&&) = default;
|
||||||
|
|
||||||
bool apply(execplan::CalpontSelectExecutionPlan& csep) const;
|
bool apply(execplan::CalpontSelectExecutionPlan& csep) const;
|
||||||
bool walk(execplan::CalpontSelectExecutionPlan& csep) const;
|
bool walk(execplan::CalpontSelectExecutionPlan& csep) const;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user