1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-10-31 18:30:33 +03:00

chore(rbo,rules,QA): clone now does not copy OB, GB, HAVING and optionally filters.

This commit is contained in:
drrtuy
2025-08-05 16:00:16 +00:00
parent c19c49ba13
commit 6c75faee88
4 changed files with 96 additions and 109 deletions

View File

@@ -967,8 +967,9 @@ execplan::SCSEP CalpontSelectExecutionPlan::cloneWORecursiveSelects()
return newPlan; return newPlan;
} }
execplan::SCSEP CalpontSelectExecutionPlan::cloneForTableWORecursiveSelects( // This clone must return CSEP w/o sub-selects, group by, order by, having limit.
const execplan::CalpontSystemCatalog::TableAliasName& targetTableAlias) execplan::SCSEP CalpontSelectExecutionPlan::cloneForTableWORecursiveSelectsGbObHaving(
const execplan::CalpontSystemCatalog::TableAliasName& targetTableAlias, const bool withFilters)
{ {
execplan::SCSEP newPlan(new CalpontSelectExecutionPlan(fLocation)); execplan::SCSEP newPlan(new CalpontSelectExecutionPlan(fLocation));
@@ -991,9 +992,6 @@ execplan::SCSEP CalpontSelectExecutionPlan::cloneForTableWORecursiveSelects(
newPlan->fSubType = fSubType; newPlan->fSubType = fSubType;
newPlan->fDerivedTbAlias = fDerivedTbAlias; newPlan->fDerivedTbAlias = fDerivedTbAlias;
newPlan->fDerivedTbView = fDerivedTbView; newPlan->fDerivedTbView = fDerivedTbView;
newPlan->fLimitStart = fLimitStart;
newPlan->fLimitNum = fLimitNum;
newPlan->fHasOrderBy = fHasOrderBy;
newPlan->fStringScanThreshold = fStringScanThreshold; newPlan->fStringScanThreshold = fStringScanThreshold;
newPlan->fQueryType = fQueryType; newPlan->fQueryType = fQueryType;
newPlan->fPriority = fPriority; newPlan->fPriority = fPriority;
@@ -1037,34 +1035,13 @@ execplan::SCSEP CalpontSelectExecutionPlan::cloneForTableWORecursiveSelects(
// Deep copy of filters // Deep copy of filters
// WIP only filters that apply to the target table must be left intact // WIP only filters that apply to the target table must be left intact
// replace all irrelevant branches with true // replace all irrelevant branches with true
if (fFilters) if (fFilters && withFilters)
{ {
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);
newPlan->havingTokenList(fHavingTokenList);
// Deep copy of group by columns
GroupByColumnList newGroupByCols;
for (const auto& col : fGroupByCols)
{
newGroupByCols.push_back(SRCP(col->clone()));
}
newPlan->groupByCols(newGroupByCols);
// Deep copy of having clause
if (fHaving)
newPlan->having(new ParseTree(*fHaving));
// Deep copy of order by columns
OrderByColumnList newOrderByCols;
for (const auto& col : fOrderByCols)
{
newOrderByCols.push_back(SRCP(col->clone()));
}
newPlan->orderByCols(newOrderByCols);
// Deep copy of column map // Deep copy of column map
ColumnMap newColumnMap; ColumnMap newColumnMap;

View File

@@ -164,7 +164,8 @@ class CalpontSelectExecutionPlan : public CalpontExecutionPlan
*/ */
execplan::SCSEP cloneWORecursiveSelects(); execplan::SCSEP cloneWORecursiveSelects();
execplan::SCSEP cloneForTableWORecursiveSelects(const execplan::CalpontSystemCatalog::TableAliasName& targetTableAlias); execplan::SCSEP cloneForTableWORecursiveSelectsGbObHaving(
const execplan::CalpontSystemCatalog::TableAliasName& targetTableAlias, const bool withFilters = true);
/** /**
* Access and mutator methods * Access and mutator methods

View File

@@ -101,7 +101,6 @@ void derivedTableOptimization(gp_walk_info* gwip, SCSEP& csep)
for (int64_t i = cols.size() - 1; i >= 0; i--) for (int64_t i = cols.size() - 1; i >= 0; i--)
{ {
// if (cols[i]->derivedTable().empty())
if (cols[i]->refCount() == 0) if (cols[i]->refCount() == 0)
{ {
if (cols[i]->derivedRefCol()) if (cols[i]->derivedRefCol())

View File

@@ -248,6 +248,7 @@ std::optional<FilterRangeBounds<T>> populateRangeBounds(Histogram_json_hb* colum
return bounds; return bounds;
} }
// TODO char and other numerical types support // TODO char and other numerical types support
execplan::CalpontSelectExecutionPlan::SelectList makeUnionFromTable( execplan::CalpontSelectExecutionPlan::SelectList makeUnionFromTable(
execplan::CalpontSelectExecutionPlan& csep, execplan::CalpontSystemCatalog::TableAliasName& table, execplan::CalpontSelectExecutionPlan& csep, execplan::CalpontSystemCatalog::TableAliasName& table,
@@ -282,7 +283,7 @@ execplan::CalpontSelectExecutionPlan::SelectList makeUnionFromTable(
{ {
for (size_t i = 0; i <= bounds.size() - 2; ++i) for (size_t i = 0; i <= bounds.size() - 2; ++i)
{ {
auto clonedCSEP = csep.cloneForTableWORecursiveSelects(table); auto clonedCSEP = csep.cloneForTableWORecursiveSelectsGbObHaving(table);
// Add BETWEEN based on key column range // Add BETWEEN based on key column range
auto filter = filtersWithNewRange(clonedCSEP, keyColumn, bounds[i], false); auto filter = filtersWithNewRange(clonedCSEP, keyColumn, bounds[i], false);
clonedCSEP->filters(filter); clonedCSEP->filters(filter);
@@ -295,7 +296,7 @@ execplan::CalpontSelectExecutionPlan::SelectList makeUnionFromTable(
// TODO add NULLs into filter of the last step // TODO add NULLs into filter of the last step
if (!bounds.empty()) if (!bounds.empty())
{ {
auto clonedCSEP = csep.cloneForTableWORecursiveSelects(table); auto clonedCSEP = csep.cloneForTableWORecursiveSelectsGbObHaving(table);
auto filter = filtersWithNewRange(clonedCSEP, keyColumn, bounds.back(), true); auto filter = filtersWithNewRange(clonedCSEP, keyColumn, bounds.back(), true);
clonedCSEP->columnMap().insert({keyColumn.columnName(), execplan::SRCP(keyColumn.clone())}); clonedCSEP->columnMap().insert({keyColumn.columnName(), execplan::SRCP(keyColumn.clone())});
clonedCSEP->filters(filter); clonedCSEP->filters(filter);
@@ -304,13 +305,45 @@ execplan::CalpontSelectExecutionPlan::SelectList makeUnionFromTable(
return unionVec; return unionVec;
} }
bool applyParallelCES(execplan::CalpontSelectExecutionPlan& csep, RBOptimizerContext& ctx)
execplan::SCSEP createDerivedTableFromTable(
execplan::CalpontSelectExecutionPlan& csep,
const execplan::CalpontSystemCatalog::TableAliasName& table,
const std::string& tableAlias,
optimizer::RBOptimizerContext& ctx)
{
// Don't copy filters for this
auto derivedSCEP = csep.cloneForTableWORecursiveSelectsGbObHaving(table, false);
// Remove the filters as they were pushed down to union units
// This is inappropriate for EXISTS filter and join conditions
// WIP replace with filters applied to filters, so that only relevant filters are left
// WIP Ugly hack to avoid leaks
auto* derivedCSEP = dynamic_cast<execplan::CalpontSelectExecutionPlan*>(derivedSCEP.get());
// TODO more rigorous error handling.
if (!derivedCSEP)
{
return execplan::SCSEP();
}
auto additionalUnionVec = makeUnionFromTable(*derivedCSEP, const_cast<execplan::CalpontSystemCatalog::TableAliasName&>(table), ctx);
// TODO add original alias to support multiple same name tables
derivedSCEP->location(execplan::CalpontSelectExecutionPlan::FROM);
derivedSCEP->subType(execplan::CalpontSelectExecutionPlan::FROM_SUBS);
derivedSCEP->derivedTbAlias(tableAlias);
derivedSCEP->unionVec().insert(derivedSCEP->unionVec().end(), additionalUnionVec.begin(),
additionalUnionVec.end());
return derivedSCEP;
}
bool applyParallelCES(execplan::CalpontSelectExecutionPlan& csep, optimizer::RBOptimizerContext& ctx)
{ {
auto tables = csep.tableList(); auto tables = csep.tableList();
execplan::CalpontSelectExecutionPlan::TableList newTableList; execplan::CalpontSelectExecutionPlan::TableList newTableList;
// TODO support CSEPs with derived tables // TODO support CSEPs with derived tables
execplan::CalpontSelectExecutionPlan::SelectList newDerivedTableList; execplan::CalpontSelectExecutionPlan::SelectList newDerivedTableList;
cal_impl_if::TableAliasMap tableAliasMap; optimizer::TableAliasMap tableAliasMap;
bool ruleHasBeenApplied = false; bool ruleHasBeenApplied = false;
for (auto& table : tables) for (auto& table : tables)
@@ -323,37 +356,14 @@ bool applyParallelCES(execplan::CalpontSelectExecutionPlan& csep, RBOptimizerCon
// TODO add column statistics check to the corresponding match // TODO add column statistics check to the corresponding match
if (!table.isColumnstore() && anyColumnStatistics) if (!table.isColumnstore() && anyColumnStatistics)
{ {
// Don't copy filters for this std::string tableAlias = optimizer::RewrittenSubTableAliasPrefix + table.schema + "_" + table.table + "_" +
auto derivedSCEP = csep.cloneForTableWORecursiveSelects(table);
// Remove the filters as they were pushed down to union units
// This is inappropriate for EXISTS filter and join conditions
// WIP replace with filters applied to filters, so that only relevant filters are left
// WIP Ugly hack to avoid leaks
auto unusedFilters = derivedSCEP->filters();
delete unusedFilters;
derivedSCEP->filters(nullptr);
auto* derivedCSEP = dynamic_cast<execplan::CalpontSelectExecutionPlan*>(derivedSCEP.get());
if (!derivedCSEP)
{
continue;
}
auto additionalUnionVec = makeUnionFromTable(*derivedCSEP, table, ctx);
// need to add a level here
std::string tableAlias = RewrittenSubTableAliasPrefix + table.schema + "_" + table.table + "_" +
std::to_string(ctx.uniqueId); std::to_string(ctx.uniqueId);
// TODO add original alias to support multiple same name tables
tableAliasMap.insert({table, {tableAlias, 0}}); tableAliasMap.insert({table, {tableAlias, 0}});
derivedSCEP->location(execplan::CalpontSelectExecutionPlan::FROM);
derivedSCEP->subType(execplan::CalpontSelectExecutionPlan::FROM_SUBS);
derivedSCEP->derivedTbAlias(tableAlias);
derivedSCEP->unionVec().insert(derivedSCEP->unionVec().end(), additionalUnionVec.begin(),
additionalUnionVec.end());
newDerivedTableList.push_back(derivedSCEP);
execplan::CalpontSystemCatalog::TableAliasName tn = execplan::make_aliasview("", "", tableAlias, ""); execplan::CalpontSystemCatalog::TableAliasName tn = execplan::make_aliasview("", "", tableAlias, "");
newTableList.push_back(tn); newTableList.push_back(tn);
auto derivedSCEP = createDerivedTableFromTable(csep, table, tableAlias, ctx);
newDerivedTableList.push_back(std::move(derivedSCEP));
ruleHasBeenApplied = true; ruleHasBeenApplied = true;
} }
else else