diff options
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r-- | sql/opt_subselect.cc | 56 |
1 files changed, 24 insertions, 32 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 85f5645949e..d0be72b8d51 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -446,7 +446,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred); static bool convert_subq_to_jtbm(JOIN *parent_join, Item_in_subselect *subq_pred, bool *remove); static TABLE_LIST *alloc_join_nest(THD *thd); -static uint get_tmp_table_rec_length(Item **p_list, uint elements); +static uint get_tmp_table_rec_length(Ref_ptr_array p_list, uint elements); static double get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size); static double get_tmp_table_write_cost(THD *thd, double row_count, @@ -513,6 +513,7 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs, (Subquery is correlated to the immediate outer query && Subquery !contains {GROUP BY, ORDER BY [LIMIT], aggregate functions}) && subquery predicate is not under "NOT IN")) + 5. Subquery does not contain recursive references A note about prepared statements: we want the if-branch to be taken on PREPARE and each EXECUTE. The rewrites are only done once, but we need @@ -529,7 +530,8 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) || //3 optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) && //3 - !in_subs->is_correlated) //4 + !in_subs->is_correlated && //4 + !in_subs->with_recursive_reference) //5 { return TRUE; } @@ -1094,8 +1096,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) while ((in_subq= li++)) { SELECT_LEX *subq_sel= in_subq->get_select_lex(); - if (subq_sel->handle_derived(thd->lex, DT_OPTIMIZE)) - DBUG_RETURN(1); if (subq_sel->handle_derived(thd->lex, DT_MERGE)) DBUG_RETURN(TRUE); subq_sel->update_used_tables(); @@ -1455,8 +1455,8 @@ static bool replace_where_subcondition(JOIN *join, Item **expr, static int subq_sj_candidate_cmp(Item_in_subselect* el1, Item_in_subselect* el2, void *arg) { - return (el1->sj_convert_priority > el2->sj_convert_priority) ? 1 : - ( (el1->sj_convert_priority == el2->sj_convert_priority)? 0 : -1); + return (el1->sj_convert_priority > el2->sj_convert_priority) ? -1 : + ( (el1->sj_convert_priority == el2->sj_convert_priority)? 0 : 1); } @@ -2455,13 +2455,9 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map) JOIN_TAB *tab= join->best_positions[i].table; join->map2table[tab->table->tablenr]= tab; } - //List_iterator<Item> it(right_expr_list); - Item **ref_array= subq_select->ref_pointer_array; - Item **ref_array_end= ref_array + subq_select->item_list.elements; table_map map= 0; - //while ((item= it++)) - for (;ref_array < ref_array_end; ref_array++) - map |= (*ref_array)->used_tables(); + for (uint i=0; i < subq_select->item_list.elements; i++) + map|= subq_select->ref_pointer_array[i]->used_tables(); map= map & ~PSEUDO_TABLE_BITS; Table_map_iterator tm_it(map); int tableno; @@ -2525,15 +2521,14 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map) Length of the temptable record, in bytes */ -static uint get_tmp_table_rec_length(Item **p_items, uint elements) +static uint get_tmp_table_rec_length(Ref_ptr_array p_items, uint elements) { uint len= 0; Item *item; //List_iterator<Item> it(items); - Item **p_item; - for (p_item= p_items; p_item < p_items + elements ; p_item++) + for (uint i= 0; i < elements ; i++) { - item = *p_item; + item = p_items[i]; switch (item->result_type()) { case REAL_RESULT: len += sizeof(double); @@ -2776,8 +2771,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, LooseScan detector in best_access_path) */ remaining_tables &= ~new_join_tab->table->map; - table_map dups_producing_tables, prev_dups_producing_tables= 0, - prev_sjm_lookup_tables= 0; + table_map dups_producing_tables, UNINIT_VAR(prev_dups_producing_tables), + UNINIT_VAR(prev_sjm_lookup_tables); if (idx == join->const_tables) dups_producing_tables= 0; @@ -2788,7 +2783,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, if ((emb_sj_nest= new_join_tab->emb_sj_nest)) dups_producing_tables |= emb_sj_nest->sj_inner_tables; - Semi_join_strategy_picker **strategy, **prev_strategy= NULL; + Semi_join_strategy_picker **strategy, **prev_strategy= 0; if (idx == join->const_tables) { /* First table, initialize pickers */ @@ -3989,13 +3984,13 @@ bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab) */ sjm->copy_field= new Copy_field[sjm->sjm_table_cols.elements]; //it.rewind(); - Item **p_item= emb_sj_nest->sj_subq_pred->unit->first_select()->ref_pointer_array; + Ref_ptr_array p_items= emb_sj_nest->sj_subq_pred->unit->first_select()->ref_pointer_array; for (uint i=0; i < sjm->sjm_table_cols.elements; i++) { bool dummy; Item_equal *item_eq; //Item *item= (it++)->real_item(); - Item *item= (*(p_item++))->real_item(); + Item *item= p_items[i]->real_item(); DBUG_ASSERT(item->type() == Item::FIELD_ITEM); Field *copy_to= ((Item_field*)item)->field; /* @@ -4220,7 +4215,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) { /* if we run out of slots or we are not using tempool */ sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid, - thd->thread_id, thd->tmp_table++); + (ulong) thd->thread_id, thd->tmp_table++); } fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME); @@ -4243,7 +4238,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) &tmpname, (uint) strlen(path)+1, &group_buff, (!using_unique_constraint ? uniq_tuple_length_arg : 0), - &bitmaps, bitmap_buffer_size(1)*5, + &bitmaps, bitmap_buffer_size(1)*6, NullS)) { if (temp_pool_slot != MY_BIT_NONE) @@ -4265,7 +4260,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) table->alias.set("weedout-tmp", sizeof("weedout-tmp")-1, table_alias_charset); table->reginfo.lock_type=TL_WRITE; /* Will be updated */ - table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE; + table->db_stat=HA_OPEN_KEYFILE; table->map=1; table->temp_pool_slot = temp_pool_slot; table->copy_blobs= 1; @@ -4400,13 +4395,13 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) field->set_table_name(&table->alias); } - if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit + if (thd->variables.tmp_memory_table_size == ~ (ulonglong) 0) // No limit share->max_rows= ~(ha_rows) 0; else share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ? - MY_MIN(thd->variables.tmp_table_size, - thd->variables.max_heap_table_size) : - thd->variables.tmp_table_size) / + MY_MIN(thd->variables.tmp_memory_table_size, + thd->variables.max_heap_table_size) : + thd->variables.tmp_memory_table_size) / share->reclength); set_if_bigger(share->max_rows,1); // For dummy start options @@ -4440,7 +4435,6 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) field->null_ptr, field->null_bit))) goto err; - key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL; //todo need this? } keyinfo->key_length+= key_part_info->length; } @@ -5004,8 +4998,6 @@ int clear_sj_tmp_tables(JOIN *join) { if ((res= table->file->ha_delete_all_rows())) return res; /* purecov: inspected */ - free_io_cache(table); - filesort_free_buffers(table,0); } SJ_MATERIALIZATION_INFO *sjm; @@ -5870,7 +5862,7 @@ bool JOIN::choose_subquery_plan(table_map join_tables) */ /* C.1 Compute the cost of the materialization strategy. */ //uint rowlen= get_tmp_table_rec_length(unit->first_select()->item_list); - uint rowlen= get_tmp_table_rec_length(ref_pointer_array, + uint rowlen= get_tmp_table_rec_length(ref_ptrs, select_lex->item_list.elements); /* The cost of writing one row into the temporary table. */ double write_cost= get_tmp_table_write_cost(thd, inner_record_count_1, |