mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Removed TABLE->sort to make it possible to have multiple active calls to
filesort and init_read_record() for the same table. This will simplify code for WINDOW FUNCTIONS (MDEV-6115) - Filesort_info renamed to SORT_INFO and moved to filesort.h - filesort now returns SORT_INFO - init_read_record() now takes a SORT_INFO parameter. - unique declaration is moved to uniques.h - subselect caching of buffers is now more explicit than before - filesort_buffer is now reusable even if rec_length has changed. - filsort_free_buffers() and free_io_cache() calls are removed - Remove one malloc() when using get_addon_fields() Other things: - Added --debug-assert-on-not-freed-memory option to make it easier to debug some not-freed-memory issues.
This commit is contained in:
@@ -1435,7 +1435,7 @@ JOIN::optimize_inner()
|
||||
}
|
||||
|
||||
select= make_select(*table, const_table_map,
|
||||
const_table_map, conds, 1, &error);
|
||||
const_table_map, conds, (SORT_INFO*) 0, 1, &error);
|
||||
if (error)
|
||||
{ /* purecov: inspected */
|
||||
error= -1; /* purecov: inspected */
|
||||
@@ -2373,15 +2373,11 @@ JOIN::reinit()
|
||||
{
|
||||
exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE);
|
||||
exec_tmp_table1->file->ha_delete_all_rows();
|
||||
free_io_cache(exec_tmp_table1);
|
||||
filesort_free_buffers(exec_tmp_table1,0);
|
||||
}
|
||||
if (exec_tmp_table2)
|
||||
{
|
||||
exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE);
|
||||
exec_tmp_table2->file->ha_delete_all_rows();
|
||||
free_io_cache(exec_tmp_table2);
|
||||
filesort_free_buffers(exec_tmp_table2,0);
|
||||
}
|
||||
clear_sj_tmp_tables(this);
|
||||
if (items0)
|
||||
@@ -3198,12 +3194,12 @@ void JOIN::exec_inner()
|
||||
DBUG_VOID_RETURN;
|
||||
sortorder= curr_join->sortorder;
|
||||
if (curr_join->const_tables != curr_join->table_count &&
|
||||
!curr_join->join_tab[curr_join->const_tables].table->sort.io_cache)
|
||||
!curr_join->join_tab[curr_join->const_tables].filesort)
|
||||
{
|
||||
/*
|
||||
If no IO cache exists for the first table then we are using an
|
||||
INDEX SCAN and no filesort. Thus we should not remove the sorted
|
||||
attribute on the INDEX SCAN.
|
||||
If no filesort for the first table then we are using an
|
||||
INDEX SCAN. Thus we should not remove the sorted attribute
|
||||
on the INDEX SCAN.
|
||||
*/
|
||||
skip_sort_order= 1;
|
||||
}
|
||||
@@ -4100,6 +4096,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
select= make_select(s->table, found_const_table_map,
|
||||
found_const_table_map,
|
||||
*s->on_expr_ref ? *s->on_expr_ref : join->conds,
|
||||
(SORT_INFO*) 0,
|
||||
1, &error);
|
||||
if (!select)
|
||||
goto error;
|
||||
@@ -9048,13 +9045,21 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
|
||||
/*
|
||||
Reuse TABLE * and JOIN_TAB if already allocated by a previous call
|
||||
to this function through JOIN::exec (may happen for sub-queries).
|
||||
*/
|
||||
if (!parent->join_tab_reexec &&
|
||||
!(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
|
||||
// psergey-todo: here, save the pointer for original join_tabs.
|
||||
join_tab= parent->join_tab_reexec;
|
||||
psergey-todo: here, save the pointer for original join_tabs.
|
||||
*/
|
||||
if (!(join_tab= parent->join_tab_reexec))
|
||||
{
|
||||
if (!(join_tab= parent->join_tab_reexec=
|
||||
(JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Free memory used by previous allocations */
|
||||
delete join_tab->filesort;
|
||||
}
|
||||
|
||||
table= &parent->table_reexec[0]; parent->table_reexec[0]= temp_table;
|
||||
table_count= top_join_tab_count= 1;
|
||||
|
||||
@@ -11417,13 +11422,16 @@ bool error_if_full_join(JOIN *join)
|
||||
void JOIN_TAB::cleanup()
|
||||
{
|
||||
DBUG_ENTER("JOIN_TAB::cleanup");
|
||||
DBUG_PRINT("enter", ("table %s.%s",
|
||||
DBUG_PRINT("enter", ("tab: %p table %s.%s",
|
||||
this,
|
||||
(table ? table->s->db.str : "?"),
|
||||
(table ? table->s->table_name.str : "?")));
|
||||
delete select;
|
||||
select= 0;
|
||||
delete quick;
|
||||
quick= 0;
|
||||
delete filesort;
|
||||
filesort= 0;
|
||||
if (cache)
|
||||
{
|
||||
cache->free();
|
||||
@@ -11822,8 +11830,8 @@ void JOIN::cleanup(bool full)
|
||||
JOIN_TAB *first_tab= first_top_level_tab(this, WITHOUT_CONST_TABLES);
|
||||
if (first_tab->table)
|
||||
{
|
||||
free_io_cache(first_tab->table);
|
||||
filesort_free_buffers(first_tab->table, full);
|
||||
delete first_tab->filesort;
|
||||
first_tab->filesort= 0;
|
||||
}
|
||||
}
|
||||
if (full)
|
||||
@@ -17598,7 +17606,6 @@ free_tmp_table(THD *thd, TABLE *entry)
|
||||
/* free blobs */
|
||||
for (Field **ptr=entry->field ; *ptr ; ptr++)
|
||||
(*ptr)->free();
|
||||
free_io_cache(entry);
|
||||
|
||||
if (entry->temp_pool_slot != MY_BIT_NONE)
|
||||
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
|
||||
@@ -19061,7 +19068,7 @@ int join_init_read_record(JOIN_TAB *tab)
|
||||
if (!tab->preread_init_done && tab->preread_init())
|
||||
return 1;
|
||||
if (init_read_record(&tab->read_record, tab->join->thd, tab->table,
|
||||
tab->select,1,1, FALSE))
|
||||
tab->select, tab->filesort, 1,1, FALSE))
|
||||
return 1;
|
||||
return (*tab->read_record.read_record)(&tab->read_record);
|
||||
}
|
||||
@@ -19079,7 +19086,7 @@ join_read_record_no_init(JOIN_TAB *tab)
|
||||
save_copy_end= tab->read_record.copy_field_end;
|
||||
|
||||
init_read_record(&tab->read_record, tab->join->thd, tab->table,
|
||||
tab->select,1,1, FALSE);
|
||||
tab->select, tab->filesort, 1, 1, FALSE);
|
||||
|
||||
tab->read_record.copy_field= save_copy;
|
||||
tab->read_record.copy_field_end= save_copy_end;
|
||||
@@ -19324,11 +19331,9 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
TABLE *table=jt->table;
|
||||
|
||||
join->select_options ^= OPTION_FOUND_ROWS;
|
||||
if (table->sort.record_pointers ||
|
||||
(table->sort.io_cache && my_b_inited(table->sort.io_cache)))
|
||||
if (jt->filesort) // If filesort was used
|
||||
{
|
||||
/* Using filesort */
|
||||
join->send_records= table->sort.found_records;
|
||||
join->send_records= jt->filesort->found_rows;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -21058,8 +21063,7 @@ use_filesort:
|
||||
'join' is modified to use this index.
|
||||
- If no index, create with filesort() an index file that can be used to
|
||||
retrieve rows in order (should be done with 'read_record').
|
||||
The sorted data is stored in tab->table and will be freed when calling
|
||||
free_io_cache(tab->table).
|
||||
The sorted data is stored in tab->filesort
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
@@ -21072,15 +21076,12 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
ha_rows filesort_limit, ha_rows select_limit,
|
||||
bool is_order_by)
|
||||
{
|
||||
uint length= 0;
|
||||
ha_rows examined_rows;
|
||||
ha_rows found_rows;
|
||||
ha_rows filesort_retval= HA_POS_ERROR;
|
||||
uint length;
|
||||
TABLE *table;
|
||||
SQL_SELECT *select;
|
||||
JOIN_TAB *tab;
|
||||
int err= 0;
|
||||
bool quick_created= FALSE;
|
||||
SORT_INFO *file_sort= 0;
|
||||
DBUG_ENTER("create_sort_index");
|
||||
|
||||
if (join->table_count == join->const_tables)
|
||||
@@ -21165,15 +21166,19 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
}
|
||||
tab->update_explain_data(join->const_tables);
|
||||
|
||||
/*
|
||||
Calculate length of join->order as this may be longer than 'order',
|
||||
which may come from 'group by'. This is needed as join->sortorder is
|
||||
used both for grouping and ordering.
|
||||
*/
|
||||
length= 0;
|
||||
for (ORDER *ord= join->order; ord; ord= ord->next)
|
||||
length++;
|
||||
if (!(join->sortorder=
|
||||
|
||||
if (!(join->sortorder=
|
||||
make_unireg_sortorder(thd, order, &length, join->sortorder)))
|
||||
goto err; /* purecov: inspected */
|
||||
|
||||
table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_WME | MY_ZEROFILL|
|
||||
MY_THREAD_SPECIFIC));
|
||||
table->status=0; // May be wrong if quick_select
|
||||
|
||||
if (!tab->preread_init_done && tab->preread_init())
|
||||
@@ -21217,12 +21222,18 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
|
||||
if (table->s->tmp_table)
|
||||
table->file->info(HA_STATUS_VARIABLE); // Get record count
|
||||
filesort_retval= filesort(thd, table, join->sortorder, length,
|
||||
select, filesort_limit, 0,
|
||||
&examined_rows, &found_rows,
|
||||
join->explain->ops_tracker.report_sorting(thd));
|
||||
table->sort.found_records= filesort_retval;
|
||||
tab->records= join->select_options & OPTION_FOUND_ROWS ? found_rows : filesort_retval;
|
||||
file_sort= filesort(thd, table, join->sortorder, length,
|
||||
select, filesort_limit, 0,
|
||||
join->explain->ops_tracker.report_sorting(thd));
|
||||
DBUG_ASSERT(tab->filesort == 0);
|
||||
tab->filesort= file_sort;
|
||||
tab->records= 0;
|
||||
if (file_sort)
|
||||
{
|
||||
tab->records= join->select_options & OPTION_FOUND_ROWS ?
|
||||
file_sort->found_rows : file_sort->return_rows;
|
||||
tab->join->join_examined_rows+= file_sort->examined_rows;
|
||||
}
|
||||
|
||||
if (quick_created)
|
||||
{
|
||||
@@ -21245,12 +21256,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
tab->type=JT_ALL; // Read with normal read_record
|
||||
tab->read_first_record= join_init_read_record;
|
||||
tab->table->file->ha_index_or_rnd_end();
|
||||
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
tab->join->join_examined_rows+= examined_rows;
|
||||
DBUG_RETURN(filesort_retval == HA_POS_ERROR);
|
||||
DBUG_RETURN(file_sort == 0);
|
||||
err:
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
@@ -21373,7 +21380,6 @@ remove_duplicates(JOIN *join, TABLE *table, List<Item> &fields, Item *having)
|
||||
if (thd->killed == ABORT_QUERY)
|
||||
thd->reset_killed();
|
||||
|
||||
free_io_cache(table); // Safety
|
||||
table->file->info(HA_STATUS_VARIABLE);
|
||||
if (table->s->db_type() == heap_hton ||
|
||||
(!table->s->blob_fields &&
|
||||
@@ -23136,8 +23142,8 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
|
||||
}
|
||||
join_tab->set_select_cond(cond, __LINE__);
|
||||
}
|
||||
else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
|
||||
&error)))
|
||||
else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond,
|
||||
(SORT_INFO*) 0, 0, &error)))
|
||||
join_tab->set_select_cond(cond, __LINE__);
|
||||
|
||||
DBUG_RETURN(error ? TRUE : FALSE);
|
||||
|
||||
Reference in New Issue
Block a user