summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2010-10-28 19:04:23 +0200
committerSergei Golubchik <sergii@pisem.net>2010-10-28 19:04:23 +0200
commit8e7ebfbce89a472b3c5a6c30e6de101e567a8218 (patch)
tree9f9950feb45222c7df4f37c841f4af593ec75ee5 /sql/sql_select.cc
parent3bdede3c67032345ca5f71dd53ca308377dc2398 (diff)
parent7c24e8d54d1d41374b7836e3273e7e5eaf22e2c4 (diff)
downloadmariadb-git-8e7ebfbce89a472b3c5a6c30e6de101e567a8218.tar.gz
5.2 merge
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc108
1 files changed, 78 insertions, 30 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index d43353a3b53..debd1b07fe5 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2381,14 +2381,9 @@ JOIN::destroy()
having_equal= 0;
cleanup(1);
- /* Cleanup items referencing temporary table columns */
- if (!tmp_all_fields3.is_empty())
- {
- List_iterator_fast<Item> it(tmp_all_fields3);
- Item *item;
- while ((item= it++))
- item->cleanup();
- }
+ /* Cleanup items referencing temporary table columns */
+ cleanup_item_list(tmp_all_fields1);
+ cleanup_item_list(tmp_all_fields3);
if (exec_tmp_table1)
free_tmp_table(thd, exec_tmp_table1);
if (exec_tmp_table2)
@@ -2400,6 +2395,19 @@ JOIN::destroy()
DBUG_RETURN(error);
}
+
+void JOIN::cleanup_item_list(List<Item> &items) const
+{
+ if (!items.is_empty())
+ {
+ List_iterator_fast<Item> it(items);
+ Item *item;
+ while ((item= it++))
+ item->cleanup();
+ }
+}
+
+
/**
An entry point to single-unit select (a select without UNION).
@@ -4599,12 +4607,10 @@ best_access_path(JOIN *join,
tmp= records;
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
if (table->covering_keys.is_set(key))
- {
- /* we can use only index tree */
- tmp= record_count * table->file->keyread_read_time(key, 1, tmp);
- }
+ tmp= table->file->keyread_time(key, 1, tmp);
else
- tmp= record_count*min(tmp,s->worst_seeks);
+ tmp= table->file->read_time(key, 1, min(tmp,s->worst_seeks)-1);
+ tmp*= record_count;
}
}
else
@@ -4764,12 +4770,10 @@ best_access_path(JOIN *join,
/* Limit the number of matched rows */
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
if (table->covering_keys.is_set(key))
- {
- /* we can use only index tree */
- tmp= record_count * table->file->keyread_read_time(key, 1, tmp);
- }
+ tmp= table->file->keyread_time(key, 1, tmp);
else
- tmp= record_count * min(tmp,s->worst_seeks);
+ tmp= table->file->read_time(key, 1, min(tmp,s->worst_seeks)-1);
+ tmp*= record_count;
}
else
tmp= best_time; // Do nothing
@@ -4777,7 +4781,7 @@ best_access_path(JOIN *join,
loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp);
} /* not ft_key */
- if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
+ if (tmp + 0.0001 < best_time - records/(double) TIME_FOR_COMPARE)
{
best_time= tmp + records/(double) TIME_FOR_COMPARE;
best= tmp;
@@ -7797,6 +7801,8 @@ bool error_if_full_join(JOIN *join)
{
if (tab->type == JT_ALL && (!tab->select || !tab->select->quick))
{
+ /* This error should not be ignored. */
+ join->select_lex->no_error= FALSE;
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
return(1);
@@ -9975,10 +9981,10 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
no ON expression and not a semi-join => can be flattened.
*/
TABLE_LIST *right_neighbor= NULL;
- bool fix_name_res= FALSE;
li.rewind();
while ((table= li++))
{
+ bool fix_name_res= FALSE;
nested_join= table->nested_join;
if (table->sj_on_expr && !in_sj)
{
@@ -14298,7 +14304,9 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!end_of_records)
{
copy_fields(&join->tmp_table_param);
- copy_funcs(join->tmp_table_param.items_to_copy);
+ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
+
#ifdef TO_BE_DELETED
if (!table->uniques) // If not unique handling
{
@@ -14406,7 +14414,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
memcpy(table->record[0]+key_part->offset, group->buff, 1);
}
init_tmptable_sum_functions(join->sum_funcs);
- copy_funcs(join->tmp_table_param.items_to_copy);
+ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
if ((error= table->file->ha_write_row(table->record[0])))
{
if (create_internal_tmp_table_from_heap(join->thd, table,
@@ -14447,7 +14456,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
init_tmptable_sum_functions(join->sum_funcs);
copy_fields(&join->tmp_table_param); // Groups are copied twice.
- copy_funcs(join->tmp_table_param.items_to_copy);
+ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
if (!(error= table->file->ha_write_row(table->record[0])))
join->send_records++; // New group
@@ -14536,7 +14546,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (idx < (int) join->send_group_parts)
{
copy_fields(&join->tmp_table_param);
- copy_funcs(join->tmp_table_param.items_to_copy);
+ if (copy_funcs(join->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]))
DBUG_RETURN(NESTED_LOOP_ERROR);
if (join->procedure)
@@ -15015,9 +15026,20 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
}
+/**
+ Find shortest key suitable for full table scan.
+
+ @param table Table to scan
+ @param usable_keys Allowed keys
+
+ @return
+ MAX_KEY no suitable key found
+ key index otherwise
+*/
+
uint find_shortest_key(TABLE *table, const key_map *usable_keys)
{
- uint min_length= (uint) ~0;
+ double min_cost= DBL_MAX;
uint best= MAX_KEY;
if (!usable_keys->is_clear_all())
{
@@ -15025,9 +15047,10 @@ uint find_shortest_key(TABLE *table, const key_map *usable_keys)
{
if (usable_keys->is_set(nr))
{
- if (table->key_info[nr].key_length < min_length)
+ double cost= table->file->keyread_time(nr, 1, table->file->records());
+ if (cost < min_cost)
{
- min_length=table->key_info[nr].key_length;
+ min_cost= cost;
best=nr;
}
}
@@ -17627,14 +17650,39 @@ update_sum_func(Item_sum **func_ptr)
return 0;
}
-/** Copy result of functions to record in tmp_table. */
+/**
+ Copy result of functions to record in tmp_table.
-void
-copy_funcs(Item **func_ptr)
+ Uses the thread pointer to check for errors in
+ some of the val_xxx() methods called by the
+ save_in_result_field() function.
+ TODO: make the Item::val_xxx() return error code
+
+ @param func_ptr array of the function Items to copy to the tmp table
+ @param thd pointer to the current thread for error checking
+ @retval
+ FALSE if OK
+ @retval
+ TRUE on error
+*/
+
+bool
+copy_funcs(Item **func_ptr, const THD *thd)
{
Item *func;
for (; (func = *func_ptr) ; func_ptr++)
+ {
func->save_in_result_field(1);
+ /*
+ Need to check the THD error state because Item::val_xxx() don't
+ return error code, but can generate errors
+ TODO: change it for a real status check when Item::val_xxx()
+ are extended to return status code.
+ */
+ if (thd->is_error())
+ return TRUE;
+ }
+ return FALSE;
}