diff options
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4fb05fe71c8..38b9b643d10 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2012 Oracle and/or its affiliates. +/* Copyright (c) 2000, 2013 Oracle and/or its affiliates. Copyright (c) 2009, 2013 Monty Program Ab. This program is free software; you can redistribute it and/or modify @@ -553,25 +553,25 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array, ORDER *group, bool *hidden_group_fields) { int res; - nesting_map save_allow_sum_func=thd->lex->allow_sum_func ; + st_select_lex *const select= thd->lex->current_select; + nesting_map save_allow_sum_func= thd->lex->allow_sum_func; /* Need to save the value, so we can turn off only any new non_agg_field_used additions coming from the WHERE */ - const bool saved_non_agg_field_used= - thd->lex->current_select->non_agg_field_used(); + const bool saved_non_agg_field_used= select->non_agg_field_used(); DBUG_ENTER("setup_without_group"); - thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level); + thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level); res= setup_conds(thd, tables, leaves, conds); /* it's not wrong to have non-aggregated columns in a WHERE */ - thd->lex->current_select->set_non_agg_field_used(saved_non_agg_field_used); + select->set_non_agg_field_used(saved_non_agg_field_used); - thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; + thd->lex->allow_sum_func|= (nesting_map)1 << select->nest_level; res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, order); - thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level); + thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level); res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields, group, hidden_group_fields); thd->lex->allow_sum_func= save_allow_sum_func; @@ -720,7 +720,7 @@ JOIN::prepare(Item ***rref_pointer_array, { nesting_map save_allow_sum_func= thd->lex->allow_sum_func; thd->where="having clause"; - thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level; + thd->lex->allow_sum_func|= (nesting_map)1 << select_lex_arg->nest_level; select_lex->having_fix_field= 1; /* Wrap alone field in HAVING clause in case it will be outer field of subquery @@ -2187,6 +2187,7 @@ JOIN::exec() { List<Item> *columns_list= &fields_list; int tmp_error; + DBUG_ENTER("JOIN::exec"); thd_proc_info(thd, "executing"); @@ -5438,7 +5439,8 @@ best_access_path(JOIN *join, in ReuseRangeEstimateForRef-3. */ if (table->quick_keys.is_set(key) && - (const_part & ((1 << table->quick_key_parts[key])-1)) == + (const_part & + (((key_part_map)1 << table->quick_key_parts[key])-1)) == (((key_part_map)1 << table->quick_key_parts[key])-1) && table->quick_n_ranges[key] == 1 && records > (double) table->quick_rows[key]) @@ -5602,7 +5604,8 @@ best_access_path(JOIN *join, */ if (table->quick_keys.is_set(key) && table->quick_key_parts[key] <= max_key_part && - const_part & (1 << table->quick_key_parts[key]) && + const_part & + ((key_part_map)1 << table->quick_key_parts[key]) && table->quick_n_ranges[key] == 1 + test(ref_or_null_part & const_part) && records > (double) table->quick_rows[key]) @@ -7933,7 +7936,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, j->ref.items[i]=keyuse->val; // Save for cond removal j->ref.cond_guards[i]= keyuse->cond_guard; if (keyuse->null_rejecting) - j->ref.null_rejecting |= 1 << i; + j->ref.null_rejecting|= (key_part_map)1 << i; keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; if (!keyuse->val->used_tables() && !thd->lex->describe) { // Compare against constant @@ -8209,7 +8212,7 @@ static void add_not_null_conds(JOIN *join) { for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++) { - if (tab->ref.null_rejecting & (1 << keypart)) + if (tab->ref.null_rejecting & ((key_part_map)1 << keypart)) { Item *item= tab->ref.items[keypart]; Item *notnull; @@ -14604,11 +14607,11 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, } else { - recinfo->null_bit= 1 << (null_count & 7); + recinfo->null_bit= (uint8)1 << (null_count & 7); recinfo->null_pos= null_count/8; } field->move_field(pos,null_flags+null_count/8, - 1 << (null_count & 7)); + (uint8)1 << (null_count & 7)); null_count++; } else @@ -15056,7 +15059,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list) { cur_field->move_field(field_pos, (uchar*) null_pos, null_bit); null_bit<<= 1; - if (null_bit == (1 << 8)) + if (null_bit == (uint)1 << 8) { ++null_pos; null_bit= 1; @@ -19103,17 +19106,29 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, if (!keep_quick) { select->cleanup(); - /* - The select object should now be ready for the next use. If it - is re-used then there exists a backup copy of this join tab - which has the pointer to it. The join tab will be restored in - JOIN::reset(). So here we just delete the pointer to it. - */ - tab->select= NULL; - // If we deleted the quick select object we need to clear quick_keys + + // If we deleted the quick object we need to clear quick_keys table->quick_keys.clear_all(); table->intersect_keys.clear_all(); } + else + { + // Need to close the index scan in order to re-use the handler + tab->select->quick->range_end(); + } + + /* + The select object is now ready for the next use. To avoid that + the select object is used when reading the records in sorted + order we set the pointer to it to NULL. The select pointer will + be restored from the saved_select pointer when this select + operation is completed (@see JOIN::exec). This ensures that it + will be re-used when filesort is used by subqueries that are + executed multiple times. + */ + tab->saved_select= tab->select; + tab->select= NULL; + // Restore the output resultset table->sort.io_cache= tablesort_result_cache; } |