1
0
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:
Monty
2016-03-22 21:51:59 +02:00
parent d0a47704c5
commit 260dd476b0
40 changed files with 665 additions and 584 deletions

View File

@@ -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);