Commit 6378c95e authored by Monty's avatar Monty

Fix that end_bulk_insert() doesn't write to to-be-deleted files

This affected mainly MyISAM and Aria engines.
Also fixed that end_bulk_insert() detects errors from
internal mi_end_bulk_insert() and ma_end_bulk_insert()

- delete_tree() and delete_tree_element() now has an
  extra argument that marks if future calls to
  tree->free should be ignored.
- tree->free changed to function returning int, to be
  able to signal errors.
- Restored deleting flag in MyISAM that was accidently
  disabled in mi_extra(PREPARE_FOR_DROP)
parent 314350a7
...@@ -392,7 +392,7 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows, ulonglong key_map, ...@@ -392,7 +392,7 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows, ulonglong key_map,
int maria_init_bulk_insert(MARIA_HA *info, size_t cache_size, ha_rows rows); int maria_init_bulk_insert(MARIA_HA *info, size_t cache_size, ha_rows rows);
void maria_flush_bulk_insert(MARIA_HA *info, uint inx); void maria_flush_bulk_insert(MARIA_HA *info, uint inx);
void maria_end_bulk_insert(MARIA_HA *info); int maria_end_bulk_insert(MARIA_HA *info, my_bool abort);
int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves); int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves);
void maria_versioning(MARIA_HA *info, my_bool versioning); void maria_versioning(MARIA_HA *info, my_bool versioning);
void maria_ignore_trids(MARIA_HA *info); void maria_ignore_trids(MARIA_HA *info);
......
...@@ -48,7 +48,7 @@ typedef uint32 element_count; ...@@ -48,7 +48,7 @@ typedef uint32 element_count;
typedef int (*tree_walk_action)(void *,element_count,void *); typedef int (*tree_walk_action)(void *,element_count,void *);
typedef enum { free_init, free_free, free_end } TREE_FREE; typedef enum { free_init, free_free, free_end } TREE_FREE;
typedef void (*tree_element_free)(void*, TREE_FREE, void *); typedef int (*tree_element_free)(void*, TREE_FREE, void *);
typedef struct st_tree_element { typedef struct st_tree_element {
struct st_tree_element *left,*right; struct st_tree_element *left,*right;
...@@ -77,8 +77,8 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, ...@@ -77,8 +77,8 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit,
int size, qsort_cmp2 compare, int size, qsort_cmp2 compare,
tree_element_free free_element, void *custom_arg, tree_element_free free_element, void *custom_arg,
myf my_flags); myf my_flags);
void delete_tree(TREE*); int delete_tree(TREE*, my_bool abort);
void reset_tree(TREE*); int reset_tree(TREE*);
/* similar to delete tree, except we do not my_free() blocks in mem_root */ /* similar to delete tree, except we do not my_free() blocks in mem_root */
#define is_tree_inited(tree) ((tree)->root != 0) #define is_tree_inited(tree) ((tree)->root != 0)
......
...@@ -418,7 +418,7 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map, ...@@ -418,7 +418,7 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map,
int mi_init_bulk_insert(MI_INFO *info, size_t cache_size, ha_rows rows); int mi_init_bulk_insert(MI_INFO *info, size_t cache_size, ha_rows rows);
void mi_flush_bulk_insert(MI_INFO *info, uint inx); void mi_flush_bulk_insert(MI_INFO *info, uint inx);
void mi_end_bulk_insert(MI_INFO *info); int mi_end_bulk_insert(MI_INFO *info, my_bool abort);
int mi_assign_to_key_cache(MI_INFO *info, ulonglong key_map, int mi_assign_to_key_cache(MI_INFO *info, ulonglong key_map,
KEY_CACHE *key_cache); KEY_CACHE *key_cache);
void mi_change_key_cache(KEY_CACHE *old_key_cache, void mi_change_key_cache(KEY_CACHE *old_key_cache,
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
#define DEFAULT_ALLOC_SIZE 8192 #define DEFAULT_ALLOC_SIZE 8192
#define DEFAULT_ALIGN_SIZE 8192 #define DEFAULT_ALIGN_SIZE 8192
static void delete_tree_element(TREE *,TREE_ELEMENT *); static int delete_tree_element(TREE *,TREE_ELEMENT *, my_bool abort);
static int tree_walk_left_root_right(TREE *,TREE_ELEMENT *, static int tree_walk_left_root_right(TREE *,TREE_ELEMENT *,
tree_walk_action,void *); tree_walk_action,void *);
static int tree_walk_right_root_left(TREE *,TREE_ELEMENT *, static int tree_walk_right_root_left(TREE *,TREE_ELEMENT *,
...@@ -136,22 +136,30 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, ...@@ -136,22 +136,30 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit,
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
static void free_tree(TREE *tree, myf free_flags) static int free_tree(TREE *tree, my_bool abort, myf free_flags)
{ {
int error, first_error= 0;
DBUG_ENTER("free_tree"); DBUG_ENTER("free_tree");
DBUG_PRINT("enter",("tree: 0x%lx", (long) tree)); DBUG_PRINT("enter",("tree: 0x%lx", (long) tree));
if (tree->root) /* If initialized */ if (tree->root) /* If initialized */
{ {
if (tree->with_delete) if (tree->with_delete)
delete_tree_element(tree,tree->root); {
if ((error= delete_tree_element(tree, tree->root, abort)))
{
first_error= first_error ? first_error : error;
abort= 1;
}
}
else else
{ {
if (tree->free) if (tree->free)
{ {
if (tree->memory_limit) if (tree->memory_limit)
(*tree->free)(NULL, free_init, tree->custom_arg); (*tree->free)(NULL, free_init, tree->custom_arg);
delete_tree_element(tree,tree->root); if ((error= delete_tree_element(tree, tree->root, abort)))
first_error= first_error ? first_error : error;
if (tree->memory_limit) if (tree->memory_limit)
(*tree->free)(NULL, free_end, tree->custom_arg); (*tree->free)(NULL, free_end, tree->custom_arg);
} }
...@@ -162,32 +170,61 @@ static void free_tree(TREE *tree, myf free_flags) ...@@ -162,32 +170,61 @@ static void free_tree(TREE *tree, myf free_flags)
tree->elements_in_tree=0; tree->elements_in_tree=0;
tree->allocated=0; tree->allocated=0;
DBUG_VOID_RETURN; DBUG_RETURN(first_error);
} }
void delete_tree(TREE* tree)
/**
Delete tree.
@param tree Tree
@param abort 0 if normal, 1 if tree->free should not be called.
@return 0 ok
<> 0 Returns first <> 0 from (tree->free)(*,free_free,*)
@Notes
If one (tree->free)(,free_free,) returns <> 0, no future
tree->free(*,free_free,*) will be called.
Other tree->free operations (free_init, free_end) will be called
*/
int delete_tree(TREE* tree, my_bool abort)
{ {
free_tree(tree, MYF(0)); /* my_free() mem_root if applicable */ return free_tree(tree, abort, MYF(0)); /* my_free() mem_root if applicable */
} }
void reset_tree(TREE* tree) int reset_tree(TREE* tree)
{ {
/* do not free mem_root, just mark blocks as free */ /* do not free mem_root, just mark blocks as free */
free_tree(tree, MYF(MY_MARK_BLOCKS_FREE)); return free_tree(tree, 0, MYF(MY_MARK_BLOCKS_FREE));
} }
static void delete_tree_element(TREE *tree, TREE_ELEMENT *element) static int delete_tree_element(TREE *tree, TREE_ELEMENT *element,
my_bool abort)
{ {
int error, first_error= 0;
if (element != &tree->null_element) if (element != &tree->null_element)
{ {
delete_tree_element(tree,element->left); if ((first_error= delete_tree_element(tree, element->left, abort)))
if (tree->free) abort= 1;
(*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg); if (!abort && tree->free)
delete_tree_element(tree,element->right); {
if ((error= (*tree->free)(ELEMENT_KEY(tree,element), free_free,
tree->custom_arg)))
{
first_error= first_error ? first_error : error;
abort= 1;
}
}
if ((error= delete_tree_element(tree, element->right, abort)))
first_error= first_error ? first_error : error;
if (tree->with_delete) if (tree->with_delete)
my_free(element); my_free(element);
} }
return first_error;
} }
......
...@@ -3290,7 +3290,7 @@ void Item_func_group_concat::cleanup() ...@@ -3290,7 +3290,7 @@ void Item_func_group_concat::cleanup()
table= 0; table= 0;
if (tree) if (tree)
{ {
delete_tree(tree); delete_tree(tree, 0);
tree= 0; tree= 0;
} }
if (unique_filter) if (unique_filter)
......
...@@ -298,9 +298,10 @@ bool get_ev_num_info(EV_NUM_INFO *ev_info, NUM_INFO *info, const char *num) ...@@ -298,9 +298,10 @@ bool get_ev_num_info(EV_NUM_INFO *ev_info, NUM_INFO *info, const char *num)
} // get_ev_num_info } // get_ev_num_info
void free_string(String *s) int free_string(String *s)
{ {
s->free(); s->free();
return 0;
} }
...@@ -374,7 +375,7 @@ void field_str::add() ...@@ -374,7 +375,7 @@ void field_str::add()
if (!tree_insert(&tree, (void*) &s, 0, tree.custom_arg)) if (!tree_insert(&tree, (void*) &s, 0, tree.custom_arg))
{ {
room_in_tree = 0; // Remove tree, out of RAM ? room_in_tree = 0; // Remove tree, out of RAM ?
delete_tree(&tree); delete_tree(&tree, 0);
} }
else else
{ {
...@@ -382,7 +383,7 @@ void field_str::add() ...@@ -382,7 +383,7 @@ void field_str::add()
if ((treemem += length) > pc->max_treemem) if ((treemem += length) > pc->max_treemem)
{ {
room_in_tree = 0; // Remove tree, too big tree room_in_tree = 0; // Remove tree, too big tree
delete_tree(&tree); delete_tree(&tree, 0);
} }
} }
} }
...@@ -441,7 +442,7 @@ void field_real::add() ...@@ -441,7 +442,7 @@ void field_real::add()
if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg))) if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg)))
{ {
room_in_tree = 0; // Remove tree, out of RAM ? room_in_tree = 0; // Remove tree, out of RAM ?
delete_tree(&tree); delete_tree(&tree, 0);
} }
/* /*
if element->count == 1, this element can be found only once from tree if element->count == 1, this element can be found only once from tree
...@@ -450,7 +451,7 @@ void field_real::add() ...@@ -450,7 +451,7 @@ void field_real::add()
else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements) else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements)
{ {
room_in_tree = 0; // Remove tree, too many elements room_in_tree = 0; // Remove tree, too many elements
delete_tree(&tree); delete_tree(&tree, 0);
} }
} }
...@@ -507,7 +508,7 @@ void field_decimal::add() ...@@ -507,7 +508,7 @@ void field_decimal::add()
if (!(element = tree_insert(&tree, (void*)buf, 0, tree.custom_arg))) if (!(element = tree_insert(&tree, (void*)buf, 0, tree.custom_arg)))
{ {
room_in_tree = 0; // Remove tree, out of RAM ? room_in_tree = 0; // Remove tree, out of RAM ?
delete_tree(&tree); delete_tree(&tree, 0);
} }
/* /*
if element->count == 1, this element can be found only once from tree if element->count == 1, this element can be found only once from tree
...@@ -516,7 +517,7 @@ void field_decimal::add() ...@@ -516,7 +517,7 @@ void field_decimal::add()
else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements) else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements)
{ {
room_in_tree = 0; // Remove tree, too many elements room_in_tree = 0; // Remove tree, too many elements
delete_tree(&tree); delete_tree(&tree, 0);
} }
} }
...@@ -574,7 +575,7 @@ void field_longlong::add() ...@@ -574,7 +575,7 @@ void field_longlong::add()
if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg))) if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg)))
{ {
room_in_tree = 0; // Remove tree, out of RAM ? room_in_tree = 0; // Remove tree, out of RAM ?
delete_tree(&tree); delete_tree(&tree, 0);
} }
/* /*
if element->count == 1, this element can be found only once from tree if element->count == 1, this element can be found only once from tree
...@@ -583,7 +584,7 @@ void field_longlong::add() ...@@ -583,7 +584,7 @@ void field_longlong::add()
else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements) else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements)
{ {
room_in_tree = 0; // Remove tree, too many elements room_in_tree = 0; // Remove tree, too many elements
delete_tree(&tree); delete_tree(&tree, 0);
} }
} }
...@@ -630,7 +631,7 @@ void field_ulonglong::add() ...@@ -630,7 +631,7 @@ void field_ulonglong::add()
if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg))) if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg)))
{ {
room_in_tree = 0; // Remove tree, out of RAM ? room_in_tree = 0; // Remove tree, out of RAM ?
delete_tree(&tree); delete_tree(&tree, 0);
} }
/* /*
if element->count == 1, this element can be found only once from tree if element->count == 1, this element can be found only once from tree
...@@ -639,7 +640,7 @@ void field_ulonglong::add() ...@@ -639,7 +640,7 @@ void field_ulonglong::add()
else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements) else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements)
{ {
room_in_tree = 0; // Remove tree, too many elements room_in_tree = 0; // Remove tree, too many elements
delete_tree(&tree); delete_tree(&tree, 0);
} }
} }
......
...@@ -68,7 +68,7 @@ int compare_ulonglong2(void* cmp_arg __attribute__((unused)), ...@@ -68,7 +68,7 @@ int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
int compare_decimal2(int* len, const char *s, const char *t); int compare_decimal2(int* len, const char *s, const char *t);
Procedure *proc_analyse_init(THD *thd, ORDER *param, select_result *result, Procedure *proc_analyse_init(THD *thd, ORDER *param, select_result *result,
List<Item> &field_list); List<Item> &field_list);
void free_string(String*); int free_string(String*);
class analyse; class analyse;
class field_info :public Sql_alloc class field_info :public Sql_alloc
...@@ -86,7 +86,7 @@ class field_info :public Sql_alloc ...@@ -86,7 +86,7 @@ class field_info :public Sql_alloc
nulls(0), min_length(0), max_length(0), room_in_tree(1), nulls(0), min_length(0), max_length(0), room_in_tree(1),
found(0),item(a), pc(b) {}; found(0),item(a), pc(b) {};
virtual ~field_info() { delete_tree(&tree); } virtual ~field_info() { delete_tree(&tree, 0); }
virtual void add() = 0; virtual void add() = 0;
virtual void get_opt_type(String*, ha_rows) = 0; virtual void get_opt_type(String*, ha_rows) = 0;
virtual String *get_min_arg(String *) = 0; virtual String *get_min_arg(String *) = 0;
......
...@@ -364,7 +364,7 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size, ...@@ -364,7 +364,7 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size,
Unique::~Unique() Unique::~Unique()
{ {
close_cached_file(&file); close_cached_file(&file);
delete_tree(&tree); delete_tree(&tree, 0);
delete_dynamic(&file_ptrs); delete_dynamic(&file_ptrs);
} }
...@@ -384,7 +384,7 @@ bool Unique::flush() ...@@ -384,7 +384,7 @@ bool Unique::flush()
(void*) this, left_root_right) || (void*) this, left_root_right) ||
insert_dynamic(&file_ptrs, (uchar*) &file_ptr)) insert_dynamic(&file_ptrs, (uchar*) &file_ptr))
return 1; return 1;
delete_tree(&tree); delete_tree(&tree, 0);
return 0; return 0;
} }
......
...@@ -91,7 +91,7 @@ void hp_clear_keys(HP_SHARE *info) ...@@ -91,7 +91,7 @@ void hp_clear_keys(HP_SHARE *info)
HP_KEYDEF *keyinfo = info->keydef + key; HP_KEYDEF *keyinfo = info->keydef + key;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE) if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{ {
delete_tree(&keyinfo->rb_tree); delete_tree(&keyinfo->rb_tree, 0);
} }
else else
{ {
......
...@@ -2207,14 +2207,23 @@ void ha_maria::start_bulk_insert(ha_rows rows, uint flags) ...@@ -2207,14 +2207,23 @@ void ha_maria::start_bulk_insert(ha_rows rows, uint flags)
int ha_maria::end_bulk_insert() int ha_maria::end_bulk_insert()
{ {
int err; int first_error, error;
my_bool abort= file->s->deleting;
DBUG_ENTER("ha_maria::end_bulk_insert"); DBUG_ENTER("ha_maria::end_bulk_insert");
maria_end_bulk_insert(file);
if ((err= maria_extra(file, HA_EXTRA_NO_CACHE, 0))) if ((first_error= maria_end_bulk_insert(file, abort)))
goto end; abort= 1;
if (can_enable_indexes && !file->s->deleting)
err= enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); if ((error= maria_extra(file, HA_EXTRA_NO_CACHE, 0)))
end: {
first_error= first_error ? first_error : error;
abort= 1;
}
if (!abort && can_enable_indexes)
if ((error= enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE)))
first_error= first_error ? first_error : error;
if (bulk_insert_single_undo != BULK_INSERT_NONE) if (bulk_insert_single_undo != BULK_INSERT_NONE)
{ {
DBUG_ASSERT(can_enable_indexes); DBUG_ASSERT(can_enable_indexes);
...@@ -2222,12 +2231,12 @@ int ha_maria::end_bulk_insert() ...@@ -2222,12 +2231,12 @@ int ha_maria::end_bulk_insert()
Table was transactional just before start_bulk_insert(). Table was transactional just before start_bulk_insert().
No need to flush pages if we did a repair (which already flushed). No need to flush pages if we did a repair (which already flushed).
*/ */
err|= if ((error= _ma_reenable_logging_for_table(file,
_ma_reenable_logging_for_table(file, bulk_insert_single_undo ==
bulk_insert_single_undo == BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR)))
BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR); first_error= first_error ? first_error : error;
} }
DBUG_RETURN(err); DBUG_RETURN(first_error);
} }
......
...@@ -1036,7 +1036,7 @@ void maria_ft_boolean_close_search(FT_INFO *ftb) ...@@ -1036,7 +1036,7 @@ void maria_ft_boolean_close_search(FT_INFO *ftb)
{ {
if (is_tree_inited(& ftb->no_dupes)) if (is_tree_inited(& ftb->no_dupes))
{ {
delete_tree(& ftb->no_dupes); delete_tree(&ftb->no_dupes, 0);
} }
free_root(& ftb->mem_root, MYF(0)); free_root(& ftb->mem_root, MYF(0));
my_free(ftb); my_free(ftb);
......
...@@ -320,8 +320,8 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, uchar *query, ...@@ -320,8 +320,8 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, uchar *query,
(qsort2_cmp)&FT_DOC_cmp, 0); (qsort2_cmp)&FT_DOC_cmp, 0);
err: err:
delete_tree(&aio.dtree); delete_tree(&aio.dtree, 0);
delete_tree(&wtree); delete_tree(&wtree, 0);
info->cur_row.lastpos= saved_lastpos; info->cur_row.lastpos= saved_lastpos;
DBUG_RETURN(dlist); DBUG_RETURN(dlist);
} }
......
...@@ -61,7 +61,7 @@ FT_WORD * maria_ft_linearize(TREE *wtree, MEM_ROOT *mem_root) ...@@ -61,7 +61,7 @@ FT_WORD * maria_ft_linearize(TREE *wtree, MEM_ROOT *mem_root)
docstat.sum=0; docstat.sum=0;
tree_walk(wtree,(tree_walk_action)&walk_and_copy,&docstat,left_root_right); tree_walk(wtree,(tree_walk_action)&walk_and_copy,&docstat,left_root_right);
} }
delete_tree(wtree); delete_tree(wtree, 0);
if (!wlist) if (!wlist)
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
...@@ -283,7 +283,7 @@ static int maria_ft_add_word(MYSQL_FTPARSER_PARAM *param, ...@@ -283,7 +283,7 @@ static int maria_ft_add_word(MYSQL_FTPARSER_PARAM *param,
w.len= word_len; w.len= word_len;
if (!tree_insert(wtree, &w, 0, wtree->custom_arg)) if (!tree_insert(wtree, &w, 0, wtree->custom_arg))
{ {
delete_tree(wtree); delete_tree(wtree, 0);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
......
...@@ -1786,8 +1786,10 @@ void maria_flush_bulk_insert(MARIA_HA *info, uint inx) ...@@ -1786,8 +1786,10 @@ void maria_flush_bulk_insert(MARIA_HA *info, uint inx)
} }
} }
void maria_end_bulk_insert(MARIA_HA *info)
int maria_end_bulk_insert(MARIA_HA *info, my_bool abort)
{ {
int first_error= 0;
DBUG_ENTER("maria_end_bulk_insert"); DBUG_ENTER("maria_end_bulk_insert");
if (info->bulk_insert) if (info->bulk_insert)
{ {
...@@ -1796,15 +1798,20 @@ void maria_end_bulk_insert(MARIA_HA *info) ...@@ -1796,15 +1798,20 @@ void maria_end_bulk_insert(MARIA_HA *info)
{ {
if (is_tree_inited(&info->bulk_insert[i])) if (is_tree_inited(&info->bulk_insert[i]))
{ {
int error;
if (info->s->deleting) if (info->s->deleting)
reset_free_element(&info->bulk_insert[i]); reset_free_element(&info->bulk_insert[i]);
delete_tree(&info->bulk_insert[i]); if ((error= delete_tree(&info->bulk_insert[i], abort)))
{
first_error= first_error ? first_error : error;
abort= 1;
}
} }
} }
my_free(info->bulk_insert); my_free(info->bulk_insert);
info->bulk_insert= 0; info->bulk_insert= 0;
} }
DBUG_VOID_RETURN; DBUG_RETURN(first_error);
} }
......
...@@ -836,7 +836,7 @@ static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, uint trees, ...@@ -836,7 +836,7 @@ static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, uint trees,
if (huff_counts[i].tree_buff) if (huff_counts[i].tree_buff)
{ {
my_free(huff_counts[i].tree_buff); my_free(huff_counts[i].tree_buff);
delete_tree(&huff_counts[i].int_tree); delete_tree(&huff_counts[i].int_tree, 0);
} }
} }
my_free(huff_counts); my_free(huff_counts);
...@@ -934,7 +934,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts) ...@@ -934,7 +934,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
(count->field_length == 1 && (count->field_length == 1 &&
count->int_tree.elements_in_tree > 1)) count->int_tree.elements_in_tree > 1))
{ {
delete_tree(&count->int_tree); delete_tree(&count->int_tree, 0);
my_free(count->tree_buff); my_free(count->tree_buff);
count->tree_buff=0; count->tree_buff=0;
} }
...@@ -1333,7 +1333,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, ...@@ -1333,7 +1333,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
else else
{ {
my_free(huff_counts->tree_buff); my_free(huff_counts->tree_buff);
delete_tree(&huff_counts->int_tree); delete_tree(&huff_counts->int_tree, 0);
huff_counts->tree_buff=0; huff_counts->tree_buff=0;
} }
if (tree.element_buffer) if (tree.element_buffer)
...@@ -3156,7 +3156,7 @@ static void fakebigcodes(HUFF_COUNTS *huff_counts, HUFF_COUNTS *end_count) ...@@ -3156,7 +3156,7 @@ static void fakebigcodes(HUFF_COUNTS *huff_counts, HUFF_COUNTS *end_count)
if (huff_counts->tree_buff) if (huff_counts->tree_buff)
{ {
my_free(huff_counts->tree_buff); my_free(huff_counts->tree_buff);
delete_tree(&huff_counts->int_tree); delete_tree(&huff_counts->int_tree, 0);
huff_counts->tree_buff= NULL; huff_counts->tree_buff= NULL;
DBUG_PRINT("fakebigcodes", ("freed distinct column values")); DBUG_PRINT("fakebigcodes", ("freed distinct column values"));
} }
......
...@@ -1039,7 +1039,7 @@ void ft_boolean_close_search(FT_INFO *ftb) ...@@ -1039,7 +1039,7 @@ void ft_boolean_close_search(FT_INFO *ftb)
{ {
if (is_tree_inited(& ftb->no_dupes)) if (is_tree_inited(& ftb->no_dupes))
{ {
delete_tree(& ftb->no_dupes); delete_tree(&ftb->no_dupes, 0);
} }
free_root(& ftb->mem_root, MYF(0)); free_root(& ftb->mem_root, MYF(0));
my_free(ftb); my_free(ftb);
......
...@@ -316,8 +316,8 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, uchar *query, ...@@ -316,8 +316,8 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, uchar *query,
0); 0);
err: err:
delete_tree(&aio.dtree); delete_tree(&aio.dtree, 0);
delete_tree(&wtree); delete_tree(&wtree, 0);
info->lastpos=saved_lastpos; info->lastpos=saved_lastpos;
DBUG_RETURN(dlist); DBUG_RETURN(dlist);
} }
......
...@@ -59,7 +59,7 @@ FT_WORD * ft_linearize(TREE *wtree, MEM_ROOT *mem_root) ...@@ -59,7 +59,7 @@ FT_WORD * ft_linearize(TREE *wtree, MEM_ROOT *mem_root)
docstat.sum=0; docstat.sum=0;
tree_walk(wtree,(tree_walk_action)&walk_and_copy,&docstat,left_root_right); tree_walk(wtree,(tree_walk_action)&walk_and_copy,&docstat,left_root_right);
} }
delete_tree(wtree); delete_tree(wtree, 0);
if (!wlist) if (!wlist)
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
...@@ -277,7 +277,7 @@ static int ft_add_word(MYSQL_FTPARSER_PARAM *param, ...@@ -277,7 +277,7 @@ static int ft_add_word(MYSQL_FTPARSER_PARAM *param,
w.len= word_len; w.len= word_len;
if (!tree_insert(wtree, &w, 0, wtree->custom_arg)) if (!tree_insert(wtree, &w, 0, wtree->custom_arg))
{ {
delete_tree(wtree); delete_tree(wtree, 0);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
......
...@@ -38,11 +38,12 @@ static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)), ...@@ -38,11 +38,12 @@ static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)),
(uchar *)w2->pos,w2->len,0); (uchar *)w2->pos,w2->len,0);
} }
static void FT_STOPWORD_free(FT_STOPWORD *w, TREE_FREE action, static int FT_STOPWORD_free(FT_STOPWORD *w, TREE_FREE action,
void *arg __attribute__((unused))) void *arg __attribute__((unused)))
{ {
if (action == free_free) if (action == free_free)
my_free((void*)w->pos); my_free((void*)w->pos);
return 0;
} }
static int ft_add_stopword(const char *w) static int ft_add_stopword(const char *w)
...@@ -134,7 +135,7 @@ void ft_free_stopwords() ...@@ -134,7 +135,7 @@ void ft_free_stopwords()
if (stopwords3) if (stopwords3)
{ {
delete_tree(stopwords3); /* purecov: inspected */ delete_tree(stopwords3, 0); /* purecov: inspected */
my_free(stopwords3); my_free(stopwords3);
stopwords3=0; stopwords3=0;
} }
......
...@@ -1689,8 +1689,9 @@ void ha_myisam::start_bulk_insert(ha_rows rows, uint flags) ...@@ -1689,8 +1689,9 @@ void ha_myisam::start_bulk_insert(ha_rows rows, uint flags)
which have been activated by start_bulk_insert(). which have been activated by start_bulk_insert().
SYNOPSIS SYNOPSIS
end_bulk_insert() end_bulk_insert(fatal_error)
no arguments abort 0 normal end, store everything
1 abort quickly. No need to flush/write anything. Table will be deleted
RETURN RETURN
0 OK 0 OK
...@@ -1699,10 +1700,20 @@ void ha_myisam::start_bulk_insert(ha_rows rows, uint flags) ...@@ -1699,10 +1700,20 @@ void ha_myisam::start_bulk_insert(ha_rows rows, uint flags)
int ha_myisam::end_bulk_insert() int ha_myisam::end_bulk_insert()
{ {
int first_error, error;
my_bool abort= file->s->deleting;
DBUG_ENTER("ha_myisam::end_bulk_insert"); DBUG_ENTER("ha_myisam::end_bulk_insert");
mi_end_bulk_insert(file);
int err=mi_extra(file, HA_EXTRA_NO_CACHE, 0); if ((first_error= mi_end_bulk_insert(file, abort)))
if (!err && !file->s->deleting) abort= 1;
if ((error= mi_extra(file, HA_EXTRA_NO_CACHE, 0)))
{
first_error= first_error ? first_error : error;
abort= 1;
}
if (!abort)
{ {
if (can_enable_indexes) if (can_enable_indexes)
{ {
...@@ -1713,16 +1724,17 @@ int ha_myisam::end_bulk_insert() ...@@ -1713,16 +1724,17 @@ int ha_myisam::end_bulk_insert()
setting the indexes as active and trying to recreate them. setting the indexes as active and trying to recreate them.
*/ */
if (((err= enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE)) != 0) && if (((first_error= enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE)) != 0) &&
table->in_use->killed) table->in_use->killed)
{ {
delete_all_rows(); delete_all_rows();
/* not crashed, despite being killed during repair */ /* not crashed, despite being killed during repair */
file->s->state.changed&= ~(STATE_CRASHED|STATE_CRASHED_ON_REPAIR); file->s->state.changed&= ~(STATE_CRASHED|STATE_CRASHED_ON_REPAIR);
} }
} }
} }
DBUG_RETURN(err); DBUG_PRINT("exit", ("first_error: %d", first_error));
DBUG_RETURN(first_error);
} }
......
...@@ -259,7 +259,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) ...@@ -259,7 +259,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
break; break;
case HA_EXTRA_PREPARE_FOR_DROP: case HA_EXTRA_PREPARE_FOR_DROP:
/* Signals about intent to delete this table */ /* Signals about intent to delete this table */
//share->deleting= TRUE; share->deleting= TRUE;
share->global_changed= FALSE; /* force writing changed flag */ share->global_changed= FALSE; /* force writing changed flag */
_mi_mark_file_changed(info); _mi_mark_file_changed(info);
/* Fall trough */ /* Fall trough */
......
...@@ -1033,8 +1033,9 @@ void mi_flush_bulk_insert(MI_INFO *info, uint inx) ...@@ -1033,8 +1033,9 @@ void mi_flush_bulk_insert(MI_INFO *info, uint inx)
} }
} }
void mi_end_bulk_insert(MI_INFO *info) int mi_end_bulk_insert(MI_INFO *info, my_bool abort)
{ {
int first_error= 0;
if (info->bulk_insert) if (info->bulk_insert)
{ {
uint i; uint i;
...@@ -1042,10 +1043,16 @@ void mi_end_bulk_insert(MI_INFO *info) ...@@ -1042,10 +1043,16 @@ void mi_end_bulk_insert(MI_INFO *info)
{ {
if (is_tree_inited(& info->bulk_insert[i])) if (is_tree_inited(& info->bulk_insert[i]))
{ {
delete_tree(& info->bulk_insert[i]); int error;
if ((error= delete_tree(& info->bulk_insert[i], abort)))
{
first_error= first_error ? first_error : error;
abort= 1;
}
} }
} }
my_free(info->bulk_insert); my_free(info->bulk_insert);
info->bulk_insert=0; info->bulk_insert=0;
} }
return first_error;
} }
...@@ -649,7 +649,7 @@ static int examine_log(char * file_name, char **table_names) ...@@ -649,7 +649,7 @@ static int examine_log(char * file_name, char **table_names)
} }
} }
end_key_cache(dflt_key_cache,1); end_key_cache(dflt_key_cache,1);
delete_tree(&tree); delete_tree(&tree, 0);
(void) end_io_cache(&cache); (void) end_io_cache(&cache);
(void) my_close(file,MYF(0)); (void) my_close(file,MYF(0));
if (write_file && my_fclose(write_file,MYF(MY_WME))) if (write_file && my_fclose(write_file,MYF(MY_WME)))
...@@ -669,7 +669,7 @@ static int examine_log(char * file_name, char **table_names) ...@@ -669,7 +669,7 @@ static int examine_log(char * file_name, char **table_names)
fflush(stderr); fflush(stderr);
end: end:
end_key_cache(dflt_key_cache, 1); end_key_cache(dflt_key_cache, 1);
delete_tree(&tree); delete_tree(&tree, 0);
(void) end_io_cache(&cache); (void) end_io_cache(&cache);
(void) my_close(file,MYF(0)); (void) my_close(file,MYF(0));
if (write_file) if (write_file)
......
...@@ -861,7 +861,7 @@ static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, uint trees, ...@@ -861,7 +861,7 @@ static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, uint trees,
if (huff_counts[i].tree_buff) if (huff_counts[i].tree_buff)
{ {
my_free(huff_counts[i].tree_buff); my_free(huff_counts[i].tree_buff);
delete_tree(&huff_counts[i].int_tree); delete_tree(&huff_counts[i].int_tree, 0);
} }
} }
my_free(huff_counts); my_free(huff_counts);
...@@ -967,7 +967,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts) ...@@ -967,7 +967,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
(count->field_length == 1 && (count->field_length == 1 &&
count->int_tree.elements_in_tree > 1)) count->int_tree.elements_in_tree > 1))
{ {
delete_tree(&count->int_tree); delete_tree(&count->int_tree, 0);
my_free(count->tree_buff); my_free(count->tree_buff);
count->tree_buff=0; count->tree_buff=0;
} }
...@@ -1366,7 +1366,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, ...@@ -1366,7 +1366,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
else else
{ {
my_free(huff_counts->tree_buff); my_free(huff_counts->tree_buff);
delete_tree(&huff_counts->int_tree); delete_tree(&huff_counts->int_tree, 0);
huff_counts->tree_buff=0; huff_counts->tree_buff=0;
} }
if (tree.element_buffer) if (tree.element_buffer)
...@@ -3166,7 +3166,7 @@ static void fakebigcodes(HUFF_COUNTS *huff_counts, HUFF_COUNTS *end_count) ...@@ -3166,7 +3166,7 @@ static void fakebigcodes(HUFF_COUNTS *huff_counts, HUFF_COUNTS *end_count)
if (huff_counts->tree_buff) if (huff_counts->tree_buff)
{ {
my_free(huff_counts->tree_buff); my_free(huff_counts->tree_buff);
delete_tree(&huff_counts->int_tree); delete_tree(&huff_counts->int_tree, 0);
huff_counts->tree_buff= NULL; huff_counts->tree_buff= NULL;
DBUG_PRINT("fakebigcodes", ("freed distinct column values")); DBUG_PRINT("fakebigcodes", ("freed distinct column values"));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment