mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Fix for bug#22338 "Valgrind warning: uninitialized variable in
create_tmp_table()".
The fix for bug 21787 "COUNT(*) + ORDER BY + LIMIT returns wrong
result" introduced valgrind warnings which occured during execution
of information_schema.test and sp-prelocking.test in version 5.0.
There were no user visible effects.
The latter fix made create_tmp_table() dependant on
THD::lex::current_select value. Valgrind warnings occured when this
function was executed and THD::lex::current_select member pointed
to uninitialized SELECT_LEX instance.
This fix tries to remove this dependancy by moving some logic
outside of create_tmp_table() function.
sql/sql_select.cc:
create_tmp_table():
Moved code which is responsible for determining if optimization
which pushes down LIMIT clause to temporary table creation is
applicable out of this function.
Such move made this function independant of THD::lex::current_select
value and removed valgrind warnings which occured in cases when this
member pointed to uninitialized SELECT_LEX object (particularly these
warnings occured in sp-prelocking.test and information_schema.test
in 5.0). This seems like a better solution than trying to force this
pointer always to point to relevant select because:
- In some cases when we use create_tmp_table() there are no relevant
SELECT_LEX object (we use it just to create temporary table/object).
- There is only one place in code where we call this funciton and
where this optimization can be enabled. And in this place we
already have some logic which tries to determine if it is applicable.
This commit is contained in:
@@ -932,17 +932,28 @@ JOIN::optimize()
|
||||
|
||||
tmp_table_param.hidden_field_count= (all_fields.elements -
|
||||
fields_list.elements);
|
||||
ORDER *tmp_group= ((!simple_group && !procedure &&
|
||||
!(test_flags & TEST_NO_KEY_GROUP)) ? group_list :
|
||||
(ORDER*) 0);
|
||||
/*
|
||||
Pushing LIMIT to the temporary table creation is not applicable
|
||||
when there is ORDER BY or GROUP BY or there is no GROUP BY, but
|
||||
there are aggregate functions, because in all these cases we need
|
||||
all result rows.
|
||||
*/
|
||||
ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order ||
|
||||
test(select_options & OPTION_BUFFER_RESULT)) &&
|
||||
!tmp_group &&
|
||||
!thd->lex->current_select->with_sum_func) ?
|
||||
select_limit : HA_POS_ERROR;
|
||||
|
||||
if (!(exec_tmp_table1 =
|
||||
create_tmp_table(thd, &tmp_table_param, all_fields,
|
||||
((!simple_group && !procedure &&
|
||||
!(test_flags & TEST_NO_KEY_GROUP)) ?
|
||||
group_list : (ORDER*) 0),
|
||||
tmp_group,
|
||||
group_list ? 0 : select_distinct,
|
||||
group_list && simple_group,
|
||||
select_options,
|
||||
(order == 0 || skip_sort_order ||
|
||||
test(select_options & OPTION_BUFFER_RESULT)) ?
|
||||
select_limit : HA_POS_ERROR,
|
||||
tmp_rows_limit,
|
||||
(char *) "")))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
@@ -5566,6 +5577,13 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||
thd->variables.max_heap_table_size) :
|
||||
thd->variables.tmp_table_size)/ table->reclength);
|
||||
set_if_bigger(table->max_rows,1); // For dummy start options
|
||||
/*
|
||||
Push the LIMIT clause to the temporary table creation, so that we
|
||||
materialize only up to 'rows_limit' records instead of all result records.
|
||||
*/
|
||||
set_if_smaller(table->max_rows, rows_limit);
|
||||
param->end_write_records= rows_limit;
|
||||
|
||||
keyinfo=param->keyinfo;
|
||||
|
||||
if (group)
|
||||
@@ -5686,19 +5704,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Push the LIMIT clause to the temporary table creation, so that we
|
||||
materialize only up to 'rows_limit' records instead of all result records.
|
||||
This optimization is not applicable when there is GROUP BY or there is
|
||||
no GROUP BY, but there are aggregate functions, because both must be
|
||||
computed for all result rows.
|
||||
*/
|
||||
if (!group && !thd->lex->current_select->with_sum_func)
|
||||
{
|
||||
set_if_smaller(table->max_rows, rows_limit);
|
||||
param->end_write_records= rows_limit;
|
||||
}
|
||||
|
||||
if (thd->is_fatal_error) // If end of memory
|
||||
goto err; /* purecov: inspected */
|
||||
table->db_record_offset=1;
|
||||
|
||||
Reference in New Issue
Block a user