/* Copyright (C) 2014 InfiniDB, Inc. Copyright (C) 2016 MariaDB Corporation Copyright (C) 2019 MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef HA_MCS_IMPL_IF_H__ #define HA_MCS_IMPL_IF_H__ #include #include #ifdef _MSC_VER #include #else #include #endif #include #include #include #include #include "idb_mysql.h" struct st_ha_create_information; #include "configcpp.h" #include "idberrorinfo.h" #include "calpontselectexecutionplan.h" #include "windowfunctioncolumn.h" #include "pseudocolumn.h" #include "querystats.h" #include "sm.h" #include "functor.h" /** Debug macro */ #ifdef INFINIDB_DEBUG #define IDEBUG(x) {x;} #else #define IDEBUG(x) {} #endif namespace execplan { class ReturnedColumn; class SimpleColumn; class SimpleFilter; class AggregateColumn; class FunctionColumn; class ArithmeticColumn; class ParseTree; class ConstantColumn; class RowColumn; } namespace cal_impl_if { class SubQuery; class View; struct JoinInfo { execplan::CalpontSystemCatalog::TableAliasName tn; uint32_t joinTimes; std::vector IDs; }; enum ClauseType { INIT = 0, SELECT, FROM, WHERE, HAVING, GROUP_BY, ORDER_BY }; typedef std::vector JoinInfoVec; typedef std::map > TableMap; struct gp_walk_info { // MCOL-2178 Marked for removal after 1.4 std::vector selectCols; execplan::CalpontSelectExecutionPlan::ReturnedColumnList returnedCols; execplan::CalpontSelectExecutionPlan::ReturnedColumnList groupByCols; execplan::CalpontSelectExecutionPlan::ReturnedColumnList subGroupByCols; execplan::CalpontSelectExecutionPlan::ReturnedColumnList orderByCols; std::vector extSelAggColsItems; execplan::CalpontSelectExecutionPlan::ColumnMap columnMap; // This vector temporarily hold the projection columns to be added // to the returnedCols vector for subquery processing. It will be appended // to the end of returnedCols when the processing is finished. execplan::CalpontSelectExecutionPlan::ReturnedColumnList additionalRetCols; // the sequence # of the subselect local columns need to be set after // the additionRetCols are merged to the returnedCols. std::vector localCols; std::stack rcWorkStack; std::stack ptWorkStack; boost::shared_ptr scsp; uint32_t sessionid; bool fatalParseError; std::string parseErrorText; // for outer join walk. the column that is not of the outerTable has the returnAll flag set. std::set innerTables; // the followinig members are used for table mode bool condPush; bool dropCond; std::string funcName; std::vector count_asterisk_list; std::vector no_parm_func_list; std::vector windowFuncList; TableMap tableMap; boost::shared_ptr csc; int8_t internalDecimalScale; THD* thd; uint64_t subSelectType; // the type of sub select filter that owns the gwi SubQuery* subQuery; execplan::CalpontSelectExecutionPlan::SelectList derivedTbList; execplan::CalpontSelectExecutionPlan::TableList tbList; std::vector correlatedTbNameVec; ClauseType clauseType; execplan::CalpontSystemCatalog::TableAliasName viewName; bool aggOnSelect; bool hasWindowFunc; bool hasSubSelect; SubQuery* lastSub; std::vector viewList; std::map derivedTbFilterMap; uint32_t derivedTbCnt; std::vector subselectList; // Workaround for duplicate equi-JOIN predicates // See isDuplicateSF() for more info. List equiCondSFList; // Kludge for Bug 750 int32_t recursionLevel; int32_t recursionHWM; std::stack rcBookMarkStack; // Kludge for MCOL-1472 bool inCaseStmt; bool cs_vtable_is_update_with_derive; bool cs_vtable_impossible_where_on_union; bool isGroupByHandler; gp_walk_info() : sessionid(0), fatalParseError(false), condPush(false), dropCond(false), internalDecimalScale(4), thd(0), subSelectType(uint64_t(-1)), subQuery(0), clauseType(INIT), aggOnSelect(false), hasWindowFunc(false), hasSubSelect(false), lastSub(0), derivedTbCnt(0), recursionLevel(-1), recursionHWM(0), inCaseStmt(false), cs_vtable_is_update_with_derive(false), cs_vtable_impossible_where_on_union(false), isGroupByHandler(false) {} ~gp_walk_info() {} }; struct cal_table_info { enum RowSources { FROM_ENGINE, FROM_FILE }; cal_table_info() : tpl_ctx(0), c(0), msTablePtr(0), conn_hndl(0), condInfo(0), moreRows(false) { } ~cal_table_info() {} sm::cpsm_tplh_t* tpl_ctx; std::stack tpl_ctx_st; sm::sp_cpsm_tplsch_t tpl_scan_ctx; std::stack tpl_scan_ctx_st; unsigned c; // for debug purpose TABLE* msTablePtr; // no ownership sm::cpsm_conhdl_t* conn_hndl; gp_walk_info* condInfo; execplan::SCSEP csep; bool moreRows; //are there more rows to consume (b/c of limit) }; struct cal_group_info { cal_group_info() : groupByFields(0), groupByTables(0), groupByWhere(0), groupByGroup(0), groupByOrder(0), groupByHaving(0), groupByDistinct(false) { } ~cal_group_info() { } List* groupByFields; // MCOL-1052 SELECT TABLE_LIST* groupByTables; // MCOL-1052 FROM Item* groupByWhere; // MCOL-1052 WHERE ORDER* groupByGroup; // MCOL-1052 GROUP BY ORDER* groupByOrder; // MCOL-1052 ORDER BY Item* groupByHaving; // MCOL-1052 HAVING bool groupByDistinct; //MCOL-1052 DISTINCT std::vector pushedPts; }; typedef std::tr1::unordered_map CalTableMap; typedef std::vector ColValuesList; typedef std::vector ColNameList; typedef std::map TableValuesMap; typedef std::bitset<4096> NullValuesBitset; struct cal_connection_info { enum AlterTableState { NOT_ALTER, ALTER_SECOND_RENAME, ALTER_FIRST_RENAME }; cal_connection_info() : cal_conn_hndl(0), queryState(0), currentTable(0), traceFlags(0), alterTableState(NOT_ALTER), isAlter(false), bulkInsertRows(0), singleInsert(true), isLoaddataInfile(false), isCacheInsert(false), dmlProc(0), rowsHaveInserted(0), rc(0), tableOid(0), localPm(-1), isSlaveNode(false), expressionId(0), mysqld_pid(getpid()), cpimport_pid(0), filePtr(0), headerLength(0), useXbit(false), useCpimport(1), delimiter('\7'), affectedRows(0) { // check if this is a slave mysql daemon isSlaveNode = checkSlave(); } static bool checkSlave() { config::Config* cf = config::Config::makeConfig(); std::string configVal = cf->getConfig("Installation", "MySQLRep"); bool isMysqlRep = (configVal == "y" || configVal == "Y"); if (!isMysqlRep) return false; configVal = cf->getConfig("SystemConfig", "PrimaryUMModuleName"); std::string module = execplan::ClientRotator::getModule(); if (boost::iequals(configVal, module)) return false; return true; } sm::cpsm_conhdl_t* cal_conn_hndl; std::stack cal_conn_hndl_st; int queryState; CalTableMap tableMap; std::set physTablesList; sm::tableid_t currentTable; uint32_t traceFlags; std::string queryStats; AlterTableState alterTableState; bool isAlter; ha_rows bulkInsertRows; bool singleInsert; bool isLoaddataInfile; bool isCacheInsert; std::string extendedStats; std::string miniStats; messageqcpp::MessageQueueClient* dmlProc; ha_rows rowsHaveInserted; ColNameList colNameList; TableValuesMap tableValuesMap; NullValuesBitset nullValuesBitset; int rc; uint32_t tableOid; querystats::QueryStats stats; std::string warningMsg; int64_t localPm; bool isSlaveNode; uint32_t expressionId; // for F&E pid_t mysqld_pid; pid_t cpimport_pid; int fdt[2]; #ifdef _MSC_VER // Used for launching cpimport for Load Data Infile HANDLE cpimport_stdin_Rd; HANDLE cpimport_stdin_Wr; HANDLE cpimport_stdout_Rd; HANDLE cpimport_stdout_Wr; PROCESS_INFORMATION cpimportProcInfo; #endif FILE* filePtr; uint8_t headerLength; bool useXbit; uint8_t useCpimport; char delimiter; char enclosed_by; std::vector columnTypes; // MCOL-1101 remove compilation unit variable rmParms std::vector rmParms; long long affectedRows; }; const std::string infinidb_err_msg = "\nThe query includes syntax that is not supported by MariaDB Columnstore. Use 'show warnings;' to get more information. Review the MariaDB Columnstore Syntax guide for additional information on supported distributed syntax or consider changing the MariaDB Columnstore Operating Mode (infinidb_vtable_mode)."; int cp_get_plan(THD* thd, execplan::SCSEP& csep); int cp_get_table_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_table_info& ti); int cp_get_group_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_group_info& gi); int cs_get_derived_plan(derived_handler* handler, THD* thd, execplan::SCSEP& csep, gp_walk_info& gwi); int cs_get_select_plan(select_handler* handler, THD* thd, execplan::SCSEP& csep, gp_walk_info& gwi); int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, bool isUnion = false, bool isSelectHandlerTop = false, const std::vector& condStack = std::vector()); int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, cal_group_info& gi, bool isUnion = false); void setError(THD* thd, uint32_t errcode, const std::string errmsg, gp_walk_info* gwi); void setError(THD* thd, uint32_t errcode, const std::string errmsg); void gp_walk(const Item* item, void* arg); void parse_item (Item* item, std::vector& field_vec, bool& hasNonSupportItem, uint16& parseInfo, gp_walk_info* gwip = NULL); const std::string bestTableName(const Item_field* ifp); bool isMCSTable(TABLE* table_ptr); // execution plan util functions prototypes execplan::ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupport, bool isRefItem = false); execplan::ReturnedColumn* buildFunctionColumn(Item_func* item, gp_walk_info& gwi, bool& nonSupport, bool selectBetweenIn = false); execplan::ArithmeticColumn* buildArithmeticColumn(Item_func* item, gp_walk_info& gwi, bool& nonSupport); execplan::ConstantColumn* buildDecimalColumn(Item* item, gp_walk_info& gwi); execplan::SimpleColumn* buildSimpleColumn(Item_field* item, gp_walk_info& gwi); execplan::FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonSupport); execplan::ParseTree* buildParseTree(Item_func* item, gp_walk_info& gwi, bool& nonSupport); execplan::ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi); execplan::ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& nonSupport); execplan::ReturnedColumn* buildPseudoColumn(Item* item, gp_walk_info& gwi, bool& nonSupport, uint32_t pseudoType); void addIntervalArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms); void castCharArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms); void castDecimalArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms); void castTypeArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms); //void parse_item (Item* item, std::vector& field_vec, bool& hasNonSupportItem, uint16& parseInfo); bool isPredicateFunction(Item* item, gp_walk_info* gwip); execplan::ParseTree* buildRowPredicate(THD* thd, execplan::RowColumn* lhs, execplan::RowColumn* rhs, std::string predicateOp); bool buildRowColumnFilter(gp_walk_info* gwip, execplan::RowColumn* rhs, execplan::RowColumn* lhs, Item_func* ifp); bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip); void collectAllCols(gp_walk_info& gwi, Item_field* ifp); void buildSubselectFunc(Item_func* ifp, gp_walk_info* gwip); uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex); std::string getViewName(TABLE_LIST* table_ptr); bool buildConstPredicate(Item_func* ifp, execplan::ReturnedColumn* rhs, gp_walk_info* gwip); execplan::CalpontSystemCatalog::ColType fieldType_MysqlToIDB (const Field* field); execplan::CalpontSystemCatalog::ColType colType_MysqlToIDB (const Item* item); execplan::SPTP getIntervalType(THD* thd, int interval_type); uint32_t isPseudoColumn(std::string funcName); void setDerivedTable(execplan::ParseTree* n); execplan::ParseTree* setDerivedFilter(THD* thd, execplan::ParseTree*& n, std::map& obj, execplan::CalpontSelectExecutionPlan::SelectList& derivedTbList); void derivedTableOptimization(THD* thd, execplan::SCSEP& csep); #ifdef DEBUG_WALK_COND void debug_walk(const Item* item, void* arg); #endif } #endif