diff --git a/dbcon/mysql/ha_mcs_execplan.cpp b/dbcon/mysql/ha_mcs_execplan.cpp index e23cf47e6..b01e40c16 100644 --- a/dbcon/mysql/ha_mcs_execplan.cpp +++ b/dbcon/mysql/ha_mcs_execplan.cpp @@ -9197,11 +9197,12 @@ int cs_get_derived_plan(ha_columnstore_derived_handler* handler, THD* /*thd*/, S else if (status < 0) return status; -#ifdef DEBUG_WALK_COND - cerr << "---------------- cs_get_derived_plan EXECUTION PLAN ----------------" << endl; - cerr << *csep << endl; - cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; -#endif + if (csep->traceOn()) + { + cerr << "---------------- cs_get_derived_plan EXECUTION PLAN ----------------" << endl; + cerr << *csep << endl; + cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; + } // Derived table projection and filter optimization. derivedTableOptimization(&gwi, csep); return 0; @@ -9230,25 +9231,24 @@ 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 + if (csep->traceOn()) + { + cerr << "---------------- cs_get_select_plan EXECUTION PLAN ----------------" << endl; + cerr << *csep << endl; + cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; + } + // Derived table projection and filter optimization. derivedTableOptimization(&gwi, csep); - optimizer::Rule parallelCES{"parallelCES", optimizer::matchParallelCES, optimizer::applyParallelCES}; - + bool csepWasOptimized = optimizer::optimizeCSEP(*csep); + if (csep->traceOn() && csepWasOptimized) { - parallelCES.apply(*csep); + cerr << "---------------- cs_get_select_plan optimized EXECUTION PLAN ----------------" << endl; + cerr << *csep << endl; + cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; } - cerr << "---------------- cs_get_select_plan rewritten EXECUTION PLAN ----------------" << endl; - cerr << *csep << endl; - cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; - - return 0; } diff --git a/dbcon/mysql/ha_mcs_sysvars.cpp b/dbcon/mysql/ha_mcs_sysvars.cpp index 04fdbdaed..6829877c0 100644 --- a/dbcon/mysql/ha_mcs_sysvars.cpp +++ b/dbcon/mysql/ha_mcs_sysvars.cpp @@ -224,7 +224,9 @@ static my_bool innodb_queries_use_mcs; static MYSQL_SYSVAR_BOOL(innodb_queries_use_mcs, innodb_queries_use_mcs, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Direct all InnoDB-only queries into MCS via Select Handler.", NULL, NULL, FALSE); - +static MYSQL_THDVAR_BOOL(unstable_optimizer, PLUGIN_VAR_RQCMDARG, + "Apply optimizer rules after translation from SELECT_LEX/UNION", NULL, NULL, FALSE); + st_mysql_sys_var* mcs_system_variables[] = { MYSQL_SYSVAR(compression_type), MYSQL_SYSVAR(fe_conn_info_ptr), @@ -663,6 +665,15 @@ void set_max_allowed_in_values(THD* thd, ulong value) THDVAR(thd, max_allowed_in_values) = value; } +bool get_unstable_optimizer(THD* thd) +{ + return (thd == NULL) ? 0 : THDVAR(thd, unstable_optimizer); +} +void set_unstable_optimizer(THD* thd, bool value) +{ + THDVAR(thd, unstable_optimizer) = value; +} + bool get_innodb_queries_uses_mcs() { return SYSVAR(innodb_queries_use_mcs); diff --git a/dbcon/mysql/rulebased_optimizer.cpp b/dbcon/mysql/rulebased_optimizer.cpp index f91777c7f..d3de06055 100644 --- a/dbcon/mysql/rulebased_optimizer.cpp +++ b/dbcon/mysql/rulebased_optimizer.cpp @@ -21,36 +21,52 @@ namespace optimizer { -bool Rule::apply(execplan::CalpontSelectExecutionPlan& csep) +bool optimizeCSEPWithRules(execplan::CalpontSelectExecutionPlan& root, const std::vector& rules) { + + bool changed = false; + for (const auto& rule : rules) + { + changed |= rule.apply(root); + } + return changed; +} + +bool optimizeCSEP(execplan::CalpontSelectExecutionPlan& root) +{ + optimizer::Rule parallelCES{"parallelCES", optimizer::matchParallelCES, optimizer::applyParallelCES}; + + std::vector rules = {parallelCES}; + + return optimizeCSEPWithRules(root, rules); +} + +// DFS walk +bool Rule::apply(execplan::CalpontSelectExecutionPlan& csep) const { bool rewrite = false; + for (auto& table : csep.derivedTableList()) { - auto& csepLocal = *dynamic_cast(table.get()); - if (matchRule(csepLocal)) + auto* csepPtr = dynamic_cast(table.get()); + if (!csepPtr) { - applyRule(csepLocal); - rewrite = true; - } - else - { - rewrite |= apply(csepLocal); + continue; } + + auto& csepLocal = *csepPtr; + rewrite |= apply(csepLocal); } for (auto& unionUnit : csep.unionVec()) { - auto& unionUnitLocal = *dynamic_cast(unionUnit.get()); + auto* unionUnitPtr = dynamic_cast(unionUnit.get()); + if (!unionUnitPtr) + { + continue; + } - if (matchRule(unionUnitLocal)) - { - applyRule(unionUnitLocal); - rewrite = true; - } - else - { - rewrite |= apply(unionUnitLocal); - } + auto& unionUnitLocal = *unionUnitPtr; + rewrite |= apply(unionUnitLocal); } if (matchRule(csep)) diff --git a/dbcon/mysql/rulebased_optimizer.h b/dbcon/mysql/rulebased_optimizer.h index 3f0a3e10f..65fa3f359 100644 --- a/dbcon/mysql/rulebased_optimizer.h +++ b/dbcon/mysql/rulebased_optimizer.h @@ -31,10 +31,11 @@ struct Rule std::string name; bool (*matchRule)(execplan::CalpontSelectExecutionPlan&); void (*applyRule)(execplan::CalpontSelectExecutionPlan&); - bool apply(execplan::CalpontSelectExecutionPlan& csep); + bool apply(execplan::CalpontSelectExecutionPlan& csep) const; }; bool matchParallelCES(execplan::CalpontSelectExecutionPlan& csep); void applyParallelCES(execplan::CalpontSelectExecutionPlan& csep); +bool optimizeCSEP(execplan::CalpontSelectExecutionPlan& root); } \ No newline at end of file