diff options
author | Monty <monty@mariadb.org> | 2016-03-22 21:51:59 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2016-03-22 23:44:52 +0200 |
commit | 260dd476b057b759af7973550b560dc2f56e18fd (patch) | |
tree | ef55ede44a6f47171ca9f2a2121f377a6ea15832 /sql/sql_delete.cc | |
parent | d0a47704c5d4360a3076c0e6b8abec186fac1f39 (diff) | |
download | mariadb-git-260dd476b057b759af7973550b560dc2f56e18fd.tar.gz |
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.
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r-- | sql/sql_delete.cc | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index f49a053918b..42e7f6c3569 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -40,6 +40,8 @@ #include "sql_statistics.h" #include "transaction.h" #include "records.h" // init_read_record, +#include "filesort.h" +#include "uniques.h" #include "sql_derived.h" // mysql_handle_list_of_derived // end_read_record #include "sql_partition.h" // make_used_partitions_str @@ -227,10 +229,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, int error, loc_error; TABLE *table; SQL_SELECT *select=0; + SORT_INFO *file_sort= 0; READ_RECORD info; bool using_limit=limit != HA_POS_ERROR; bool transactional_table, safe_update, const_cond; bool const_cond_result; + bool return_error= 0; ha_rows deleted= 0; bool reverse= FALSE; ORDER *order= (ORDER *) ((order_list && order_list->elements) ? @@ -405,7 +409,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, table->covering_keys.clear_all(); table->quick_keys.clear_all(); // Can't use 'only index' - select=make_select(table, 0, 0, conds, 0, &error); + select=make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error); if (error) DBUG_RETURN(TRUE); if ((select && select->check_quick(thd, safe_update, limit)) || !limit) @@ -486,32 +490,21 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (query_plan.using_filesort) { - ha_rows examined_rows; - ha_rows found_rows; uint length= 0; SORT_FIELD *sortorder; { DBUG_ASSERT(query_plan.index == MAX_KEY); - table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL | - MY_THREAD_SPECIFIC)); Filesort_tracker *fs_tracker= thd->lex->explain->get_upd_del_plan()->filesort_tracker; if (!(sortorder= make_unireg_sortorder(thd, order, &length, NULL)) || - (table->sort.found_records= filesort(thd, table, sortorder, length, - select, HA_POS_ERROR, - true, - &examined_rows, &found_rows, - fs_tracker)) - == HA_POS_ERROR) - { - delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); - DBUG_RETURN(TRUE); - } - thd->inc_examined_row_count(examined_rows); + !(file_sort= filesort(thd, table, sortorder, length, + select, HA_POS_ERROR, + true, + fs_tracker))) + goto got_error; + thd->inc_examined_row_count(file_sort->examined_rows); /* Filesort has already found and selected the rows we want to delete, so we don't need the where clause @@ -524,24 +517,16 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, /* If quick select is used, initialize it before retrieving rows. */ if (select && select->quick && select->quick->reset()) - { - delete select; - free_underlaid_joins(thd, select_lex); - DBUG_RETURN(TRUE); - } + goto got_error; if (query_plan.index == MAX_KEY || (select && select->quick)) - error= init_read_record(&info, thd, table, select, 1, 1, FALSE); + error= init_read_record(&info, thd, table, select, file_sort, 1, 1, FALSE); else error= init_read_record_idx(&info, thd, table, 1, query_plan.index, reverse); if (error) - { - delete select; - free_underlaid_joins(thd, select_lex); - DBUG_RETURN(TRUE); - } - + goto got_error; + init_ftfuncs(thd, select_lex, 1); THD_STAGE_INFO(thd, stage_updating); @@ -697,8 +682,6 @@ cleanup: } DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table); - - free_underlaid_joins(thd, select_lex); if (error < 0 || (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error)) { @@ -711,6 +694,8 @@ cleanup: my_ok(thd, deleted); DBUG_PRINT("info",("%ld records deleted",(long) deleted)); } + delete file_sort; + free_underlaid_joins(thd, select_lex); DBUG_RETURN(error >= 0 || thd->is_error()); /* Special exits */ @@ -729,9 +714,16 @@ send_nothing_and_leave: */ delete select; + delete file_sort; free_underlaid_joins(thd, select_lex); //table->set_keyread(false); - DBUG_RETURN((thd->is_error() || thd->killed) ? 1 : 0); + + DBUG_ASSERT(!return_error || thd->is_error() || thd->killed); + DBUG_RETURN((return_error || thd->is_error() || thd->killed) ? 1 : 0); + +got_error: + return_error= 1; + goto send_nothing_and_leave; } @@ -1183,7 +1175,8 @@ int multi_delete::do_deletes() if (tempfiles[counter]->get(table)) DBUG_RETURN(1); - local_error= do_table_deletes(table, thd->lex->ignore); + local_error= do_table_deletes(table, &tempfiles[counter]->sort, + thd->lex->ignore); if (thd->killed && !local_error) DBUG_RETURN(1); @@ -1213,14 +1206,15 @@ int multi_delete::do_deletes() @retval 1 Triggers or handler reported error. @retval -1 End of file from handler. */ -int multi_delete::do_table_deletes(TABLE *table, bool ignore) +int multi_delete::do_table_deletes(TABLE *table, SORT_INFO *sort_info, + bool ignore) { int local_error= 0; READ_RECORD info; ha_rows last_deleted= deleted; DBUG_ENTER("do_deletes_for_table"); - if (init_read_record(&info, thd, table, NULL, 0, 1, FALSE)) + if (init_read_record(&info, thd, table, NULL, sort_info, 0, 1, FALSE)) DBUG_RETURN(1); /* |