diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2011-03-27 03:45:16 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2011-03-27 03:45:16 +0400 |
commit | 5de770f31736e1ed7088b6d609a4237083d4fe47 (patch) | |
tree | 7a806cb868f740609a99d3dcdd352f68d8dcb188 | |
parent | 290a72d50b65975e0bdd5caffa74d04acee906a5 (diff) | |
download | mariadb-git-5de770f31736e1ed7088b6d609a4237083d4fe47.tar.gz |
MWL#90: Address review feedback part #14
-rw-r--r-- | sql/item_subselect.cc | 6 | ||||
-rw-r--r-- | sql/opt_range.cc | 4 | ||||
-rw-r--r-- | sql/opt_subselect.cc | 49 | ||||
-rw-r--r-- | sql/sql_cursor.cc | 8 | ||||
-rw-r--r-- | sql/sql_delete.cc | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 147 | ||||
-rw-r--r-- | sql/sql_select.h | 12 | ||||
-rw-r--r-- | sql/sql_union.cc | 2 |
8 files changed, 139 insertions, 96 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 283a96d6149..1f37c4711fd 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2316,7 +2316,7 @@ bool Item_in_subselect::init_left_expr_cache() An IN predicate might be evaluated in a query for which all tables have been optimzied away. */ - if (!outer_join || !outer_join->tables || !outer_join->tables_list) + if (!outer_join || !outer_join->table_count || !outer_join->tables_list) return TRUE; if (!(left_expr_cache= new List<Cached_item>)) @@ -2701,9 +2701,9 @@ int subselect_single_select_engine::exec() pushed down into the subquery. Those optimizations are ref[_or_null] acceses. Change them to be full table scans. */ - for (uint i=join->const_tables ; i < join->tables ; i++) + for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab; + tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) { - JOIN_TAB *tab=join->join_tab+i; if (tab && tab->keyuse) { for (uint i= 0; i < tab->ref.key_parts; i++) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 72e5daf91f4..1d76bb35132 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -4319,7 +4319,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) return 1; */ JOIN *join= param->thd->lex->select_lex.join; - if (!join || join->tables == 1) + if (!join || join->table_count == 1) { /* No join, assume reading is done in one 'sweep' */ result= busy_blocks*(DISK_SEEK_BASE_COST + @@ -11270,7 +11270,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) /* Perform few 'cheap' tests whether this access method is applicable. */ if (!join) DBUG_RETURN(NULL); /* This is not a select statement. */ - if ((join->tables != 1) || /* The query must reference one table. */ + if ((join->table_count != 1) || /* The query must reference one table. */ ((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */ (!join->select_distinct)) || (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */ diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index d08e2f1ec65..c12a6008c38 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -203,6 +203,9 @@ static bool sj_table_is_included(JOIN *join, JOIN_TAB *join_tab); static Item *remove_additional_cond(Item* conds); static void remove_subq_pushed_predicates(JOIN *join, Item **where); +enum_nested_loop_state +end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records); + /* Check if we need JOIN::prepare()-phase subquery rewrites and if yes, do them @@ -644,7 +647,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) { st_select_lex *child_select= (*in_subq)->get_select_lex(); JOIN *child_join= child_select->join; - child_join->outer_tables = child_join->tables; + child_join->outer_tables = child_join->table_count; /* child_select->where contains only the WHERE predicate of the @@ -693,15 +696,15 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) bool remove_item= TRUE; if ((*in_subq)->is_flattenable_semijoin) { - if (join->tables + - (*in_subq)->unit->first_select()->join->tables >= MAX_TABLES) + if (join->table_count + + (*in_subq)->unit->first_select()->join->table_count >= MAX_TABLES) break; if (convert_subq_to_sj(join, *in_subq)) DBUG_RETURN(TRUE); } else { - if (join->tables + 1 >= MAX_TABLES) + if (join->table_count + 1 >= MAX_TABLES) break; if (convert_subq_to_jtbm(join, *in_subq, &remove_item)) DBUG_RETURN(TRUE); @@ -830,7 +833,8 @@ void get_delayed_table_estimates(TABLE *table, double read_time; /* Calculate #rows and cost of join execution */ - get_partial_join_cost(join, join->tables - join->const_tables, &read_time, &rows); + get_partial_join_cost(join, join->table_count - join->const_tables, + &read_time, &rows); *out_rows= (ha_rows)rows; *startup_cost= read_time; @@ -1097,8 +1101,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred) subq_pred->exec_method= Item_in_subselect::SEMI_JOIN; // for subsequent executions /*TODO: also reset the 'with_subselect' there. */ - /* n. Adjust the parent_join->tables counter */ - uint table_no= parent_join->tables; + /* n. Adjust the parent_join->table_count counter */ + uint table_no= parent_join->table_count; /* n. Walk through child's tables and adjust table->map */ for (tl= subq_lex->leaf_tables; tl; tl= tl->next_leaf, table_no++) { @@ -1111,7 +1115,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred) emb= emb->embedding) emb->select_lex= parent_join->select_lex; } - parent_join->tables += subq_lex->join->tables; + parent_join->table_count += subq_lex->join->table_count; /* Put the subquery's WHERE into semi-join's sj_on_expr @@ -1300,11 +1304,11 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, ((subselect_hash_sj_engine*)subq_pred->engine); jtbm->table= hash_sj_engine->tmp_table; - jtbm->table->tablenr= parent_join->tables; - jtbm->table->map= table_map(1) << (parent_join->tables); + jtbm->table->tablenr= parent_join->table_count; + jtbm->table->map= table_map(1) << (parent_join->table_count); - parent_join->tables++; - DBUG_ASSERT(parent_join->tables < MAX_TABLES); + parent_join->table_count++; + DBUG_ASSERT(parent_join->table_count < MAX_TABLES); Item *conds= hash_sj_engine->semi_join_conds; conds->fix_after_pullout(parent_lex, &conds); @@ -2479,7 +2483,7 @@ at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab, void fix_semijoin_strategies_for_picked_join_order(JOIN *join) { - uint table_count=join->tables; + uint table_count=join->table_count; uint tablenr; table_map remaining_tables= 0; table_map handled_tabs= 0; @@ -2643,8 +2647,6 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) } } -enum_nested_loop_state -end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records); /* Setup semi-join materialization strategy for one semi-join nest @@ -3505,6 +3507,7 @@ int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl) FALSE OK TRUE Out of memory error */ +JOIN_TAB *first_linear_tab(JOIN *join, enum enum_with_const_tables const_tbls); int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, uint no_jbuf_after) @@ -3512,17 +3515,19 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, uint i; THD *thd= join->thd; DBUG_ENTER("setup_semijoin_dups_elimination"); - - for (i= join->const_tables ; i < join->tables; ) + + POSITION *pos= join->best_positions + join->const_tables; + for (i= join->const_tables ; i < join->top_jtrange_tables; ) { JOIN_TAB *tab=join->join_tab + i; - POSITION *pos= join->best_positions + i; + //POSITION *pos= join->best_positions + i; uint keylen, keyno; switch (pos->sj_strategy) { case SJ_OPT_MATERIALIZE: case SJ_OPT_MATERIALIZE_SCAN: /* Do nothing */ - i+= pos->n_sj_tables; + i+= 1;// It used to be pos->n_sj_tables, but now they are embedded in a nest + pos += pos->n_sj_tables; break; case SJ_OPT_LOOSE_SCAN: { @@ -3539,6 +3544,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, if (pos->n_sj_tables > 1) tab[pos->n_sj_tables - 1].do_firstmatch= tab; i+= pos->n_sj_tables; + pos+= pos->n_sj_tables; break; } case SJ_OPT_DUPS_WEEDOUT: @@ -3636,6 +3642,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, join->join_tab[i + pos->n_sj_tables - 1].check_weed_out_table= sjtbl; i+= pos->n_sj_tables; + pos+= pos->n_sj_tables; break; } case SJ_OPT_FIRST_MATCH: @@ -3658,10 +3665,12 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, } j[-1].do_firstmatch= jump_to; i+= pos->n_sj_tables; + pos+= pos->n_sj_tables; break; } case SJ_OPT_NONE: i++; + pos++; break; } } @@ -3848,7 +3857,7 @@ int rewrite_to_index_subquery_engine(JOIN *join) if (!join->group_list && !join->order && join->unit->item && join->unit->item->substype() == Item_subselect::IN_SUBS && - join->tables == 1 && join->conds && + join->table_count == 1 && join->conds && !join->unit->is_union()) { if (!join->having) diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 308c49fc15c..915a4dd0c9c 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -381,14 +381,14 @@ Sensitive_cursor::open(JOIN *join_arg) /* Prepare JOIN for reading rows. */ join->tmp_table= 0; - join->join_tab[join->tables-1].next_select= setup_end_select_func(join); + join->join_tab[join->top_jtrange_tables - 1].next_select= setup_end_select_func(join); join->send_records= 0; join->fetch_limit= join->unit->offset_limit_cnt; /* Disable JOIN CACHE as it is not working with cursors yet */ - for (JOIN_TAB *tab= join_tab; - tab != join->join_tab + join->tables - 1; - tab++) + for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); + tab != join->join_tab + join->top_jtrange_tables - 1; + tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) { if (tab->next_select == sub_select_cache) tab->next_select= sub_select; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index e2cb17090a1..49ffa3913f8 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -677,9 +677,10 @@ multi_delete::initialize_tables(JOIN *join) walk= delete_tables; - for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables; - tab < end; - tab++) + + for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES); + tab; + tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) { if (tab->table->map & tables_to_delete_from) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 96d61acdcce..e68fcd14e00 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -520,7 +520,7 @@ JOIN::prepare(Item ***rref_pointer_array, for (table_ptr= select_lex->leaf_tables; table_ptr; table_ptr= table_ptr->next_leaf) - tables++; + table_count++; if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) || select_lex->setup_ref_array(thd, og_num) || @@ -840,7 +840,7 @@ JOIN::optimize() "Impossible HAVING" : "Impossible WHERE")); zero_result_cause= having_value == Item::COND_FALSE ? "Impossible HAVING" : "Impossible WHERE"; - tables= 0; + table_count= 0; error= 0; goto setup_subq_exit; } @@ -890,7 +890,7 @@ JOIN::optimize() { DBUG_PRINT("info",("No matching min/max row")); zero_result_cause= "No matching min/max row"; - tables= 0; + table_count= 0; error=0; goto setup_subq_exit; } @@ -904,14 +904,14 @@ JOIN::optimize() { DBUG_PRINT("info",("No matching min/max row")); zero_result_cause= "No matching min/max row"; - tables= 0; + table_count= 0; error=0; goto setup_subq_exit; } DBUG_PRINT("info",("Select tables optimized away")); zero_result_cause= "Select tables optimized away"; tables_list= 0; // All tables resolved - const_tables= tables; + const_tables= table_count; /* Extract all table-independent conditions and replace the WHERE clause with them. All other conditions were computed by opt_sum_query @@ -967,7 +967,7 @@ JOIN::optimize() else { /* Remove distinct if only const tables */ - select_distinct= select_distinct && (const_tables != tables); + select_distinct= select_distinct && (const_tables != table_count); } thd_proc_info(thd, "preparing"); @@ -1125,7 +1125,7 @@ JOIN::optimize() The FROM clause must contain a single non-constant table. */ - if (tables - const_tables == 1 && (group_list || select_distinct) && + if (table_count - const_tables == 1 && (group_list || select_distinct) && !tmp_table_param.sum_func_count && (!join_tab[const_tables].select || !join_tab[const_tables].select->quick || @@ -1176,7 +1176,7 @@ JOIN::optimize() if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE) select_distinct=0; } - else if (select_distinct && tables - const_tables == 1 && + else if (select_distinct && table_count - const_tables == 1 && rollup.state == ROLLUP::STATE_NONE) { /* @@ -1305,7 +1305,7 @@ JOIN::optimize() When the WITH ROLLUP modifier is present, we cannot skip temporary table creation for the DISTINCT clause just because there are only const tables. */ - need_tmp= ((const_tables != tables && + need_tmp= ((const_tables != table_count && ((select_distinct || !simple_order || !simple_group) || (group_list && order) || test(select_options & OPTION_BUFFER_RESULT))) || @@ -1319,7 +1319,7 @@ JOIN::optimize() Yet the current implementation of FORCE INDEX hints does not allow us to do it in a clean manner. */ - no_jbuf_after= 1 ? tables : make_join_orderinfo(this); + no_jbuf_after= 1 ? table_count : make_join_orderinfo(this); select_opts_for_readinfo= (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | @@ -1351,7 +1351,7 @@ JOIN::optimize() */ if (need_tmp || select_distinct || group_list || order) { - for (uint i= 0; i < tables; i++) + for (uint i= 0; i < table_count; i++) { if (!(table[i]->map & const_table_map)) table[i]->prepare_for_position(); @@ -1360,7 +1360,7 @@ JOIN::optimize() DBUG_EXECUTE("info",TEST_join(this);); - if (const_tables != tables) + if (const_tables != table_count) { /* Because filesort always does a full table scan or a quick range scan @@ -1535,7 +1535,7 @@ JOIN::optimize() if (exec_tmp_table1->distinct) { table_map used_tables= thd->used_tables; - JOIN_TAB *last_join_tab= join_tab+tables-1; + JOIN_TAB *last_join_tab= join_tab + top_jtrange_tables - 1; do { if (used_tables & last_join_tab->table->map) @@ -1761,12 +1761,17 @@ JOIN::reinit() set_items_ref_array(items0); if (join_tab_save) - memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables); + memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * table_count); /* need to reset ref access state (see join_read_key) */ if (join_tab) - for (uint i= 0; i < tables; i++) - join_tab[i].ref.key_err= TRUE; + { + for (JOIN_TAB *tab= first_linear_tab(this, WITH_CONST_TABLES); tab; + tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) + { + tab->ref.key_err= TRUE; + } + } if (tmp_join) restore_tmp(); @@ -1823,7 +1828,7 @@ JOIN::save_join_tab() if (!join_tab_save && select_lex->master_unit()->uncacheable) { if (!(join_tab_save= (JOIN_TAB*)thd->memdup((uchar*) join_tab, - sizeof(JOIN_TAB) * tables))) + sizeof(JOIN_TAB) * table_count))) return 1; } return 0; @@ -1863,7 +1868,7 @@ JOIN::exec() } (void) result->prepare2(); // Currently, this cannot fail. - if (!tables_list && (tables || !select_lex->with_sum_func)) + if (!tables_list && (table_count || !select_lex->with_sum_func)) { // Only test of functions if (select_options & SELECT_DESCRIBE) select_describe(this, FALSE, FALSE, FALSE, @@ -1916,7 +1921,7 @@ JOIN::exec() FOUND_ROWS() may be called. Never reset the examined row count here. It must be accumulated from all join iterations of all join parts. */ - if (tables) + if (table_count) thd->limit_found_rows= 0; if (zero_result_cause) @@ -1953,7 +1958,7 @@ JOIN::exec() } if (order && (order != group_list || !(select_options & SELECT_BIG_RESULT)) && - (const_tables == tables || + (const_tables == table_count || ((simple_order || skip_sort_order) && test_if_skip_sort_order(&join_tab[const_tables], order, select_limit, 0, @@ -1964,7 +1969,7 @@ JOIN::exec() select_describe(this, need_tmp, order != 0 && !skip_sort_order, select_distinct, - !tables ? "No tables used" : NullS); + !table_count ? "No tables used" : NullS); DBUG_VOID_RETURN; } @@ -1998,7 +2003,7 @@ JOIN::exec() thd_proc_info(thd, copy_to_tmp_table); DBUG_PRINT("info", ("%s", thd->proc_info)); if (!curr_join->sort_and_group && - curr_join->const_tables != curr_join->tables) + curr_join->const_tables != curr_join->table_count) { JOIN_TAB *first_tab= curr_join->join_tab + curr_join->const_tables; first_tab->sorted= test(first_tab->loosescan_match_tab); @@ -2169,7 +2174,7 @@ JOIN::exec() DBUG_VOID_RETURN; curr_join->group_list= 0; if (!curr_join->sort_and_group && - curr_join->const_tables != curr_join->tables) + curr_join->const_tables != curr_join->table_count) { JOIN_TAB *first_tab= curr_join->join_tab + curr_join->const_tables; first_tab->sorted= test(first_tab->loosescan_match_tab); @@ -2182,7 +2187,7 @@ JOIN::exec() DBUG_VOID_RETURN; } end_read_record(&curr_join->join_tab->read_record); - curr_join->const_tables= curr_join->tables; // Mark free for cleanup() + curr_join->const_tables= curr_join->table_count; // Mark free for cleanup() curr_join->join_tab[0].table= 0; // Table is freed // No sum funcs anymore @@ -2385,7 +2390,7 @@ JOIN::exec() curr_join->group_list ? TRUE : FALSE)) DBUG_VOID_RETURN; sortorder= curr_join->sortorder; - if (curr_join->const_tables != curr_join->tables && + if (curr_join->const_tables != curr_join->table_count && !curr_join->join_tab[curr_join->const_tables].table->sort.io_cache) { /* @@ -2407,7 +2412,7 @@ JOIN::exec() curr_join->fields= curr_fields_list; curr_join->procedure= procedure; - if (is_top_level_join() && thd->cursor && tables != const_tables) + if (is_top_level_join() && thd->cursor && table_count != const_tables) { /* We are here if this is JOIN::exec for the last select of the main unit @@ -2474,9 +2479,11 @@ JOIN::destroy() { if (join_tab != tmp_join->join_tab) { - JOIN_TAB *tab, *end; - for (tab= join_tab, end= tab+tables ; tab != end ; tab++) + for (JOIN_TAB *tab= first_linear_tab(this, WITH_CONST_TABLES); tab; + tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) + { tab->cleanup(); + } } tmp_join->tmp_join= 0; /* @@ -2801,7 +2808,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, DBUG_ENTER("make_join_statistics"); LINT_INIT(table); /* inited in all loops */ - table_count=join->tables; + table_count=join->table_count; stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*(table_count)); stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES); @@ -2943,7 +2950,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, { if (s->dependent & s->table->map) { - join->tables=0; // Don't use join->table + join->table_count=0; // Don't use join->table my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0)); goto error; } @@ -2952,7 +2959,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, } if (conds || outer_join) - if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables, + if (update_ref_and_keys(join->thd, keyuse_array, stat, join->table_count, conds, join->cond_equal, ~outer_join, join->select_lex, &sargables)) goto error; @@ -3269,14 +3276,14 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, join->const_tables=const_count; join->found_const_table_map=found_const_table_map; - if (join->const_tables != join->tables) + if (join->const_tables != join->table_count) optimize_keyuse(join, keyuse_array); if (optimize_semijoin_nests(join, all_table_map)) DBUG_RETURN(TRUE); /* purecov: inspected */ /* Find an optimal join order of the non-constant tables. */ - if (join->const_tables != join->tables) + if (join->const_tables != join->table_count) { if (choose_plan(join, all_table_map & ~join->const_table_map)) goto error; @@ -5299,7 +5306,7 @@ choose_plan(JOIN *join, table_map join_tables) jtab_sort_func= straight_join ? join_tab_cmp_straight : join_tab_cmp; } my_qsort2(join->best_ref + join->const_tables, - join->tables - join->const_tables, sizeof(JOIN_TAB*), + join->table_count - join->const_tables, sizeof(JOIN_TAB*), jtab_sort_func, (void*)join->emb_sjm_nest); join->cur_sj_inner_tables= 0; @@ -5475,7 +5482,7 @@ join_tab_cmp_embedded_first(const void *emb, const void* ptr1, const void* ptr2 static uint determine_search_depth(JOIN *join) { - uint table_count= join->tables - join->const_tables; + uint table_count= join->table_count - join->const_tables; uint search_depth; /* TODO: this value should be determined dynamically, based on statistics: */ uint max_tables_for_exhaustive_opt= 7; @@ -6415,6 +6422,28 @@ JOIN_TAB *next_breadth_first_tab(JOIN *join, JOIN_TAB *tab) } +JOIN_TAB *first_top_level_tab(JOIN *join, enum enum_with_const_tables with_const) +{ + JOIN_TAB *tab= join->join_tab; + if (with_const == WITH_CONST_TABLES) + { + if (join->const_tables == join->table_count) + return NULL; + tab += join->const_tables; + } + return tab; +} + + +JOIN_TAB *next_top_level_tab(JOIN *join, JOIN_TAB *tab) +{ + tab= next_breadth_first_tab(join, tab); + if (tab->bush_root_tab) + tab= NULL; + return tab; +} + + JOIN_TAB *first_linear_tab(JOIN *join, enum enum_with_const_tables const_tbls) { JOIN_TAB *first= join->join_tab; @@ -6580,7 +6609,7 @@ get_best_combination(JOIN *join) THD *thd=join->thd; DBUG_ENTER("get_best_combination"); - table_count=join->tables; + table_count=join->table_count; if (!(join->join_tab=join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count))) DBUG_RETURN(TRUE); @@ -6629,7 +6658,6 @@ get_best_combination(JOIN *join) j->on_expr_ref= (Item**) &null_ptr; j->keys= key_map(1); /* The unique index is always in 'possible keys' in EXPLAIN */ - /* 2. Proceed with processing SJM nest's join tabs, putting them into the sub-order @@ -7041,7 +7069,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table) join_tab= parent->join_tab_reexec; table= &parent->table_reexec[0]; parent->table_reexec[0]= temp_table; - tables= top_jtrange_tables= 1; + table_count= top_jtrange_tables= 1; const_tables= 0; const_table_map= 0; @@ -7383,9 +7411,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) */ if (cond) /* Because of QUICK_GROUP_MIN_MAX_SELECT */ { /* there may be a select without a cond. */ - if (join->tables > 1) + if (join->table_count > 1) cond->update_used_tables(); // Tablenr may have changed - if (join->const_tables == join->tables && + if (join->const_tables == join->table_count && thd->lex->current_select->master_unit() == &thd->lex->unit) // not upper level SELECT join->const_table_map|=RAND_TABLE_BIT; @@ -7486,7 +7514,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) Following force including random expression in last table condition. It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5 */ - if (i == join->tables-1) + if (tab == join->join_tab + join->top_jtrange_tables - 1) current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT; used_tables|=current_map; @@ -7506,7 +7534,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) We will use join cache here : prevent sorting of the first table only and sort at the end. */ - if (i != join->const_tables && join->tables > join->const_tables + 1) + if (i != join->const_tables && join->table_count > join->const_tables + 1) join->full_join= 1; } @@ -7884,9 +7912,9 @@ static uint make_join_orderinfo(JOIN *join) JOIN_TAB *tab; if (join->need_tmp) - return join->tables; + return join->table_count; tab= join->get_sort_by_join_tab(); - return tab ? tab-join->join_tab : join->tables; + return tab ? tab-join->join_tab : join->table_count; } /* @@ -8840,9 +8868,8 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) bool error_if_full_join(JOIN *join) { - for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables; - tab < end; - tab++) + for (JOIN_TAB *tab=first_top_level_tab(join, WITH_CONST_TABLES); tab; + tab= next_top_level_tab(join, tab)) { if (tab->type == JT_ALL && (!tab->select || !tab->select->quick)) { @@ -9085,7 +9112,7 @@ void JOIN::cleanup(bool full) Only a sorted table may be cached. This sorted table is always the first non const table in join->table */ - if (tables > const_tables) // Test for not-const tables + if (table_count > const_tables) // Test for not-const tables { free_io_cache(table[const_tables]); filesort_free_buffers(table[const_tables],full); @@ -9318,7 +9345,7 @@ static ORDER * remove_const(JOIN *join,ORDER *first_order, COND *cond, bool change_list, bool *simple_order) { - if (join->tables == join->const_tables) + if (join->table_count == join->const_tables) return change_list ? 0 : first_order; // No need to sort ORDER *order,**prev_ptr; @@ -9356,7 +9383,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, table for all queries containing more than one table, ROLLUP, and an outer join. */ - (join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED && + (join->table_count > 1 && join->rollup.state == ROLLUP::STATE_INITED && join->outer_join)) *simple_order=0; // Must do a temp table to sort else if (!(order_tables & not_const_tables)) @@ -9455,7 +9482,7 @@ static void clear_tables(JOIN *join) must clear only the non-const tables, as const tables are not re-calculated. */ - for (uint i= 0 ; i < join->tables ; i++) + for (uint i= 0 ; i < join->table_count ; i++) { if (!(join->table[i]->map & join->const_table_map)) mark_as_null_row(join->table[i]); // All fields are NULL @@ -13787,13 +13814,13 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) } /* Set up select_end */ Next_select_func end_select= setup_end_select_func(join); - if (join->tables) + if (join->table_count) { join->join_tab[join->top_jtrange_tables - 1].next_select= end_select; join_tab=join->join_tab+join->const_tables; } join->send_records=0; - if (join->tables == join->const_tables) + if (join->table_count == join->const_tables) { /* HAVING will be checked after processing aggregate functions, @@ -13826,7 +13853,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) } else { - DBUG_ASSERT(join->tables); + DBUG_ASSERT(join->table_count); error= sub_select(join,join_tab,0); if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS) error= sub_select(join,join_tab,1); @@ -14120,7 +14147,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (join->resume_nested_loop) { /* If not the last table, plunge down the nested loop */ - if (join_tab < join->join_tab + join->tables - 1) + if (join_tab < join->join_tab + join->top_jtrange_tables - 1) rc= (*join_tab->next_select)(join, join_tab + 1, 0); else { @@ -15152,7 +15179,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (join->select_options & OPTION_FOUND_ROWS) { JOIN_TAB *jt=join->join_tab; - if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group + if ((join->table_count == 1) && !join->tmp_table && !join->sort_and_group && !join->send_group_parts && !join->having && !jt->select_cond && !(jt->select && jt->select->quick) && (jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && @@ -15460,7 +15487,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), table->file->print_error(error, MYF(0));/* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } - join->join_tab[join->tables-1].next_select=end_unique_update; + join->join_tab[join->top_jtrange_tables-1].next_select=end_unique_update; } join->send_records++; DBUG_RETURN(NESTED_LOOP_OK); @@ -16543,7 +16570,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, ref_key_quick_rows= table->quick_rows[ref_key]; read_time= join->best_positions[tablenr].read_time; - for (uint i= tablenr+1; i < join->tables; i++) + for (uint i= tablenr+1; i < join->table_count; i++) fanout*= join->best_positions[i].records_read; // fanout is always >= 1 for (nr=0; nr < table->s->keys ; nr++) @@ -16719,7 +16746,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, */ if ((select_limit >= table_records) && (tab->type == JT_ALL && - tab->join->tables > tab->join->const_tables + 1) && + tab->join->table_count > tab->join->const_tables + 1) && ((unsigned) best_key != table->s->primary_key || !table->file->primary_key_is_clustered())) DBUG_RETURN(0); @@ -16919,7 +16946,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, JOIN_TAB *tab; DBUG_ENTER("create_sort_index"); - if (join->tables == join->const_tables) + if (join->table_count == join->const_tables) DBUG_RETURN(0); // One row, no need to sort tab= join->join_tab + join->const_tables; table= tab->table; diff --git a/sql/sql_select.h b/sql/sql_select.h index 8453037b878..6cd2828c0db 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -647,7 +647,13 @@ public: passing 1st non-const table to filesort(). NULL means no such table exists. */ TABLE *sort_by_table; - uint tables; /**< Number of tables in the join */ + /* + Number of tables in the join. + (In MySQL, it is named 'tables' and is also the number of elements in + join->join_tab array. In MariaDB, the latter is not true, so we've renamed + the variable) + */ + uint table_count; uint outer_tables; /**< Number of tables that are not inside semijoin */ uint const_tables; /* @@ -899,7 +905,7 @@ public: { join_tab= join_tab_save= 0; table= 0; - tables= 0; + table_count= 0; top_jtrange_tables= 0; const_tables= 0; eliminated_tables= 0; @@ -1015,7 +1021,7 @@ public: } inline table_map all_tables_map() { - return (table_map(1) << tables) - 1; + return (table_map(1) << table_count) - 1; } /* Return the table for which an index scan can be used to satisfy diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 8283d0e01fb..ec2f1faeb35 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -690,7 +690,7 @@ bool st_select_lex_unit::cleanup() if ((join= fake_select_lex->join)) { join->tables_list= 0; - join->tables= 0; + join->table_count= 0; join->top_jtrange_tables= 0; } error|= fake_select_lex->cleanup(); |