diff --git a/dbcon/execplan/calpontselectexecutionplan.cpp b/dbcon/execplan/calpontselectexecutionplan.cpp index a09aee082..ded936ea0 100644 --- a/dbcon/execplan/calpontselectexecutionplan.cpp +++ b/dbcon/execplan/calpontselectexecutionplan.cpp @@ -206,59 +206,58 @@ void CalpontSelectExecutionPlan::printSubCSEP(const size_t& ident, ostringstream { if (plan) { - output << endlWithIndent(ident) << "{" << endlWithIndent(ident + 2) << plan->toString(ident + 2); - // remove last two spaces from the stream. - output.seekp(-2, std::ios::cur); - output << "}" << std::endl << endlWithIndent(ident); + output << endlWithIndent(ident) << "{"; + output << plan->toString(ident + 2); + output << endlWithIndent(ident) << "}"; } } string CalpontSelectExecutionPlan::toString(const size_t ident) const { ostringstream output; - output << "SELECT "; + output << endlWithIndent(ident) << "SELECT "; if (distinct()) { - output << "DISTINCT "; + output << endlWithIndent(ident) << "DISTINCT "; } - output << "limit: " << limitStart() << " - " << limitNum() << endlWithIndent(ident); + output << endlWithIndent(ident) << "limit: " << limitStart() << " - " << limitNum(); switch (location()) { - case CalpontSelectExecutionPlan::MAIN: output << "MAIN" << endlWithIndent(ident); break; + case CalpontSelectExecutionPlan::MAIN: output << endlWithIndent(ident) << "MAIN"; break; - case CalpontSelectExecutionPlan::FROM: output << "FROM" << endlWithIndent(ident); break; + case CalpontSelectExecutionPlan::FROM: output << endlWithIndent(ident) << "FROM"; break; - case CalpontSelectExecutionPlan::WHERE: output << "WHERE" << endlWithIndent(ident); break; + case CalpontSelectExecutionPlan::WHERE: output << endlWithIndent(ident) << "WHERE"; break; case CalpontSelectExecutionPlan::HAVING: output << "HAVING" << endlWithIndent(ident); break; } // Returned Column CalpontSelectExecutionPlan::ReturnedColumnList retCols = returnedCols(); - output << ">>Returned Columns" << endlWithIndent(ident); + output << endlWithIndent(ident) << ">>Returned Columns"; uint32_t seq = 0; for (unsigned int i = 0; i < retCols.size(); i++) { - output << *retCols[i] << endlWithIndent(ident+2); // WIP replace with constant + output << endlWithIndent(ident+2) << *retCols[i]; // WIP replace with constant if (retCols[i]->colSource() & SELECT_SUB) { - output << "select sub -- " << endlWithIndent(ident + 2); + output << endlWithIndent(ident + 2) << "select sub -- "; CalpontSelectExecutionPlan* plan = dynamic_cast(fSelectSubList[seq++].get()); - printSubCSEP(ident, output, plan); + printSubCSEP(ident + 2, output, plan); } } // From Clause CalpontSelectExecutionPlan::TableList tables = tableList(); - output << ">>From Tables" << endlWithIndent(ident + 2); + output << endlWithIndent(ident) <<">>From Tables"; seq = 0; for (unsigned int i = 0; i < tables.size(); i++) @@ -266,28 +265,29 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const // derived table if (tables[i].schema.length() == 0 && tables[i].table.length() == 0) { - output << "derived table - " << tables[i].alias << endlWithIndent(ident+2); + output << endlWithIndent(ident+2) << "derived table - " << tables[i].alias; CalpontSelectExecutionPlan* plan = dynamic_cast(fDerivedTableList[seq++].get()); - printSubCSEP(ident, output, plan); + printSubCSEP(ident + 2, output, plan); } else { - output << tables[i] << endlWithIndent(ident+2); + output << endlWithIndent(ident+2) << tables[i]; } } // Filters - output << ">>Filters" << endlWithIndent(ident); + output << endlWithIndent(ident) << ">>Filters"; if (filters() != nullptr) { + output << endlWithIndent(ident + 2); filters()->walk(ParseTree::print, output); } else { - output << "empty filter tree" << endlWithIndent(ident); + output << endlWithIndent(ident + 2) << "empty filter tree"; } // Group by columns @@ -295,12 +295,12 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const if (gbc.size() > 0) { - output << ">>Group By Columns" << endlWithIndent(ident); + output << endlWithIndent(ident) << ">>Group By Columns"; output << std::string(ident, ' '); for (unsigned int i = 0; i < gbc.size(); i++) { - output << *gbc[i] << endlWithIndent(ident); + output << endlWithIndent(ident + 2) << *gbc[i]; } output << std::string(ident, ' '); } @@ -308,8 +308,7 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const // Having if (having() != nullptr) { - output << ">>Having" << endlWithIndent(ident); - output << std::string(ident, ' '); + output << endlWithIndent(ident) << ">>Having" << endlWithIndent(ident + 2); having()->walk(ParseTree::print, output); } @@ -318,33 +317,35 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const if (obc.size() > 0) { - output << ">>Order By Columns" << endlWithIndent(ident); + output << endlWithIndent(ident) << ">>Order By Columns"; for (unsigned int i = 0; i < obc.size(); i++) - output << *obc[i] << endlWithIndent(ident); + output << endlWithIndent(ident + 2) << *obc[i]; } - output << "SessionID: " << fSessionID << endlWithIndent(ident); - output << "TxnID: " << fTxnID << endlWithIndent(ident); - output << "VerID: " << fVerID << endlWithIndent(ident); - output << "TraceFlags: " << fTraceFlags << endlWithIndent(ident); - output << "StatementID: " << fStatementID << endlWithIndent(ident); - output << "DistUnionNum: " << (int)fDistinctUnionNum << endlWithIndent(ident); - output << "Limit: " << fLimitStart << " - " << fLimitNum << endlWithIndent(ident); - output << "String table threshold: " << fStringTableThreshold << endlWithIndent(ident); + output << endlWithIndent(ident) << "SessionID: " << fSessionID; + output << endlWithIndent(ident) << "TxnID: " << fTxnID; + output << endlWithIndent(ident) << "VerID: " << fVerID; + output << endlWithIndent(ident) << "TraceFlags: " << fTraceFlags; + output << endlWithIndent(ident) << "StatementID: " << fStatementID; + output << endlWithIndent(ident) << "DistUnionNum: " << (int)fDistinctUnionNum; + output << endlWithIndent(ident) << "Limit: " << fLimitStart << " - " << fLimitNum; + output << endlWithIndent(ident) << "String table threshold: " << fStringTableThreshold; - output << "--- Column Map ---" << endlWithIndent(ident); + output << endlWithIndent(ident) << "--- Column Map ---"; CalpontSelectExecutionPlan::ColumnMap::const_iterator iter; for (iter = columnMap().begin(); iter != columnMap().end(); iter++) - output << (*iter).first << " : " << (*iter).second << endlWithIndent(ident); + { + output << endlWithIndent(ident + 2) << (*iter).first << " : " << (*iter).second; + } - output << "UUID: " << fUuid << endlWithIndent(ident); - output << "QueryType: " << queryType() << endlWithIndent(ident); + output << endlWithIndent(ident) << "UUID: " << fUuid; + output << endlWithIndent(ident) << "QueryType: " << queryType(); if (!unionVec().empty()) { - output << "--- Union Unit ---"; + output << endlWithIndent(ident) << "--- Union Unit ---"; } for (unsigned i = 0; i < unionVec().size(); i++) diff --git a/dbcon/mysql/ha_mcs_execplan.cpp b/dbcon/mysql/ha_mcs_execplan.cpp index b01e40c16..dcbcdcfd8 100644 --- a/dbcon/mysql/ha_mcs_execplan.cpp +++ b/dbcon/mysql/ha_mcs_execplan.cpp @@ -9209,7 +9209,7 @@ int cs_get_derived_plan(ha_columnstore_derived_handler* handler, THD* /*thd*/, S } -int cs_get_select_plan(ha_columnstore_select_handler* handler, THD* /*thd*/, SCSEP& csep, gp_walk_info& gwi, +int cs_get_select_plan(ha_columnstore_select_handler* handler, THD* thd, SCSEP& csep, gp_walk_info& gwi, bool isSelectLexUnit) { SELECT_LEX& select_lex = handler->select_lex ? *handler->select_lex : *handler->lex_unit->first_select(); @@ -9241,12 +9241,15 @@ int cs_get_select_plan(ha_columnstore_select_handler* handler, THD* /*thd*/, SCS // Derived table projection and filter optimization. derivedTableOptimization(&gwi, csep); - bool csepWasOptimized = optimizer::optimizeCSEP(*csep); - if (csep->traceOn() && csepWasOptimized) + if (get_unstable_optimizer(thd)) { - cerr << "---------------- cs_get_select_plan optimized EXECUTION PLAN ----------------" << endl; - cerr << *csep << endl; - cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; + bool csepWasOptimized = optimizer::optimizeCSEP(*csep); + if (csep->traceOn() && csepWasOptimized) + { + cerr << "---------------- cs_get_select_plan optimized 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 6829877c0..551f1586b 100644 --- a/dbcon/mysql/ha_mcs_sysvars.cpp +++ b/dbcon/mysql/ha_mcs_sysvars.cpp @@ -269,6 +269,7 @@ st_mysql_sys_var* mcs_system_variables[] = { MYSQL_SYSVAR(pron), MYSQL_SYSVAR(max_allowed_in_values), MYSQL_SYSVAR(innodb_queries_use_mcs), + MYSQL_SYSVAR(unstable_optimizer), NULL}; st_mysql_show_var mcs_status_variables[] = {{"columnstore_version", (char*)&cs_version, SHOW_CHAR}, diff --git a/dbcon/mysql/ha_mcs_sysvars.h b/dbcon/mysql/ha_mcs_sysvars.h index 92612bb53..4675eb2a0 100644 --- a/dbcon/mysql/ha_mcs_sysvars.h +++ b/dbcon/mysql/ha_mcs_sysvars.h @@ -175,4 +175,7 @@ const char* get_pron(THD* thd); void set_pron(THD* thd, char* value); ulong get_max_allowed_in_values(THD* thd); -void set_max_allowed_in_values(THD* thd, ulong value); \ No newline at end of file +void set_max_allowed_in_values(THD* thd, ulong value); + +bool get_unstable_optimizer(THD* thd); +void set_unstable_optimizer(THD* thd, bool value); diff --git a/dbcon/mysql/rulebased_optimizer.cpp b/dbcon/mysql/rulebased_optimizer.cpp index 4e9c22b96..b4c926b26 100644 --- a/dbcon/mysql/rulebased_optimizer.cpp +++ b/dbcon/mysql/rulebased_optimizer.cpp @@ -110,7 +110,7 @@ bool tableIsInUnion(const execplan::CalpontSystemCatalog::TableAliasName& table, bool matchParallelCES(execplan::CalpontSelectExecutionPlan& csep) { 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 in neither UNION, nor derived table. // 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); @@ -142,13 +142,14 @@ void applyParallelCES(execplan::CalpontSelectExecutionPlan& csep) if (!table.isColumnstore()) { auto derivedSCEP = csep.cloneWORecursiveSelects(); - // need to intro a level + // need to add a level here std::string alias = aliasPrefix + table.schema + "_" + table.table; derivedSCEP->location(execplan::CalpontSelectExecutionPlan::FROM); derivedSCEP->subType(execplan::CalpontSelectExecutionPlan::FROM_SUBS); derivedSCEP->derivedTbAlias(alias); + // TODO: hardcoded for now size_t parallelFactor = 2; auto additionalUnionVec = makeUnionFromTable(parallelFactor, csep); derivedSCEP->unionVec().insert(derivedSCEP->unionVec().end(), additionalUnionVec.begin(), additionalUnionVec.end()); @@ -166,23 +167,15 @@ void applyParallelCES(execplan::CalpontSelectExecutionPlan& csep) } } - // WIP need to work with existing derived tables newDerivedTableList.push_back(derivedSCEP); - // WIP execplan::CalpontSystemCatalog::TableAliasName tn = execplan::make_aliasview("", "", alias, ""); newTableList.push_back(tn); } } - // SimpleColumn* sc = new SimpleColumn("test", "i1", "i", false, csep.sessionID()); - // string alias(table->alias.c_ptr()); - // sc->timeZone(csep.timeZone()); - // sc->partitions(getPartitions(table)); - // boost::shared_ptr spsc(sc); - - // csep.columnMap().insert({"`test`.`i1`.`i`", spsc}); - + // There must be no derived at this point. csep.derivedTableList(newDerivedTableList); + // Replace table list with new table list populated with union units csep.tableList(newTableList); } }