diff options
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 625 |
1 files changed, 353 insertions, 272 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 958ab0201e0..4a4c078f686 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -309,7 +309,7 @@ void dbug_serve_apcs(THD *thd, int n_calls) thd_proc_info(thd, "show_explain_trap"); my_sleep(30000); thd_proc_info(thd, save_proc_info); - if (thd->check_killed()) + if (unlikely(thd->check_killed())) break; } } @@ -351,7 +351,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result, ulong setup_tables_done_option) { bool res; - register SELECT_LEX *select_lex = &lex->select_lex; + SELECT_LEX *select_lex = &lex->select_lex; DBUG_ENTER("handle_select"); MYSQL_SELECT_START(thd->query()); @@ -386,7 +386,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result, res|= thd->is_error(); if (unlikely(res)) result->abort_result_set(); - if (thd->killed == ABORT_QUERY && !thd->no_errors) + if (unlikely(thd->killed == ABORT_QUERY && !thd->no_errors)) { /* If LIMIT ROWS EXAMINED interrupted query execution, issue a warning, @@ -693,7 +693,7 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd) return false; } -void vers_select_conds_t::print(String *str, enum_query_type query_type) +void vers_select_conds_t::print(String *str, enum_query_type query_type) const { switch (type) { case SYSTEM_TIME_UNSPECIFIED: @@ -765,14 +765,14 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) { TABLE_LIST* derived= master_unit()->derived; // inner SELECT may not be a derived table (derived == NULL) - while (derived && outer_slex && !derived->vers_conditions) + while (derived && outer_slex && !derived->vers_conditions.is_set()) { derived= outer_slex->master_unit()->derived; outer_slex= outer_slex->outer_select(); } if (derived && outer_slex) { - DBUG_ASSERT(derived->vers_conditions); + DBUG_ASSERT(derived->vers_conditions.is_set()); outer_table= derived; } } @@ -791,13 +791,9 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) */ if (table->partition_names && table->table->part_info->vers_info) { - if (vers_conditions) + if (vers_conditions.is_set()) { -#define PART_VERS_ERR_MSG "%s PARTITION (%s)" - char buf[NAME_LEN*2 + sizeof(PART_VERS_ERR_MSG)]; - my_snprintf(buf, sizeof(buf), PART_VERS_ERR_MSG, table->alias.str, - table->partition_names->head()->c_ptr()); - my_error(ER_VERS_NOT_VERSIONED, MYF(0), buf); + my_error(ER_VERS_QUERY_IN_PARTITION, MYF(0), table->alias.str); DBUG_RETURN(-1); } else @@ -805,7 +801,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) } #endif - if (outer_table && !vers_conditions) + if (outer_table && !vers_conditions.is_set()) { // propagate system_time from nearest outer SELECT_LEX vers_conditions= outer_table->vers_conditions; @@ -813,15 +809,15 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) } // propagate system_time from sysvar - if (!vers_conditions) + if (!vers_conditions.is_set()) { if (vers_conditions.init_from_sysvar(thd)) DBUG_RETURN(-1); } - if (vers_conditions) + if (vers_conditions.is_set()) { - if (vers_conditions == SYSTEM_TIME_ALL) + if (vers_conditions.type == SYSTEM_TIME_ALL) continue; lock_type= TL_READ; // ignore TL_WRITE, history is immutable anyway @@ -837,13 +833,15 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) bool timestamps_only= table->table->versioned(VERS_TIMESTAMP); - if (vers_conditions) + if (vers_conditions.is_set()) { + thd->where= "FOR SYSTEM_TIME"; /* TODO: do resolve fix_length_and_dec(), fix_fields(). This requires storing vers_conditions as Item and make some magic related to vers_system_time_t/VERS_TRX_ID at stage of fix_fields() (this is large refactoring). */ - vers_conditions.resolve_units(timestamps_only); + if (vers_conditions.resolve_units(thd)) + DBUG_RETURN(-1); if (timestamps_only && (vers_conditions.start.unit == VERS_TRX_ID || vers_conditions.end.unit == VERS_TRX_ID)) { @@ -852,10 +850,9 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) } } - Item *cond1= 0, *cond2= 0, *curr= 0; - // Temporary tables of can be created from INNODB tables and thus will - // have uint64 type of sys_trx_(start|end) field. - // They need special handling. + Item *cond1= NULL, *cond2= NULL, *cond3= NULL, *curr= NULL; + Item *point_in_time1= vers_conditions.start.item; + Item *point_in_time2= vers_conditions.end.item; TABLE *t= table->table; if (t->versioned(VERS_TIMESTAMP)) { @@ -869,19 +866,21 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) cond1= newx Item_func_eq(thd, row_end, curr); break; case SYSTEM_TIME_AS_OF: - cond1= newx Item_func_le(thd, row_start, vers_conditions.start.item); - cond2= newx Item_func_gt(thd, row_end, vers_conditions.start.item); + cond1= newx Item_func_le(thd, row_start, point_in_time1); + cond2= newx Item_func_gt(thd, row_end, point_in_time1); break; case SYSTEM_TIME_FROM_TO: - cond1= newx Item_func_lt(thd, row_start, vers_conditions.end.item); - cond2= newx Item_func_ge(thd, row_end, vers_conditions.start.item); + cond1= newx Item_func_lt(thd, row_start, point_in_time2); + cond2= newx Item_func_gt(thd, row_end, point_in_time1); + cond3= newx Item_func_lt(thd, point_in_time1, point_in_time2); break; case SYSTEM_TIME_BETWEEN: - cond1= newx Item_func_le(thd, row_start, vers_conditions.end.item); - cond2= newx Item_func_ge(thd, row_end, vers_conditions.start.item); + cond1= newx Item_func_le(thd, row_start, point_in_time2); + cond2= newx Item_func_gt(thd, row_end, point_in_time1); + cond3= newx Item_func_le(thd, point_in_time1, point_in_time2); break; case SYSTEM_TIME_BEFORE: - cond1= newx Item_func_lt(thd, row_end, vers_conditions.start.item); + cond1= newx Item_func_lt(thd, row_end, point_in_time1); break; default: DBUG_ASSERT(0); @@ -901,29 +900,33 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) break; case SYSTEM_TIME_AS_OF: trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP - ? newx Item_func_vtq_id(thd, vers_conditions.start.item, TR_table::FLD_TRX_ID) - : vers_conditions.start.item; - cond1= newx Item_func_vtq_trx_sees_eq(thd, trx_id0, row_start); - cond2= newx Item_func_vtq_trx_sees(thd, row_end, trx_id0); + ? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID) + : point_in_time1; + cond1= newx Item_func_trt_trx_sees_eq(thd, trx_id0, row_start); + cond2= newx Item_func_trt_trx_sees(thd, row_end, trx_id0); break; case SYSTEM_TIME_FROM_TO: + cond3= newx Item_func_lt(thd, point_in_time1, point_in_time2); + /* fall through */ case SYSTEM_TIME_BETWEEN: trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP - ? newx Item_func_vtq_id(thd, vers_conditions.start.item, TR_table::FLD_TRX_ID, true) - : vers_conditions.start.item; + ? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID, true) + : point_in_time1; trx_id1= vers_conditions.end.unit == VERS_TIMESTAMP - ? newx Item_func_vtq_id(thd, vers_conditions.end.item, TR_table::FLD_TRX_ID, false) - : vers_conditions.end.item; + ? newx Item_func_trt_id(thd, point_in_time2, TR_table::FLD_TRX_ID, false) + : point_in_time2; cond1= vers_conditions.type == SYSTEM_TIME_FROM_TO - ? newx Item_func_vtq_trx_sees(thd, trx_id1, row_start) - : newx Item_func_vtq_trx_sees_eq(thd, trx_id1, row_start); - cond2= newx Item_func_vtq_trx_sees_eq(thd, row_end, trx_id0); + ? newx Item_func_trt_trx_sees(thd, trx_id1, row_start) + : newx Item_func_trt_trx_sees_eq(thd, trx_id1, row_start); + cond2= newx Item_func_trt_trx_sees_eq(thd, row_end, trx_id0); + if (!cond3) + cond3= newx Item_func_le(thd, point_in_time1, point_in_time2); break; case SYSTEM_TIME_BEFORE: trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP - ? newx Item_func_vtq_id(thd, vers_conditions.start.item, TR_table::FLD_TRX_ID) - : vers_conditions.start.item; - cond1= newx Item_func_lt(thd, row_end, trx_id0); + ? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID, true) + : point_in_time1; + cond1= newx Item_func_trt_trx_sees(thd, trx_id0, row_end); break; default: DBUG_ASSERT(0); @@ -933,6 +936,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) if (cond1) { cond1= and_items(thd, cond2, cond1); + cond1= and_items(thd, cond3, cond1); table->on_expr= and_items(thd, table->on_expr, cond1); } @@ -1079,7 +1083,9 @@ JOIN::prepare(TABLE_LIST *tables_init, select_lex != select_lex->master_unit()->global_parameters()) real_og_num+= select_lex->order_list.elements; - if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num)) + DBUG_ASSERT(select_lex->hidden_bit_fields == 0); + if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num, + &select_lex->hidden_bit_fields)) DBUG_RETURN(-1); if (select_lex->setup_ref_array(thd, real_og_num)) DBUG_RETURN(-1); @@ -1140,7 +1146,7 @@ JOIN::prepare(TABLE_LIST *tables_init, having->check_cols(1))); select_lex->having_fix_field= 0; - if (having_fix_rc || thd->is_error()) + if (unlikely(having_fix_rc || thd->is_error())) DBUG_RETURN(-1); /* purecov: inspected */ thd->lex->allow_sum_func= save_allow_sum_func; @@ -1285,7 +1291,7 @@ JOIN::prepare(TABLE_LIST *tables_init, } procedure= setup_procedure(thd, proc_param, result, fields_list, &error); - if (error) + if (unlikely(error)) goto err; /* purecov: inspected */ if (procedure) { @@ -1390,16 +1396,28 @@ bool JOIN::build_explain() { create_explain_query_if_not_exists(thd->lex, thd->mem_root); have_query_plan= QEP_AVAILABLE; - if (save_explain_data(thd->lex->explain, false /* can overwrite */, + + /* + explain data must be created on the Explain_query::mem_root. Because it's + just a memroot, not an arena, explain data must not contain any Items + */ + MEM_ROOT *old_mem_root= thd->mem_root; + Item *old_free_list __attribute__((unused))= thd->free_list; + thd->mem_root= thd->lex->explain->mem_root; + bool res= save_explain_data(thd->lex->explain, false /* can overwrite */, need_tmp, !skip_sort_order && !no_order && (order || group_list), - select_distinct)) + select_distinct); + thd->mem_root= old_mem_root; + DBUG_ASSERT(thd->free_list == old_free_list); // no Items were created + if (res) return 1; + uint select_nr= select_lex->select_number; JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt(); for (uint i= 0; i < aggr_tables; i++, curr_tab++) { - if (select_nr == INT_MAX) + if (select_nr == INT_MAX) { /* this is a fake_select_lex of a union */ select_nr= select_lex->master_unit()->first_select()->select_number; @@ -1553,9 +1571,6 @@ JOIN::optimize_inner() eval_select_list_used_tables(); - if (optimize_constant_subqueries()) - DBUG_RETURN(1); - table_count= select_lex->leaf_tables.elements; if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */ @@ -1596,7 +1611,11 @@ JOIN::optimize_inner() /* The following code will allocate the new items in a permanent MEMROOT for prepared statements and stored procedures. + + But first we need to ensure that thd->lex->explain is allocated + in the execution arena */ + create_explain_query_if_not_exists(thd->lex, thd->mem_root); Query_arena *arena, backup; arena= thd->activate_stmt_arena_if_needed(&backup); @@ -1605,8 +1624,12 @@ JOIN::optimize_inner() /* Convert all outer joins to inner joins if possible */ conds= simplify_joins(this, join_list, conds, TRUE, FALSE); - if (select_lex->save_leaf_tables(thd)) + if (thd->is_error() || select_lex->save_leaf_tables(thd)) + { + if (arena) + thd->restore_active_arena(arena, &backup); DBUG_RETURN(1); + } build_bitmap_for_nested_joins(join_list, 0); sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0; @@ -1617,6 +1640,9 @@ JOIN::optimize_inner() thd->restore_active_arena(arena, &backup); } + if (optimize_constant_subqueries()) + DBUG_RETURN(1); + List<Item> eq_list; if (setup_degenerate_jtbm_semi_joins(this, join_list, eq_list)) @@ -1724,7 +1750,8 @@ JOIN::optimize_inner() if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE)) DBUG_RETURN(1); } - if (thd->is_error()) + + if (unlikely(thd->is_error())) { error= 1; DBUG_PRINT("error",("Error from optimize_cond")); @@ -1735,7 +1762,7 @@ JOIN::optimize_inner() having= optimize_cond(this, having, join_list, TRUE, &having_value, &having_equal); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_PRINT("error",("Error from optimize_cond")); @@ -1877,7 +1904,7 @@ JOIN::optimize_inner() group_list= remove_const(this, group_list, conds, rollup.state == ROLLUP::STATE_NONE, &simple_group); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_RETURN(1); @@ -1887,13 +1914,26 @@ JOIN::optimize_inner() /* Calculate how to do the join */ THD_STAGE_INFO(thd, stage_statistics); result->prepare_to_read_rows(); - if (make_join_statistics(this, select_lex->leaf_tables, &keyuse) || - thd->is_fatal_error) + if (unlikely(make_join_statistics(this, select_lex->leaf_tables, + &keyuse)) || + unlikely(thd->is_fatal_error)) { DBUG_PRINT("error",("Error: make_join_statistics() failed")); DBUG_RETURN(1); } + /* + If a splittable materialized derived/view dt_i is embedded into + into another splittable materialized derived/view dt_o then + splitting plans for dt_i and dt_o are evaluated independently. + First the optimizer looks for the best splitting plan sp_i for dt_i. + It happens when non-splitting plans for dt_o are evaluated. + The cost of sp_i is considered as the cost of materialization of dt_i + when evaluating any splitting plan for dt_o. + */ + if (fix_all_splittings_in_plan()) + DBUG_RETURN(1); + setup_subq_exit: with_two_phase_optimization= check_two_phase_optimization(thd); if (with_two_phase_optimization) @@ -1917,7 +1957,7 @@ int JOIN::optimize_stage2() if (subq_exit_fl) goto setup_subq_exit; - if (thd->check_killed()) + if (unlikely(thd->check_killed())) DBUG_RETURN(1); /* Generate an execution plan from the found optimal join order. */ @@ -1993,7 +2033,7 @@ int JOIN::optimize_stage2() select= make_select(*table, const_table_map, const_table_map, conds, (SORT_INFO*) 0, 1, &error); - if (error) + if (unlikely(error)) { /* purecov: inspected */ error= -1; /* purecov: inspected */ DBUG_PRINT("error",("Error: make_select() failed")); @@ -2016,7 +2056,7 @@ int JOIN::optimize_stage2() { conds= substitute_for_best_equal_field(thd, NO_PARTICULAR_TAB, conds, cond_equal, map2table); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_PRINT("error",("Error from substitute_for_best_equal")); @@ -2042,7 +2082,7 @@ int JOIN::optimize_stage2() *tab->on_expr_ref, tab->cond_equal, map2table); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_PRINT("error",("Error from substitute_for_best_equal")); @@ -2072,7 +2112,7 @@ int JOIN::optimize_stage2() { ref_item= substitute_for_best_equal_field(thd, tab, ref_item, equals, map2table); - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(1); if (first_inner) @@ -2142,7 +2182,7 @@ int JOIN::optimize_stage2() { ORDER *org_order= order; order=remove_const(this, order,conds,1, &simple_order); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_RETURN(1); @@ -2304,7 +2344,7 @@ int JOIN::optimize_stage2() group_list= remove_const(this, group_list, conds, rollup.state == ROLLUP::STATE_NONE, &simple_group); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_RETURN(1); @@ -2325,7 +2365,7 @@ int JOIN::optimize_stage2() { group_list= procedure->group= remove_const(this, procedure->group, conds, 1, &simple_group); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_RETURN(1); @@ -2552,7 +2592,7 @@ int JOIN::optimize_stage2() ordered_index_usage= ordered_index_order_by; } } - } + } if (having) having_is_correlated= MY_TEST(having->used_tables() & OUTER_REF_TABLE_BIT); @@ -2694,6 +2734,25 @@ bool JOIN::add_having_as_table_cond(JOIN_TAB *tab) } +bool JOIN::add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *table_fields) +{ + /* + this will not walk into semi-join materialization nests but this is ok + because we will never need to save current rowids for those. + */ + for (JOIN_TAB *tab=join_tab; tab < cur; tab++) + { + if (!tab->keep_current_rowid) + continue; + Item *item= new (thd->mem_root) Item_temptable_rowid(tab->table); + item->fix_fields(thd, 0); + table_fields->push_back(item, thd->mem_root); + cur->tmp_table_param->func_count++; + } + return 0; +} + + /** Set info for aggregation tables @@ -3000,13 +3059,13 @@ bool JOIN::make_aggr_tables_info() (select_distinct && tmp_table_param.using_outer_summary_function)) { /* Must copy to another table */ DBUG_PRINT("info",("Creating group table")); - + calc_group_buffer(this, group_list); count_field_types(select_lex, &tmp_table_param, tmp_all_fields1, select_distinct && !group_list); - tmp_table_param.hidden_field_count= + tmp_table_param.hidden_field_count= tmp_all_fields1.elements - tmp_fields_list1.elements; - + curr_tab++; aggr_tables++; bzero(curr_tab, sizeof(JOIN_TAB)); @@ -3021,12 +3080,11 @@ bool JOIN::make_aggr_tables_info() if (join_tab->is_using_loose_index_scan()) tmp_table_param.precomputed_group_by= TRUE; - tmp_table_param.hidden_field_count= + tmp_table_param.hidden_field_count= curr_all_fields->elements - curr_fields_list->elements; ORDER *dummy= NULL; //TODO can use table->group here also - if (create_postjoin_aggr_table(curr_tab, - curr_all_fields, dummy, true, + if (create_postjoin_aggr_table(curr_tab, curr_all_fields, dummy, true, distinct, keep_row_order)) DBUG_RETURN(true); @@ -3162,7 +3220,7 @@ bool JOIN::make_aggr_tables_info() !join_tab || !join_tab-> is_using_agg_loose_index_scan())) DBUG_RETURN(true); - if (setup_sum_funcs(thd, sum_funcs) || thd->is_fatal_error) + if (unlikely(setup_sum_funcs(thd, sum_funcs) || thd->is_fatal_error)) DBUG_RETURN(true); } if (group_list || order) @@ -3252,7 +3310,7 @@ bool JOIN::make_aggr_tables_info() - duplicate value removal Both of these operations are done after window function computation step. */ - curr_tab= join_tab + exec_join_tab_cnt() + aggr_tables - 1; + curr_tab= join_tab + total_join_tab_cnt(); if (select_lex->window_funcs.elements) { if (!(curr_tab->window_funcs_step= new Window_funcs_computation)) @@ -3297,11 +3355,13 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields, */ ha_rows table_rows_limit= ((order == NULL || skip_sort_order) && !table_group && - !select_lex->with_sum_func) ? - select_limit : HA_POS_ERROR; + !select_lex->with_sum_func) ? select_limit + : HA_POS_ERROR; if (!(tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param))) DBUG_RETURN(true); + if (tmp_table_keep_current_rowid) + add_fields_for_current_rowid(tab, table_fields); tab->tmp_table_param->skip_create_table= true; TABLE* table= create_tmp_table(thd, tab->tmp_table_param, *table_fields, table_group, distinct, @@ -3696,7 +3756,7 @@ bool JOIN::prepare_result(List<Item> **columns_list) select_lex->handle_derived(thd->lex, DT_CREATE)) goto err; - if (result->prepare2()) + if (result->prepare2(this)) goto err; if ((select_lex->options & OPTION_SCHEMA_TABLE) && @@ -3723,7 +3783,7 @@ bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite, bool distinct) { /* - If there is SELECT in this statemet with the same number it must be the + If there is SELECT in this statement with the same number it must be the same SELECT */ DBUG_ASSERT(select_lex->select_number == UINT_MAX || @@ -3833,7 +3893,7 @@ void JOIN::exec_inner() } columns_list= &procedure_fields_list; } - if (result->prepare2()) + if (result->prepare2(this)) DBUG_VOID_RETURN; if (!tables_list && (table_count || !select_lex->with_sum_func) && @@ -3877,7 +3937,7 @@ void JOIN::exec_inner() } else send_records= 0; - if (!error) + if (likely(!error)) { join_free(); // Unlock all cursors error= (int) result->send_eof(); @@ -3903,7 +3963,7 @@ void JOIN::exec_inner() /* We've called exec_const_cond->val_int(). This may have caused an error. */ - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= thd->is_error(); DBUG_VOID_RETURN; @@ -3948,7 +4008,7 @@ void JOIN::exec_inner() while ((cur_const_item= const_item_it++)) { cur_const_item->val_str(); // This caches val_str() to Item::str_value - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= thd->is_error(); DBUG_VOID_RETURN; @@ -3982,7 +4042,7 @@ void JOIN::exec_inner() join_examined_rows= 0; /* XXX: When can we have here thd->is_error() not zero? */ - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= thd->is_error(); DBUG_VOID_RETURN; @@ -4190,7 +4250,7 @@ mysql_select(THD *thd, join->having_history= (join->having?join->having:join->tmp_having); } - if (thd->is_error()) + if (unlikely(thd->is_error())) goto err; join->exec(); @@ -4224,17 +4284,20 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, int error; DBUG_ENTER("get_quick_record_count"); uchar buff[STACK_BUFF_ALLOC]; - if (check_stack_overrun(thd, STACK_MIN_SIZE, buff)) + if (unlikely(check_stack_overrun(thd, STACK_MIN_SIZE, buff))) DBUG_RETURN(0); // Fatal error flag is set if (select) { select->head=table; table->reginfo.impossible_range=0; - if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0, - limit, 0, FALSE, - TRUE /* remove_where_parts*/)) == 1) + if (likely((error= + select->test_quick_select(thd, *(key_map *)keys, + (table_map) 0, + limit, 0, FALSE, + TRUE /* remove_where_parts*/)) == + 1)) DBUG_RETURN(select->quick->records); - if (error == -1) + if (unlikely(error == -1)) { table->reginfo.impossible_range=1; DBUG_RETURN(0); @@ -4341,7 +4404,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, DBUG_EXECUTE_IF("bug11747970_raise_error", { join->thd->set_killed(KILL_QUERY_HARD); }); - if (error) + if (unlikely(error)) { table->file->print_error(error, MYF(0)); goto error; @@ -8597,7 +8660,7 @@ best_extension_by_limited_search(JOIN *join, dbug_serve_apcs(thd, 1); ); - if (thd->check_killed()) // Abort + if (unlikely(thd->check_killed())) // Abort DBUG_RETURN(TRUE); DBUG_EXECUTE("opt", print_plan(join, idx, read_time, record_count, idx, @@ -9393,7 +9456,7 @@ bool JOIN::get_best_combination() */ uint aggr_tables= (group_list ? 1 : 0) + (select_distinct ? - (tmp_table_param. using_outer_summary_function ? 2 : 1) : 0) + + (tmp_table_param.using_outer_summary_function ? 2 : 1) : 0) + (order ? 1 : 0) + (select_options & (SELECT_BIG_RESULT | OPTION_BUFFER_RESULT) ? 1 : 0) ; @@ -9412,9 +9475,6 @@ bool JOIN::get_best_combination() full_join=0; hash_join= FALSE; - if (fix_all_splittings_in_plan()) - DBUG_RETURN(TRUE); - fix_semijoin_strategies_for_picked_join_order(this); JOIN_TAB_RANGE *root_range; @@ -9857,7 +9917,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, keyinfo->key_part[i].length, keyuse->val, FALSE); - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(TRUE); tmp.copy(); j->ref.const_ref_part_map |= key_part_map(1) << i ; @@ -11335,9 +11395,9 @@ end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) DBUG_RETURN(NESTED_LOOP_OK); } fill_record(thd, table, table->field, sjm->sjm_table_cols, TRUE, FALSE); - if (thd->is_error()) + if (unlikely(thd->is_error())) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if ((error= table->file->ha_write_tmp_row(table->record[0]))) + if (unlikely((error= table->file->ha_write_tmp_row(table->record[0])))) { /* create_myisam_from_heap will generate error if needed */ if (table->file->is_fatal_error(error, HA_CHECK_DUP) && @@ -13145,7 +13205,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, if (prev_ptr == &first_order) // Nothing to sort/group *simple_order=1; #ifndef DBUG_OFF - if (join->thd->is_error()) + if (unlikely(join->thd->is_error())) DBUG_PRINT("error",("Error from remove_const")); #endif DBUG_PRINT("exit",("simple_order: %d",(int) *simple_order)); @@ -13251,7 +13311,7 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables, bool send_error= FALSE; if (send_row) send_error= result->send_data(fields) > 0; - if (!send_error) + if (likely(!send_error)) result->send_eof(); // Should be safe } DBUG_RETURN(0); @@ -16906,6 +16966,10 @@ setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps) temporary table @param table_alias possible name of the temporary table that can be used for name resolving; can be "". + @param do_not_open only create the TABLE object, do not + open the table in the engine + @param keep_row_order rows need to be read in the order they were + inserted, the engine should preserve this order */ TABLE * @@ -17216,11 +17280,11 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, */ item->marker == 4 || param->bit_fields_as_long, force_copy_fields); - if (!new_field) + if (unlikely(!new_field)) { - if (thd->is_fatal_error) - goto err; // Got OOM - continue; // Some kind of const item + if (unlikely(thd->is_fatal_error)) + goto err; // Got OOM + continue; // Some kind of const item } DBUG_ASSERT(!new_field->field_name.str || strlen(new_field->field_name.str) == new_field->field_name.length); if (type == Item::SUM_FUNC_ITEM) @@ -17730,7 +17794,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, } } - if (thd->is_fatal_error) // If end of memory + if (unlikely(thd->is_fatal_error)) // If end of memory goto err; /* purecov: inspected */ share->db_record_offset= 1; table->used_for_duplicate_elimination= (param->sum_func_count == 0 && @@ -17934,9 +17998,10 @@ bool Virtual_tmp_table::sp_set_all_fields_from_item(THD *thd, Item *value) bool open_tmp_table(TABLE *table) { int error; - if ((error= table->file->ha_open(table, table->s->table_name.str, O_RDWR, - HA_OPEN_TMP_TABLE | - HA_OPEN_INTERNAL_TABLE))) + if (unlikely((error= table->file->ha_open(table, table->s->table_name.str, + O_RDWR, + HA_OPEN_TMP_TABLE | + HA_OPEN_INTERNAL_TABLE)))) { table->file->print_error(error, MYF(0)); /* purecov: inspected */ table->db_stat= 0; @@ -18130,14 +18195,14 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, } } - if ((error= maria_create(share->table_name.str, - file_type, - share->keys, &keydef, - (uint) (*recinfo-start_recinfo), - start_recinfo, - share->uniques, &uniquedef, - &create_info, - create_flags))) + if (unlikely((error= maria_create(share->table_name.str, + file_type, + share->keys, &keydef, + (uint) (*recinfo-start_recinfo), + start_recinfo, + share->uniques, &uniquedef, + &create_info, + create_flags)))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->db_stat=0; @@ -18285,15 +18350,17 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, bzero((char*) &create_info,sizeof(create_info)); create_info.data_file_length= table->in_use->variables.tmp_disk_table_size; - if ((error=mi_create(share->table_name.str, share->keys, &keydef, - (uint) (*recinfo-start_recinfo), - start_recinfo, - share->uniques, &uniquedef, - &create_info, - HA_CREATE_TMP_TABLE | HA_CREATE_INTERNAL_TABLE | - ((share->db_create_options & HA_OPTION_PACK_RECORD) ? - HA_PACK_RECORD : 0) - ))) + if (unlikely((error= mi_create(share->table_name.str, share->keys, &keydef, + (uint) (*recinfo-start_recinfo), + start_recinfo, + share->uniques, &uniquedef, + &create_info, + HA_CREATE_TMP_TABLE | + HA_CREATE_INTERNAL_TABLE | + ((share->db_create_options & + HA_OPTION_PACK_RECORD) ? + HA_PACK_RECORD : 0) + )))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->db_stat=0; @@ -18347,11 +18414,11 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, share= *table->s; new_table.s= &share; new_table.s->db_plugin= ha_lock_engine(thd, TMP_ENGINE_HTON); - if (!(new_table.file= get_new_handler(&share, &new_table.mem_root, - new_table.s->db_type()))) + if (unlikely(!(new_table.file= get_new_handler(&share, &new_table.mem_root, + new_table.s->db_type())))) DBUG_RETURN(1); // End of memory - if (new_table.file->set_ha_share_ref(&share.ha_share)) + if (unlikely(new_table.file->set_ha_share_ref(&share.ha_share))) { delete new_table.file; DBUG_RETURN(1); @@ -18394,7 +18461,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;); if (write_err) goto err; - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { thd->send_kill_message(); goto err_killed; @@ -18403,7 +18470,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, if (!new_table.no_rows && new_table.file->ha_end_bulk_insert()) goto err; /* copy row that filled HEAP table */ - if ((write_err=new_table.file->ha_write_tmp_row(table->record[0]))) + if (unlikely((write_err=new_table.file->ha_write_tmp_row(table->record[0])))) { if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) || !ignore_last_dupp_key_error) @@ -18692,7 +18759,7 @@ do_select(JOIN *join, Procedure *procedure) (the join condition and piece of where clause relevant to this join table). */ - if (join->thd->is_error()) + if (unlikely(join->thd->is_error())) error= NESTED_LOOP_ERROR; } else @@ -18710,13 +18777,14 @@ do_select(JOIN *join, Procedure *procedure) error= NESTED_LOOP_NO_MORE_ROWS; else error= join->first_select(join,join_tab,0); - if (error >= NESTED_LOOP_OK && join->thd->killed != ABORT_QUERY) + if (error >= NESTED_LOOP_OK && likely(join->thd->killed != ABORT_QUERY)) error= join->first_select(join,join_tab,1); } join->thd->limit_found_rows= join->send_records - join->duplicate_rows; - if (error == NESTED_LOOP_NO_MORE_ROWS || join->thd->killed == ABORT_QUERY) + if (error == NESTED_LOOP_NO_MORE_ROWS || + unlikely(join->thd->killed == ABORT_QUERY)) error= NESTED_LOOP_OK; /* @@ -18763,7 +18831,7 @@ do_select(JOIN *join, Procedure *procedure) Sic: this branch works even if rc != 0, e.g. when send_data above returns an error. */ - if (join->result->send_eof()) + if (unlikely(join->result->send_eof())) rc= 1; // Don't send error DBUG_PRINT("info",("%ld records output", (long) join->send_records)); } @@ -18783,7 +18851,7 @@ do_select(JOIN *join, Procedure *procedure) int rr_sequential_and_unpack(READ_RECORD *info) { int error; - if ((error= rr_sequential(info))) + if (unlikely((error= rr_sequential(info)))) return error; for (Copy_field *cp= info->copy_field; cp != info->copy_field_end; cp++) @@ -18954,7 +19022,7 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) rc= sub_select(join, join_tab, end_of_records); DBUG_RETURN(rc); } - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { /* The user has aborted the execution of the query */ join->thd->send_kill_message(); @@ -19190,10 +19258,10 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) error= info->read_record(); - if (skip_over && !error) + if (skip_over && likely(!error)) { - if(!key_cmp(join_tab->table->key_info[join_tab->loosescan_key].key_part, - join_tab->loosescan_buf, join_tab->loosescan_key_len)) + if (!key_cmp(join_tab->table->key_info[join_tab->loosescan_key].key_part, + join_tab->loosescan_buf, join_tab->loosescan_key_len)) { /* This is the LooseScan action: skip over records with the same key @@ -19205,7 +19273,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) skip_over= FALSE; } - if (join_tab->keep_current_rowid && !error) + if (join_tab->keep_current_rowid && likely(!error)) join_tab->table->file->position(join_tab->table->record[0]); rc= evaluate_join_record(join, join_tab, error); @@ -19250,11 +19318,12 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, " cond: %p error: %d alias %s", join, join_tab, select_cond, error, join_tab->table->alias.ptr())); - if (error > 0 || (join->thd->is_error())) // Fatal error + + if (error > 0 || unlikely(join->thd->is_error())) // Fatal error DBUG_RETURN(NESTED_LOOP_ERROR); if (error < 0) DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); - if (join->thd->check_killed()) // Aborted by user + if (unlikely(join->thd->check_killed())) // Aborted by user { join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ @@ -19267,7 +19336,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, select_cond_result= MY_TEST(select_cond->val_int()); /* check for errors evaluating the condition */ - if (join->thd->is_error()) + if (unlikely(join->thd->is_error())) DBUG_RETURN(NESTED_LOOP_ERROR); } @@ -19397,7 +19466,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, join->return_tab= return_tab; /* check for errors evaluating the condition */ - if (join->thd->is_error()) + if (unlikely(join->thd->is_error())) DBUG_RETURN(NESTED_LOOP_ERROR); if (join->return_tab < join_tab) @@ -19546,10 +19615,11 @@ int safe_index_read(JOIN_TAB *tab) { int error; TABLE *table= tab->table; - if ((error= table->file->ha_index_read_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_KEY_EXACT))) + if (unlikely((error= + table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_KEY_EXACT)))) return report_error(table, error); return 0; } @@ -19597,7 +19667,7 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos) } else if (tab->type == JT_SYSTEM) { - if ((error=join_read_system(tab))) + if (unlikely((error=join_read_system(tab)))) { // Info for DESCRIBE tab->info= ET_CONST_ROW_NOT_FOUND; /* Mark for EXPLAIN that the row was not found */ @@ -19623,7 +19693,7 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos) } error=join_read_const(tab); table->file->ha_end_keyread(); - if (error) + if (unlikely(error)) { tab->info= ET_UNIQUE_ROW_NOT_FOUND; /* Mark for EXPLAIN that the row was not found */ @@ -19701,8 +19771,9 @@ join_read_system(JOIN_TAB *tab) int error; if (table->status & STATUS_GARBAGE) // If first read { - if ((error= table->file->ha_read_first_row(table->record[0], - table->s->primary_key))) + if (unlikely((error= + table->file->ha_read_first_row(table->record[0], + table->s->primary_key)))) { if (error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -19747,7 +19818,7 @@ join_read_const(JOIN_TAB *tab) make_prev_keypart_map(tab->ref.key_parts), HA_READ_KEY_EXACT); } - if (error) + if (unlikely(error)) { table->status= STATUS_NOT_FOUND; mark_as_null_row(tab->table); @@ -19803,7 +19874,7 @@ int join_read_key2(THD *thd, JOIN_TAB *tab, TABLE *table, TABLE_REF *table_ref) if (!table->file->inited) { error= table->file->ha_index_init(table_ref->key, tab ? tab->sorted : TRUE); - if (error) + if (unlikely(error)) { (void) report_error(table, error); return 1; @@ -19843,10 +19914,11 @@ int join_read_key2(THD *thd, JOIN_TAB *tab, TABLE *table, TABLE_REF *table_ref) table_ref->key_buff, make_prev_keypart_map(table_ref->key_parts), HA_READ_KEY_EXACT); - if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) + if (unlikely(error) && + error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) return report_error(table, error); - if (! error) + if (likely(!error)) { table_ref->has_record= TRUE; table_ref->use_count= 1; @@ -19907,16 +19979,19 @@ join_read_always_key(JOIN_TAB *tab) /* Initialize the index first */ if (!table->file->inited) { - if ((error= table->file->ha_index_init(tab->ref.key, tab->sorted))) + if (unlikely((error= table->file->ha_index_init(tab->ref.key, + tab->sorted)))) { (void) report_error(table, error); return 1; } } - if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref)) + if (unlikely(cp_buffer_from_ref(tab->join->thd, table, &tab->ref))) return -1; - if ((error= table->file->prepare_index_key_scan_map(tab->ref.key_buff, make_prev_keypart_map(tab->ref.key_parts)))) + if (unlikely((error= + table->file->prepare_index_key_scan_map(tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts))))) { report_error(table,error); return -1; @@ -19946,23 +20021,26 @@ join_read_last_key(JOIN_TAB *tab) TABLE *table= tab->table; if (!table->file->inited && - (error= table->file->ha_index_init(tab->ref.key, tab->sorted))) + unlikely((error= table->file->ha_index_init(tab->ref.key, tab->sorted)))) { (void) report_error(table, error); return 1; } - if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref)) + if (unlikely(cp_buffer_from_ref(tab->join->thd, table, &tab->ref))) return -1; - if ((error= table->file->prepare_index_key_scan_map(tab->ref.key_buff, make_prev_keypart_map(tab->ref.key_parts)))) + if (unlikely((error= + table->file->prepare_index_key_scan_map(tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts)))) ) { report_error(table,error); return -1; } - if ((error= table->file->ha_index_read_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_PREFIX_LAST))) + if (unlikely((error= + table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_PREFIX_LAST)))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -19987,9 +20065,9 @@ join_read_next_same(READ_RECORD *info) TABLE *table= info->table; JOIN_TAB *tab=table->reginfo.join_tab; - if ((error= table->file->ha_index_next_same(table->record[0], - tab->ref.key_buff, - tab->ref.key_length))) + if (unlikely((error= table->file->ha_index_next_same(table->record[0], + tab->ref.key_buff, + tab->ref.key_length)))) { if (error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -20007,7 +20085,7 @@ join_read_prev_same(READ_RECORD *info) TABLE *table= info->table; JOIN_TAB *tab=table->reginfo.join_tab; - if ((error= table->file->ha_index_prev(table->record[0]))) + if (unlikely((error= table->file->ha_index_prev(table->record[0])))) return report_error(table, error); if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key, tab->ref.key_length)) @@ -20030,7 +20108,7 @@ join_init_quick_read_record(JOIN_TAB *tab) int read_first_record_seq(JOIN_TAB *tab) { - if (tab->read_record.table->file->ha_rnd_init_with_error(1)) + if (unlikely(tab->read_record.table->file->ha_rnd_init_with_error(1))) return 1; return tab->read_record.read_record(); } @@ -20153,9 +20231,10 @@ join_read_first(JOIN_TAB *tab) tab->read_record.record=table->record[0]; if (!table->file->inited) error= table->file->ha_index_init(tab->index, tab->sorted); - if (!error) + if (likely(!error)) error= table->file->prepare_index_scan(); - if (error || (error=tab->table->file->ha_index_first(tab->table->record[0]))) + if (unlikely(error) || + unlikely(error= tab->table->file->ha_index_first(tab->table->record[0]))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) report_error(table, error); @@ -20169,7 +20248,7 @@ static int join_read_next(READ_RECORD *info) { int error; - if ((error= info->table->file->ha_index_next(info->record))) + if (unlikely((error= info->table->file->ha_index_next(info->record)))) return report_error(info->table, error); return 0; @@ -20193,9 +20272,10 @@ join_read_last(JOIN_TAB *tab) tab->read_record.record=table->record[0]; if (!table->file->inited) error= table->file->ha_index_init(tab->index, 1); - if (!error) + if (likely(!error)) error= table->file->prepare_index_scan(); - if (error || (error= tab->table->file->ha_index_last(tab->table->record[0]))) + if (unlikely(error) || + unlikely(error= tab->table->file->ha_index_last(tab->table->record[0]))) DBUG_RETURN(report_error(table, error)); DBUG_RETURN(0); @@ -20206,7 +20286,7 @@ static int join_read_prev(READ_RECORD *info) { int error; - if ((error= info->table->file->ha_index_prev(info->record))) + if (unlikely((error= info->table->file->ha_index_prev(info->record)))) return report_error(info->table, error); return 0; } @@ -20227,7 +20307,7 @@ join_ft_read_first(JOIN_TAB *tab) table->file->ft_init(); - if ((error= table->file->ha_ft_read(table->record[0]))) + if (unlikely((error= table->file->ha_ft_read(table->record[0])))) return report_error(table, error); return 0; } @@ -20236,7 +20316,7 @@ static int join_ft_read_next(READ_RECORD *info) { int error; - if ((error= info->table->file->ha_ft_read(info->table->record[0]))) + if (unlikely((error= info->table->file->ha_ft_read(info->table->record[0])))) return report_error(info->table, error); return 0; } @@ -20266,7 +20346,7 @@ int join_read_next_same_or_null(READ_RECORD *info) { int error; - if ((error= join_read_next_same(info)) >= 0) + if (unlikely((error= join_read_next_same(info)) >= 0)) return error; JOIN_TAB *tab= info->table->reginfo.join_tab; @@ -20338,7 +20418,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { int error; /* result < 0 if row was not accepted and should not be counted */ - if ((error= join->result->send_data(*fields))) + if (unlikely((error= join->result->send_data(*fields)))) { if (error > 0) DBUG_RETURN(NESTED_LOOP_ERROR); @@ -20487,7 +20567,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (join->do_send_rows) { error=join->result->send_data(*fields); - if (error < 0) + if (unlikely(error < 0)) { /* Duplicate row, don't count */ join->duplicate_rows++; @@ -20497,13 +20577,13 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), join->send_records++; join->group_sent= true; } - if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0) + if (unlikely(join->rollup.state != ROLLUP::STATE_NONE && error <= 0)) { if (join->rollup_send_data((uint) (idx+1))) error= 1; } } - if (error > 0) + if (unlikely(error > 0)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ if (end_of_records) DBUG_RETURN(NESTED_LOOP_OK); @@ -20573,14 +20653,14 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if (!join_tab->having || join_tab->having->val_int()) + if (likely(!join_tab->having || join_tab->having->val_int())) { int error; join->found_records++; if ((error= table->file->ha_write_tmp_row(table->record[0]))) { - if (!table->file->is_fatal_error(error, HA_CHECK_DUP)) - goto end; + if (likely(!table->file->is_fatal_error(error, HA_CHECK_DUP))) + goto end; // Ignore duplicate keys bool is_duplicate; if (create_internal_tmp_table_from_heap(join->thd, table, join_tab->tmp_table_param->start_recinfo, @@ -20603,7 +20683,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } } end: - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ @@ -20662,8 +20742,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { /* Update old record */ restore_record(table,record[1]); update_tmptable_sum_func(join->sum_funcs,table); - if ((error= table->file->ha_update_tmp_row(table->record[1], - table->record[0]))) + if (unlikely((error= table->file->ha_update_tmp_row(table->record[1], + table->record[0])))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ @@ -20672,9 +20752,10 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } init_tmptable_sum_functions(join->sum_funcs); - if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) + if (unlikely(copy_funcs(join_tab->tmp_table_param->items_to_copy, + join->thd))) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if ((error= table->file->ha_write_tmp_row(table->record[0]))) + if (unlikely((error= table->file->ha_write_tmp_row(table->record[0])))) { if (create_internal_tmp_table_from_heap(join->thd, table, join_tab->tmp_table_param->start_recinfo, @@ -20682,7 +20763,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), error, 0, NULL)) DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error /* Change method to update rows */ - if ((error= table->file->ha_index_init(0, 0))) + if (unlikely((error= table->file->ha_index_init(0, 0)))) { table->file->print_error(error, MYF(0)); DBUG_RETURN(NESTED_LOOP_ERROR); @@ -20692,7 +20773,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } join_tab->send_records++; end: - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ @@ -20719,30 +20800,30 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if (!(error= table->file->ha_write_tmp_row(table->record[0]))) + if (likely(!(error= table->file->ha_write_tmp_row(table->record[0])))) join_tab->send_records++; // New group else { - if ((int) table->file->get_dup_key(error) < 0) + if (unlikely((int) table->file->get_dup_key(error) < 0)) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } - if (table->file->ha_rnd_pos(table->record[1],table->file->dup_ref)) + if (unlikely(table->file->ha_rnd_pos(table->record[1],table->file->dup_ref))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } restore_record(table,record[1]); update_tmptable_sum_func(join->sum_funcs,table); - if ((error= table->file->ha_update_tmp_row(table->record[1], - table->record[0]))) + if (unlikely((error= table->file->ha_update_tmp_row(table->record[1], + table->record[0])))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } } - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ @@ -20790,17 +20871,18 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (!join_tab->having || join_tab->having->val_int()) { int error= table->file->ha_write_tmp_row(table->record[0]); - if (error && + if (unlikely(error) && create_internal_tmp_table_from_heap(join->thd, table, join_tab->tmp_table_param->start_recinfo, &join_tab->tmp_table_param->recinfo, error, 0, NULL)) DBUG_RETURN(NESTED_LOOP_ERROR); } - if (join->rollup.state != ROLLUP::STATE_NONE) + if (unlikely(join->rollup.state != ROLLUP::STATE_NONE)) { - if (join->rollup_write_data((uint) (idx+1), - join_tab->tmp_table_param, table)) + if (unlikely(join->rollup_write_data((uint) (idx+1), + join_tab->tmp_table_param, + table))) { DBUG_RETURN(NESTED_LOOP_ERROR); } @@ -20819,21 +20901,23 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (idx < (int) join->send_group_parts) { copy_fields(join_tab->tmp_table_param); - if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) + if (unlikely(copy_funcs(join_tab->tmp_table_param->items_to_copy, + join->thd))) DBUG_RETURN(NESTED_LOOP_ERROR); - if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1])) + if (unlikely(init_sum_functions(join->sum_funcs, + join->sum_funcs_end[idx+1]))) DBUG_RETURN(NESTED_LOOP_ERROR); - if (join->procedure) + if (unlikely(join->procedure)) join->procedure->add(); goto end; } } - if (update_sum_func(join->sum_funcs)) + if (unlikely(update_sum_func(join->sum_funcs))) DBUG_RETURN(NESTED_LOOP_ERROR); - if (join->procedure) + if (unlikely(join->procedure)) join->procedure->add(); end: - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ @@ -22283,7 +22367,8 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort) { DBUG_ASSERT(tab->type == JT_REF || tab->type == JT_EQ_REF); // Update ref value - if ((cp_buffer_from_ref(thd, table, &tab->ref) && thd->is_fatal_error)) + if (unlikely(cp_buffer_from_ref(thd, table, &tab->ref) && + thd->is_fatal_error)) goto err; // out of memory } } @@ -22291,7 +22376,7 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort) /* Fill schema tables with data before filesort if it's necessary */ if ((join->select_lex->options & OPTION_SCHEMA_TABLE) && - get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX)) + unlikely(get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))) goto err; if (table->s->tmp_table) @@ -22459,37 +22544,32 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, int error; DBUG_ENTER("remove_dup_with_compare"); - if (file->ha_rnd_init_with_error(1)) + if (unlikely(file->ha_rnd_init_with_error(1))) DBUG_RETURN(1); error= file->ha_rnd_next(record); for (;;) { - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { thd->send_kill_message(); error=0; goto err; } - if (error) + if (unlikely(error)) { - if (error == HA_ERR_RECORD_DELETED) - { - error= file->ha_rnd_next(record); - continue; - } if (error == HA_ERR_END_OF_FILE) break; goto err; } if (having && !having->val_int()) { - if ((error= file->ha_delete_row(record))) + if (unlikely((error= file->ha_delete_row(record)))) goto err; error= file->ha_rnd_next(record); continue; } - if (copy_blobs(first_field)) + if (unlikely(copy_blobs(first_field))) { my_message(ER_OUTOFMEMORY, ER_THD(thd,ER_OUTOFMEMORY), MYF(ME_FATALERROR)); @@ -22502,30 +22582,28 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, bool found=0; for (;;) { - if ((error= file->ha_rnd_next(record))) + if (unlikely((error= file->ha_rnd_next(record)))) { - if (error == HA_ERR_RECORD_DELETED) - continue; if (error == HA_ERR_END_OF_FILE) break; goto err; } if (compare_record(table, first_field) == 0) { - if ((error= file->ha_delete_row(record))) + if (unlikely((error= file->ha_delete_row(record)))) goto err; } else if (!found) { found=1; - if ((error= file->remember_rnd_pos())) + if (unlikely((error= file->remember_rnd_pos()))) goto err; } } if (!found) break; // End of file /* Restart search on saved row */ - if ((error= file->restart_rnd_next(record))) + if (unlikely((error= file->restart_rnd_next(record)))) goto err; } @@ -22561,49 +22639,48 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, Field **ptr; DBUG_ENTER("remove_dup_with_hash_index"); - if (!my_multi_malloc(MYF(MY_WME), - &key_buffer, - (uint) ((key_length + extra_length) * - (long) file->stats.records), - &field_lengths, - (uint) (field_count*sizeof(*field_lengths)), - NullS)) + if (unlikely(!my_multi_malloc(MYF(MY_WME), + &key_buffer, + (uint) ((key_length + extra_length) * + (long) file->stats.records), + &field_lengths, + (uint) (field_count*sizeof(*field_lengths)), + NullS))) DBUG_RETURN(1); for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++) (*field_length++)= (*ptr)->sort_length(); - if (my_hash_init(&hash, &my_charset_bin, (uint) file->stats.records, 0, - key_length, (my_hash_get_key) 0, 0, 0)) + if (unlikely(my_hash_init(&hash, &my_charset_bin, + (uint) file->stats.records, 0, + key_length, (my_hash_get_key) 0, 0, 0))) { my_free(key_buffer); DBUG_RETURN(1); } - if ((error= file->ha_rnd_init(1))) + if (unlikely((error= file->ha_rnd_init(1)))) goto err; key_pos=key_buffer; for (;;) { uchar *org_key_pos; - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { thd->send_kill_message(); error=0; goto err; } - if ((error= file->ha_rnd_next(record))) + if (unlikely((error= file->ha_rnd_next(record)))) { - if (error == HA_ERR_RECORD_DELETED) - continue; if (error == HA_ERR_END_OF_FILE) break; goto err; } if (having && !having->val_int()) { - if ((error= file->ha_delete_row(record))) + if (unlikely((error= file->ha_delete_row(record)))) goto err; continue; } @@ -22620,7 +22697,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, if (my_hash_search(&hash, org_key_pos, key_length)) { /* Duplicated found ; Remove the row */ - if ((error= file->ha_delete_row(record))) + if (unlikely((error= file->ha_delete_row(record)))) goto err; } else @@ -22641,7 +22718,7 @@ err: my_hash_free(&hash); file->extra(HA_EXTRA_NO_CACHE); (void) file->ha_rnd_end(); - if (error) + if (unlikely(error)) file->print_error(error,MYF(0)); DBUG_RETURN(1); } @@ -23337,13 +23414,10 @@ get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables, calc how big buffer we need for comparing group entries. */ -static void -calc_group_buffer(JOIN *join,ORDER *group) +void calc_group_buffer(TMP_TABLE_PARAM *param, ORDER *group) { uint key_length=0, parts=0, null_parts=0; - if (group) - join->group= 1; for (; group ; group=group->next) { Item *group_item= *group->item; @@ -23413,9 +23487,16 @@ calc_group_buffer(JOIN *join,ORDER *group) if (group_item->maybe_null) null_parts++; } - join->tmp_table_param.group_length=key_length+null_parts; - join->tmp_table_param.group_parts=parts; - join->tmp_table_param.group_null_parts=null_parts; + param->group_length= key_length + null_parts; + param->group_parts= parts; + param->group_null_parts= null_parts; +} + +static void calc_group_buffer(JOIN *join, ORDER *group) +{ + if (group) + join->group= 1; + calc_group_buffer(&join->tmp_table_param, group); } @@ -24132,7 +24213,7 @@ copy_funcs(Item **func_ptr, const THD *thd) TODO: change it for a real status check when Item::val_xxx() are extended to return status code. */ - if (thd->is_error()) + if (unlikely(thd->is_error())) return TRUE; } return FALSE; @@ -24166,7 +24247,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) value), thd->mem_root); } - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(TRUE); if (!cond->fixed) { @@ -24658,7 +24739,8 @@ int JOIN::rollup_write_data(uint idx, TMP_TABLE_PARAM *tmp_table_param_arg, TABL item->save_in_result_field(1); } copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]); - if ((write_error= table_arg->file->ha_write_tmp_row(table_arg->record[0]))) + if (unlikely((write_error= + table_arg->file->ha_write_tmp_row(table_arg->record[0])))) { if (create_internal_tmp_table_from_heap(thd, table_arg, tmp_table_param_arg->start_recinfo, @@ -24756,7 +24838,7 @@ int print_explain_message_line(select_result_sink *result, else item_list.push_back(item_null, mem_root); - if (thd->is_fatal_error || result->send_data(item_list)) + if (unlikely(thd->is_fatal_error) || unlikely(result->send_data(item_list))) return 1; return 0; } @@ -24827,9 +24909,9 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, if (filesort) { if (!(eta->pre_join_sort= - new Explain_aggr_filesort(thd->mem_root, - thd->lex->analyze_stmt, - filesort))) + new (thd->mem_root) Explain_aggr_filesort(thd->mem_root, + thd->lex->analyze_stmt, + filesort))) return 1; } @@ -25267,7 +25349,7 @@ bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel) { // Each aggregate means a temp.table prev_node= node; - if (!(node= new Explain_aggr_tmp_table)) + if (!(node= new (thd->mem_root) Explain_aggr_tmp_table)) return 1; node->child= prev_node; @@ -25288,7 +25370,7 @@ bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel) if (join_tab->distinct) { prev_node= node; - if (!(node= new Explain_aggr_remove_dups)) + if (!(node= new (thd->mem_root) Explain_aggr_remove_dups)) return 1; node->child= prev_node; } @@ -25296,7 +25378,7 @@ bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel) if (join_tab->filesort) { Explain_aggr_filesort *eaf = - new Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort); + new (thd->mem_root) Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort); if (!eaf) return 1; prev_node= node; @@ -25590,7 +25672,8 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) unit->fake_select_lex->type= unit_operation_text[unit->common_op()]; unit->fake_select_lex->options|= SELECT_DESCRIBE; } - if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE))) + if (!(res= unit->prepare(unit->derived, result, + SELECT_NO_UNLOCK | SELECT_DESCRIBE))) res= unit->exec(); } else @@ -26156,7 +26239,7 @@ bool JOIN::change_result(select_result *new_result, select_result *old_result) { result= new_result; if (result->prepare(fields_list, select_lex->master_unit()) || - result->prepare2()) + result->prepare2(this)) DBUG_RETURN(true); /* purecov: inspected */ DBUG_RETURN(false); } @@ -26987,22 +27070,20 @@ ulong check_selectivity(THD *thd, } it.rewind(); - if (file->ha_rnd_init_with_error(1)) + if (unlikely(file->ha_rnd_init_with_error(1))) DBUG_RETURN(0); do { error= file->ha_rnd_next(record); - if (thd->killed) + if (unlikely(thd->killed)) { thd->send_kill_message(); count= 0; goto err; } - if (error) + if (unlikely(error)) { - if (error == HA_ERR_RECORD_DELETED) - continue; if (error == HA_ERR_END_OF_FILE) break; goto err; @@ -27154,11 +27235,11 @@ AGGR_OP::end_send() else error= join_tab->read_record.read_record(); - if (error > 0 || (join->thd->is_error())) // Fatal error + if (unlikely(error > 0 || (join->thd->is_error()))) // Fatal error rc= NESTED_LOOP_ERROR; else if (error < 0) break; - else if (join->thd->killed) // Aborted by user + else if (unlikely(join->thd->killed)) // Aborted by user { join->thd->send_kill_message(); rc= NESTED_LOOP_KILLED; |