From f2ca9c87845655083f186fb0d102699d78c6b22a Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Thu, 10 Feb 2011 22:40:59 +0200 Subject: Applied patch for lp:585688 "maridb crashes in federatedx code" from lp:~atcurtis/maria/federatedx: - Fixed Partition engine to store CONNECTION string for partitions. Removed HA_NO_PARTITION flag from FederatedX. Added test 'federated_partition' to suite. - lp:#585688 - maridb crashes in federatedx code FederatedX handler instances, created on one thread and used on another thread (via table cache) when "show table status" is executed crashed because txn member was not initialized for current thread. Added test 'federated_bug_585688' to suite. Author for the patch is Antony Curtis mysql-test/suite/federated/federated_bug_585688.result: Test for lp:585688 mysql-test/suite/federated/federated_bug_585688.test: Test for lp:585688 mysql-test/suite/federated/federated_partition-slave.opt: Test for partition support in federatedx mysql-test/suite/federated/federated_partition.result: Test for partition support in federatedx mysql-test/suite/federated/federated_partition.test: Test for partition support in federatedx mysql-test/t/partition_federated.test: Updated error message sql/ha_partition.cc: Added support for connection strings to partitions for federatedx sql/ha_partition.h: Added support for connection strings to partitions for federatedx sql/partition_element.h: Added support for connection strings to partitions for federatedx sql/sql_yacc.yy: Added support for connection strings to partitions for federatedx storage/federatedx/ha_federatedx.cc: Added support for partitions. FederatedX handler instances, created on one thread and used on another thread (via table cache) when "show table status" is executed crashed because txn member was not initialized for current thread. --- sql/ha_partition.cc | 74 +++++++++++++++++++++++++++++++++++++++++++------ sql/ha_partition.h | 2 ++ sql/partition_element.h | 1 + sql/sql_yacc.yy | 6 ++++ 4 files changed, 74 insertions(+), 9 deletions(-) (limited to 'sql') diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index a08e0c93865..286cb94c830 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -167,6 +167,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share) m_is_sub_partitioned(0) { DBUG_ENTER("ha_partition::ha_partition(table)"); + init_alloc_root(&m_mem_root, 512, 512); init_handler_variables(); DBUG_VOID_RETURN; } @@ -188,6 +189,7 @@ ha_partition::ha_partition(handlerton *hton, partition_info *part_info) m_is_sub_partitioned(m_part_info->is_sub_partitioned()) { DBUG_ENTER("ha_partition::ha_partition(part_info)"); + init_alloc_root(&m_mem_root, 512, 512); init_handler_variables(); DBUG_ASSERT(m_part_info); DBUG_VOID_RETURN; @@ -212,6 +214,7 @@ void ha_partition::init_handler_variables() m_file_buffer= NULL; m_name_buffer_ptr= NULL; m_engine_array= NULL; + m_connect_string= NULL; m_file= NULL; m_file_tot_parts= 0; m_reorged_file= NULL; @@ -286,9 +289,11 @@ ha_partition::~ha_partition() for (i= 0; i < m_tot_parts; i++) delete m_file[i]; } - my_free((char*) m_ordered_rec_buffer, MYF(MY_ALLOW_ZERO_PTR)); clear_handler_file(); + + free_root(&m_mem_root, MYF(0)); + DBUG_VOID_RETURN; } @@ -555,6 +560,13 @@ int ha_partition::create(const char *name, TABLE *table_arg, char t_name[FN_REFLEN]; DBUG_ENTER("ha_partition::create"); + if (create_info->used_fields & HA_CREATE_USED_CONNECTION) + { + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), + "CONNECTION not valid for partition"); + DBUG_RETURN(1); + } + strmov(t_name, name); DBUG_ASSERT(*fn_rext((char*)name) == '\0'); if (del_ren_cre_table(t_name, NULL, table_arg, create_info)) @@ -1227,6 +1239,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl, if ((error= set_up_table_before_create(tbl, part_name, create_info, 0, p_elem))) goto error_create; + tbl->s->connect_string = p_elem->connect_string; if ((error= file->ha_create(part_name, tbl, create_info))) { /* @@ -1747,6 +1760,8 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info) create_info->auto_increment_value= stats.auto_increment_value; create_info->data_file_name= create_info->index_file_name = NULL; + create_info->connect_string.str= NULL; + create_info->connect_string.length= 0; return; } @@ -2034,6 +2049,10 @@ int ha_partition::set_up_table_before_create(TABLE *tbl, } info->index_file_name= part_elem->index_file_name; info->data_file_name= part_elem->data_file_name; + info->connect_string= part_elem->connect_string; + if (info->connect_string.length) + info->used_fields|= HA_CREATE_USED_CONNECTION; + tbl->s->connect_string= part_elem->connect_string; DBUG_RETURN(0); } @@ -2148,8 +2167,10 @@ bool ha_partition::create_handler_file(const char *name) tot_name_words= (tot_name_len + 3) / 4; tot_len_words= 4 + tot_partition_words + tot_name_words; tot_len_byte= 4 * tot_len_words; - if (!(file_buffer= (uchar *) my_malloc(tot_len_byte, MYF(MY_ZEROFILL)))) + file_buffer= (uchar *) my_alloca(tot_len_byte); + if (!file_buffer) DBUG_RETURN(TRUE); + bzero(file_buffer, tot_len_byte); engine_array= (file_buffer + 12); name_buffer_ptr= (char*) (file_buffer + ((4 + tot_partition_words) * 4)); part_it.rewind(); @@ -2205,11 +2226,23 @@ bool ha_partition::create_handler_file(const char *name) { result= my_write(file, (uchar *) file_buffer, tot_len_byte, MYF(MY_WME | MY_NABP)) != 0; + + part_it.rewind(); + for (i= 0; i < no_parts; i++) + { + uchar buffer[4]; + part_elem= part_it++; + uint length = part_elem->connect_string.length; + int4store(buffer, length); + my_write(file, buffer, 4, MYF(MY_WME | MY_NABP)); + my_write(file, (uchar *) part_elem->connect_string.str, length, + MYF(MY_WME | MY_NABP)); + } VOID(my_close(file, MYF(0))); } else result= TRUE; - my_free((char*) file_buffer, MYF(0)); + my_afree((char*) file_buffer); DBUG_RETURN(result); } @@ -2227,10 +2260,11 @@ void ha_partition::clear_handler_file() { if (m_engine_array) plugin_unlock_list(NULL, m_engine_array, m_tot_parts); - my_free((char*) m_file_buffer, MYF(MY_ALLOW_ZERO_PTR)); - my_free((char*) m_engine_array, MYF(MY_ALLOW_ZERO_PTR)); + free_root(&m_mem_root, MYF(MY_KEEP_PREALLOC)); m_file_buffer= NULL; m_engine_array= NULL; + m_connect_string= NULL; + m_ordered_rec_buffer= NULL; } /* @@ -2389,7 +2423,7 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root) goto err1; len_words= uint4korr(buff); len_bytes= 4 * len_words; - if (!(file_buffer= (char*) my_malloc(len_bytes, MYF(0)))) + if (!(file_buffer= (char*) alloc_root(&m_mem_root, len_bytes))) goto err1; VOID(my_seek(file, 0, MY_SEEK_SET, MYF(0))); if (my_read(file, (uchar *) file_buffer, len_bytes, MYF(MY_NABP))) @@ -2418,12 +2452,33 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root) if (len_words != (tot_partition_words + tot_name_words + 4)) goto err3; name_buffer_ptr= file_buffer + 16 + 4 * tot_partition_words; + + if (!(m_connect_string= (LEX_STRING*) + alloc_root(&m_mem_root, m_tot_parts * sizeof(LEX_STRING)))) + goto err3; + bzero(m_connect_string, m_tot_parts * sizeof(LEX_STRING)); + + for (i= 0; i < m_tot_parts; i++) + { + LEX_STRING connect_string; + uchar buffer[4]; + if (my_read(file, buffer, 4, MYF(MY_NABP))) + break; + connect_string.length= uint4korr(buffer); + connect_string.str= (char*) alloc_root(&m_mem_root, connect_string.length+1); + if (my_read(file, (uchar*) connect_string.str, connect_string.length, + MYF(MY_NABP))) + break; + connect_string.str[connect_string.length]= 0; + m_connect_string[i]= connect_string; + } + VOID(my_close(file, MYF(0))); m_file_buffer= file_buffer; // Will be freed in clear_handler_file() m_name_buffer_ptr= name_buffer_ptr; if (!(m_engine_array= (plugin_ref*) - my_malloc(m_tot_parts * sizeof(plugin_ref), MYF(MY_WME)))) + alloc_root(&m_mem_root, m_tot_parts * sizeof(plugin_ref)))) goto err3; for (i= 0; i < m_tot_parts; i++) @@ -2441,7 +2496,6 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root) err3: my_afree((gptr) engine_array); err2: - my_free(file_buffer, MYF(0)); err1: VOID(my_close(file, MYF(0))); DBUG_RETURN(TRUE); @@ -2514,7 +2568,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) alloc_len+= table_share->max_key_length; if (!m_ordered_rec_buffer) { - if (!(m_ordered_rec_buffer= (uchar*)my_malloc(alloc_len, MYF(MY_WME)))) + if (!(m_ordered_rec_buffer= (uchar*) alloc_root(&m_mem_root, alloc_len))) { DBUG_RETURN(1); } @@ -2557,9 +2611,11 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) { create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME, FALSE); + table->s->connect_string = m_connect_string[(uint)(file-m_file)]; if ((error= (*file)->ha_open(table, (const char*) name_buff, mode, test_if_locked))) goto err_handler; + bzero(&table->s->connect_string, sizeof(LEX_STRING)); m_no_locks+= (*file)->lock_count(); name_buffer_ptr+= strlen(name_buffer_ptr) + 1; set_if_bigger(ref_length, ((*file)->ref_length)); diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 76b91e160ca..b5463a8f48e 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -73,12 +73,14 @@ private: uint m_open_test_lock; // Open test_if_locked char *m_file_buffer; // Buffer with names char *m_name_buffer_ptr; // Pointer to first partition name + MEM_ROOT m_mem_root; plugin_ref *m_engine_array; // Array of types of the handlers handler **m_file; // Array of references to handler inst. uint m_file_tot_parts; // Debug handler **m_new_file; // Array of references to new handlers handler **m_reorged_file; // Reorganised partitions handler **m_added_file; // Added parts kept for errors + LEX_STRING *m_connect_string; partition_info *m_part_info; // local reference to partition Field **m_part_field_array; // Part field array locally to save acc uchar *m_ordered_rec_buffer; // Row and key buffer for ord. idx scan diff --git a/sql/partition_element.h b/sql/partition_element.h index 905bc38165b..2fe2bba74cd 100644 --- a/sql/partition_element.h +++ b/sql/partition_element.h @@ -65,6 +65,7 @@ public: char* data_file_name; char* index_file_name; handlerton *engine_type; + LEX_STRING connect_string; enum partition_state part_state; uint16 nodegroup_id; bool has_null_value; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c6a84323bd4..6f89b2bd837 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4501,6 +4501,12 @@ opt_part_option: lex->part_info->curr_part_elem->engine_type= $4; lex->part_info->default_engine_type= $4; } + | CONNECTION_SYM opt_equal TEXT_STRING_sys + { + LEX *lex= Lex; + lex->part_info->curr_part_elem->connect_string.str= $3.str; + lex->part_info->curr_part_elem->connect_string.length= $3.length; + } | NODEGROUP_SYM opt_equal real_ulong_num { Lex->part_info->curr_part_elem->nodegroup_id= (uint16) $3; } | MAX_ROWS opt_equal real_ulonglong_num -- cgit v1.2.1