diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e0b3de07305..83303da1c71 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4914,7 +4914,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, if (share->db_type() == partition_hton && share->partition_info_str_len) { - tmp_db_type= share->default_part_db_type; + tmp_db_type= plugin_hton(share->default_part_plugin); is_partitioned= TRUE; } #endif diff --git a/sql/table.cc b/sql/table.cc index 01b7ae3445e..b5550e090a1 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -454,6 +454,7 @@ void TABLE_SHARE::destroy() ha_data_destroy= NULL; } #ifdef WITH_PARTITION_STORAGE_ENGINE + plugin_unlock(NULL, default_part_plugin); if (ha_part_data_destroy) { ha_part_data_destroy(ha_part_data); @@ -798,6 +799,16 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, options= extra2; options_len= length; break; + case EXTRA2_DEFAULT_PART_ENGINE: +#ifdef WITH_PARTITION_STORAGE_ENGINE + { + LEX_STRING name= { (char*)extra2, length }; + share->default_part_plugin= ha_resolve_by_name(NULL, &name); + if (!share->default_part_plugin) + goto err; + } +#endif + break; default: /* abort frm parsing if it's an unknown but important extra2 value */ if (type >= EXTRA2_ENGINE_IMPORTANT) @@ -828,11 +839,14 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->frm_version= FRM_VER_TRUE_VARCHAR; #ifdef WITH_PARTITION_STORAGE_ENGINE - if (frm_image[61] && - !(share->default_part_db_type= - ha_checktype(thd, (enum legacy_db_type) (uint) frm_image[61], 1, 0))) - goto err; - DBUG_PRINT("info", ("default_part_db_type = %u", frm_image[61])); + if (frm_image[61] && !share->default_part_plugin) + { + enum legacy_db_type db_type= (enum legacy_db_type) (uint) frm_image[61]; + share->default_part_plugin= + ha_lock_engine(NULL, ha_checktype(thd, db_type, 1, 0)); + if (!share->default_part_plugin) + goto err; + } #endif legacy_db_type= (enum legacy_db_type) (uint) frm_image[3]; /* @@ -2697,7 +2711,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, tmp= mysql_unpack_partition(thd, share->partition_info_str, share->partition_info_str_len, outparam, is_create_table, - share->default_part_db_type, + plugin_hton(share->default_part_plugin), &work_part_info_used); if (tmp) { diff --git a/sql/table.h b/sql/table.h index e376ee2ad2f..068cbe9a763 100644 --- a/sql/table.h +++ b/sql/table.h @@ -741,7 +741,7 @@ struct TABLE_SHARE char *partition_info_str; uint partition_info_str_len; uint partition_info_buffer_size; - handlerton *default_part_db_type; + plugin_ref default_part_plugin; #endif /** diff --git a/sql/unireg.cc b/sql/unireg.cc index 099f8ccbc78..d90db0ebab8 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -46,6 +46,38 @@ static bool pack_fields(uchar *, List &, ulong); static size_t packed_fields_length(List &); static bool make_empty_rec(THD *, uchar *, uint, List &, uint, ulong); +static uchar *extra2_write_len(uchar *pos, size_t len) +{ + if (len < 255) + *pos++= len; + else + { + /* + At the moment we support options_len up to 64K. + We can easily extend it in the future, if the need arises. + */ + DBUG_ASSERT(len <= 65535); + int2store(pos + 1, len); + pos+= 3; + } + return pos; +} + +static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type, + LEX_STRING *str) +{ + *pos++ = type; + pos= extra2_write_len(pos, str->length); + memcpy(pos, str->str, str->length); + return pos + str->length; +} + +static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type, + LEX_CUSTRING *str) +{ + return extra2_write(pos, type, reinterpret_cast(str)); +} + /** Create a frm (table definition) file @@ -200,6 +232,9 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, if (options_len) extra2_size+= 1 + (options_len > 255 ? 3 : 1) + options_len; + if (part_info) + extra2_size+= 1 + 1 + hton_name(part_info->default_engine_type)->length; + key_buff_length= uint4korr(fileinfo+47); frm.length= FRM_HEADER_SIZE; // fileinfo; @@ -223,27 +258,17 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, /* write the extra2 segment */ pos = frm_ptr + 64; compile_time_assert(EXTRA2_TABLEDEF_VERSION != '/'); - *pos++ = EXTRA2_TABLEDEF_VERSION; // old servers write '/' here - *pos++ = create_info->tabledef_version.length; - memcpy(pos, create_info->tabledef_version.str, - create_info->tabledef_version.length); - pos+= create_info->tabledef_version.length; + pos= extra2_write(pos, EXTRA2_TABLEDEF_VERSION, + &create_info->tabledef_version); + + if (part_info) + pos= extra2_write(pos, EXTRA2_DEFAULT_PART_ENGINE, + hton_name(part_info->default_engine_type)); if (options_len) { *pos++= EXTRA2_ENGINE_TABLEOPTS; - if (options_len < 255) - *pos++= options_len; - else - { - /* - At the moment we support options_len up to 64K. - We can easily extend it in the future, if the need arises. - */ - DBUG_ASSERT(options_len <= 65535); - int2store(pos + 1, options_len); - pos+= 3; - } + pos= extra2_write_len(pos, options_len); pos= engine_table_options_frm_image(pos, create_info->option_list, create_fields, keys, key_info); } diff --git a/sql/unireg.h b/sql/unireg.h index 5e232becbb2..6662c63871e 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -181,6 +181,7 @@ */ enum extra2_frm_value_type { EXTRA2_TABLEDEF_VERSION=0, + EXTRA2_DEFAULT_PART_ENGINE=1, #define EXTRA2_ENGINE_IMPORTANT 128