diff --git a/dbcon/mysql/ha_mcs_opt_rewrites.cpp b/dbcon/mysql/ha_mcs_opt_rewrites.cpp index 00c08d9e0..6d0d24e68 100644 --- a/dbcon/mysql/ha_mcs_opt_rewrites.cpp +++ b/dbcon/mysql/ha_mcs_opt_rewrites.cpp @@ -18,7 +18,7 @@ // Search simplify_joins() function in the server's code for detail COND * -simplify_joins_(JOIN *join, List *join_list, COND *conds, bool top, +simplify_joins_cs(JOIN *join, List *join_list, COND *conds, bool top, bool in_sj) { TABLE_LIST *table; @@ -26,7 +26,7 @@ simplify_joins_(JOIN *join, List *join_list, COND *conds, bool top, TABLE_LIST *prev_table= 0; List_iterator li(*join_list); bool straight_join= MY_TEST(join->select_options & SELECT_STRAIGHT_JOIN); - DBUG_ENTER("simplify_joins"); + DBUG_ENTER("simplify_joins_cs"); /* Try to simplify join operations from join_list. @@ -54,7 +54,7 @@ simplify_joins_(JOIN *join, List *join_list, COND *conds, bool top, the outer join is converted to an inner join and the corresponding on expression is added to E. */ - expr= simplify_joins_(join, &nested_join->join_list, + expr= simplify_joins_cs(join, &nested_join->join_list, expr, FALSE, in_sj || table->sj_on_expr); if (!table->prep_on_expr || expr != table->on_expr) @@ -67,7 +67,7 @@ simplify_joins_(JOIN *join, List *join_list, COND *conds, bool top, } nested_join->used_tables= (table_map) 0; nested_join->not_null_tables=(table_map) 0; - conds= simplify_joins_(join, &nested_join->join_list, conds, top, + conds= simplify_joins_cs(join, &nested_join->join_list, conds, top, in_sj || table->sj_on_expr); used_tables= nested_join->used_tables; not_null_tables= nested_join->not_null_tables; @@ -241,5 +241,5 @@ simplify_joins_(JOIN *join, List *join_list, COND *conds, bool top, li.replace(repl_list); } } - DBUG_RETURN(conds); + DBUG_RETURN(conds); } diff --git a/dbcon/mysql/ha_mcs_opt_rewrites.h b/dbcon/mysql/ha_mcs_opt_rewrites.h index d433c06a5..30d6b4dbe 100644 --- a/dbcon/mysql/ha_mcs_opt_rewrites.h +++ b/dbcon/mysql/ha_mcs_opt_rewrites.h @@ -20,7 +20,6 @@ #include "idb_mysql.h" -COND *simplify_joins_(JOIN *join, List *join_list, COND *conds, bool top, bool in_sj); - +COND *simplify_joins_cs(JOIN *join, List *join_list, COND *conds, bool top, bool in_sj); #endif diff --git a/dbcon/mysql/ha_mcs_pushdown.cpp b/dbcon/mysql/ha_mcs_pushdown.cpp index bd3b2cd44..65b369661 100644 --- a/dbcon/mysql/ha_mcs_pushdown.cpp +++ b/dbcon/mysql/ha_mcs_pushdown.cpp @@ -21,7 +21,6 @@ void check_walk(const Item* item, void* arg); - void disable_indices_for_CEJ(THD *thd_) { TABLE_LIST* global_list; @@ -42,7 +41,7 @@ void disable_indices_for_CEJ(THD *thd_) } } -bool optimize_unflattened_subqueries_(SELECT_LEX *select_lex) +bool optimize_unflattened_subqueries_cs(SELECT_LEX *select_lex) { bool result = false; TABLE_LIST *tbl; @@ -52,7 +51,7 @@ bool optimize_unflattened_subqueries_(SELECT_LEX *select_lex) if (tbl->is_view_or_derived()) { SELECT_LEX *dsl = tbl->derived->first_select(); - result = optimize_unflattened_subqueries_(dsl); + result = optimize_unflattened_subqueries_cs(dsl); } } @@ -546,7 +545,7 @@ create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived) //To search for CROSS JOIN-s we use tree invariant //G(V,E) where [V] = [E]+1 List join_preds_list; - TABLE_LIST *tl; + TABLE_LIST *tl; for (tl = sl->get_table_list(); !unsupported_feature && tl; tl = tl->next_local) { Item_cond* where_icp= 0; @@ -808,7 +807,6 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) return handler; } - bool unsupported_feature = false; // Select_handler use the short-cut that effectively disables // INSERT..SELECT, LDI, SELECT..INTO OUTFILE if ((thd->lex)->sql_command == SQLCOM_INSERT_SELECT @@ -816,28 +814,41 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) || (thd->lex)->exchange) { - unsupported_feature = true; + return handler; } + // We apply dedicated rewrites from MDB here so the data structures + // becomes dirty and CS has to raise an error in case of any problem. + bool unsupported_feature = false; + logging::Message::Args args; JOIN *join= select_lex->join; - // Next block tries to execute the query using SH very early to fallback - // if execution fails. - if (!unsupported_feature) { disable_indices_for_CEJ(thd); if (select_lex->handle_derived(thd->lex, DT_MERGE)) { - // early quit b/c of the error in handle_derived - return handler; + // set to true b/c of an error in handle_derived + unsupported_feature = true; + args.add("in handle_derived()"); } - COND *conds = simplify_joins_(join, select_lex->join_list, join->conds, TRUE, FALSE); + COND *conds; + if (!unsupported_feature) + { + conds = simplify_joins_cs(join, select_lex->join_list, + join->conds, TRUE, FALSE); + } + // MCOL-3747 IN-TO-EXISTS rewrite inside MDB didn't add // an equi-JOIN condition. - optimize_unflattened_subqueries_(select_lex); + if (!unsupported_feature + && optimize_unflattened_subqueries_cs(select_lex)) + { + unsupported_feature = true; + args.add("in optimize_unflattened_subqueries_cs()"); + } - if (conds) + if (!unsupported_feature && conds) { #ifdef DEBUG_WALK_COND conds->traverse_cond(cal_impl_if::debug_walk, NULL, Item::POSTFIX); @@ -845,15 +856,6 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) join->conds = conds; } - // Impossible HAVING or WHERE - // TODO replace with function call - if (unsupported_feature - || select_lex->having_value == Item::COND_FALSE - || select_lex->cond_value == Item::COND_FALSE ) - { - unsupported_feature = true; - restore_optimizer_flags(thd); - } } // Restore back the saved group_list @@ -874,6 +876,7 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) item_check(item, &unsupported_feature); if (unsupported_feature) { + args.add("in item_check()"); break; } } @@ -890,13 +893,20 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex) { rc= ha_cs_impl_pushdown_init(&mhi, handler->table); } + unsupported_feature = (rc) ? true : unsupported_feature; // Return SH even if init fails b/c CS changed SELECT_LEX structures - // with simplify_joins_() - if (rc) - unsupported_feature = true; + // with simplify_joins_cs and other rewrites() + // the handler will return error on next_row() return handler; } + else + { + std::string emsg= + logging::IDBErrorInfo::instance()->errorMsg(ER_INTERNAL_ERROR, args); + thd->raise_error_printf(ER_INTERNAL_ERROR, emsg.c_str()); + } + restore_optimizer_flags(thd); return NULL; }