------------------------------------------------------------
revno: 3589
committer: Sergei Golubchik <sergii@pisem.net>
branch nick: 10.0
timestamp: Fri 2013-03-15 16:58:26 +0100
message:
  Introduce handler_share. Use it to create handlers. Fix engines to comply.
  Remove TABLE_SHARE::ha_data. Move shared partitioning data into hs_partition.
  Move option_struct and option_list into handler_share.
  Remove now unused get_new_handler().
modified:
  sql/create_options.cc
  sql/ha_partition.cc
  sql/ha_partition.h
  sql/handler.cc
  sql/handler.h
  sql/opt_subselect.cc
  sql/partition_element.h
  sql/sql_base.cc
  sql/sql_derived.cc
  sql/sql_partition.cc
  sql/sql_partition.h
  sql/sql_select.cc
  sql/sql_show.cc
  sql/sql_table.cc
  sql/table.cc
  sql/table.h
  storage/archive/ha_archive.cc
  storage/archive/ha_archive.h
  storage/blackhole/ha_blackhole.cc
  storage/blackhole/ha_blackhole.h
  storage/csv/ha_tina.cc
  storage/csv/ha_tina.h
  storage/example/ha_example.cc
  storage/example/ha_example.h
  storage/federated/ha_federated.cc
  storage/federated/ha_federated.h
  storage/federatedx/ha_federatedx.cc
  storage/federatedx/ha_federatedx.h
  storage/heap/ha_heap.cc
  storage/heap/ha_heap.h
  storage/innobase/handler/ha_innodb.cc
  storage/innobase/handler/ha_innodb.h
  storage/maria/ha_maria.cc
  storage/maria/ha_maria.h
  storage/myisam/ha_myisam.cc
  storage/myisam/ha_myisam.h
  storage/myisammrg/ha_myisammrg.cc
  storage/myisammrg/ha_myisammrg.h
  storage/perfschema/ha_perfschema.cc
  storage/perfschema/ha_perfschema.h
  storage/sequence/sequence.cc
  storage/sphinx/ha_sphinx.cc
  storage/sphinx/ha_sphinx.h
  storage/test_sql_discovery/test_sql_discovery.cc
  storage/xtradb/handler/ha_innodb.cc
  storage/xtradb/handler/ha_innodb.h
diff:
=== modified file 'sql/create_options.cc'
--- sql/create_options.cc	2012-10-18 21:33:06 +0000
+++ sql/create_options.cc	2013-03-15 15:58:26 +0000
@@ -329,8 +329,9 @@ my_bool parse_engine_table_options(THD *
   MEM_ROOT *root= &share->mem_root;
   DBUG_ENTER("parse_engine_table_options");
 
-  if (parse_option_list(thd, &share->option_struct, share->option_list,
-                        ht->table_options, TRUE, root))
+  if (parse_option_list(thd, &share->ha_share->option_struct,
+                        share->ha_share->option_list, ht->table_options,
+                        TRUE, root))
     DBUG_RETURN(TRUE);
 
   for (Field **field= share->field; *field; field++)
@@ -554,8 +555,9 @@ my_bool engine_table_options_frm_read(co
 
   while (buff < buff_end && *buff)
   {
-    if (!(buff= engine_option_value::frm_read(buff, &share->option_list, &end,
-                                              root)))
+    if (!(buff= engine_option_value::frm_read(buff,
+                                              &share->ha_share->option_list,
+                                              &end, root)))
       DBUG_RETURN(TRUE);
   }
   buff++;

=== modified file 'sql/ha_partition.cc'
--- sql/ha_partition.cc	2013-03-12 17:02:37 +0000
+++ sql/ha_partition.cc	2013-03-15 15:58:26 +0000
@@ -73,9 +73,8 @@ static const char *ha_par_ext= ".par";
                 MODULE create/delete handler object
 ****************************************************************************/
 
-static handler *partition_create_handler(handlerton *hton,
-                                         TABLE_SHARE *share,
-                                         MEM_ROOT *mem_root);
+static handler *partition_create_handler(handler_share *, MEM_ROOT *);
+static handler_share *partition_create_share(handlerton *, TABLE_SHARE *, MEM_ROOT *);
 static uint partition_flags();
 static uint alter_table_flags(uint flags);
 
@@ -99,6 +98,7 @@ static int partition_initialize(void *p)
   partition_hton->state= SHOW_OPTION_YES;
   partition_hton->db_type= DB_TYPE_PARTITION_DB;
   partition_hton->create= partition_create_handler;
+  partition_hton->create_share= partition_create_share;
   partition_hton->partition_flags= partition_flags;
   partition_hton->alter_table_flags= alter_table_flags;
   partition_hton->flags= HTON_NOT_USER_SELECTABLE |
@@ -120,11 +120,9 @@ static int partition_initialize(void *p)
     New partition object
 */
 
-static handler *partition_create_handler(handlerton *hton, 
-                                         TABLE_SHARE *share,
-                                         MEM_ROOT *mem_root)
+static handler *partition_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  ha_partition *file= new (mem_root) ha_partition(hton, share);
+  ha_partition *file= new (mem_root) ha_partition(hs);
   if (file && file->initialize_partition(mem_root))
   {
     delete file;
@@ -134,6 +132,62 @@ static handler *partition_create_handler
 }
 
 /*
+  Create new partition hs_share
+
+  SYNOPSIS
+    partition_create_share()
+
+  RETURN VALUE
+    New partition object
+*/
+
+static handler_share *partition_create_share(handlerton *hton,
+                                             TABLE_SHARE *share,
+                                             MEM_ROOT *where)
+{
+  return new (where) hs_partition(hton, share, where);
+}
+
+handler *hs_partition::create_handler(MEM_ROOT *where)
+{
+  return partition_create_handler(this, where);
+}
+
+bool hs_partition::init_parts(uint tp, handlerton **hton)
+{
+  if (parts)
+  {
+    DBUG_ASSERT(tp == tot_parts);
+    return 0;
+  }
+
+  tot_parts= tp;
+
+  parts= (handler_share**) alloc_root(mem_root,
+                                      sizeof(handler_share*) * tot_parts);
+  if (!parts)
+    return 1;
+
+  bool ret= 0;
+  for (uint i=0; i < tot_parts; i++)
+  {
+    parts[i]= hton[i]->create_share(hton[i], table_share, mem_root);
+    ret|= parts[i] == 0;
+  }
+  return ret;
+}
+
+void hs_partition::free_parts()
+{
+  if (parts)
+  {
+    for (uint i=0; i < tot_parts; i++)
+      delete parts[i];
+    parts= 0;
+  }
+}
+
+/*
   HA_CAN_PARTITION:
   Used by storage engines that can handle partitioning without this
   partition handler
@@ -176,8 +230,7 @@ const uint ha_partition::NO_CURRENT_PART
     NONE
 */
 
-ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share)
-  :handler(hton, share)
+ha_partition::ha_partition(handler_share *hs) :handler(hs)
 {
   DBUG_ENTER("ha_partition::ha_partition(table)");
   init_alloc_root(&m_mem_root, 512, 512, MYF(0));
@@ -198,7 +251,7 @@ ha_partition::ha_partition(handlerton *h
 */
 
 ha_partition::ha_partition(handlerton *hton, partition_info *part_info)
-  :handler(hton, NULL)
+  :handler(0)
 {
   DBUG_ENTER("ha_partition::ha_partition(part_info)");
   DBUG_ASSERT(part_info);
@@ -222,11 +275,10 @@ ha_partition::ha_partition(handlerton *h
   @return New partition handler
 */
 
-ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share,
+ha_partition::ha_partition(handler_share *hs,
                            partition_info *part_info_arg,
                            ha_partition *clone_arg,
-                           MEM_ROOT *clone_mem_root_arg)
-  :handler(hton, share)
+                           MEM_ROOT *clone_mem_root_arg) :handler(hs)
 {
   DBUG_ENTER("ha_partition::ha_partition(clone)");
   init_alloc_root(&m_mem_root, 512, 512, MYF(0));
@@ -1603,10 +1655,10 @@ int ha_partition::change_partitions(HA_C
       uint j= 0;
       do
       {
-        if (!(new_file_array[part_count++]=
-              get_new_handler(table->s,
-                              thd->mem_root,
-                              part_elem->engine_type)))
+        new_file_array[part_count]=
+          part_elem->create_handler(table->s, thd->mem_root);
+
+        if (!(new_file_array[part_count++]))
         {
           mem_alloc_error(sizeof(handler));
           DBUG_RETURN(ER_OUTOFMEMORY);
@@ -1852,9 +1904,8 @@ void ha_partition::update_create_info(HA
 
 void ha_partition::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
 {
+  handler::change_table_ptr(table_arg, share);
   handler **file_array;
-  table= table_arg;
-  m_table_share= share;
   /*
     m_file can be NULL when using an old cached table in DROP TABLE, when the
     table just has REMOVED PARTITIONING, see Bug#42438
@@ -2506,11 +2557,8 @@ bool ha_partition::create_handlers(MEM_R
   bzero((char*) m_file, alloc_len);
   for (i= 0; i < m_tot_parts; i++)
   {
-    handlerton *hton= plugin_data(m_engine_array[i], handlerton*);
-    if (!(m_file[i]= get_new_handler(table_share(), mem_root,
-                                     hton)))
+    if (!(m_file[i]= hs()->parts[i]->ha_create_handler(mem_root)))
       DBUG_RETURN(TRUE);
-    DBUG_PRINT("info", ("engine_type: %u", hton->db_type));
   }
   /* For the moment we only support partition over the same table engine */
   hton0= plugin_data(m_engine_array[0], handlerton*);
@@ -2571,8 +2619,8 @@ bool ha_partition::new_handlers_from_par
     {
       for (j= 0; j < m_part_info->num_subparts; j++)
       {
-	if (!(m_file[part_count++]= get_new_handler(table_share(), mem_root,
-                                                    part_elem->engine_type)))
+	m_file[part_count]= part_elem->create_handler(table_share(), mem_root);
+	if (!m_file[part_count++])
           goto error;
 	DBUG_PRINT("info", ("engine_type: %u",
                    (uint) ha_legacy_type(part_elem->engine_type)));
@@ -2580,8 +2628,8 @@ bool ha_partition::new_handlers_from_par
     }
     else
     {
-      if (!(m_file[part_count++]= get_new_handler(table_share(), mem_root,
-                                                  part_elem->engine_type)))
+      m_file[part_count]= part_elem->create_handler(table_share(), mem_root);
+      if (!m_file[part_count++])
         goto error;
       DBUG_PRINT("info", ("engine_type: %u",
                  (uint) ha_legacy_type(part_elem->engine_type)));
@@ -2735,8 +2783,10 @@ bool ha_partition::setup_engine_array(ME
   for (i= 0; i < m_tot_parts; i++)
     m_engine_array[i]= ha_lock_engine(NULL, engine_array[i]);
 
+  hs()->init_parts(m_tot_parts, engine_array);
+
   my_afree(engine_array);
-    
+
   if (create_handlers(mem_root))
   {
     clear_handler_file();
@@ -2790,18 +2840,6 @@ bool ha_partition::get_from_handler_file
 ****************************************************************************/
 
 
-/**
-  A destructor for partition-specific TABLE_SHARE data.
-*/
-
-void ha_data_partition_destroy(HA_DATA_PARTITION* ha_part_data)
-{
-  if (ha_part_data)
-  {
-    mysql_mutex_destroy(&ha_part_data->LOCK_auto_inc);
-  }
-}
-
 /*
   Open handler object
 
@@ -2831,7 +2869,6 @@ int ha_partition::open(const char *name,
   int error= HA_ERR_INITIALIZATION;
   handler **file;
   char name_buff[FN_REFLEN];
-  bool is_not_tmp_table= (table_share()->tmp_table == NO_TMP_TABLE);
   ulonglong check_table_flags;
   DBUG_ENTER("ha_partition::open");
 
@@ -2966,34 +3003,6 @@ int ha_partition::open(const char *name,
   clear_handler_file();
 
   /*
-    Use table_share()->ha_part_data to share auto_increment_value among
-    all handlers for the same table.
-  */
-  if (is_not_tmp_table)
-    mysql_mutex_lock(&table_share()->LOCK_ha_data);
-  if (!table_share()->ha_part_data)
-  {
-    /* currently only needed for auto_increment */
-    table_share()->ha_part_data= (HA_DATA_PARTITION*)
-                                   alloc_root(&table_share()->mem_root,
-                                              sizeof(HA_DATA_PARTITION));
-    if (!table_share()->ha_part_data)
-    {
-      if (is_not_tmp_table)
-        mysql_mutex_unlock(&table_share()->LOCK_ha_data);
-      goto err_handler;
-    }
-    DBUG_PRINT("info", ("table_share()->ha_part_data 0x%p",
-                        table_share()->ha_part_data));
-    bzero(table_share()->ha_part_data, sizeof(HA_DATA_PARTITION));
-    table_share()->ha_part_data_destroy= ha_data_partition_destroy;
-    mysql_mutex_init(key_PARTITION_LOCK_auto_inc,
-                     &table_share()->ha_part_data->LOCK_auto_inc,
-                     MY_MUTEX_INIT_FAST);
-  }
-  if (is_not_tmp_table)
-    mysql_mutex_unlock(&table_share()->LOCK_ha_data);
-  /*
     Some handlers update statistics as part of the open call. This will in
     some cases corrupt the statistics of the partition handler and thus
     to ensure we have correct statistics we call info from open after
@@ -3043,8 +3052,8 @@ handler *ha_partition::clone(const char
   ha_partition *new_handler;
 
   DBUG_ENTER("ha_partition::clone");
-  new_handler= new (mem_root) ha_partition(partition_hton, table_share(),
-                                           m_part_info, this, mem_root);
+  new_handler= new (mem_root) ha_partition(ha_share, m_part_info,
+                                           this, mem_root);
   /*
     Allocate new_handler->ref here because otherwise ha_open will allocate it
     on this->table->mem_root and we will not be able to reclaim that memory 
@@ -3460,7 +3469,7 @@ int ha_partition::write_row(uchar * buf)
   */
   if (have_auto_increment)
   {
-    if (!table_share()->ha_part_data->auto_inc_initialized &&
+    if (!hs()->auto_inc_initialized &&
         !table_share()->next_number_keypart)
     {
       /*
@@ -3621,7 +3630,7 @@ int ha_partition::update_row(const uchar
 exit:
   /*
     if updating an auto_increment column, update
-    table_share()->ha_part_data->next_auto_inc_val if needed.
+    hs()->next_auto_inc_val if needed.
     (not to be used if auto_increment on secondary field in a multi-column
     index)
     mysql_update does not set table->next_number_field, so we use
@@ -3634,7 +3643,7 @@ int ha_partition::update_row(const uchar
       bitmap_is_set(table->write_set,
                     table->found_next_number_field->field_index))
   {
-    if (!table_share()->ha_part_data->auto_inc_initialized)
+    if (!hs()->auto_inc_initialized)
       info(HA_STATUS_AUTO);
     set_auto_increment_if_higher(table->found_next_number_field);
   }
@@ -3745,8 +3754,8 @@ int ha_partition::truncate()
     it so that it will be initialized again at the next use.
   */
   lock_auto_increment();
-  table_share()->ha_part_data->next_auto_inc_val= 0;
-  table_share()->ha_part_data->auto_inc_initialized= FALSE;
+  hs()->next_auto_inc_val= 0;
+  hs()->auto_inc_initialized= FALSE;
   unlock_auto_increment();
 
   file= m_file;
@@ -3787,8 +3796,8 @@ int ha_partition::truncate_partition(Alt
     it so that it will be initialized again at the next use.
   */
   lock_auto_increment();
-  table_share()->ha_part_data->next_auto_inc_val= 0;
-  table_share()->ha_part_data->auto_inc_initialized= FALSE;
+  hs()->next_auto_inc_val= 0;
+  hs()->auto_inc_initialized= FALSE;
   unlock_auto_increment();
 
   *binlog_stmt= true;
@@ -5707,19 +5716,19 @@ int ha_partition::info(uint flag)
     DBUG_PRINT("info", ("HA_STATUS_AUTO"));
     if (!table->found_next_number_field)
       stats.auto_increment_value= 0;
-    else if (table_share()->ha_part_data->auto_inc_initialized)
+    else if (hs()->auto_inc_initialized)
     {
       lock_auto_increment();
-      stats.auto_increment_value= table_share()->ha_part_data->next_auto_inc_val;
+      stats.auto_increment_value= hs()->next_auto_inc_val;
       unlock_auto_increment();
     }
     else
     {
       lock_auto_increment();
       /* to avoid two concurrent initializations, check again when locked */
-      if (table_share()->ha_part_data->auto_inc_initialized)
+      if (hs()->auto_inc_initialized)
         stats.auto_increment_value=
-                                 table_share()->ha_part_data->next_auto_inc_val;
+                                 hs()->next_auto_inc_val;
       else
       {
         handler *file, **file_array;
@@ -5739,11 +5748,11 @@ int ha_partition::info(uint flag)
         stats.auto_increment_value= auto_increment_value;
         if (auto_inc_is_first_in_idx)
         {
-          set_if_bigger(table_share()->ha_part_data->next_auto_inc_val,
+          set_if_bigger(hs()->next_auto_inc_val,
                         auto_increment_value);
-          table_share()->ha_part_data->auto_inc_initialized= TRUE;
+          hs()->auto_inc_initialized= TRUE;
           DBUG_PRINT("info", ("initializing next_auto_inc_val to %lu",
-                       (ulong) table_share()->ha_part_data->next_auto_inc_val));
+                       (ulong) hs()->next_auto_inc_val));
         }
       }
       unlock_auto_increment();
@@ -7440,8 +7449,8 @@ int ha_partition::reset_auto_increment(u
   int res;
   DBUG_ENTER("ha_partition::reset_auto_increment");
   lock_auto_increment();
-  table_share()->ha_part_data->auto_inc_initialized= FALSE;
-  table_share()->ha_part_data->next_auto_inc_val= 0;
+  hs()->auto_inc_initialized= FALSE;
+  hs()->next_auto_inc_val= 0;
   do
   {
     if ((res= (*file)->ha_reset_auto_increment(value)) != 0)
@@ -7455,7 +7464,7 @@ int ha_partition::reset_auto_increment(u
 /**
   This method is called by update_auto_increment which in turn is called
   by the individual handlers as part of write_row. We use the
-  table_share()->ha_part_data->next_auto_inc_val, or search all
+  hs()->next_auto_inc_val, or search all
   partitions for the highest auto_increment_value if not initialized or
   if auto_increment field is a secondary part of a key, we must search
   every partition when holding a mutex to be sure of correctness.
@@ -7511,9 +7520,9 @@ void ha_partition::get_auto_increment(ul
     /*
       This is initialized in the beginning of the first write_row call.
     */
-    DBUG_ASSERT(table_share()->ha_part_data->auto_inc_initialized);
+    DBUG_ASSERT(hs()->auto_inc_initialized);
     /*
-      Get a lock for handling the auto_increment in table_share()->ha_part_data
+      Get a lock for handling the auto_increment in hs()
       for avoiding two concurrent statements getting the same number.
     */ 
 
@@ -7540,8 +7549,8 @@ void ha_partition::get_auto_increment(ul
     }
 
     /* this gets corrected (for offset/increment) in update_auto_increment */
-    *first_value= table_share()->ha_part_data->next_auto_inc_val;
-    table_share()->ha_part_data->next_auto_inc_val+=
+    *first_value= hs()->next_auto_inc_val;
+    hs()->next_auto_inc_val+=
                                               nb_desired_values * increment;
 
     unlock_auto_increment();
@@ -7564,7 +7573,7 @@ void ha_partition::release_auto_incremen
   {
     ulonglong next_auto_inc_val;
     lock_auto_increment();
-    next_auto_inc_val= table_share()->ha_part_data->next_auto_inc_val;
+    next_auto_inc_val= hs()->next_auto_inc_val;
     /*
       If the current auto_increment values is lower than the reserved
       value, and the reserved value was reserved by this thread,
@@ -7579,10 +7588,10 @@ void ha_partition::release_auto_incremen
         with SET INSERT_ID, i.e. forced/non generated values.
       */
       if (thd->auto_inc_intervals_forced.maximum() < next_insert_id)
-        table_share()->ha_part_data->next_auto_inc_val= next_insert_id;
+        hs()->next_auto_inc_val= next_insert_id;
     }
-    DBUG_PRINT("info", ("table_share()->ha_part_data->next_auto_inc_val: %lu",
-                        (ulong) table_share()->ha_part_data->next_auto_inc_val));
+    DBUG_PRINT("info", ("hs()->next_auto_inc_val: %lu",
+                        (ulong) hs()->next_auto_inc_val));
 
     /* Unlock the multi row statement lock taken in get_auto_increment */
     if (auto_increment_safe_stmt_log_lock)

=== modified file 'sql/ha_partition.h'
--- sql/ha_partition.h	2013-03-12 17:02:37 +0000
+++ sql/ha_partition.h	2013-03-15 15:58:26 +0000
@@ -48,9 +48,50 @@ enum partition_keywords
 /* offset to the engines array */
 #define PAR_ENGINES_OFFSET 12
 
+class hs_partition: public handler_share
+{
+  public:
+  hs_partition(handlerton *h, TABLE_SHARE *s, MEM_ROOT *m) :
+    handler_share(h, s), mem_root(m), auto_inc_initialized(0),
+    next_auto_inc_val(0), auto_partitioned(0), partition_info_str(0),
+    partition_info_str_len(0), partition_info_buffer_size(0),
+    default_part_db_type(0), tot_parts(0), parts(0)
+  {
+    mysql_mutex_init(key_PARTITION_LOCK_auto_inc, &LOCK_auto_inc,
+                     MY_MUTEX_INIT_FAST);
+  }
+  ~hs_partition()
+  {
+    free_parts();
+    mysql_mutex_destroy(&LOCK_auto_inc);
+  }
+  handler *create_handler(MEM_ROOT *where);
+
+  MEM_ROOT *mem_root;
+
+  bool auto_inc_initialized;
+  mysql_mutex_t LOCK_auto_inc;                 /**< protecting auto_inc val */
+  ulonglong next_auto_inc_val;                 /**< first non reserved value */
+
+  /* filled in when reading from frm */
+  bool auto_partitioned;
+  char *partition_info_str;
+  uint  partition_info_str_len;
+  uint  partition_info_buffer_size;
+  handlerton *default_part_db_type;
+
+  uint tot_parts;
+  handler_share **parts;
+
+  bool init_parts(uint tp, handlerton **hton);
+  void free_parts();
+};
+
 class ha_partition :public handler
 {
 private:
+  hs_partition *hs() const { return static_cast<hs_partition*>(ha_share); }
+
   enum partition_index_scan_type
   {
     partition_index_read= 0,
@@ -188,8 +229,9 @@ class ha_partition :public handler
   bool m_key_not_found;
 public:
   handler *clone(const char *name, MEM_ROOT *mem_root);
-  virtual void set_part_info(partition_info *part_info)
+  virtual void set_part_info(partition_info *part_info, bool create)
   {
+     m_create_handler= create;
      m_part_info= part_info;
      m_is_sub_partitioned= part_info->is_sub_partitioned();
   }
@@ -204,12 +246,10 @@ class ha_partition :public handler
     partition handler.
     -------------------------------------------------------------------------
   */
-    ha_partition(handlerton *hton, TABLE_SHARE * table);
+    ha_partition(handler_share *hs);
     ha_partition(handlerton *hton, partition_info * part_info);
-    ha_partition(handlerton *hton, TABLE_SHARE *share,
-                 partition_info *part_info_arg,
-                 ha_partition *clone_arg,
-                 MEM_ROOT *clone_mem_root_arg);
+    ha_partition(handler_share *hs, partition_info *part_info_arg,
+                 ha_partition *clone_arg, MEM_ROOT *clone_mem_root_arg);
    ~ha_partition();
   /*
     A partition handler has no characteristics in itself. It only inherits
@@ -951,16 +991,14 @@ class ha_partition :public handler
     /* lock already taken */
     if (auto_increment_safe_stmt_log_lock)
       return;
-    DBUG_ASSERT(table_share()->ha_part_data && !auto_increment_lock);
     if(table_share()->tmp_table == NO_TMP_TABLE)
     {
       auto_increment_lock= TRUE;
-      mysql_mutex_lock(&table_share()->ha_part_data->LOCK_auto_inc);
+      mysql_mutex_lock(&hs()->LOCK_auto_inc);
     }
   }
   virtual void unlock_auto_increment()
   {
-    DBUG_ASSERT(table_share()->ha_part_data);
     /*
       If auto_increment_safe_stmt_log_lock is true, we have to keep the lock.
       It will be set to false and thus unlocked at the end of the statement by
@@ -968,7 +1006,7 @@ class ha_partition :public handler
     */
     if(auto_increment_lock && !auto_increment_safe_stmt_log_lock)
     {
-      mysql_mutex_unlock(&table_share()->ha_part_data->LOCK_auto_inc);
+      mysql_mutex_unlock(&hs()->LOCK_auto_inc);
       auto_increment_lock= FALSE;
     }
   }
@@ -977,10 +1015,10 @@ class ha_partition :public handler
     ulonglong nr= (((Field_num*) field)->unsigned_flag ||
                    field->val_int() > 0) ? field->val_int() : 0;
     lock_auto_increment();
-    DBUG_ASSERT(table_share()->ha_part_data->auto_inc_initialized == TRUE);
+    DBUG_ASSERT(hs()->auto_inc_initialized == TRUE);
     /* must check when the mutex is taken */
-    if (nr >= table_share()->ha_part_data->next_auto_inc_val)
-      table_share()->ha_part_data->next_auto_inc_val= nr + 1;
+    if (nr >= hs()->next_auto_inc_val)
+      hs()->next_auto_inc_val= nr + 1;
     unlock_auto_increment();
   }
 

=== modified file 'sql/handler.cc'
--- sql/handler.cc	2013-03-12 17:28:58 +0000
+++ sql/handler.cc	2013-03-15 15:58:26 +0000
@@ -236,48 +236,49 @@ handlerton *ha_checktype(THD *thd, enum
 } /* ha_checktype */
 
 
-handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
-                         handlerton *db_type)
+/*
+  This is useful when we need to create a handler object
+  that does not have an associated TABLE_SHARE, that is a handler
+  object that does not correspond to any open table.
+
+  It is used in DROP TABLE and RENAME TABLE, for example.
+
+  This function creates a temporary non-shared handler_share object
+  on the same MEM_ROOT as the handler itself.
+
+  It is a hack which shall go away when the functionality
+  of the handler object will be split between a handler_cursor, handler,
+  handler_share, and handlerton objects, and we won't need to create
+  fake unopened handlers anymore.
+*/
+handler *get_fake_handler(MEM_ROOT *where, handlerton *hton)
 {
   handler *file;
-  DBUG_ENTER("get_new_handler");
-  DBUG_PRINT("enter", ("alloc: 0x%lx", (long) alloc));
+  DBUG_ENTER("get_fake_handler");
 
-  if (db_type && db_type->state == SHOW_OPTION_YES && db_type->create)
+  if (hton && hton->state == SHOW_OPTION_YES && hton->create_share)
   {
-    if ((file= db_type->create(db_type, share, alloc)))
-      file->init();
+    handler_share *ha_share= hton->create_share(hton, 0, where);
+    if (!ha_share)
+      DBUG_RETURN(0);
+
+    file= ha_share->ha_create_handler(where);
     DBUG_RETURN(file);
   }
   /* Try the default table type */
-  file= get_new_handler(share, alloc, ha_default_handlerton(current_thd));
+  file= get_fake_handler(where, ha_default_handlerton(current_thd));
   DBUG_RETURN(file);
 }
 
-
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-handler *get_ha_partition(partition_info *part_info)
+void delete_fake_handler(handler *h)
 {
-  ha_partition *partition;
-  DBUG_ENTER("get_ha_partition");
-  if ((partition= new ha_partition(partition_hton, part_info)))
+  if (h)
   {
-    if (partition->initialize_partition(current_thd->mem_root))
-    {
-      delete partition;
-      partition= 0;
-    }
-    else
-      partition->init();
+    handler_share *ha_share= h->ha_share;
+    delete h;
+    delete ha_share;
   }
-  else
-  {
-    my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(ha_partition)));
-  }
-  DBUG_RETURN(((handler*) partition));
 }
-#endif
-
 
 static const char **handler_errmsgs;
 
@@ -380,6 +381,23 @@ static int ha_finish_errors(void)
   return 0;
 }
 
+class Default_handler_share: public handler_share
+{
+  public:
+  Default_handler_share(handlerton *h, TABLE_SHARE *s) : handler_share(h, s) {} 
+  handler *create_handler(MEM_ROOT *where)
+  {
+    return hton->create(this, where);
+  }
+};
+
+static handler_share *create_default_handler_share(handlerton *hton,
+                                                   TABLE_SHARE *share,
+                                                   MEM_ROOT *where)
+{
+  return new (where) Default_handler_share(hton, share);
+}
+
 static volatile int32 need_full_discover_for_existence= 0;
 static volatile int32 engines_with_discover_table_names= 0;
 
@@ -492,6 +510,10 @@ int ha_initialize_handlerton(st_plugin_i
     goto err;
   }
 
+  // switch old handlers to use handler_share
+  if (!hton->create_share && hton->create)
+    hton->create_share= create_default_handler_share;
+
   // hton_ext_based_table_discovery() works only when discovery
   // is supported and the engine if file-based.
   if (hton->discover_table_names == hton_ext_based_table_discovery &&
@@ -2188,7 +2210,7 @@ int ha_delete_table(THD *thd, handlerton
 
   /* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
   if (table_type == NULL || table_type == view_pseudo_hton ||
-      ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type)))
+      ! (file=get_fake_handler(thd->mem_root, table_type)))
     DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
 
   bzero((char*) &dummy_table, sizeof(dummy_table));
@@ -2231,16 +2253,22 @@ int ha_delete_table(THD *thd, handlerton
     push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, error,
                 ha_delete_table_error_handler.buff);
   }
-  delete file;
+  delete_fake_handler(file);
   DBUG_RETURN(error);
 }
 
 /****************************************************************************
 ** General handler functions
 ****************************************************************************/
+handler_share::handler_share(handlerton *h, TABLE_SHARE *s)
+  : hton(h), table_share(s), option_list(0), option_struct(0)
+{
+  name= s ? s->normalized_path : null_lex_str;
+}
+
 handler *handler::clone(const char *name, MEM_ROOT *mem_root)
 {
-  handler *new_handler= get_new_handler(table->s, mem_root, hton());
+  handler *new_handler= ha_share->ha_create_handler(mem_root);
   if (! new_handler)
     return NULL;
 
@@ -2268,6 +2296,23 @@ handler *handler::clone(const char *name
   return new_handler;
 }
 
+/*
+  This hack is used in ha_delete_table on the created fake handler,
+  where it's switched to a fake TABLE_SHARE for handler::print_error to work.
+  And in create_internal_tmp_table_from_heap2, where a TABLE_SHARE and TABLE
+  of a temporary table are binary-copied to create a new table.
+*/
+void handler::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
+{
+  /* we can only modify ha_share if it's not really shared */
+  DBUG_ASSERT(ha_share->table_share == 0 ||
+              ha_share->table_share->tmp_table == INTERNAL_TMP_TABLE ||
+              ha_share->table_share->tmp_table == SYSTEM_TMP_TABLE);
+
+  ha_share->table_share= share;
+  table= table_arg;
+  reset_statistics();
+}
 
 double handler::keyread_time(uint index, uint ranges, ha_rows rows)
 {

=== modified file 'sql/handler.h'
--- sql/handler.h	2013-03-12 17:28:58 +0000
+++ sql/handler.h	2013-03-15 15:58:26 +0000
@@ -812,6 +812,8 @@ struct handler_iterator {
 };
 
 class handler;
+class handler_share;
+
 /*
   handlerton is a singleton structure - one instance per storage engine -
   to provide access to storage engine functionality that works on the
@@ -1037,7 +1039,8 @@ struct handlerton
    void *(*create_cursor_read_view)(handlerton *hton, THD *thd);
    void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
    void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
-   handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
+   handler *(*create)(handler_share *hs, MEM_ROOT *mem_root);
+   handler_share *(*create_share)(handlerton *, TABLE_SHARE *, MEM_ROOT *);
    void (*drop_database)(handlerton *hton, char* path);
    int (*panic)(handlerton *hton, enum ha_panic_function flag);
    int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
@@ -1820,6 +1823,30 @@ class handler_add_index : public Sql_all
 
 class Query_cache;
 struct Query_cache_block_table;
+
+/*
+  handler_share object. An engine version of the TABLE_SHARE
+*/
+
+class handler_share : public Sql_alloc
+{
+  public:
+  handlerton       *hton;
+  TABLE_SHARE      *table_share;
+  engine_option_value *option_list;     /* text options for table */
+  ha_table_option_struct *option_struct; /* structure with parsed options */
+  LEX_STRING        name;
+
+  handler_share(handlerton *h, TABLE_SHARE *s);
+  virtual ~handler_share() {}
+
+  inline handler *ha_create_handler(MEM_ROOT *where);
+
+  private:
+  virtual handler *create_handler(MEM_ROOT *where)= 0;
+};
+
+
 /**
   The handler class is the interface for dynamically loadable
   storage engines. Do not add ifdefs and take care when adding or
@@ -1834,10 +1861,9 @@ class handler :public Sql_alloc
   TABLE *table;               /* The current open table */
   Table_flags cached_table_flags;       /* Set on init() and open() */
 private:
-  handlerton *m_ht;                 /* storage engine of this handler */
-  TABLE_SHARE *m_table_share;   /* The table definition */
   ha_rows estimation_rows_to_insert;
 public:
+  handler_share *ha_share;
   uchar *ref;				/* Pointer to current row */
   uchar *dup_ref;			/* Pointer to duplicate row */
 
@@ -1934,9 +1960,8 @@ class handler :public Sql_alloc
   */
   PSI_table *m_psi;
 
-  handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
-    :table(0), m_ht(ht_arg),m_table_share(share_arg),
-    estimation_rows_to_insert(0),
+  handler(handler_share *hs)
+    :table(0), estimation_rows_to_insert(0), ha_share(hs),
     ref(0), end_range(NULL), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
     in_range_check_pushed_down(FALSE),
     ref_length(sizeof(my_off_t)),
@@ -2097,12 +2122,9 @@ class handler :public Sql_alloc
     rows_read= rows_changed= rows_tmp_read= 0;
     bzero(index_rows_read, sizeof(index_rows_read));
   }
-  virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
-  {
-    table= table_arg;
-    m_table_share= share;
-    reset_statistics();
-  }
+
+  virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
+
   virtual double scan_time()
   { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
   virtual double read_time(uint index, uint ranges, ha_rows rows)
@@ -2498,8 +2520,8 @@ class handler :public Sql_alloc
   { return; }       /* prepare InnoDB for HANDLER */
   virtual void free_foreign_key_create_info(char* str) {}
   /** The following can be called without an open handler */
-  handlerton *hton() const { return m_ht; }
-  TABLE_SHARE *table_share() const { return m_table_share; }
+  handlerton *hton() const { return ha_share->hton; }
+  TABLE_SHARE *table_share() const { return ha_share->table_share; }
   enum legacy_db_type db_type() const { return hton()->db_type; }
   LEX_STRING *engine_name() const { return hton_name(hton()); }
   const char **bas_ext() const { return hton()->tablefile_extensions; }
@@ -2513,7 +2535,7 @@ class handler :public Sql_alloc
     *no_parts= 0;
     return 0;
   }
-  virtual void set_part_info(partition_info *part_info) {return;}
+  virtual void set_part_info(partition_info *part_info, bool create) {return;}
 
   virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
 
@@ -3041,6 +3063,14 @@ class handler :public Sql_alloc
   friend enum icp_result handler_index_cond_check(void* h_arg);
 };
 
+inline handler *handler_share::ha_create_handler(MEM_ROOT *where)
+{
+  handler *file= create_handler(where);
+  if (file)
+    file->init();
+  return file;
+}
+
 #include "multi_range_read.h"
 
 bool key_uses_partial_cols(TABLE *table, uint keyno);
@@ -3059,8 +3089,8 @@ handlerton *ha_default_handlerton(THD *t
 plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
 plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
-handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
-                         handlerton *db_type);
+handler *get_fake_handler(MEM_ROOT *alloc, handlerton *db_type);
+void delete_fake_handler(handler *h);
 handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
                           bool no_substitute, bool report_error);
 
@@ -3082,7 +3112,7 @@ static inline bool ha_check_storage_engi
 
 static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
 {
-  return (db_type && db_type->create) ?
+  return (db_type && db_type->create_share) ?
          (db_type->state == SHOW_OPTION_YES) : FALSE;
 }
 

=== modified file 'sql/opt_subselect.cc'
--- sql/opt_subselect.cc	2013-02-25 23:20:17 +0000
+++ sql/opt_subselect.cc	2013-03-15 15:58:26 +0000
@@ -3962,16 +3962,12 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_tabl
   uint reclength= field->pack_length();
   if (using_unique_constraint)
   { 
-    share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
-    table->file= get_new_handler(share, &table->mem_root,
-                                 share->db_type());
+    table->init_ha_share_and_file(TMP_ENGINE_HTON);
     DBUG_ASSERT(uniq_tuple_length_arg <= table->file->max_key_length());
   }
   else
   {
-    share->db_plugin= ha_lock_engine(0, heap_hton);
-    table->file= get_new_handler(share, &table->mem_root,
-                                 share->db_type());
+    table->init_ha_share_and_file(heap_hton);
   }
   if (!table->file)
     goto err;

=== modified file 'sql/partition_element.h'
--- sql/partition_element.h	2011-11-03 18:17:05 +0000
+++ sql/partition_element.h	2013-03-15 15:58:26 +0000
@@ -104,6 +104,7 @@ class partition_element :public Sql_allo
   char* index_file_name;
   handlerton *engine_type;
   LEX_STRING connect_string;
+  handler_share *ha_share;
   enum partition_state part_state;
   uint16 nodegroup_id;
   bool has_null_value;
@@ -116,7 +117,7 @@ class partition_element :public Sql_allo
     partition_name(NULL), tablespace_name(NULL),
     log_entry(NULL), part_comment(NULL),
     data_file_name(NULL), index_file_name(NULL),
-    engine_type(NULL), part_state(PART_NORMAL),
+    engine_type(NULL), ha_share(0), part_state(PART_NORMAL),
     nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE),
     signed_flag(FALSE), max_value(FALSE)
   {
@@ -140,7 +141,19 @@ class partition_element :public Sql_allo
     connect_string.str= 0;
     connect_string.length= 0;
   }
-  ~partition_element() {}
+  ~partition_element()
+  {
+    if (ha_share)
+      delete ha_share;
+  }
+  handler *create_handler(TABLE_SHARE *s, MEM_ROOT *mem_root)
+  {
+    ha_share= engine_type->create_share(engine_type, s, mem_root);
+    if (!ha_share)
+      return 0;
+
+    return ha_share->ha_create_handler(mem_root);
+  }
 };
 
 #endif /* PARTITION_ELEMENT_INCLUDED */

=== modified file 'sql/sql_base.cc'
--- sql/sql_base.cc	2013-03-12 16:04:31 +0000
+++ sql/sql_base.cc	2013-03-15 15:58:26 +0000
@@ -6010,14 +6010,14 @@ bool rm_temporary_table(handlerton *base
   if (mysql_file_delete(key_file_frm, path, MYF(0)))
     error=1; /* purecov: inspected */
   *ext= 0;				// remove extension
-  file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
+  file= get_fake_handler(current_thd->mem_root, base);
   if (file && file->ha_delete_table(path))
   {
     error=1;
     sql_print_warning("Could not remove temporary table: '%s', error: %d",
                       path, my_errno);
   }
-  delete file;
+  delete_fake_handler(file);
   DBUG_RETURN(error);
 }
 
@@ -9085,8 +9085,7 @@ my_bool mysql_rm_tmp_tables(void)
           filePathCopy[filePath_len - ext_len]= 0;
           init_tmp_table_share(thd, &share, "", 0, "", filePathCopy);
           if (!open_table_def(thd, &share) &&
-              ((handler_file= get_new_handler(&share, thd->mem_root,
-                                              share.db_type()))))
+              ((handler_file= share.ha_share->ha_create_handler(thd->mem_root))))
           {
             handler_file->ha_delete_table(filePathCopy);
             delete handler_file;

=== modified file 'sql/sql_derived.cc'
--- sql/sql_derived.cc	2012-03-17 08:26:58 +0000
+++ sql/sql_derived.cc	2013-03-15 15:58:26 +0000
@@ -691,7 +691,6 @@ bool mysql_derived_prepare(THD *thd, LEX
   {
     TABLE *table= derived->table;
     table->derived_select_number= first_select->select_number;
-    table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
     if (derived->referencing_view)
       table->grant= derived->grant;

=== modified file 'sql/sql_partition.cc'
--- sql/sql_partition.cc	2013-02-27 11:23:42 +0000
+++ sql/sql_partition.cc	2013-03-15 15:58:26 +0000
@@ -4203,7 +4203,7 @@ bool mysql_unpack_partition(THD *thd,
     *work_part_info_used= true;
   }
   table->part_info= part_info;
-  table->file->set_part_info(part_info);
+  table->file->set_part_info(part_info, 0);
   if (!part_info->default_engine_type)
     part_info->default_engine_type= default_db_type;
   DBUG_ASSERT(part_info->default_engine_type == default_db_type);

=== modified file 'sql/sql_partition.h'
--- sql/sql_partition.h	2013-03-06 10:55:44 +0000
+++ sql/sql_partition.h	2013-03-15 15:58:26 +0000
@@ -84,7 +84,6 @@ char *are_partitions_in_table(partition_
 bool check_reorganise_list(partition_info *new_part_info,
                            partition_info *old_part_info,
                            List<char> list_part_names);
-handler *get_ha_partition(partition_info *part_info);
 int get_parts_for_update(const uchar *old_data, uchar *new_data,
                          const uchar *rec0, partition_info *part_info,
                          uint32 *old_part_id, uint32 *new_part_id,

=== modified file 'sql/sql_select.cc'
--- sql/sql_select.cc	2013-02-03 14:40:58 +0000
+++ sql/sql_select.cc	2013-03-15 15:58:26 +0000
@@ -14690,9 +14690,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PAR
       || (select_options & TMP_TABLE_FORCE_MYISAM)
       || thd->variables.tmp_table_size == 0)
   {
-    share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
-    table->file= get_new_handler(share, &table->mem_root,
-                                 share->db_type());
+    table->init_ha_share_and_file(TMP_ENGINE_HTON);
     if (group &&
 	(param->group_parts > table->file->max_key_parts() ||
 	 param->group_length > table->file->max_key_length()))
@@ -14700,9 +14698,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PAR
   }
   else
   {
-    share->db_plugin= ha_lock_engine(0, heap_hton);
-    table->file= get_new_handler(share, &table->mem_root,
-                                 share->db_type());
+    table->init_ha_share_and_file(heap_hton);
   }
   if (!table->file)
     goto err;
@@ -15678,9 +15674,8 @@ create_internal_tmp_table_from_heap2(THD
   new_table= *table;
   share= *table->s;
   new_table.s= &share;
-  new_table.s->db_plugin= ha_lock_engine(thd, hton);
-  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
-                                        new_table.s->db_type())))
+  new_table.init_ha_share_and_file(hton);
+  if (!new_table.file)
     DBUG_RETURN(1);				// End of memory
 
   save_proc_info=thd->proc_info;
@@ -15742,8 +15737,6 @@ create_internal_tmp_table_from_heap2(THD
   (void) table->file->ha_close();          // This deletes the table !
   delete table->file;
   table->file=0;
-  plugin_unlock(0, table->s->db_plugin);
-  share.db_plugin= my_plugin_lock(0, share.db_plugin);
   new_table.s= table->s;                       // Keep old share
   *table= new_table;
   *table->s= share;
@@ -15800,7 +15793,6 @@ free_tmp_table(THD *thd, TABLE *entry)
   if (entry->temp_pool_slot != MY_BIT_NONE)
     bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
 
-  plugin_unlock(0, entry->s->db_plugin);
   entry->alias.free();
 
   free_root(&own_root, MYF(0)); /* the table is allocated in its own root */

=== modified file 'sql/sql_show.cc'
--- sql/sql_show.cc	2013-03-12 17:28:58 +0000
+++ sql/sql_show.cc	2013-03-15 15:58:26 +0000
@@ -20,7 +20,8 @@
 #include "my_global.h"                          /* NO_EMBEDDED_ACCESS_CHECKS */
 #include "sql_priv.h"
 #include "unireg.h"
-#include "sql_acl.h"                        // fill_schema_*_privileges
+#include "sql_acl.h"     // TABLE_ACLS, check_grant, DB_ACLS, acl_get,
+                         // check_grant_db, fill_schema_*_privileges
 #include "sql_select.h"                         // For select_describe
 #include "sql_base.h"                       // close_tables_for_reopen
 #include "create_options.h"
@@ -36,15 +37,12 @@
 #include "sql_db.h"     // check_db_dir_existence, load_db_opt_by_name
 #include "sql_time.h"   // interval_type_to_name
 #include "tztime.h"                             // struct Time_zone
-#include "sql_acl.h"     // TABLE_ACLS, check_grant, DB_ACLS, acl_get,
-                         // check_grant_db
 #include "filesort.h"    // filesort_free_buffers
 #include "sp.h"
 #include "sp_head.h"
 #include "sp_pcontext.h"
 #include "set_var.h"
 #include "sql_trigger.h"
-#include "sql_derived.h"
 #include "sql_statistics.h"
 #include "sql_connect.h"
 #include "authors.h"
@@ -1849,7 +1847,7 @@ int store_create_info(THD *thd, TABLE_LI
       packet->append(STRING_WITH_LEN(" CONNECTION="));
       append_unescaped(packet, share->connect_string.str, share->connect_string.length);
     }
-    append_create_options(thd, packet, share->option_list);
+    append_create_options(thd, packet, share->ha_share->option_list);
     append_directory(thd, packet, "DATA",  create_info.data_file_name);
     append_directory(thd, packet, "INDEX", create_info.index_file_name);
   }
@@ -4819,10 +4817,10 @@ static int get_schema_tables_record(THD
     /* Collect table info from the table share */
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE
-    if (share->db_type() == partition_hton &&
-        share->partition_info_str_len)
+    if (share->db_type() == partition_hton)
     {
-      tmp_db_type= share->default_part_db_type;
+      hs_partition *hs= static_cast<hs_partition *>(share->ha_share);
+      tmp_db_type= hs->default_part_db_type;
       is_partitioned= TRUE;
     }
 #endif
@@ -4892,7 +4890,7 @@ static int get_schema_tables_record(THD
       str.qs_append(STRING_WITH_LEN(" transactional="));
       str.qs_append(ha_choice_values[(uint) share->transactional]);
     }
-    append_create_options(thd, &str, share->option_list);
+    append_create_options(thd, &str, share->ha_share->option_list);
 
     if (str.length())
       table->field[19]->store(str.ptr()+1, str.length()-1, cs);

=== modified file 'sql/sql_table.cc'
--- sql/sql_table.cc	2013-03-12 16:04:31 +0000
+++ sql/sql_table.cc	2013-03-15 15:58:26 +0000
@@ -43,6 +43,7 @@
 #include "my_pthread.h"                // pthread_mutex_t
 #include "log_event.h"                 // Query_log_event
 #include "sql_statistics.h"
+#include "ha_partition.h"
 #include <hash.h>
 #include <myisam.h>
 #include <my_dir.h>
@@ -970,7 +971,7 @@ static int execute_ddl_log_action(THD *t
       goto error;
     }
     hton= plugin_data(plugin, handlerton*);
-    file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton);
+    file= get_fake_handler(&mem_root, hton);
     if (!file)
     {
       mem_alloc_error(sizeof(handler));
@@ -1050,7 +1051,7 @@ static int execute_ddl_log_action(THD *t
       DBUG_ASSERT(0);
       break;
   }
-  delete file;
+  delete_fake_handler(file);
 error:
   free_root(&mem_root, MYF(0)); 
   DBUG_RETURN(error);
@@ -1763,6 +1764,7 @@ bool mysql_write_frm(ALTER_PARTITION_PAR
     if (part_info && (flags & WFRM_KEEP_SHARE))
     {
       TABLE_SHARE *share= lpt->table->s;
+      hs_partition *hs= static_cast<hs_partition *>(share->ha_share);
       char *tmp_part_syntax_str;
       if (!(part_syntax_buf= generate_partition_syntax(part_info,
                                                        &syntax_len,
@@ -1773,9 +1775,9 @@ bool mysql_write_frm(ALTER_PARTITION_PAR
         error= 1;
         goto err;
       }
-      if (share->partition_info_buffer_size < syntax_len + 1)
+      if (hs->partition_info_buffer_size < syntax_len + 1)
       {
-        share->partition_info_buffer_size= syntax_len+1;
+        hs->partition_info_buffer_size= syntax_len+1;
         if (!(tmp_part_syntax_str= (char*) strmake_root(&share->mem_root,
                                                         part_syntax_buf,
                                                         syntax_len)))
@@ -1783,12 +1785,12 @@ bool mysql_write_frm(ALTER_PARTITION_PAR
           error= 1;
           goto err;
         }
-        share->partition_info_str= tmp_part_syntax_str;
+        hs->partition_info_str= tmp_part_syntax_str;
       }
       else
-        memcpy((char*) share->partition_info_str, part_syntax_buf,
+        memcpy((char*) hs->partition_info_str, part_syntax_buf,
                syntax_len + 1);
-      share->partition_info_str_len= part_info->part_info_len= syntax_len;
+      hs->partition_info_str_len= part_info->part_info_len= syntax_len;
       part_info->part_info_string= part_syntax_buf;
     }
 #endif
@@ -4065,8 +4067,7 @@ handler *mysql_create_frm_image(THD *thd
       create_info->row_type != ROW_TYPE_FIXED &&
       create_info->row_type != ROW_TYPE_DEFAULT)
     db_options|= HA_OPTION_PACK_RECORD;
-  if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
-                              create_info->db_type)))
+  if (!(file= get_fake_handler(thd->mem_root, create_info->db_type)))
   {
     mem_alloc_error(sizeof(handler));
     DBUG_RETURN(NULL);
@@ -4180,10 +4181,14 @@ handler *mysql_create_frm_image(THD *thd
       */
       DBUG_PRINT("info", ("db_type: %s",
                         ha_resolve_storage_engine_name(create_info->db_type)));
-      delete file;
+      delete_fake_handler(file);
       create_info->db_type= partition_hton;
-      if (!(file= get_ha_partition(part_info)))
+      if (!(file= get_fake_handler(thd->mem_root, partition_hton)))
         DBUG_RETURN(NULL);
+      file->set_part_info(part_info, 1);
+      if (((ha_partition*)file)->initialize_partition(thd->mem_root))
+        goto err;
+     file->init();
 
       /*
         If we have default number of partitions or subpartitions we
@@ -4221,9 +4226,8 @@ handler *mysql_create_frm_image(THD *thd
         We have switched engine from defaults, most likely only specified
         engines in partition clauses.
       */
-      delete file;
-      if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
-                                  engine_type)))
+      delete_fake_handler(file);
+      if (!(file= get_fake_handler(thd->mem_root, engine_type)))
       {
         mem_alloc_error(sizeof(handler));
         DBUG_RETURN(NULL);
@@ -4246,7 +4250,7 @@ handler *mysql_create_frm_image(THD *thd
     DBUG_RETURN(file);
 
 err:
-  delete file;
+  delete_fake_handler(file);
   DBUG_RETURN(NULL);
 }
 
@@ -4374,7 +4378,8 @@ bool mysql_create_table_no_lock(THD *thd
     /* prepare everything for discovery */
     share.field= &no_fields;
     share.db_plugin= plugin_int_to_ref(hton2plugin[hton->slot]);
-    share.option_list= create_info->option_list;
+    share.ha_share= hton->create_share(hton, &share, &share.mem_root);
+    share.ha_share->option_list= create_info->option_list;
     share.connect_string= create_info->connect_string;
 
     if (parse_engine_table_options(thd, hton, &share))
@@ -4448,7 +4453,7 @@ bool mysql_create_table_no_lock(THD *thd
 err:
   thd_proc_info(thd, "After create");
   my_free(const_cast<uchar*>(frm.str));
-  delete file;
+  delete_fake_handler(file);
   DBUG_RETURN(error);
 
 warn:
@@ -4590,8 +4595,7 @@ mysql_rename_table(handlerton *base, con
   DBUG_PRINT("enter", ("old: '%s'.'%s'  new: '%s'.'%s'",
                        old_db, old_name, new_db, new_name));
 
-  file= (base == NULL ? 0 :
-         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
+  file= (base == NULL ? 0 : get_fake_handler(thd->mem_root, base));
 
   build_table_filename(from, sizeof(from) - 1, old_db, old_name, "",
                        flags & FN_FROM_IS_TMP);
@@ -4633,7 +4637,7 @@ mysql_rename_table(handlerton *base, con
       }
     }
   }
-  delete file;
+  delete_fake_handler(file);
   if (error == HA_ERR_WRONG_COMMAND)
     my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
   else if (error)
@@ -5529,7 +5533,7 @@ mysql_prepare_alter_table(THD *thd, TABL
 
   restore_record(table, s->default_values);     // Empty record for DEFAULT
 
-  create_info->option_list= merge_engine_table_options(table->s->option_list,
+  create_info->option_list= merge_engine_table_options(table->s->ha_share->option_list,
                                         create_info->option_list, thd->mem_root);
   /*
     First collect all fields from table which isn't in drop_list

=== modified file 'sql/table.cc'
--- sql/table.cc	2013-03-10 20:42:03 +0000
+++ sql/table.cc	2013-03-15 15:58:26 +0000
@@ -41,6 +41,7 @@
 #include "sql_statistics.h"
 #include "discover.h"
 #include "mdl.h"                 // MDL_wait_for_graph_visitor
+#include "ha_partition.h"        // hs_partition
 
 /* INFORMATION_SCHEMA name */
 LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
@@ -449,18 +450,12 @@ void TABLE_SHARE::destroy()
       info_it->flags= 0;
     }
   }
-  if (ha_data_destroy)
+  if (ha_share)
   {
-    ha_data_destroy(ha_data);
-    ha_data_destroy= NULL;
+    delete ha_share;
+    ha_share= NULL;
   }
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-  if (ha_part_data_destroy)
-  {
-    ha_part_data_destroy(ha_part_data);
-    ha_part_data_destroy= NULL;
-  }
-#endif /* WITH_PARTITION_STORAGE_ENGINE */
+
   /*
     Make a copy since the share is allocated in its own root,
     and free_root() updates its argument after freeing the memory.
@@ -717,7 +712,7 @@ int TABLE_SHARE::init_from_binary_frm_im
   ulong *rec_per_key= NULL;
   ulong rec_buff_length;
   handler *handler_file= 0;
-  KEY	*keyinfo;
+  handlerton *hton;
   KEY_PART_INFO *key_part= NULL;
   Field  **field_ptr, *reg_field;
   const char **interval_array;
@@ -728,14 +723,14 @@ int TABLE_SHARE::init_from_binary_frm_im
   char *vcol_screen_pos;
   const uchar *options= 0;
   KEY first_keyinfo;
+  KEY *keyinfo= &first_keyinfo;
   uint len;
   KEY_PART_INFO *first_key_part= NULL;
   uint ext_key_parts= 0;
   uint first_key_parts= 0;
   plugin_ref se_plugin= 0;
-  keyinfo= &first_keyinfo;
-  share->ext_key_parts= 0;
   MEM_ROOT **root_ptr, *old_root;
+  struct { LEX_CUSTRING info; uchar auto_partitioned; } partition={{0,0},0};
   DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
 
   root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
@@ -817,13 +812,6 @@ int TABLE_SHARE::init_from_binary_frm_im
   if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && frm_image[33] == 5)
     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]));
-#endif
   legacy_db_type= (enum legacy_db_type) (uint) frm_image[3];
   /*
     if the storage engine is dynamic, no point in resolving it by its
@@ -912,6 +900,7 @@ int TABLE_SHARE::init_from_binary_frm_im
     to change the type of this flag for an enumeration type.                 
   */   
 
+  share->ext_key_parts= 0;
   for (i=0 ; i < keys ; i++, keyinfo++)
   {
     if (new_frm_ver >= 3)
@@ -1118,33 +1107,14 @@ int TABLE_SHARE::init_from_binary_frm_im
     }
     if (next_chunk + 5 < buff_end)
     {
-      uint32 partition_info_str_len = uint4korr(next_chunk);
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-      if ((share->partition_info_buffer_size=
-             share->partition_info_str_len= partition_info_str_len))
-      {
-        if (!(share->partition_info_str= (char*)
-              memdup_root(&share->mem_root, next_chunk + 4,
-                          partition_info_str_len + 1)))
-        {
-          goto err;
-        }
-      }
-#else
-      if (partition_info_str_len)
-      {
-        DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined"));
-        goto err;
-      }
-#endif
-      next_chunk+= 5 + partition_info_str_len;
+      partition.info.length  = uint4korr(next_chunk);
+      partition.info.str     = next_chunk + 4;
+      next_chunk+= 5 + partition.info.length;
     }
     if (share->mysql_version >= 50110 && next_chunk < buff_end)
     {
       /* New auto_partitioned indicator introduced in 5.1.11 */
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-      share->auto_partitioned= *next_chunk;
-#endif
+      partition.auto_partitioned= *next_chunk;
       next_chunk++;
     }
     keyinfo= share->key_info;
@@ -1296,9 +1266,36 @@ int TABLE_SHARE::init_from_binary_frm_im
   if (keynames)
     fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
 
- /* Allocate handler */
-  if (!(handler_file= get_new_handler(share, thd->mem_root,
-                                      plugin_data(se_plugin, handlerton *))))
+  hton= plugin_data(se_plugin, handlerton *);
+
+  ha_share= hton->create_share(hton, share, &share->mem_root);
+  if (!ha_share)
+    goto err;
+
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+  if (hton == partition_hton)
+  {
+    hs_partition *hs= static_cast<hs_partition *>(ha_share);
+
+    if (frm_image[61] &&
+        !(hs->default_part_db_type= 
+          ha_checktype(thd, (enum legacy_db_type) (uint) frm_image[61], 1, 0)))
+      goto err;
+
+    hs->auto_partitioned= partition.auto_partitioned;
+    hs->partition_info_str= (char*)memdup_root(&mem_root, partition.info.str,
+                                               partition.info.length + 1);
+    hs->partition_info_str_len= partition.info.length;
+    hs->partition_info_buffer_size= partition.info.length;
+
+    if (!hs->partition_info_str)
+      goto err;
+  }
+#endif
+
+  /* Allocate handler */
+  handler_file= ha_share->ha_create_handler(thd->mem_root);
+  if (!handler_file)
     goto err;
 
   record= share->default_values-1;              /* Fieldstart = 1 */
@@ -1937,18 +1934,11 @@ int TABLE_SHARE::init_from_binary_frm_im
   delete handler_file;
   plugin_unlock(0, se_plugin);
   my_hash_free(&share->name_hash);
-  if (share->ha_data_destroy)
+  if (share->ha_share)
   {
-    share->ha_data_destroy(share->ha_data);
-    share->ha_data_destroy= NULL;
+    delete share->ha_share;
+    share->ha_share= NULL;
   }
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-  if (share->ha_part_data_destroy)
-  {
-    share->ha_part_data_destroy(share->ha_part_data);
-    share->ha_data_destroy= NULL;
-  }
-#endif /* WITH_PARTITION_STORAGE_ENGINE */
 
   if (!thd->is_error())
     open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
@@ -2057,12 +2047,16 @@ int TABLE_SHARE::init_from_sql_statement
                                &thd->lex->create_info, &thd->lex->alter_info,
                                C_ORDINARY_CREATE, &frm);
   error|= file == 0;
-  delete file;
+  delete_fake_handler(file);
 
   if (frm.str)
   {
-    option_list= 0;             // cleanup existing options ...
-    option_struct= 0;           // ... if it's an assisted discovery
+    if (ha_share)
+    {
+      /* assisted discovery: cleanup existing options before parsing frm */
+      ha_share->option_list= 0;
+      ha_share->option_struct= 0;
+    }
     error= init_from_binary_frm_image(thd, write, frm.str, frm.length);
   }
 
@@ -2092,7 +2086,7 @@ bool TABLE_SHARE::write_frm_image(const
 
 bool TABLE_SHARE::read_frm_image(const uchar **frm, size_t *len)
 {
-  if (partition_info_str)               // cannot discover a partition
+  if (db_type() == partition_hton)           // cannot discover a partition
   {
     DBUG_ASSERT(db_type()->discover_table == 0);
     return 1;
@@ -2455,8 +2449,8 @@ enum open_frm_error open_table_from_shar
   outparam->file= 0;
   if (!(prgflag & OPEN_FRM_FILE_ONLY))
   {
-    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
-                                          share->db_type())))
+    outparam->file= share->ha_share->ha_create_handler(&outparam->mem_root);
+    if (!outparam->file)
       goto err;
   }
   else
@@ -2633,7 +2627,7 @@ enum open_frm_error open_table_from_shar
   }
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE
-  if (share->partition_info_str_len && outparam->file)
+  if (share->db_type() == partition_hton && outparam->file)
   {
   /*
     In this execution we must avoid calling thd->change_item_tree since
@@ -2654,11 +2648,12 @@ enum open_frm_error open_table_from_shar
     thd->stmt_arena= &part_func_arena;
     bool tmp;
     bool work_part_info_used;
+    hs_partition *hs= static_cast<hs_partition *>(share->ha_share);
 
-    tmp= mysql_unpack_partition(thd, share->partition_info_str,
-                                share->partition_info_str_len,
+    tmp= mysql_unpack_partition(thd, hs->partition_info_str,
+                                hs->partition_info_str_len,
                                 outparam, is_create_table,
-                                share->default_part_db_type,
+                                hs->default_part_db_type,
                                 &work_part_info_used);
     if (tmp)
     {
@@ -2666,8 +2661,8 @@ enum open_frm_error open_table_from_shar
       thd->restore_active_arena(&part_func_arena, &backup_arena);
       goto partititon_err;
     }
-    outparam->part_info->is_auto_partitioned= share->auto_partitioned;
-    DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
+    outparam->part_info->is_auto_partitioned= hs->auto_partitioned;
+    DBUG_PRINT("info", ("autopartitioned: %u", hs->auto_partitioned));
     /* we should perform the fix_partition_func in either local or
        caller's arena depending on work_part_info_used value
     */
@@ -3193,7 +3188,7 @@ void update_create_info_from_table(HA_CR
   create_info->comment= share->comment;
   create_info->transactional= share->transactional;
   create_info->page_checksum= share->page_checksum;
-  create_info->option_list= share->option_list;
+  create_info->option_list= share->ha_share->option_list;
 
   DBUG_VOID_RETURN;
 }

=== modified file 'sql/table.h'
--- sql/table.h	2013-03-06 18:27:13 +0000
+++ sql/table.h	2013-03-15 15:58:26 +0000
@@ -496,19 +496,6 @@ typedef struct st_table_field_def
 } TABLE_FIELD_DEF;
 
 
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-/**
-  Partition specific ha_data struct.
-*/
-typedef struct st_ha_data_partition
-{
-  bool auto_inc_initialized;
-  mysql_mutex_t LOCK_auto_inc;                 /**< protecting auto_inc val */
-  ulonglong next_auto_inc_val;                 /**< first non reserved value */
-} HA_DATA_PARTITION;
-#endif
-
-
 class Table_check_intact
 {
 protected:
@@ -606,7 +593,7 @@ struct TABLE_SHARE
   TYPELIB keynames;			/* Pointers to keynames */
   TYPELIB fieldnames;			/* Pointer to fieldnames */
   TYPELIB *intervals;			/* pointer to interval info */
-  mysql_mutex_t LOCK_ha_data;           /* To protect access to ha_data */
+  mysql_mutex_t LOCK_ha_data;           /* To protect access to this share */
   TABLE_SHARE *next, **prev;            /* Link to unused shares */
 
   /*
@@ -618,9 +605,6 @@ struct TABLE_SHARE
 
   LEX_CUSTRING tabledef_version;
 
-  engine_option_value *option_list;     /* text options for table */
-  ha_table_option_struct *option_struct; /* structure with parsed options */
-
   /* The following is copied to each TABLE on OPEN */
   Field **field;
   Field **found_next_number_field;
@@ -671,6 +655,9 @@ struct TABLE_SHARE
            db_plugin ? plugin_data(db_plugin, handlerton*)
                      : NULL;
   }
+
+  handler_share *ha_share;
+
   enum row_type row_type;		/* How rows are stored */
   enum tmp_table_type tmp_table;
 
@@ -732,15 +719,6 @@ struct TABLE_SHARE
   */
   int cached_row_logging_check;
 
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-  /* filled in when reading from frm */
-  bool auto_partitioned;
-  char *partition_info_str;
-  uint  partition_info_str_len;
-  uint  partition_info_buffer_size;
-  handlerton *default_part_db_type;
-#endif
-
   /**
     Cache the checked structure of this table.
 
@@ -753,17 +731,6 @@ struct TABLE_SHARE
   */
   const TABLE_FIELD_DEF *table_field_def_cache;
 
-  /** place to store storage engine specific data */
-  void *ha_data;
-  void (*ha_data_destroy)(void *); /* An optional destructor for ha_data */
-
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-  /** place to store partition specific data, LOCK_ha_data hold while init. */
-  HA_DATA_PARTITION *ha_part_data;
-  /* Destructor for ha_part_data */
-  void (*ha_part_data_destroy)(HA_DATA_PARTITION *);
-#endif
-
   /** Instrumentation for this table share. */
   PSI_table_share *m_psi;
 
@@ -1327,6 +1294,20 @@ struct TABLE
   ulong actual_key_flags(KEY *keyinfo);
   int update_default_fields();
   inline ha_rows stat_records() { return used_stat_records; }
+
+  /* this helper comes handy when working with temp tables */
+  void init_ha_share_and_file(handlerton *hton)
+  {
+    DBUG_ASSERT(s->tmp_table == INTERNAL_TMP_TABLE ||
+                s->tmp_table == SYSTEM_TMP_TABLE);
+    DBUG_ASSERT(in_use);
+
+    s->db_plugin= ha_lock_engine(in_use, hton);
+
+    s->ha_share= hton->create_share(hton, s, &mem_root);
+
+    file= s->ha_share->ha_create_handler(&mem_root);
+  }
 };
 
 

=== modified file 'storage/archive/ha_archive.cc'
--- storage/archive/ha_archive.cc	2013-03-06 20:23:01 +0000
+++ storage/archive/ha_archive.cc	2013-03-15 15:58:26 +0000
@@ -118,9 +118,7 @@ extern "C" PSI_file_key arch_key_file_da
 #endif
 
 /* Static declarations for handerton */
-static handler *archive_create_handler(handlerton *hton, 
-                                       TABLE_SHARE *table, 
-                                       MEM_ROOT *mem_root);
+static handler *archive_create_handler(handler_share *hs, MEM_ROOT *mem_root);
 int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share);
 
 /*
@@ -133,11 +131,9 @@ int archive_discover(handlerton *hton, T
 */
 #define ARCHIVE_ROW_HEADER_SIZE 4
 
-static handler *archive_create_handler(handlerton *hton,
-                                       TABLE_SHARE *table, 
-                                       MEM_ROOT *mem_root)
+static handler *archive_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_archive(hton, table);
+  return new (mem_root) ha_archive(hs);
 }
 
 /*
@@ -256,8 +252,8 @@ int archive_db_done(void *p)
 }
 
 
-ha_archive::ha_archive(handlerton *hton, TABLE_SHARE *table_arg)
-  :handler(hton, table_arg), delayed_insert(0), bulk_insert(0)
+ha_archive::ha_archive(handler_share *hs)
+  :handler(hs), delayed_insert(0), bulk_insert(0)
 {
   /* Set our original buffer from pre-allocated memory */
   buffer.set((char *)byte_buffer, IO_SIZE, system_charset_info);

=== modified file 'storage/archive/ha_archive.h'
--- storage/archive/ha_archive.h	2013-02-27 11:23:42 +0000
+++ storage/archive/ha_archive.h	2013-03-15 15:58:26 +0000
@@ -80,7 +80,7 @@ class ha_archive: public handler
   int frm_compare(azio_stream *src);
 
 public:
-  ha_archive(handlerton *hton, TABLE_SHARE *table_arg);
+  ha_archive(handler_share *hs);
   ~ha_archive()
   {
   }

=== modified file 'storage/blackhole/ha_blackhole.cc'
--- storage/blackhole/ha_blackhole.cc	2013-03-12 17:02:37 +0000
+++ storage/blackhole/ha_blackhole.cc	2013-03-15 15:58:26 +0000
@@ -27,11 +27,9 @@
 
 /* Static declarations for handlerton */
 
-static handler *blackhole_create_handler(handlerton *hton,
-                                         TABLE_SHARE *table,
-                                         MEM_ROOT *mem_root)
+static handler *blackhole_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_blackhole(hton, table);
+  return new (mem_root) ha_blackhole(hs);
 }
 
 
@@ -47,9 +45,7 @@ static void free_share(st_blackhole_shar
 ** BLACKHOLE tables
 *****************************************************************************/
 
-ha_blackhole::ha_blackhole(handlerton *hton,
-                           TABLE_SHARE *table_arg)
-  :handler(hton, table_arg)
+ha_blackhole::ha_blackhole(handler_share *hs) :handler(hs)
 {}
 
 

=== modified file 'storage/blackhole/ha_blackhole.h'
--- storage/blackhole/ha_blackhole.h	2013-03-12 17:02:37 +0000
+++ storage/blackhole/ha_blackhole.h	2013-03-15 15:58:26 +0000
@@ -43,7 +43,7 @@ class ha_blackhole: public handler
   st_blackhole_share *share;
 
 public:
-  ha_blackhole(handlerton *hton, TABLE_SHARE *table_arg);
+  ha_blackhole(handler_share *hs);
   ~ha_blackhole()
   {
   }

=== modified file 'storage/csv/ha_tina.cc'
--- storage/csv/ha_tina.cc	2013-03-12 16:03:27 +0000
+++ storage/csv/ha_tina.cc	2013-03-15 15:58:26 +0000
@@ -81,7 +81,7 @@ extern "C" my_bool tina_check_status(voi
 /* Stuff for shares */
 mysql_mutex_t tina_mutex;
 static HASH tina_open_tables;
-static handler *tina_create_handler(handlerton *, TABLE_SHARE *, MEM_ROOT *);
+static handler *tina_create_handler(handler_share *, MEM_ROOT *);
 
 
 /*****************************************************************************
@@ -485,16 +485,13 @@ my_off_t find_eoln_buff(Transparent_file
 }
 
 
-static handler *tina_create_handler(handlerton *hton,
-                                    TABLE_SHARE *table, 
-                                    MEM_ROOT *mem_root)
+static handler *tina_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_tina(hton, table);
+  return new (mem_root) ha_tina(hs);
 }
 
 
-ha_tina::ha_tina(handlerton *hton, TABLE_SHARE *table_arg)
-  :handler(hton, table_arg),
+ha_tina::ha_tina(handler_share *hs) :handler(hs),
   /*
     These definitions are found in handler.h
     They are not probably completely right.

=== modified file 'storage/csv/ha_tina.h'
--- storage/csv/ha_tina.h	2013-02-27 11:23:42 +0000
+++ storage/csv/ha_tina.h	2013-03-15 15:58:26 +0000
@@ -94,7 +94,7 @@ class ha_tina: public handler
   int init_data_file();
 
 public:
-  ha_tina(handlerton *hton, TABLE_SHARE *table_arg);
+  ha_tina(handler_share *hs);
   ~ha_tina()
   {
     if (chain_alloced)

=== modified file 'storage/example/ha_example.cc'
--- storage/example/ha_example.cc	2013-02-27 11:23:42 +0000
+++ storage/example/ha_example.cc	2013-03-15 15:58:26 +0000
@@ -102,9 +102,7 @@
 #include "ha_example.h"
 #include "sql_class.h"
 
-static handler *example_create_handler(handlerton *hton,
-                                       TABLE_SHARE *table, 
-                                       MEM_ROOT *mem_root);
+static handler *example_create_handler(handler_share *hs, MEM_ROOT *mem_root);
 
 handlerton *example_hton;
 
@@ -364,15 +362,12 @@ static int free_share(EXAMPLE_SHARE *sha
   return 0;
 }
 
-static handler* example_create_handler(handlerton *hton,
-                                       TABLE_SHARE *table, 
-                                       MEM_ROOT *mem_root)
+static handler* example_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_example(hton, table);
+  return new (mem_root) ha_example(hs);
 }
 
-ha_example::ha_example(handlerton *hton, TABLE_SHARE *table_arg)
-  :handler(hton, table_arg)
+ha_example::ha_example(handler_share *hs) :handler(hs)
 {}
 
 
@@ -401,7 +396,7 @@ int ha_example::open(const char *name, i
   thr_lock_data_init(&share->lock,&lock,NULL);
 
 #ifndef DBUG_OFF
-  ha_table_option_struct *options= table->s->option_struct;
+  ha_table_option_struct *options= table->s->ha_share->option_struct;
 
   DBUG_ASSERT(options);
   DBUG_PRINT("info", ("strparam: '%-.64s'  ullparam: %llu  enumparam: %u  "\
@@ -951,7 +946,7 @@ int ha_example::create(const char *name,
                        HA_CREATE_INFO *create_info)
 {
 #ifndef DBUG_OFF
-  ha_table_option_struct *options= table_arg->s->option_struct;
+  ha_table_option_struct *options= table_arg->s->ha_share->option_struct;
   DBUG_ENTER("ha_example::create");
   /*
     This example shows how to support custom engine specific table and field
@@ -1004,7 +999,7 @@ bool ha_example::check_if_incompatible_d
                       param_new->ullparam, param_new->enumparam,
                       param_new->boolparam));
 
-  param_old= table->s->option_struct;
+  param_old= table->s->ha_share->option_struct;
   DBUG_PRINT("info", ("old strparam: '%-.64s'  ullparam: %llu  enumparam: %u  "
                       "boolparam: %u",
                       (param_old->strparam ? param_old->strparam : "<NULL>"),

=== modified file 'storage/example/ha_example.h'
--- storage/example/ha_example.h	2013-02-27 11:23:42 +0000
+++ storage/example/ha_example.h	2013-03-15 15:58:26 +0000
@@ -62,7 +62,7 @@ class ha_example: public handler
   EXAMPLE_SHARE *share;    ///< Shared lock info
 
 public:
-  ha_example(handlerton *hton, TABLE_SHARE *table_arg);
+  ha_example(handler_share *hs);
   ~ha_example()
   {
   }

=== modified file 'storage/federated/ha_federated.cc'
--- storage/federated/ha_federated.cc	2013-02-27 11:23:42 +0000
+++ storage/federated/ha_federated.cc	2013-03-15 15:58:26 +0000
@@ -412,19 +412,15 @@ static const uint sizeof_trailing_and= s
 static const uint sizeof_trailing_where= sizeof(" WHERE ") - 1;
 
 /* Static declaration for handerton */
-static handler *federated_create_handler(handlerton *hton,
-                                         TABLE_SHARE *table,
-                                         MEM_ROOT *mem_root);
+static handler *federated_create_handler(handler_share *hs, MEM_ROOT *mem_root);
 static int federated_commit(handlerton *hton, THD *thd, bool all);
 static int federated_rollback(handlerton *hton, THD *thd, bool all);
 
 /* Federated storage engine handlerton */
 
-static handler *federated_create_handler(handlerton *hton, 
-                                         TABLE_SHARE *table,
-                                         MEM_ROOT *mem_root)
+static handler *federated_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_federated(hton, table);
+  return new (mem_root) ha_federated(hs);
 }
 
 
@@ -901,9 +897,7 @@ static int parse_url(MEM_ROOT *mem_root,
 ** FEDERATED tables
 *****************************************************************************/
 
-ha_federated::ha_federated(handlerton *hton,
-                           TABLE_SHARE *table_arg)
-  :handler(hton, table_arg),
+ha_federated::ha_federated(handler_share *hs) :handler(hs),
   mysql(0), stored_result(0)
 {
   trx_next= 0;

=== modified file 'storage/federated/ha_federated.h'
--- storage/federated/ha_federated.h	2013-02-27 11:23:42 +0000
+++ storage/federated/ha_federated.h	2013-03-15 15:58:26 +0000
@@ -123,7 +123,7 @@ class ha_federated: public handler
   int real_query(const char *query, size_t length);
   int real_connect();
 public:
-  ha_federated(handlerton *hton, TABLE_SHARE *table_arg);
+  ha_federated(handler_share *hs);
   ~ha_federated() {}
   /*
     Next pointer used in transaction

=== modified file 'storage/federatedx/ha_federatedx.cc'
--- storage/federatedx/ha_federatedx.cc	2013-03-12 16:04:31 +0000
+++ storage/federatedx/ha_federatedx.cc	2013-03-15 15:58:26 +0000
@@ -343,17 +343,13 @@ static const uint sizeof_trailing_and= s
 static const uint sizeof_trailing_where= sizeof(" WHERE ") - 1;
 
 /* Static declaration for handerton */
-static handler *federatedx_create_handler(handlerton *hton,
-                                         TABLE_SHARE *table,
-                                         MEM_ROOT *mem_root);
+static handler *federatedx_create_handler(handler_share *hs, MEM_ROOT *mem_root);
 
 /* FederatedX storage engine handlerton */
 
-static handler *federatedx_create_handler(handlerton *hton, 
-                                         TABLE_SHARE *table,
-                                         MEM_ROOT *mem_root)
+static handler *federatedx_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_federatedx(hton, table);
+  return new (mem_root) ha_federatedx(hs);
 }
 
 
@@ -828,9 +824,7 @@ static int parse_url(MEM_ROOT *mem_root,
 ** FEDERATEDX tables
 *****************************************************************************/
 
-ha_federatedx::ha_federatedx(handlerton *hton,
-                           TABLE_SHARE *table_arg)
-  :handler(hton, table_arg),
+ha_federatedx::ha_federatedx(handler_share *hs) :handler(hs),
    txn(0), io(0), stored_result(0)
 {
   bzero(&bulk_insert, sizeof(bulk_insert));

=== modified file 'storage/federatedx/ha_federatedx.h'
--- storage/federatedx/ha_federatedx.h	2013-03-10 10:49:49 +0000
+++ storage/federatedx/ha_federatedx.h	2013-03-15 15:58:26 +0000
@@ -311,7 +311,7 @@ class ha_federatedx: public handler
   int real_query(const char *query, uint length);
   int real_connect(FEDERATEDX_SHARE *my_share, uint create_flag);
 public:
-  ha_federatedx(handlerton *hton, TABLE_SHARE *table_arg);
+  ha_federatedx(handler_share *hs);
   ~ha_federatedx() {}
   /*
     The name of the index type that will be used for display

=== modified file 'storage/heap/ha_heap.cc'
--- storage/heap/ha_heap.cc	2013-03-12 16:04:31 +0000
+++ storage/heap/ha_heap.cc	2013-03-15 15:58:26 +0000
@@ -27,7 +27,7 @@
 #include "heapdef.h"
 #include "sql_base.h"                    // enum_tdc_remove_table_type
 
-static handler *heap_create_handler(handlerton *, TABLE_SHARE *, MEM_ROOT *);
+static handler *heap_create_handler(handler_share *, MEM_ROOT *);
 static int
 heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
                             HP_CREATE_INFO *hp_create_info);
@@ -56,11 +56,9 @@ int heap_init(void *p)
   return 0;
 }
 
-static handler *heap_create_handler(handlerton *hton,
-                                    TABLE_SHARE *table, 
-                                    MEM_ROOT *mem_root)
+static handler *heap_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_heap(hton, table);
+  return new (mem_root) ha_heap(hs);
 }
 
 
@@ -68,8 +66,8 @@ static handler *heap_create_handler(hand
 ** HEAP tables
 *****************************************************************************/
 
-ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
-  :handler(hton, table_arg), file(0), records_changed(0), key_stat_version(0), 
+ha_heap::ha_heap(handler_share *hs)
+  :handler(hs), file(0), records_changed(0), key_stat_version(0), 
   internal_table(0)
 {}
 
@@ -139,26 +137,6 @@ int ha_heap::close(void)
 }
 
 
-/*
-  Create a copy of this table
-
-  DESCRIPTION
-    Do same as default implementation but use file->s->name instead of 
-    table->s->path. This is needed by Windows where the clone() call sees
-    '/'-delimited path in table->s->path, while ha_heap::open() was called 
-    with '\'-delimited path.
-*/
-
-handler *ha_heap::clone(const char *name, MEM_ROOT *mem_root)
-{
-  handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
-  if (new_handler && !new_handler->ha_open(table, file->s->name, table->db_stat,
-                                           HA_OPEN_IGNORE_IF_LOCKED))
-    return new_handler;
-  return NULL;  /* purecov: inspected */
-}
-
-
 /*
   Compute which keys to use for scanning
 

=== modified file 'storage/heap/ha_heap.h'
--- storage/heap/ha_heap.h	2013-03-12 17:02:37 +0000
+++ storage/heap/ha_heap.h	2013-03-15 15:58:26 +0000
@@ -35,9 +35,8 @@ class ha_heap: public handler
   uint    key_stat_version;
   my_bool internal_table;
 public:
-  ha_heap(handlerton *hton, TABLE_SHARE *table);
+  ha_heap(handler_share *hs);
   ~ha_heap() {}
-  handler *clone(const char *name, MEM_ROOT *mem_root);
   const char *index_type(uint inx)
   {
     return ((table_share()->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- storage/innobase/handler/ha_innodb.cc	2013-03-12 16:04:31 +0000
+++ storage/innobase/handler/ha_innodb.cc	2013-03-15 15:58:26 +0000
@@ -352,7 +352,7 @@ static int innobase_savepoint(handlerton
 static int innobase_release_savepoint(handlerton *hton, THD* thd,
            void *savepoint);
 static void innobase_checkpoint_request(handlerton *hton, void *cookie);
-static handler *innobase_create_handler(handlerton *, TABLE_SHARE *, MEM_ROOT *);
+static handler *innobase_create_handler(handler_share *, MEM_ROOT *);
 
 /* "GEN_CLUST_INDEX" is the name reserved for Innodb default
 system primary index. */
@@ -451,11 +451,9 @@ static MYSQL_THDVAR_ULONG(lock_wait_time
   NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
 
-static handler *innobase_create_handler(handlerton *hton,
-                                        TABLE_SHARE *table,
-                                        MEM_ROOT *mem_root)
+static handler *innobase_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_innobase(hton, table);
+  return new (mem_root) ha_innobase(hs);
 }
 
 /*******************************************************************//**
@@ -1705,8 +1703,7 @@ trx_is_started(
 /*********************************************************************//**
 Construct ha_innobase handler. */
 UNIV_INTERN
-ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg)
-  :handler(hton, table_arg),
+ha_innobase::ha_innobase(handler_share *hs) :handler(hs),
   int_table_flags(HA_REC_NOT_IN_SEQ |
 		  HA_NULL_IN_KEY |
 		  HA_CAN_INDEX_BLOBS |

=== modified file 'storage/innobase/handler/ha_innodb.h'
--- storage/innobase/handler/ha_innodb.h	2013-01-15 18:13:32 +0000
+++ storage/innobase/handler/ha_innodb.h	2013-03-15 15:58:26 +0000
@@ -115,7 +115,7 @@ class ha_innobase: public handler
 
 	/* Init values for the class: */
  public:
-	ha_innobase(handlerton *hton, TABLE_SHARE *table_arg);
+	ha_innobase(handler_share *hs);
 	~ha_innobase();
 	/*
 	  Get the row type from the storage engine.  If this method returns

=== modified file 'storage/maria/ha_maria.cc'
--- storage/maria/ha_maria.cc	2013-03-12 17:02:37 +0000
+++ storage/maria/ha_maria.cc	2013-03-15 15:58:26 +0000
@@ -380,11 +380,9 @@ static void init_aria_psi_keys(void)
 ** MARIA tables
 *****************************************************************************/
 
-static handler *maria_create_handler(handlerton *hton,
-                                     TABLE_SHARE * table,
-                                     MEM_ROOT *mem_root)
+static handler *maria_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_maria(hton, table);
+  return new (mem_root) ha_maria(hs);
 }
 
 
@@ -962,8 +960,7 @@ my_bool ma_killed_in_mariadb(MARIA_HA *i
 */
 #define BULK_INSERT_NONE      0
 
-ha_maria::ha_maria(handlerton *hton, TABLE_SHARE *table_arg):
-handler(hton, table_arg), file(0),
+ha_maria::ha_maria(handler_share *hs): handler(hs), file(0),
 int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
                 HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
                 HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |

=== modified file 'storage/maria/ha_maria.h'
--- storage/maria/ha_maria.h	2013-02-27 11:23:42 +0000
+++ storage/maria/ha_maria.h	2013-03-15 15:58:26 +0000
@@ -57,7 +57,7 @@ class ha_maria :public handler
   int zerofill(THD * thd, HA_CHECK_OPT *check_opt);
 
 public:
-  ha_maria(handlerton *hton, TABLE_SHARE * table_arg);
+  ha_maria(handler_share *hs);
   ~ha_maria() {}
   handler *clone(const char *name, MEM_ROOT *mem_root);
   const char *index_type(uint key_number);

=== modified file 'storage/myisam/ha_myisam.cc'
--- storage/myisam/ha_myisam.cc	2013-03-12 17:02:37 +0000
+++ storage/myisam/ha_myisam.cc	2013-03-15 15:58:26 +0000
@@ -122,11 +122,9 @@ static void debug_wait_for_kill(const ch
 ** MyISAM tables
 *****************************************************************************/
 
-static handler *myisam_create_handler(handlerton *hton,
-                                      TABLE_SHARE *table, 
-                                      MEM_ROOT *mem_root)
+static handler *myisam_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_myisam(hton, table);
+  return new (mem_root) ha_myisam(hs);
 }
 
 // collect errors printed by mi_check routines
@@ -650,8 +648,7 @@ my_bool mi_killed_in_mariadb(MI_INFO *in
 
 }
 
-ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
-  :handler(hton, table_arg), file(0),
+ha_myisam::ha_myisam(handler_share *hs) :handler(hs), file(0),
   int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
                   HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
                   HA_CAN_VIRTUAL_COLUMNS |

=== modified file 'storage/myisam/ha_myisam.h'
--- storage/myisam/ha_myisam.h	2013-03-06 10:55:44 +0000
+++ storage/myisam/ha_myisam.h	2013-03-15 15:58:26 +0000
@@ -51,7 +51,7 @@ class ha_myisam: public handler
   int repair(THD *thd, HA_CHECK &param, bool optimize);
 
  public:
-  ha_myisam(handlerton *hton, TABLE_SHARE *table_arg);
+  ha_myisam(handler_share *hs);
   ~ha_myisam() {}
   handler *clone(const char *name, MEM_ROOT *mem_root);
   const char *index_type(uint key_number);

=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- storage/myisammrg/ha_myisammrg.cc	2013-03-12 17:02:37 +0000
+++ storage/myisammrg/ha_myisammrg.cc	2013-03-15 15:58:26 +0000
@@ -105,11 +105,9 @@
 #include "sql_class.h"                          // THD
 #include "debug_sync.h"
 
-static handler *myisammrg_create_handler(handlerton *hton,
-                                         TABLE_SHARE *table,
-                                         MEM_ROOT *mem_root)
+static handler *myisammrg_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_myisammrg(hton, table);
+  return new (mem_root) ha_myisammrg(hs);
 }
 
 
@@ -117,8 +115,7 @@ static handler *myisammrg_create_handler
   @brief Constructor
 */
 
-ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg)
-  :handler(hton, table_arg), file(0), is_cloned(0)
+ha_myisammrg::ha_myisammrg(handler_share *hs) :handler(hs), file(0), is_cloned(0)
 {
   init_sql_alloc(&children_mem_root,
                  FN_REFLEN + ALLOC_ROOT_MIN_BLOCK_SIZE, 0, MYF(0));
@@ -714,7 +711,7 @@ handler *ha_myisammrg::clone(const char
 {
   MYRG_TABLE    *u_table,*newu_table;
   ha_myisammrg *new_handler= 
-    (ha_myisammrg*) get_new_handler(table->s, mem_root, table->s->db_type());
+    (ha_myisammrg*) ha_share->ha_create_handler(mem_root);
   if (!new_handler)
     return NULL;
   

=== modified file 'storage/myisammrg/ha_myisammrg.h'
--- storage/myisammrg/ha_myisammrg.h	2013-03-12 17:02:37 +0000
+++ storage/myisammrg/ha_myisammrg.h	2013-03-15 15:58:26 +0000
@@ -81,7 +81,7 @@ class ha_myisammrg: public handler
   TABLE_LIST    **children_last_l;      /* children list end */
   uint          test_if_locked;         /* flags from ::open() */
 
-  ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg);
+  ha_myisammrg(handler_share *hs);
   ~ha_myisammrg();
   const char *index_type(uint key_number);
   ulonglong table_flags() const

=== modified file 'storage/perfschema/ha_perfschema.cc'
--- storage/perfschema/ha_perfschema.cc	2013-03-12 17:02:37 +0000
+++ storage/perfschema/ha_perfschema.cc	2013-03-15 15:58:26 +0000
@@ -42,11 +42,9 @@
 
 handlerton *pfs_hton= NULL;
 
-static handler* pfs_create_handler(handlerton *hton,
-                                   TABLE_SHARE *table,
-                                   MEM_ROOT *mem_root)
+static handler* pfs_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_perfschema(hton, table);
+  return new (mem_root) ha_perfschema(hs);
 }
 
 static int compare_database_names(const char *name1, const char *name2)
@@ -189,8 +187,8 @@ maria_declare_plugin(perfschema)
 }
 maria_declare_plugin_end;
 
-ha_perfschema::ha_perfschema(handlerton *hton, TABLE_SHARE *share)
-  : handler(hton, share), m_table_share(NULL), m_table(NULL)
+ha_perfschema::ha_perfschema(handler_share *hs)
+  : handler(hs), m_table_share(NULL), m_table(NULL)
 {}
 
 ha_perfschema::~ha_perfschema()

=== modified file 'storage/perfschema/ha_perfschema.h'
--- storage/perfschema/ha_perfschema.h	2013-02-06 18:17:12 +0000
+++ storage/perfschema/ha_perfschema.h	2013-03-15 15:58:26 +0000
@@ -38,7 +38,7 @@ extern const char *pfs_engine_name;
 class ha_perfschema : public handler
 {
 public:
-  ha_perfschema(handlerton *hton, TABLE_SHARE *share);
+  ha_perfschema(handler_share *hs);
 
   ~ha_perfschema();
 

=== modified file 'storage/sequence/sequence.cc'
--- storage/sequence/sequence.cc	2013-03-10 10:46:29 +0000
+++ storage/sequence/sequence.cc	2013-03-15 15:58:26 +0000
@@ -25,34 +25,42 @@
 #include <table.h>
 #include <field.h>
 
-typedef struct st_share {
-  const char *name;
+handlerton *ht_seq;
+
+class hs_seq: public handler_share
+{
+  public:
   THR_LOCK lock;
-  uint use_count;
-  struct st_share *next;
+
+  hs_seq(handlerton *h, TABLE_SHARE *s) : handler_share(h, s)
+  { thr_lock_init(&lock); }
+  ~hs_seq()
+  { thr_lock_delete(&lock); }
+  handler *create_handler(MEM_ROOT *where);
 
   ulonglong from, to, step;
   bool reverse;
-} SHARE;
+  ulonglong nvalues() { return (to - from)/step; }
+};
 
 class ha_seq: public handler
 {
 private:
   THR_LOCK_DATA lock;
-  SHARE *seqs;
   ulonglong cur;
 
 public:
-  ha_seq(handlerton *hton, TABLE_SHARE *table_arg)
-    : handler(hton, table_arg), seqs(0) { }
+  ha_seq(handler_share *hs) : handler(hs) { }
   ulonglong table_flags() const { return 0; }
 
+  hs_seq *seqs() { return static_cast<hs_seq*>(ha_share); };
+
   /* open/close/locking */
   int create(const char *name, TABLE *table_arg,
              HA_CREATE_INFO *create_info) { return HA_ERR_WRONG_COMMAND; }
 
   int open(const char *name, int mode, uint test_if_locked);
-  int close(void);
+  int close(void) { return 0; }
   THR_LOCK_DATA **store_lock(THD *, THR_LOCK_DATA **, enum thr_lock_type);
 
   /* table scan */
@@ -76,13 +84,12 @@ class ha_seq: public handler
   ha_rows records_in_range(uint inx, key_range *min_key,
                                    key_range *max_key);
 
-  double scan_time() { return nvalues(); }
+  double scan_time() { return seqs()->nvalues(); }
   double read_time(uint index, uint ranges, ha_rows rows) { return rows; }
   double keyread_time(uint index, uint ranges, ha_rows rows) { return rows; }
 
 private:
   void set(uchar *buf);
-  ulonglong nvalues() { return (seqs->to - seqs->from)/seqs->step; }
 };
 
 THR_LOCK_DATA **ha_seq::store_lock(THD *thd, THR_LOCK_DATA **to,
@@ -94,6 +101,12 @@ THR_LOCK_DATA **ha_seq::store_lock(THD *
   return to;
 }
 
+handler *hs_seq::create_handler(MEM_ROOT *where)
+{
+  return new (where) ha_seq(this);
+}
+
+
 void ha_seq::set(unsigned char *buf)
 {
   my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->write_set);
@@ -107,13 +120,13 @@ void ha_seq::set(unsigned char *buf)
 
 int ha_seq::rnd_init(bool scan)
 {
-  cur= seqs->reverse ? seqs->to : seqs->from;
+  cur= seqs()->reverse ? seqs()->to : seqs()->from;
   return 0;
 }
 
 int ha_seq::rnd_next(unsigned char *buf)
 {
-  if (seqs->reverse)
+  if (seqs()->reverse)
     return index_prev(buf);
   else
     return index_next(buf);
@@ -133,7 +146,7 @@ int ha_seq::rnd_pos(uchar *buf, uchar *p
 int ha_seq::info(uint flag)
 {
   if (flag & HA_STATUS_VARIABLE)
-    stats.records = nvalues();
+    stats.records = seqs()->nvalues();
   return 0;
 }
 
@@ -147,18 +160,18 @@ int ha_seq::index_read_map(uchar *buf, c
     key++;
     // fall through
   case HA_READ_KEY_OR_NEXT:
-    if (cur <= seqs->from)
-      cur= seqs->from;
+    if (cur <= seqs()->from)
+      cur= seqs()->from;
     else
     {
-      cur= (key - seqs->from + seqs->step - 1) / seqs->step * seqs->step + seqs->from;
-      if (cur >= seqs->to)
+      cur= (key - seqs()->from + seqs()->step - 1) / seqs()->step * seqs()->step + seqs()->from;
+      if (cur >= seqs()->to)
         return HA_ERR_KEY_NOT_FOUND;
     }
     return index_next(buf);
 
   case HA_READ_KEY_EXACT:
-    if ((key - seqs->from) % seqs->step != 0 || key < seqs->from || key >= seqs->to)
+    if ((key - seqs()->from) % seqs()->step != 0 || key < seqs()->from || key >= seqs()->to)
       return HA_ERR_KEY_NOT_FOUND;
     cur= key;
     return index_next(buf);
@@ -167,13 +180,13 @@ int ha_seq::index_read_map(uchar *buf, c
     key--;
     // fall through
   case HA_READ_PREFIX_LAST_OR_PREV:
-    if (key >= seqs->to)
-      cur= seqs->to;
+    if (key >= seqs()->to)
+      cur= seqs()->to;
     else
     {
-      if (cur < seqs->from)
+      if (cur < seqs()->from)
         return HA_ERR_KEY_NOT_FOUND;
-      cur= (key - seqs->from) / seqs->step * seqs->step + seqs->from;
+      cur= (key - seqs()->from) / seqs()->step * seqs()->step + seqs()->from;
     }
     return index_prev(buf);
   default: return HA_ERR_WRONG_COMMAND;
@@ -183,19 +196,19 @@ int ha_seq::index_read_map(uchar *buf, c
 
 int ha_seq::index_next(uchar *buf)
 {
-  if (cur == seqs->to)
+  if (cur == seqs()->to)
     return HA_ERR_END_OF_FILE;
   set(buf);
-  cur+= seqs->step;
+  cur+= seqs()->step;
   return 0;
 }
 
 
 int ha_seq::index_prev(uchar *buf)
 {
-  if (cur == seqs->from)
+  if (cur == seqs()->from)
     return HA_ERR_END_OF_FILE;
-  cur-= seqs->step;
+  cur-= seqs()->step;
   set(buf);
   return 0;
 }
@@ -203,56 +216,40 @@ int ha_seq::index_prev(uchar *buf)
 
 int ha_seq::index_first(uchar *buf)
 {
-  cur= seqs->from;
+  cur= seqs()->from;
   return index_next(buf);
 }
 
 
 int ha_seq::index_last(uchar *buf)
 {
-  cur= seqs->to;
+  cur= seqs()->to;
   return index_prev(buf);
 }
 
 ha_rows ha_seq::records_in_range(uint inx, key_range *min_key,
                                  key_range *max_key)
 {
-  ulonglong kmin= min_key ? uint8korr(min_key->key) : seqs->from;
-  ulonglong kmax= max_key ? uint8korr(max_key->key) : seqs->to;
-  if (kmin >= seqs->to || kmax < seqs->from || kmin > kmax)
+  ulonglong kmin= min_key ? uint8korr(min_key->key) : seqs()->from;
+  ulonglong kmax= max_key ? uint8korr(max_key->key) : seqs()->to;
+  if (kmin >= seqs()->to || kmax < seqs()->from || kmin > kmax)
     return 0;
-  return (kmax - seqs->from) / seqs->step -
-         (kmin - seqs->from + seqs->step - 1) / seqs->step + 1;
+  return (kmax - seqs()->from) / seqs()->step -
+         (kmin - seqs()->from + seqs()->step - 1) / seqs()->step + 1;
 }
 
 
 int ha_seq::open(const char *name, int mode, uint test_if_locked)
 {
-  mysql_mutex_lock(&table->s->LOCK_ha_data);
-  seqs= (SHARE*)table->s->ha_data;
-  DBUG_ASSERT(my_strcasecmp(table_alias_charset, name, seqs->name) == 0);
-  if (seqs->use_count++ == 0)
-    thr_lock_init(&seqs->lock);
-  mysql_mutex_unlock(&table->s->LOCK_ha_data);
-
   ref_length= sizeof(cur);
-  thr_lock_data_init(&seqs->lock,&lock,NULL);
-  return 0;
-}
-
-int ha_seq::close(void)
-{
-  mysql_mutex_lock(&table->s->LOCK_ha_data);
-  if (--seqs->use_count == 0)
-    thr_lock_delete(&seqs->lock);
-  mysql_mutex_unlock(&table->s->LOCK_ha_data);
+  thr_lock_data_init(&seqs()->lock,&lock,NULL);
   return 0;
 }
 
-static handler *create_handler(handlerton *hton, TABLE_SHARE *table,
-                               MEM_ROOT *mem_root)
+static handler_share *create_hs_seq(handlerton *hton, TABLE_SHARE *share,
+                                    MEM_ROOT *where)
 {
-  return new (mem_root) ha_seq(hton, table);
+  return new (where) hs_seq(hton, share);
 }
 
 static int discover_table(handlerton *hton, THD *thd, TABLE_SHARE *share)
@@ -290,15 +287,12 @@ static int discover_table(handlerton *ht
 
   to= (to - from) / step * step + step + from;
 
-  SHARE *seqs= (SHARE*)alloc_root(&share->mem_root, sizeof(*seqs));
-  bzero(seqs, sizeof(*seqs));
-  seqs->name = share->normalized_path.str;
+  hs_seq *seqs= static_cast<hs_seq*>(share->ha_share);
   seqs->from= from;
   seqs->to= to;
   seqs->step= step;
   seqs->reverse= reverse;
 
-  share->ha_data = seqs;
   return 0;
 }
 
@@ -307,14 +301,14 @@ static int dummy_ret_int() { return 0; }
 
 static int init(void *p)
 {
-  handlerton *hton = (handlerton *)p;
-  hton->create = create_handler;
-  hton->discover_table = discover_table;
-  hton->discover_table_existence =
+  ht_seq = (handlerton *)p;
+  ht_seq->create_share = create_hs_seq;
+  ht_seq->discover_table = discover_table;
+  ht_seq->discover_table_existence =
     (int (*)(handlerton *, const char *, const char *)) &dummy_ret_int;
-  hton->commit= hton->rollback= hton->prepare=
+  ht_seq->commit= ht_seq->rollback= ht_seq->prepare=
    (int (*)(handlerton *, THD *, bool)) &dummy_ret_int;
-  hton->savepoint_set= hton->savepoint_rollback= hton->savepoint_release=
+  ht_seq->savepoint_set= ht_seq->savepoint_rollback= ht_seq->savepoint_release=
    (int  (*)(handlerton *, THD *, void *)) &dummy_ret_int;
     
   return 0;

=== modified file 'storage/sphinx/ha_sphinx.cc'
--- storage/sphinx/ha_sphinx.cc	2013-03-12 16:04:31 +0000
+++ storage/sphinx/ha_sphinx.cc	2013-03-15 15:58:26 +0000
@@ -609,7 +609,7 @@ template int CSphSEQuery::ParseArray<lon
 #error Sphinx SE requires MySQL 5.1.14 or higher if compiling for 5.1.x series!
 #endif
 
-static handler *	sphinx_create_handler ( handlerton * hton, TABLE_SHARE * table, MEM_ROOT * mem_root );
+static handler *	sphinx_create_handler ( handler_share * hs, MEM_ROOT * mem_root );
 static int			sphinx_init_func ( void * p );
 static int			sphinx_close_connection ( handlerton * hton, THD * thd );
 static int			sphinx_panic ( handlerton * hton, enum ha_panic_function flag );
@@ -1220,10 +1220,9 @@ static int free_share ( CSphSEShare * pS
 
 
 #if MYSQL_VERSION_ID>50100
-static handler * sphinx_create_handler ( handlerton * hton, TABLE_SHARE * table, MEM_ROOT * mem_root )
+static handler * sphinx_create_handler ( handler_share * hs, MEM_ROOT * mem_root )
 {
-	sphinx_hton_ptr = hton;
-	return new ( mem_root ) ha_sphinx ( hton, table );
+	return new ( mem_root ) ha_sphinx ( hs );
 }
 #endif
 
@@ -2010,8 +2009,8 @@ int CSphSEQuery::BuildRequest ( char **
 ha_sphinx::ha_sphinx ( TABLE_ARG * table )
 	: handler ( &sphinx_hton, table )
 #else
-ha_sphinx::ha_sphinx ( handlerton * hton, TABLE_ARG * table )
-	: handler ( hton, table )
+ha_sphinx::ha_sphinx ( handler_share * hs )
+	: handler ( hs )
 #endif
 	, m_pShare ( NULL )
 	, m_iMatchesTotal ( 0 )

=== modified file 'storage/sphinx/ha_sphinx.h'
--- storage/sphinx/ha_sphinx.h	2013-02-06 18:17:12 +0000
+++ storage/sphinx/ha_sphinx.h	2013-03-15 15:58:26 +0000
@@ -51,7 +51,7 @@ class ha_sphinx : public handler
 #if MYSQL_VERSION_ID<50100
 					ha_sphinx ( TABLE_ARG * table_arg ); // NOLINT
 #else
-					ha_sphinx ( handlerton * hton, TABLE_ARG * table_arg );
+					ha_sphinx ( handler_share * hs );
 #endif
 					~ha_sphinx ();
 

=== modified file 'storage/test_sql_discovery/test_sql_discovery.cc'
--- storage/test_sql_discovery/test_sql_discovery.cc	2013-03-10 10:46:29 +0000
+++ storage/test_sql_discovery/test_sql_discovery.cc	2013-03-15 15:58:26 +0000
@@ -40,22 +40,26 @@ static struct st_mysql_sys_var *sysvars[
   NULL
 };
 
-typedef struct st_share {
-  const char *name;
+static handlerton *hton_tsd;
+
+class hs_tsd: public handler_share
+{
+  public:
   THR_LOCK lock;
-  uint use_count;
-  struct st_share *next;
-} SHARE;
+  hs_tsd(handlerton *h, TABLE_SHARE *s) : handler_share(h, s)
+  { thr_lock_init(&lock); }
+  ~hs_tsd()
+  { thr_lock_delete(&lock); }
+  handler *create_handler(MEM_ROOT *where);
+};
 
 class ha_tsd: public handler
 {
 private:
   THR_LOCK_DATA lock;
-  SHARE *share;
 
 public:
-  ha_tsd(handlerton *hton, TABLE_SHARE *table_arg)
-    : handler(hton, table_arg) { }
+  ha_tsd(handler_share *hs) : handler(hs) { }
   ulonglong table_flags() const
   { // NO_TRANSACTIONS and everything that affects CREATE TABLE
     return HA_NO_TRANSACTIONS | HA_CAN_GEOMETRY | HA_NULL_IN_KEY |
@@ -82,51 +86,24 @@ class ha_tsd: public handler
   uint max_supported_keys() const { return 16; }
   int create(const char *name, TABLE *table_arg,
              HA_CREATE_INFO *create_info) { return HA_ERR_WRONG_COMMAND; }
-
-  int open(const char *name, int mode, uint test_if_locked);
-  int close(void);
+  int open(const char *name, int mode, uint test_if_locked)
+  {
+    hs_tsd *s= (hs_tsd*)ha_share;
+    thr_lock_data_init(& s->lock, &lock, NULL);
+    return 0;
+  }
+  int close(void) { return 0; }
 };
 
-static SHARE *find_or_create_share(const char *table_name, TABLE *table)
+handler *hs_tsd::create_handler(MEM_ROOT *where)
 {
-  SHARE *share;
-  for (share = (SHARE*)table->s->ha_data; share; share = share->next)
-    if (my_strcasecmp(table_alias_charset, table_name, share->name) == 0)
-      return share;
-
-  share = (SHARE*)alloc_root(&table->s->mem_root, sizeof(*share));
-  bzero(share, sizeof(*share));
-  share->name = strdup_root(&table->s->mem_root, table_name);
-  share->next = (SHARE*)table->s->ha_data;
-  table->s->ha_data = share;
-  return share;
-}
-
-int ha_tsd::open(const char *name, int mode, uint test_if_locked)
-{
-  mysql_mutex_lock(&table->s->LOCK_ha_data);
-  share = find_or_create_share(name, table);
-  if (share->use_count++ == 0)
-    thr_lock_init(&share->lock);
-  mysql_mutex_unlock(&table->s->LOCK_ha_data);
-  thr_lock_data_init(&share->lock,&lock,NULL);
-
-  return 0;
-}
-
-int ha_tsd::close(void)
-{
-  mysql_mutex_lock(&table->s->LOCK_ha_data);
-  if (--share->use_count == 0)
-    thr_lock_delete(&share->lock);
-  mysql_mutex_unlock(&table->s->LOCK_ha_data);
-  return 0;
+  return new (where) ha_tsd(this);
 }
 
-static handler *create_handler(handlerton *hton, TABLE_SHARE *table,
-                               MEM_ROOT *mem_root)
+static handler_share *create_hs_tsd(handlerton *hton, TABLE_SHARE *share,
+                                    MEM_ROOT *where)
 {
-  return new (mem_root) ha_tsd(hton, table);
+  return new (where) hs_tsd(hton, share);
 }
 
 static int discover_table(handlerton *hton, THD* thd, TABLE_SHARE *share)
@@ -146,9 +123,9 @@ static int discover_table(handlerton *ht
 
 static int init(void *p)
 {
-  handlerton *hton = (handlerton *)p;
-  hton->create = create_handler;
-  hton->discover_table = discover_table;
+  hton_tsd= (handlerton *)p;
+  hton_tsd->create_share = create_hs_tsd;
+  hton_tsd->discover_table = discover_table;
   return 0;
 }
 

=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- storage/xtradb/handler/ha_innodb.cc	2013-03-12 16:04:31 +0000
+++ storage/xtradb/handler/ha_innodb.cc	2013-03-15 15:58:26 +0000
@@ -391,7 +391,7 @@ static int innobase_savepoint(handlerton
 static int innobase_release_savepoint(handlerton *hton, THD* thd,
            void *savepoint);
 static void innobase_checkpoint_request(handlerton *hton, void *cookie);
-static handler *innobase_create_handler(handlerton *, TABLE_SHARE *, MEM_ROOT *);
+static handler *innobase_create_handler(handler_share *, MEM_ROOT *);
 /* "GEN_CLUST_INDEX" is the name reserved for Innodb default
 system primary index. */
 static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
@@ -511,11 +511,9 @@ static MYSQL_THDVAR_ULONG(merge_sort_blo
   "The block size used doing external merge-sort for secondary index creation.",
   NULL, NULL, 1UL << 20, 1UL << 20, 1UL << 30, 0);
 
-static handler *innobase_create_handler(handlerton *hton,
-                                        TABLE_SHARE *table,
-                                        MEM_ROOT *mem_root)
+static handler *innobase_create_handler(handler_share *hs, MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_innobase(hton, table);
+  return new (mem_root) ha_innobase(hs);
 }
 
 /*******************************************************************//**
@@ -1937,8 +1935,7 @@ trx_is_started(
 /*********************************************************************//**
 Construct ha_innobase handler. */
 UNIV_INTERN
-ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg)
-  :handler(hton, table_arg),
+ha_innobase::ha_innobase(handler_share *hs) :handler(hs),
   int_table_flags(HA_REC_NOT_IN_SEQ |
 		  HA_NULL_IN_KEY | HA_CAN_VIRTUAL_COLUMNS |
 		  HA_CAN_INDEX_BLOBS |

=== modified file 'storage/xtradb/handler/ha_innodb.h'
--- storage/xtradb/handler/ha_innodb.h	2013-02-06 18:17:12 +0000
+++ storage/xtradb/handler/ha_innodb.h	2013-03-15 15:58:26 +0000
@@ -115,7 +115,7 @@ class ha_innobase: public handler
 
 	/* Init values for the class: */
  public:
-	ha_innobase(handlerton *hton, TABLE_SHARE *table_arg);
+	ha_innobase(handler_share *hs);
 	~ha_innobase();
 	/*
 	  Get the row type from the storage engine.  If this method returns
------------------------------------------------------------
revno: 3588
committer: Sergei Golubchik <sergii@pisem.net>
branch nick: 10.0
timestamp: Tue 2013-03-12 18:28:58 +0100
message:
  remove handler::table_type() - the name is ancient and old, the method is
  almost a duplicate of handler::engine_name()
modified:
  sql/handler.cc
  sql/handler.h
  sql/lock.cc
  sql/sql_insert.cc
  sql/sql_show.cc
diff:
=== modified file 'sql/handler.cc'
--- sql/handler.cc	2013-03-12 17:02:37 +0000
+++ sql/handler.cc	2013-03-12 17:28:58 +0000
@@ -3185,14 +3185,14 @@ void handler::print_error(int error, myf
       temporary= get_error_message(error, &str);
       if (!str.is_empty())
       {
-	const char* engine= table_type();
 	if (temporary)
 	  my_error(ER_GET_TEMPORARY_ERRMSG, errflag, error, str.c_ptr(),
-                   engine);
+                   engine_name()->str);
 	else
         {
           SET_FATAL_ERROR;
-	  my_error(ER_GET_ERRMSG, errflag, error, str.c_ptr(), engine);
+	  my_error(ER_GET_ERRMSG, errflag, error, str.c_ptr(),
+                   engine_name()->str);
         }
       }
       else

=== modified file 'sql/handler.h'
--- sql/handler.h	2013-03-12 17:02:37 +0000
+++ sql/handler.h	2013-03-12 17:28:58 +0000
@@ -2502,7 +2502,6 @@ class handler :public Sql_alloc
   TABLE_SHARE *table_share() const { return m_table_share; }
   enum legacy_db_type db_type() const { return hton()->db_type; }
   LEX_STRING *engine_name() const { return hton_name(hton()); }
-  const char *table_type() const { return engine_name()->str; }
   const char **bas_ext() const { return hton()->tablefile_extensions; }
 
   virtual int get_default_no_partitions(HA_CREATE_INFO *create_info)

=== modified file 'sql/lock.cc'
--- sql/lock.cc	2012-05-08 12:27:44 +0000
+++ sql/lock.cc	2013-03-12 17:28:58 +0000
@@ -358,7 +358,7 @@ static int lock_external(THD *thd, TABLE
 
     if ((error=(*tables)->file->ha_external_lock(thd,lock_type)))
     {
-      print_lock_error(error, (*tables)->file->table_type());
+      print_lock_error(error, (*tables)->file->engine_name()->str);
       while (--i)
       {
         tables--;
@@ -673,7 +673,7 @@ static int unlock_external(THD *thd, TAB
       if ((error=(*table)->file->ha_external_lock(thd, F_UNLCK)))
       {
 	error_code=error;
-	print_lock_error(error_code, (*table)->file->table_type());
+	print_lock_error(error_code, (*table)->file->engine_name()->str);
       }
     }
     table++;

=== modified file 'sql/sql_insert.cc'
--- sql/sql_insert.cc	2013-03-10 10:45:27 +0000
+++ sql/sql_insert.cc	2013-03-12 17:28:58 +0000
@@ -3643,7 +3643,7 @@ bool select_insert::send_eof()
   killed_state killed_status= thd->killed;
   DBUG_ENTER("select_insert::send_eof");
   DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
-                       trans_table, table->file->table_type()));
+                       trans_table, table->file->engine_name()->str));
 
   error= (thd->locked_tables_mode <= LTM_LOCK_TABLES ?
           table->file->ha_end_bulk_insert() : 0);

=== modified file 'sql/sql_show.cc'
--- sql/sql_show.cc	2013-02-27 11:23:42 +0000
+++ sql/sql_show.cc	2013-03-12 17:28:58 +0000
@@ -1737,9 +1737,9 @@ int store_create_info(THD *thd, TABLE_LI
       packet->append(ha_resolve_storage_engine_name(
                         table->part_info->default_engine_type));
     else
-      packet->append(file->table_type());
+      packet->append(file->engine_name());
 #else
-      packet->append(file->table_type());
+      packet->append(file->engine_name());
 #endif
     }
------------------------------------------------------------
revno: 3587
committer: Sergei Golubchik <sergii@pisem.net>
branch nick: 10.0
timestamp: Tue 2013-03-12 18:02:37 +0100
message:
  make handler::table_share private, provide handler::table_share() accessor
modified:
  sql/ha_partition.cc
  sql/ha_partition.h
  sql/handler.cc
  sql/handler.h
  storage/blackhole/ha_blackhole.cc
  storage/blackhole/ha_blackhole.h
  storage/heap/ha_heap.h
  storage/maria/ha_maria.cc
  storage/myisam/ha_myisam.cc
  storage/myisammrg/ha_myisammrg.cc
  storage/myisammrg/ha_myisammrg.h
  storage/perfschema/ha_perfschema.cc
diff:
=== modified file 'sql/ha_partition.cc'
--- sql/ha_partition.cc	2013-03-12 16:04:31 +0000
+++ sql/ha_partition.cc	2013-03-12 17:02:37 +0000
@@ -398,7 +398,7 @@ bool ha_partition::initialize_partition(
     if (new_handlers_from_part_info(mem_root))
       DBUG_RETURN(1);
   }
-  else if (!table_share || !table_share->normalized_path.str)
+  else if (!table_share() || !table_share()->normalized_path.str)
   {
     /*
       Called with dummy table share (delete, rename and alter table).
@@ -406,7 +406,7 @@ bool ha_partition::initialize_partition(
     */
     DBUG_RETURN(0);
   }
-  else if (get_from_handler_file(table_share->normalized_path.str,
+  else if (get_from_handler_file(table_share()->normalized_path.str,
                                  mem_root, false))
   {
     my_error(ER_FAILED_READ_FROM_PAR_FILE, MYF(0));
@@ -1186,7 +1186,7 @@ int ha_partition::handle_opt_partitions(
                 error != HA_ADMIN_ALREADY_DONE &&
                 error != HA_ADMIN_TRY_ALTER)
             {
-              print_admin_msg(thd, "error", table_share->db.str,
+              print_admin_msg(thd, "error", table_share()->db.str,
                               table->alias.c_ptr(),
                               opt_op_name[flag],
                               "Subpartition %s returned error", 
@@ -1213,7 +1213,7 @@ int ha_partition::handle_opt_partitions(
               error != HA_ADMIN_ALREADY_DONE &&
               error != HA_ADMIN_TRY_ALTER)
           {
-            print_admin_msg(thd, "error", table_share->db.str,
+            print_admin_msg(thd, "error", table_share()->db.str,
                             table->alias.c_ptr(),
                             opt_op_name[flag], "Partition %s returned error", 
                             part_elem->partition_name);
@@ -1854,7 +1854,7 @@ void ha_partition::change_table_ptr(TABL
 {
   handler **file_array;
   table= table_arg;
-  table_share= share;
+  m_table_share= share;
   /*
     m_file can be NULL when using an old cached table in DROP TABLE, when the
     table just has REMOVED PARTITIONING, see Bug#42438
@@ -1993,7 +1993,7 @@ uint ha_partition::del_ren_cre_table(con
       if ((error= set_up_table_before_create(table_arg, from_buff,
                                              create_info, i, NULL)) ||
           parse_engine_table_options(ha_thd(), (*file)->hton(),
-                                     (*file)->table_share) ||
+                                     (*file)->table_share()) ||
           ((error= (*file)->ha_create(from_buff, table_arg, create_info))))
         goto create_error;
     }
@@ -2114,7 +2114,7 @@ my_bool ha_partition::reg_query_cache_de
   {
     DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s",
                           key,
-                          key + table_share->db.length + 1));
+                          key + table_share()->db.length + 1));
     /*
       As this can change from call to call, don't reset set
       thd->lex->safe_to_cache_query
@@ -2125,7 +2125,7 @@ my_bool ha_partition::reg_query_cache_de
   (++(*block_table))->n= ++(*n);
   if (!cache->insert_table(key_len,
                            key, (*block_table),
-                           table_share->db.length,
+                           table_share()->db.length,
                            type,
                            engine_callback, engine_data,
                            FALSE))
@@ -2140,7 +2140,7 @@ my_bool ha_partition::register_query_cac
                                           uint *n)
 {
   char *name;
-  uint prefix_length= table_share->table_cache_key.length + 3;
+  uint prefix_length= table_share()->table_cache_key.length + 3;
   uint num_parts= m_part_info->num_parts;
   uint num_subparts= m_part_info->num_subparts;
   uint i= 0;
@@ -2154,10 +2154,10 @@ my_bool ha_partition::register_query_cac
     DBUG_RETURN(FALSE); // nothing to register
 
   /* prepare static part of the key */
-  memmove(key, table_share->table_cache_key.str,
-          table_share->table_cache_key.length);
+  memmove(key, table_share()->table_cache_key.str,
+          table_share()->table_cache_key.length);
 
-  name= key + table_share->table_cache_key.length - 1;
+  name= key + table_share()->table_cache_key.length - 1;
   name[0]= name[2]= '#';
   name[1]= 'P';
   name+= 3;
@@ -2507,7 +2507,7 @@ bool ha_partition::create_handlers(MEM_R
   for (i= 0; i < m_tot_parts; i++)
   {
     handlerton *hton= plugin_data(m_engine_array[i], handlerton*);
-    if (!(m_file[i]= get_new_handler(table_share, mem_root,
+    if (!(m_file[i]= get_new_handler(table_share(), mem_root,
                                      hton)))
       DBUG_RETURN(TRUE);
     DBUG_PRINT("info", ("engine_type: %u", hton->db_type));
@@ -2571,7 +2571,7 @@ bool ha_partition::new_handlers_from_par
     {
       for (j= 0; j < m_part_info->num_subparts; j++)
       {
-	if (!(m_file[part_count++]= get_new_handler(table_share, mem_root,
+	if (!(m_file[part_count++]= get_new_handler(table_share(), mem_root,
                                                     part_elem->engine_type)))
           goto error;
 	DBUG_PRINT("info", ("engine_type: %u",
@@ -2580,7 +2580,7 @@ bool ha_partition::new_handlers_from_par
     }
     else
     {
-      if (!(m_file[part_count++]= get_new_handler(table_share, mem_root,
+      if (!(m_file[part_count++]= get_new_handler(table_share(), mem_root,
                                                   part_elem->engine_type)))
         goto error;
       DBUG_PRINT("info", ("engine_type: %u",
@@ -2831,11 +2831,11 @@ int ha_partition::open(const char *name,
   int error= HA_ERR_INITIALIZATION;
   handler **file;
   char name_buff[FN_REFLEN];
-  bool is_not_tmp_table= (table_share->tmp_table == NO_TMP_TABLE);
+  bool is_not_tmp_table= (table_share()->tmp_table == NO_TMP_TABLE);
   ulonglong check_table_flags;
   DBUG_ENTER("ha_partition::open");
 
-  DBUG_ASSERT(table->s == table_share);
+  DBUG_ASSERT(table->s == table_share());
   ref_length= 0;
   m_mode= mode;
   m_open_test_lock= test_if_locked;
@@ -2845,7 +2845,7 @@ int ha_partition::open(const char *name,
   name_buffer_ptr= m_name_buffer_ptr;
   m_start_key.length= 0;
   m_rec0= table->record[0];
-  m_rec_length= table_share->stored_rec_length;
+  m_rec_length= table_share()->stored_rec_length;
   if (!m_part_ids_sorted_by_num_of_records)
   {
     if (!(m_part_ids_sorted_by_num_of_records=
@@ -2966,33 +2966,33 @@ int ha_partition::open(const char *name,
   clear_handler_file();
 
   /*
-    Use table_share->ha_part_data to share auto_increment_value among
+    Use table_share()->ha_part_data to share auto_increment_value among
     all handlers for the same table.
   */
   if (is_not_tmp_table)
-    mysql_mutex_lock(&table_share->LOCK_ha_data);
-  if (!table_share->ha_part_data)
+    mysql_mutex_lock(&table_share()->LOCK_ha_data);
+  if (!table_share()->ha_part_data)
   {
     /* currently only needed for auto_increment */
-    table_share->ha_part_data= (HA_DATA_PARTITION*)
-                                   alloc_root(&table_share->mem_root,
+    table_share()->ha_part_data= (HA_DATA_PARTITION*)
+                                   alloc_root(&table_share()->mem_root,
                                               sizeof(HA_DATA_PARTITION));
-    if (!table_share->ha_part_data)
+    if (!table_share()->ha_part_data)
     {
       if (is_not_tmp_table)
-        mysql_mutex_unlock(&table_share->LOCK_ha_data);
+        mysql_mutex_unlock(&table_share()->LOCK_ha_data);
       goto err_handler;
     }
-    DBUG_PRINT("info", ("table_share->ha_part_data 0x%p",
-                        table_share->ha_part_data));
-    bzero(table_share->ha_part_data, sizeof(HA_DATA_PARTITION));
-    table_share->ha_part_data_destroy= ha_data_partition_destroy;
+    DBUG_PRINT("info", ("table_share()->ha_part_data 0x%p",
+                        table_share()->ha_part_data));
+    bzero(table_share()->ha_part_data, sizeof(HA_DATA_PARTITION));
+    table_share()->ha_part_data_destroy= ha_data_partition_destroy;
     mysql_mutex_init(key_PARTITION_LOCK_auto_inc,
-                     &table_share->ha_part_data->LOCK_auto_inc,
+                     &table_share()->ha_part_data->LOCK_auto_inc,
                      MY_MUTEX_INIT_FAST);
   }
   if (is_not_tmp_table)
-    mysql_mutex_unlock(&table_share->LOCK_ha_data);
+    mysql_mutex_unlock(&table_share()->LOCK_ha_data);
   /*
     Some handlers update statistics as part of the open call. This will in
     some cases corrupt the statistics of the partition handler and thus
@@ -3043,7 +3043,7 @@ handler *ha_partition::clone(const char
   ha_partition *new_handler;
 
   DBUG_ENTER("ha_partition::clone");
-  new_handler= new (mem_root) ha_partition(partition_hton, table_share,
+  new_handler= new (mem_root) ha_partition(partition_hton, table_share(),
                                            m_part_info, this, mem_root);
   /*
     Allocate new_handler->ref here because otherwise ha_open will allocate it
@@ -3088,7 +3088,7 @@ int ha_partition::close(void)
   handler **file;
   DBUG_ENTER("ha_partition::close");
 
-  DBUG_ASSERT(table->s == table_share);
+  DBUG_ASSERT(table->s == table_share());
   destroy_record_priority_queue();
   bitmap_free(&m_bulk_insert_started);
   bitmap_free(&m_key_not_found_partitions);
@@ -3460,11 +3460,11 @@ int ha_partition::write_row(uchar * buf)
   */
   if (have_auto_increment)
   {
-    if (!table_share->ha_part_data->auto_inc_initialized &&
-        !table_share->next_number_keypart)
+    if (!table_share()->ha_part_data->auto_inc_initialized &&
+        !table_share()->next_number_keypart)
     {
       /*
-        If auto_increment in table_share is not initialized, start by
+        If auto_increment in table_share() is not initialized, start by
         initializing it.
       */
       info(HA_STATUS_AUTO);
@@ -3621,7 +3621,7 @@ int ha_partition::update_row(const uchar
 exit:
   /*
     if updating an auto_increment column, update
-    table_share->ha_part_data->next_auto_inc_val if needed.
+    table_share()->ha_part_data->next_auto_inc_val if needed.
     (not to be used if auto_increment on secondary field in a multi-column
     index)
     mysql_update does not set table->next_number_field, so we use
@@ -3634,7 +3634,7 @@ int ha_partition::update_row(const uchar
       bitmap_is_set(table->write_set,
                     table->found_next_number_field->field_index))
   {
-    if (!table_share->ha_part_data->auto_inc_initialized)
+    if (!table_share()->ha_part_data->auto_inc_initialized)
       info(HA_STATUS_AUTO);
     set_auto_increment_if_higher(table->found_next_number_field);
   }
@@ -3745,8 +3745,8 @@ int ha_partition::truncate()
     it so that it will be initialized again at the next use.
   */
   lock_auto_increment();
-  table_share->ha_part_data->next_auto_inc_val= 0;
-  table_share->ha_part_data->auto_inc_initialized= FALSE;
+  table_share()->ha_part_data->next_auto_inc_val= 0;
+  table_share()->ha_part_data->auto_inc_initialized= FALSE;
   unlock_auto_increment();
 
   file= m_file;
@@ -3787,8 +3787,8 @@ int ha_partition::truncate_partition(Alt
     it so that it will be initialized again at the next use.
   */
   lock_auto_increment();
-  table_share->ha_part_data->next_auto_inc_val= 0;
-  table_share->ha_part_data->auto_inc_initialized= FALSE;
+  table_share()->ha_part_data->next_auto_inc_val= 0;
+  table_share()->ha_part_data->auto_inc_initialized= FALSE;
   unlock_auto_increment();
 
   *binlog_stmt= true;
@@ -4392,7 +4392,7 @@ bool ha_partition::init_record_priority_
     /* Allocate record buffer for each used partition. */
     alloc_len= used_parts * (m_rec_length + PARTITION_BYTES_IN_POS);
     /* Allocate a key for temporary use when setting up the scan. */
-    alloc_len+= table_share->max_key_length;
+    alloc_len+= table_share()->max_key_length;
 
     if (!(m_ordered_rec_buffer= (uchar*)my_malloc(alloc_len, MYF(MY_WME))))
       DBUG_RETURN(true);
@@ -5703,23 +5703,23 @@ int ha_partition::info(uint flag)
 
   if (flag & HA_STATUS_AUTO)
   {
-    bool auto_inc_is_first_in_idx= (table_share->next_number_keypart == 0);
+    bool auto_inc_is_first_in_idx= (table_share()->next_number_keypart == 0);
     DBUG_PRINT("info", ("HA_STATUS_AUTO"));
     if (!table->found_next_number_field)
       stats.auto_increment_value= 0;
-    else if (table_share->ha_part_data->auto_inc_initialized)
+    else if (table_share()->ha_part_data->auto_inc_initialized)
     {
       lock_auto_increment();
-      stats.auto_increment_value= table_share->ha_part_data->next_auto_inc_val;
+      stats.auto_increment_value= table_share()->ha_part_data->next_auto_inc_val;
       unlock_auto_increment();
     }
     else
     {
       lock_auto_increment();
       /* to avoid two concurrent initializations, check again when locked */
-      if (table_share->ha_part_data->auto_inc_initialized)
+      if (table_share()->ha_part_data->auto_inc_initialized)
         stats.auto_increment_value=
-                                 table_share->ha_part_data->next_auto_inc_val;
+                                 table_share()->ha_part_data->next_auto_inc_val;
       else
       {
         handler *file, **file_array;
@@ -5739,11 +5739,11 @@ int ha_partition::info(uint flag)
         stats.auto_increment_value= auto_increment_value;
         if (auto_inc_is_first_in_idx)
         {
-          set_if_bigger(table_share->ha_part_data->next_auto_inc_val,
+          set_if_bigger(table_share()->ha_part_data->next_auto_inc_val,
                         auto_increment_value);
-          table_share->ha_part_data->auto_inc_initialized= TRUE;
+          table_share()->ha_part_data->auto_inc_initialized= TRUE;
           DBUG_PRINT("info", ("initializing next_auto_inc_val to %lu",
-                       (ulong) table_share->ha_part_data->next_auto_inc_val));
+                       (ulong) table_share()->ha_part_data->next_auto_inc_val));
         }
       }
       unlock_auto_increment();
@@ -7226,7 +7226,7 @@ int ha_partition::final_add_index(handle
                       "committing index failed, and when trying to revert "
                       "already committed partitions we failed allocating\n"
                       "memory for the index for table '%s'",
-                      table_share->table_name.str);
+                      table_share()->table_name.str);
       DBUG_RETURN(HA_ERR_OUT_OF_MEM);
     }
     old_key_info= table->key_info;
@@ -7254,7 +7254,7 @@ int ha_partition::final_add_index(handle
                         "committing index failed, and when trying to revert "
                         "already committed partitions we failed removing\n"
                         "the index for table '%s' partition nr %d",
-                        table_share->table_name.str, j);
+                        table_share()->table_name.str, j);
       }
     }
     else if (j > i)
@@ -7266,7 +7266,7 @@ int ha_partition::final_add_index(handle
         sql_print_error("Failed with error handling of adding index:\n"
                         "Rollback of add_index failed for table\n"
                         "'%s' partition nr %d",
-                        table_share->table_name.str, j);
+                        table_share()->table_name.str, j);
       }
     }
   }
@@ -7440,8 +7440,8 @@ int ha_partition::reset_auto_increment(u
   int res;
   DBUG_ENTER("ha_partition::reset_auto_increment");
   lock_auto_increment();
-  table_share->ha_part_data->auto_inc_initialized= FALSE;
-  table_share->ha_part_data->next_auto_inc_val= 0;
+  table_share()->ha_part_data->auto_inc_initialized= FALSE;
+  table_share()->ha_part_data->next_auto_inc_val= 0;
   do
   {
     if ((res= (*file)->ha_reset_auto_increment(value)) != 0)
@@ -7455,7 +7455,7 @@ int ha_partition::reset_auto_increment(u
 /**
   This method is called by update_auto_increment which in turn is called
   by the individual handlers as part of write_row. We use the
-  table_share->ha_part_data->next_auto_inc_val, or search all
+  table_share()->ha_part_data->next_auto_inc_val, or search all
   partitions for the highest auto_increment_value if not initialized or
   if auto_increment field is a secondary part of a key, we must search
   every partition when holding a mutex to be sure of correctness.
@@ -7511,9 +7511,9 @@ void ha_partition::get_auto_increment(ul
     /*
       This is initialized in the beginning of the first write_row call.
     */
-    DBUG_ASSERT(table_share->ha_part_data->auto_inc_initialized);
+    DBUG_ASSERT(table_share()->ha_part_data->auto_inc_initialized);
     /*
-      Get a lock for handling the auto_increment in table_share->ha_part_data
+      Get a lock for handling the auto_increment in table_share()->ha_part_data
       for avoiding two concurrent statements getting the same number.
     */ 
 
@@ -7540,8 +7540,8 @@ void ha_partition::get_auto_increment(ul
     }
 
     /* this gets corrected (for offset/increment) in update_auto_increment */
-    *first_value= table_share->ha_part_data->next_auto_inc_val;
-    table_share->ha_part_data->next_auto_inc_val+=
+    *first_value= table_share()->ha_part_data->next_auto_inc_val;
+    table_share()->ha_part_data->next_auto_inc_val+=
                                               nb_desired_values * increment;
 
     unlock_auto_increment();
@@ -7564,7 +7564,7 @@ void ha_partition::release_auto_incremen
   {
     ulonglong next_auto_inc_val;
     lock_auto_increment();
-    next_auto_inc_val= table_share->ha_part_data->next_auto_inc_val;
+    next_auto_inc_val= table_share()->ha_part_data->next_auto_inc_val;
     /*
       If the current auto_increment values is lower than the reserved
       value, and the reserved value was reserved by this thread,
@@ -7579,10 +7579,10 @@ void ha_partition::release_auto_incremen
         with SET INSERT_ID, i.e. forced/non generated values.
       */
       if (thd->auto_inc_intervals_forced.maximum() < next_insert_id)
-        table_share->ha_part_data->next_auto_inc_val= next_insert_id;
+        table_share()->ha_part_data->next_auto_inc_val= next_insert_id;
     }
-    DBUG_PRINT("info", ("table_share->ha_part_data->next_auto_inc_val: %lu",
-                        (ulong) table_share->ha_part_data->next_auto_inc_val));
+    DBUG_PRINT("info", ("table_share()->ha_part_data->next_auto_inc_val: %lu",
+                        (ulong) table_share()->ha_part_data->next_auto_inc_val));
 
     /* Unlock the multi row statement lock taken in get_auto_increment */
     if (auto_increment_safe_stmt_log_lock)

=== modified file 'sql/ha_partition.h'
--- sql/ha_partition.h	2013-03-12 16:04:31 +0000
+++ sql/ha_partition.h	2013-03-12 17:02:37 +0000
@@ -951,16 +951,16 @@ class ha_partition :public handler
     /* lock already taken */
     if (auto_increment_safe_stmt_log_lock)
       return;
-    DBUG_ASSERT(table_share->ha_part_data && !auto_increment_lock);
-    if(table_share->tmp_table == NO_TMP_TABLE)
+    DBUG_ASSERT(table_share()->ha_part_data && !auto_increment_lock);
+    if(table_share()->tmp_table == NO_TMP_TABLE)
     {
       auto_increment_lock= TRUE;
-      mysql_mutex_lock(&table_share->ha_part_data->LOCK_auto_inc);
+      mysql_mutex_lock(&table_share()->ha_part_data->LOCK_auto_inc);
     }
   }
   virtual void unlock_auto_increment()
   {
-    DBUG_ASSERT(table_share->ha_part_data);
+    DBUG_ASSERT(table_share()->ha_part_data);
     /*
       If auto_increment_safe_stmt_log_lock is true, we have to keep the lock.
       It will be set to false and thus unlocked at the end of the statement by
@@ -968,7 +968,7 @@ class ha_partition :public handler
     */
     if(auto_increment_lock && !auto_increment_safe_stmt_log_lock)
     {
-      mysql_mutex_unlock(&table_share->ha_part_data->LOCK_auto_inc);
+      mysql_mutex_unlock(&table_share()->ha_part_data->LOCK_auto_inc);
       auto_increment_lock= FALSE;
     }
   }
@@ -977,10 +977,10 @@ class ha_partition :public handler
     ulonglong nr= (((Field_num*) field)->unsigned_flag ||
                    field->val_int() > 0) ? field->val_int() : 0;
     lock_auto_increment();
-    DBUG_ASSERT(table_share->ha_part_data->auto_inc_initialized == TRUE);
+    DBUG_ASSERT(table_share()->ha_part_data->auto_inc_initialized == TRUE);
     /* must check when the mutex is taken */
-    if (nr >= table_share->ha_part_data->next_auto_inc_val)
-      table_share->ha_part_data->next_auto_inc_val= nr + 1;
+    if (nr >= table_share()->ha_part_data->next_auto_inc_val)
+      table_share()->ha_part_data->next_auto_inc_val= nr + 1;
     unlock_auto_increment();
   }
 

=== modified file 'sql/handler.cc'
--- sql/handler.cc	2013-03-12 16:04:31 +0000
+++ sql/handler.cc	2013-03-12 17:02:37 +0000
@@ -2322,7 +2322,7 @@ int handler::ha_open(TABLE *table_arg, c
               test_if_locked));
 
   table= table_arg;
-  DBUG_ASSERT(table->s == table_share);
+  DBUG_ASSERT(table->s == table_share());
   DBUG_ASSERT(alloc_root_inited(&table->mem_root));
 
   if ((error=open(name,mode,test_if_locked)))
@@ -3034,7 +3034,7 @@ void handler::print_error(int error, myf
         str.length(max_length-4);
         str.append(STRING_WITH_LEN("..."));
       }
-      my_error(ER_FOREIGN_DUPLICATE_KEY, errflag, table_share->table_name.str,
+      my_error(ER_FOREIGN_DUPLICATE_KEY, errflag, table_share()->table_name.str,
                str.c_ptr_safe(), key_nr+1);
       DBUG_VOID_RETURN;
     }
@@ -3128,8 +3128,8 @@ void handler::print_error(int error, myf
     textno=ER_TABLE_DEF_CHANGED;
     break;
   case HA_ERR_NO_SUCH_TABLE:
-    my_error(ER_NO_SUCH_TABLE_IN_ENGINE, errflag, table_share->db.str,
-             table_share->table_name.str);
+    my_error(ER_NO_SUCH_TABLE_IN_ENGINE, errflag, table_share()->db.str,
+             table_share()->table_name.str);
     DBUG_VOID_RETURN;
   case HA_ERR_RBR_LOGGING_FAILED:
     textno= ER_BINLOG_ROW_LOGGING_FAILED;
@@ -3219,11 +3219,11 @@ void handler::print_error(int error, myf
   {
     char buff[FN_REFLEN];
     strxnmov(buff, sizeof(buff),
-             table_share->normalized_path.str, bas_ext()[0], NULL);
+             table_share()->normalized_path.str, bas_ext()[0], NULL);
     my_error(textno, errflag, buff, error);
   }
   else
-    my_error(textno, errflag, table_share->table_name.str, error);
+    my_error(textno, errflag, table_share()->table_name.str, error);
   DBUG_VOID_RETURN;
 }
 
@@ -3551,10 +3551,10 @@ handler::mark_trx_read_write_part2()
   {
     DBUG_ASSERT(has_transactions());
     /*
-      table_share can be NULL in ha_delete_table(). See implementation
+      table_share() can be NULL in ha_delete_table(). See implementation
       of standalone function ha_delete_table() in sql_base.cc.
     */
-    if (table_share == NULL || table_share->tmp_table == NO_TMP_TABLE)
+    if (table_share() == NULL || table_share()->tmp_table == NO_TMP_TABLE)
       ha_info->set_trx_read_write();
   }
 }
@@ -5266,18 +5266,18 @@ int handler::ha_external_lock(THD *thd,
   {
     if (lock_type == F_RDLCK)
     {
-      MYSQL_HANDLER_RDLOCK_START(table_share->db.str,
-                                 table_share->table_name.str);
+      MYSQL_HANDLER_RDLOCK_START(table_share()->db.str,
+                                 table_share()->table_name.str);
     }
     else if (lock_type == F_WRLCK)
     {
-      MYSQL_HANDLER_WRLOCK_START(table_share->db.str,
-                                 table_share->table_name.str);
+      MYSQL_HANDLER_WRLOCK_START(table_share()->db.str,
+                                 table_share()->table_name.str);
     }
     else if (lock_type == F_UNLCK)
     {
-      MYSQL_HANDLER_UNLOCK_START(table_share->db.str,
-                                 table_share->table_name.str);
+      MYSQL_HANDLER_UNLOCK_START(table_share()->db.str,
+                                 table_share()->table_name.str);
     }
   }
 
@@ -5344,7 +5344,7 @@ int handler::ha_write_row(uchar *buf)
   DBUG_ENTER("handler::ha_write_row");
   DEBUG_SYNC_C("ha_write_row_start");
 
-  MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
+  MYSQL_INSERT_ROW_START(table_share()->db.str, table_share()->table_name.str);
   mark_trx_read_write();
   increment_statistics(&SSV::ha_write_count);
 
@@ -5372,7 +5372,7 @@ int handler::ha_update_row(const uchar *
    */
   DBUG_ASSERT(new_data == table->record[0]);
 
-  MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
+  MYSQL_UPDATE_ROW_START(table_share()->db.str, table_share()->table_name.str);
   mark_trx_read_write();
   increment_statistics(&SSV::ha_update_count);
 
@@ -5391,7 +5391,7 @@ int handler::ha_delete_row(const uchar *
   int error;
   Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
 
-  MYSQL_DELETE_ROW_START(table_share->db.str, table_share->table_name.str);
+  MYSQL_DELETE_ROW_START(table_share()->db.str, table_share()->table_name.str);
   mark_trx_read_write();
   increment_statistics(&SSV::ha_delete_count);
 

=== modified file 'sql/handler.h'
--- sql/handler.h	2013-03-12 16:04:31 +0000
+++ sql/handler.h	2013-03-12 17:02:37 +0000
@@ -1831,12 +1831,11 @@ class handler :public Sql_alloc
 public:
   typedef ulonglong Table_flags;
 protected:
-  TABLE_SHARE *table_share;   /* The table definition */
   TABLE *table;               /* The current open table */
   Table_flags cached_table_flags;       /* Set on init() and open() */
 private:
   handlerton *m_ht;                 /* storage engine of this handler */
-
+  TABLE_SHARE *m_table_share;   /* The table definition */
   ha_rows estimation_rows_to_insert;
 public:
   uchar *ref;				/* Pointer to current row */
@@ -1936,7 +1935,7 @@ class handler :public Sql_alloc
   PSI_table *m_psi;
 
   handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
-    :table_share(share_arg), table(0), m_ht(ht_arg),
+    :table(0), m_ht(ht_arg),m_table_share(share_arg),
     estimation_rows_to_insert(0),
     ref(0), end_range(NULL), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
     in_range_check_pushed_down(FALSE),
@@ -2101,7 +2100,7 @@ class handler :public Sql_alloc
   virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
   {
     table= table_arg;
-    table_share= share;
+    m_table_share= share;
     reset_statistics();
   }
   virtual double scan_time()
@@ -2500,6 +2499,7 @@ class handler :public Sql_alloc
   virtual void free_foreign_key_create_info(char* str) {}
   /** The following can be called without an open handler */
   handlerton *hton() const { return m_ht; }
+  TABLE_SHARE *table_share() const { return m_table_share; }
   enum legacy_db_type db_type() const { return hton()->db_type; }
   LEX_STRING *engine_name() const { return hton_name(hton()); }
   const char *table_type() const { return engine_name()->str; }
@@ -2809,11 +2809,11 @@ class handler :public Sql_alloc
   inline void psi_open()
   {
     DBUG_ASSERT(m_psi == NULL);
-    DBUG_ASSERT(table_share != NULL);
+    DBUG_ASSERT(table_share() != NULL);
 #ifdef HAVE_PSI_INTERFACE
     if (PSI_server)
     {
-      PSI_table_share *share_psi= ha_table_share_psi(table_share);
+      PSI_table_share *share_psi= ha_table_share_psi(table_share());
       if (share_psi)
         m_psi= PSI_server->open_table(share_psi, this);
     }

=== modified file 'storage/blackhole/ha_blackhole.cc'
--- storage/blackhole/ha_blackhole.cc	2013-02-27 11:23:42 +0000
+++ storage/blackhole/ha_blackhole.cc	2013-03-12 17:02:37 +0000
@@ -91,11 +91,11 @@ int ha_blackhole::truncate()
 const char *ha_blackhole::index_type(uint key_number)
 {
   DBUG_ENTER("ha_blackhole::index_type");
-  DBUG_RETURN((table_share->key_info[key_number].flags & HA_FULLTEXT) ? 
+  DBUG_RETURN((table_share()->key_info[key_number].flags & HA_FULLTEXT) ? 
               "FULLTEXT" :
-              (table_share->key_info[key_number].flags & HA_SPATIAL) ?
+              (table_share()->key_info[key_number].flags & HA_SPATIAL) ?
               "SPATIAL" :
-              (table_share->key_info[key_number].algorithm ==
+              (table_share()->key_info[key_number].algorithm ==
                HA_KEY_ALG_RTREE) ? "RTREE" : "BTREE");
 }
 

=== modified file 'storage/blackhole/ha_blackhole.h'
--- storage/blackhole/ha_blackhole.h	2013-02-27 11:23:42 +0000
+++ storage/blackhole/ha_blackhole.h	2013-03-12 17:02:37 +0000
@@ -61,7 +61,7 @@ class ha_blackhole: public handler
   }
   ulong index_flags(uint inx, uint part, bool all_parts) const
   {
-    return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
+    return ((table_share()->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
             0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
             HA_READ_ORDER | HA_KEYREAD_ONLY);
   }

=== modified file 'storage/heap/ha_heap.h'
--- storage/heap/ha_heap.h	2013-02-27 11:23:42 +0000
+++ storage/heap/ha_heap.h	2013-03-12 17:02:37 +0000
@@ -40,7 +40,7 @@ class ha_heap: public handler
   handler *clone(const char *name, MEM_ROOT *mem_root);
   const char *index_type(uint inx)
   {
-    return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
+    return ((table_share()->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
             "BTREE" : "HASH");
   }
   /* Rows also use a fixed-size format */
@@ -55,7 +55,7 @@ class ha_heap: public handler
   }
   ulong index_flags(uint inx, uint part, bool all_parts) const
   {
-    return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
+    return ((table_share()->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
             HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE :
             HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
   }

=== modified file 'storage/maria/ha_maria.cc'
--- storage/maria/ha_maria.cc	2013-03-12 16:04:31 +0000
+++ storage/maria/ha_maria.cc	2013-03-12 17:02:37 +0000
@@ -1011,11 +1011,11 @@ const char *ha_maria::index_type(uint ke
 ulong ha_maria::index_flags(uint inx, uint part, bool all_parts) const
 {
   ulong flags;
-  if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT)
+  if (table_share()->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT)
     flags= 0;
   else 
-  if ((table_share->key_info[inx].flags & HA_SPATIAL ||
-      table_share->key_info[inx].algorithm == HA_KEY_ALG_RTREE))
+  if ((table_share()->key_info[inx].flags & HA_SPATIAL ||
+      table_share()->key_info[inx].algorithm == HA_KEY_ALG_RTREE))
   {
     /* All GIS scans are non-ROR scans. We also disable IndexConditionPushdown */
     flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |

=== modified file 'storage/myisam/ha_myisam.cc'
--- storage/myisam/ha_myisam.cc	2013-03-12 16:04:31 +0000
+++ storage/myisam/ha_myisam.cc	2013-03-12 17:02:37 +0000
@@ -693,11 +693,11 @@ const char *ha_myisam::index_type(uint k
 ulong ha_myisam::index_flags(uint inx, uint part, bool all_parts) const
 {
   ulong flags;
-  if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT)
+  if (table_share()->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT)
     flags= 0;
   else 
-  if ((table_share->key_info[inx].flags & HA_SPATIAL ||
-      table_share->key_info[inx].algorithm == HA_KEY_ALG_RTREE))
+  if ((table_share()->key_info[inx].flags & HA_SPATIAL ||
+      table_share()->key_info[inx].algorithm == HA_KEY_ALG_RTREE))
   {
     /* All GIS scans are non-ROR scans. We also disable IndexConditionPushdown */
     flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |

=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- storage/myisammrg/ha_myisammrg.cc	2013-03-12 16:04:31 +0000
+++ storage/myisammrg/ha_myisammrg.cc	2013-03-12 17:02:37 +0000
@@ -1256,7 +1256,7 @@ int ha_myisammrg::info(uint flag)
     table->s->crashed= 1;
 #endif
   stats.data_file_length= mrg_info.data_file_length;
-  if (mrg_info.errkey >= (int) table_share->keys)
+  if (mrg_info.errkey >= (int) table_share()->keys)
   {
     /*
      If value of errkey is higher than the number of keys

=== modified file 'storage/myisammrg/ha_myisammrg.h'
--- storage/myisammrg/ha_myisammrg.h	2013-02-27 11:23:42 +0000
+++ storage/myisammrg/ha_myisammrg.h	2013-03-12 17:02:37 +0000
@@ -96,7 +96,7 @@ class ha_myisammrg: public handler
   }
   ulong index_flags(uint inx, uint part, bool all_parts) const
   {
-    return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
+    return ((table_share()->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
             0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
             HA_READ_ORDER | HA_KEYREAD_ONLY);
   }

=== modified file 'storage/perfschema/ha_perfschema.cc'
--- storage/perfschema/ha_perfschema.cc	2013-02-06 18:17:12 +0000
+++ storage/perfschema/ha_perfschema.cc	2013-03-12 17:02:37 +0000
@@ -200,8 +200,8 @@ int ha_perfschema::open(const char *name
 {
   DBUG_ENTER("ha_perfschema::open");
 
-  m_table_share= find_table_share(table_share->db.str,
-                                  table_share->table_name.str);
+  m_table_share= find_table_share(table_share()->db.str,
+                                  table_share()->table_name.str);
   if (! m_table_share)
     DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
 
@@ -410,7 +410,7 @@ void ha_perfschema::print_error(int erro
         which does not apply to performance schema tables.
       */
       my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0),
-               table_share->db.str, table_share->table_name.str);
+               table_share()->db.str, table_share()->table_name.str);
       break;
     case HA_ERR_WRONG_COMMAND:
       /*
------------------------------------------------------------
revno: 3586
committer: Sergei Golubchik <sergii@pisem.net>
branch nick: 10.0
timestamp: Tue 2013-03-12 17:04:31 +0100
message:
  make handler::ht private, provide handler::hton() accessor.
  fix storage engines that were using handler::ht to use a static variable instead.
modified:
  sql/ha_partition.cc
  sql/ha_partition.h
  sql/handler.cc
  sql/handler.h
  sql/log_event.cc
  sql/mysqld.cc
  sql/sql_admin.cc
  sql/sql_base.cc
  sql/sql_class.cc
  sql/sql_table.cc
  storage/federatedx/ha_federatedx.cc
  storage/heap/ha_heap.cc
  storage/innobase/handler/ha_innodb.cc
  storage/maria/ha_maria.cc
  storage/myisam/ha_myisam.cc
  storage/myisammrg/ha_myisammrg.cc
  storage/sphinx/ha_sphinx.cc
  storage/xtradb/handler/ha_innodb.cc
diff:
=== modified file 'sql/ha_partition.cc'
--- sql/ha_partition.cc	2013-03-10 10:46:08 +0000
+++ sql/ha_partition.cc	2013-03-12 16:04:31 +0000
@@ -91,10 +91,9 @@ static const char *ha_partition_ext[]=
 };
 
 
+handlerton *partition_hton;
 static int partition_initialize(void *p)
 {
-
-  handlerton *partition_hton;
   partition_hton= (handlerton *)p;
 
   partition_hton->state= SHOW_OPTION_YES;
@@ -1993,7 +1992,7 @@ uint ha_partition::del_ren_cre_table(con
     {
       if ((error= set_up_table_before_create(table_arg, from_buff,
                                              create_info, i, NULL)) ||
-          parse_engine_table_options(ha_thd(), (*file)->ht,
+          parse_engine_table_options(ha_thd(), (*file)->hton(),
                                      (*file)->table_share) ||
           ((error= (*file)->ha_create(from_buff, table_arg, create_info))))
         goto create_error;
@@ -3044,8 +3043,8 @@ handler *ha_partition::clone(const char
   ha_partition *new_handler;
 
   DBUG_ENTER("ha_partition::clone");
-  new_handler= new (mem_root) ha_partition(ht, table_share, m_part_info,
-                                           this, mem_root);
+  new_handler= new (mem_root) ha_partition(partition_hton, table_share,
+                                           m_part_info, this, mem_root);
   /*
     Allocate new_handler->ref here because otherwise ha_open will allocate it
     on this->table->mem_root and we will not be able to reclaim that memory 
@@ -7020,7 +7019,7 @@ uint ha_partition::alter_table_flags(uin
   uint flags_to_return, flags_to_check;
   DBUG_ENTER("ha_partition::alter_table_flags");
 
-  flags_to_return= ht->alter_table_flags(flags);
+  flags_to_return= partition_hton->alter_table_flags(flags);
   flags_to_return|= m_file[0]->alter_table_flags(flags); 
 
   /*

=== modified file 'sql/ha_partition.h'
--- sql/ha_partition.h	2013-03-10 10:46:08 +0000
+++ sql/ha_partition.h	2013-03-12 16:04:31 +0000
@@ -1147,9 +1147,9 @@ class ha_partition :public handler
   */
   virtual handlerton *partition_ht() const
   {
-    handlerton *h= m_file[0]->ht;
+    handlerton *h= m_file[0]->hton();
     for (uint i=1; i < m_tot_parts; i++)
-      DBUG_ASSERT(h == m_file[i]->ht);
+      DBUG_ASSERT(h == m_file[i]->hton());
     return h;
   }
 };

=== modified file 'sql/handler.cc'
--- sql/handler.cc	2013-03-12 16:03:27 +0000
+++ sql/handler.cc	2013-03-12 16:04:31 +0000
@@ -577,25 +577,6 @@ int ha_initialize_handlerton(st_plugin_i
     break;
   }
   
-  /* 
-    This is entirely for legacy. We will create a new "disk based" hton and a 
-    "memory" hton which will be configurable longterm. We should be able to 
-    remove partition and myisammrg.
-  */
-  switch (hton->db_type) {
-  case DB_TYPE_HEAP:
-    heap_hton= hton;
-    break;
-  case DB_TYPE_MYISAM:
-    myisam_hton= hton;
-    break;
-  case DB_TYPE_PARTITION_DB:
-    partition_hton= hton;
-    break;
-  default:
-    break;
-  };
-
   update_discovery_counters(hton, 1);
 
   DBUG_RETURN(0);
@@ -2259,7 +2240,7 @@ int ha_delete_table(THD *thd, handlerton
 ****************************************************************************/
 handler *handler::clone(const char *name, MEM_ROOT *mem_root)
 {
-  handler *new_handler= get_new_handler(table->s, mem_root, ht);
+  handler *new_handler= get_new_handler(table->s, mem_root, hton());
   if (! new_handler)
     return NULL;
 
@@ -2309,7 +2290,7 @@ double handler::keyread_time(uint index,
 
 void **handler::ha_data(THD *thd) const
 {
-  return thd_ha_data(thd, ht);
+  return thd_ha_data(thd, hton());
 }
 
 THD *handler::ha_thd(void) const
@@ -2337,7 +2318,7 @@ int handler::ha_open(TABLE *table_arg, c
   DBUG_ENTER("handler::ha_open");
   DBUG_PRINT("enter",
              ("name: %s  db_type: %d  db_stat: %d  mode: %d  lock_test: %d",
-              name, ht->db_type, table_arg->db_stat, mode,
+              name, db_type(), table_arg->db_stat, mode,
               test_if_locked));
 
   table= table_arg;
@@ -3447,7 +3428,7 @@ int handler::delete_table(const char *na
   int enoent_or_zero= ENOENT;
   char buff[FN_REFLEN];
 
-  if (ht->discover_table)
+  if (hton()->discover_table)
     enoent_or_zero= 0; // the table may not exist in the engine, it's ok
   else
     enoent_or_zero= ENOENT;  // the first file of bas_ext() *must* exist
@@ -3553,7 +3534,7 @@ int handler::ha_check(THD *thd, HA_CHECK
 void
 handler::mark_trx_read_write_part2()
 {
-  Ha_trx_info *ha_info= &ha_thd()->ha_data[ht->slot].ha_info[0];
+  Ha_trx_info *ha_info= &ha_thd()->ha_data[hton()->slot].ha_info[0];
 
   /* Don't call this function again for this statement */
   mark_trx_done= TRUE;
@@ -4040,7 +4021,7 @@ void handler::update_global_table_stats(
     memcpy(table_stats->table, table->s->table_cache_key.str,
            table->s->table_cache_key.length);
     table_stats->table_name_length= table->s->table_cache_key.length;
-    table_stats->engine_type= ht->db_type;
+    table_stats->engine_type= db_type();
     /* No need to set variables to 0, as we use MY_ZEROFILL above */
 
     if (my_hash_insert(&global_table_stats, (uchar*) table_stats))

=== modified file 'sql/handler.h'
--- sql/handler.h	2013-03-10 10:46:38 +0000
+++ sql/handler.h	2013-03-12 16:04:31 +0000
@@ -1834,10 +1834,11 @@ class handler :public Sql_alloc
   TABLE_SHARE *table_share;   /* The table definition */
   TABLE *table;               /* The current open table */
   Table_flags cached_table_flags;       /* Set on init() and open() */
+private:
+  handlerton *m_ht;                 /* storage engine of this handler */
 
   ha_rows estimation_rows_to_insert;
 public:
-  handlerton *ht;                 /* storage engine of this handler */
   uchar *ref;				/* Pointer to current row */
   uchar *dup_ref;			/* Pointer to duplicate row */
 
@@ -1935,8 +1936,8 @@ class handler :public Sql_alloc
   PSI_table *m_psi;
 
   handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
-    :table_share(share_arg), table(0),
-    estimation_rows_to_insert(0), ht(ht_arg),
+    :table_share(share_arg), table(0), m_ht(ht_arg),
+    estimation_rows_to_insert(0),
     ref(0), end_range(NULL), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
     in_range_check_pushed_down(FALSE),
     ref_length(sizeof(my_off_t)),
@@ -2498,11 +2499,11 @@ class handler :public Sql_alloc
   { return; }       /* prepare InnoDB for HANDLER */
   virtual void free_foreign_key_create_info(char* str) {}
   /** The following can be called without an open handler */
-  const char *table_type() const { return hton_name(ht)->str; }
-  const char **bas_ext() const
-  {
-    return ht->tablefile_extensions;
-  }
+  handlerton *hton() const { return m_ht; }
+  enum legacy_db_type db_type() const { return hton()->db_type; }
+  LEX_STRING *engine_name() const { return hton_name(hton()); }
+  const char *table_type() const { return engine_name()->str; }
+  const char **bas_ext() const { return hton()->tablefile_extensions; }
 
   virtual int get_default_no_partitions(HA_CREATE_INFO *create_info)
   { return 1;}
@@ -2772,13 +2773,11 @@ class handler :public Sql_alloc
   virtual void use_hidden_primary_key();
   virtual uint alter_table_flags(uint flags)
   {
-    if (ht->alter_table_flags)
-      return ht->alter_table_flags(flags);
+    if (hton()->alter_table_flags)
+      return hton()->alter_table_flags(flags);
     return 0;
   }
 
-  LEX_STRING *engine_name() { return hton_name(ht); }
-
   /*
     @brief
     Check whether the engine supports virtual columns
@@ -3036,7 +3035,7 @@ class handler :public Sql_alloc
 public:
   /* XXX to be removed, see ha_partition::partition_ht() */
   virtual handlerton *partition_ht() const
-  { return ht; }
+  { return hton(); }
   inline int ha_write_tmp_row(uchar *buf);
   inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data);
 

=== modified file 'sql/log_event.cc'
--- sql/log_event.cc	2013-02-05 08:08:15 +0000
+++ sql/log_event.cc	2013-03-12 16:04:31 +0000
@@ -10060,7 +10060,7 @@ Rows_log_event::write_row(const Relay_lo
   auto_afree_ptr<char> key(NULL);
 
   prepare_record(table, m_width,
-                 table->file->ht->db_type != DB_TYPE_NDBCLUSTER);
+                 table->file->db_type() != DB_TYPE_NDBCLUSTER);
 
   /* unpack row into table->record[0] */
   if ((error= unpack_current_row(rli)))

=== modified file 'sql/mysqld.cc'
--- sql/mysqld.cc	2013-03-10 10:45:14 +0000
+++ sql/mysqld.cc	2013-03-12 16:04:31 +0000
@@ -416,13 +416,6 @@ my_bool opt_log_slave_updates= 0;
 my_bool opt_replicate_annotate_row_events= 0;
 char *opt_slave_skip_errors;
 
-/*
-  Legacy global handlerton. These will be removed (please do not add more).
-*/
-handlerton *heap_hton;
-handlerton *myisam_hton;
-handlerton *partition_hton;
-
 my_bool read_only= 0, opt_readonly= 0;
 my_bool use_temp_pool, relay_log_purge;
 my_bool relay_log_recovery;

=== modified file 'sql/sql_admin.cc'
--- sql/sql_admin.cc	2013-02-27 11:23:42 +0000
+++ sql/sql_admin.cc	2013-03-12 16:04:31 +0000
@@ -175,7 +175,7 @@ static int prepare_for_repair(THD *thd,
     goto end;					// No data file
 
   /* A MERGE table must not come here. */
-  DBUG_ASSERT(table->file->ht->db_type != DB_TYPE_MRG_MYISAM);
+  DBUG_ASSERT(table->file->db_type() != DB_TYPE_MRG_MYISAM);
 
   // Name of data file
   strxmov(from, table->s->normalized_path.str, ext[1], NullS);

=== modified file 'sql/sql_base.cc'
--- sql/sql_base.cc	2013-02-27 11:23:42 +0000
+++ sql/sql_base.cc	2013-03-12 16:04:31 +0000
@@ -1885,7 +1885,7 @@ TABLE_LIST* find_dup_table(THD *thd, TAB
   if (table->table)
   {
     /* All MyISAMMRG children are plain MyISAM tables. */
-    DBUG_ASSERT(table->table->file->ht->db_type != DB_TYPE_MRG_MYISAM);
+    DBUG_ASSERT(table->table->file->db_type() != DB_TYPE_MRG_MYISAM);
 
     /* temporary table is always unique */
     if (table->table && table->table->s->tmp_table != NO_TMP_TABLE)
@@ -1981,7 +1981,7 @@ unique_table(THD *thd, TABLE_LIST *table
              bool check_alias)
 {
   TABLE_LIST *dup;
-  if (table->table && table->table->file->ht->db_type == DB_TYPE_MRG_MYISAM)
+  if (table->table && table->table->file->db_type() == DB_TYPE_MRG_MYISAM)
   {
     TABLE_LIST *child;
     dup= NULL;
@@ -5017,7 +5017,7 @@ bool open_tables(THD *thd, TABLE_LIST **
     TABLE *tbl= tables->table;
 
     /* Schema tables may not have a TABLE object here. */
-    if (tbl && tbl->file->ht->db_type == DB_TYPE_MRG_MYISAM)
+    if (tbl && tbl->file->db_type() == DB_TYPE_MRG_MYISAM)
     {
       /* MERGE tables need to access parent and child TABLE_LISTs. */
       DBUG_ASSERT(tbl->pos_in_table_list == tables);
@@ -5440,7 +5440,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST
     */
     DBUG_ASSERT(table_list->table);
     table= table_list->table;
-    if (table->file->ht->db_type == DB_TYPE_MRG_MYISAM)
+    if (table->file->db_type() == DB_TYPE_MRG_MYISAM)
     {
       /* A MERGE table must not come here. */
       /* purecov: begin tested */

=== modified file 'sql/sql_class.cc'
--- sql/sql_class.cc	2013-02-27 11:23:42 +0000
+++ sql/sql_class.cc	2013-03-12 16:04:31 +0000
@@ -4716,8 +4716,8 @@ int THD::decide_logging_format(TABLE_LIS
                           table->table_name, flags));
       if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
       {
-        if (prev_write_table && prev_write_table->file->ht !=
-            table->table->file->ht)
+        if (prev_write_table && prev_write_table->file->hton() !=
+            table->table->file->hton())
           multi_write_engine= TRUE;
 
         my_bool trans= table->table->file->has_transactions();
@@ -4752,8 +4752,8 @@ int THD::decide_logging_format(TABLE_LIS
                                                LEX::STMT_READS_NON_TRANS_TABLE);
       }
 
-      if (prev_access_table && prev_access_table->file->ht !=
-          table->table->file->ht)
+      if (prev_access_table && prev_access_table->file->hton() !=
+          table->table->file->hton())
         multi_access_engine= TRUE;
 
       prev_access_table= table->table;

=== modified file 'sql/sql_table.cc'
--- sql/sql_table.cc	2013-03-10 10:46:38 +0000
+++ sql/sql_table.cc	2013-03-12 16:04:31 +0000
@@ -3838,7 +3838,7 @@ mysql_prepare_create_table(THD *thd, HA_
   /* Give warnings for not supported table options */
 #if defined(WITH_ARIA_STORAGE_ENGINE)
   extern handlerton *maria_hton;
-  if (file->ht != maria_hton)
+  if (file->hton() != maria_hton)
 #endif
     if (create_info->transactional)
       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,

=== modified file 'storage/federatedx/ha_federatedx.cc'
--- storage/federatedx/ha_federatedx.cc	2013-03-10 10:49:49 +0000
+++ storage/federatedx/ha_federatedx.cc	2013-03-12 16:04:31 +0000
@@ -324,6 +324,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #define MIN_PORT 0
 #endif
 
+static handlerton *federatedx_hton;
+
 /* Variables for federatedx share methods */
 static HASH federatedx_open_tables;             // To track open tables
 static HASH federatedx_open_servers;            // To track open servers
@@ -415,7 +417,7 @@ int federatedx_db_init(void *p)
 {
   DBUG_ENTER("federatedx_db_init");
   init_federated_psi_keys();
-  handlerton *federatedx_hton= (handlerton *)p;
+  federatedx_hton= (handlerton *)p;
   federatedx_hton->state= SHOW_OPTION_YES;
   /* Needed to work with old .frm files */
   federatedx_hton->db_type= DB_TYPE_FEDERATED_DB;
@@ -3460,7 +3462,7 @@ int ha_federatedx::start_stmt(MYSQL_THD
   if (!txn->in_transaction())
   {
     txn->stmt_begin();
-    trans_register_ha(thd, FALSE, ht);
+    trans_register_ha(thd, FALSE, federatedx_hton);
   }
   DBUG_RETURN(0);
 }
@@ -3483,12 +3485,12 @@ int ha_federatedx::external_lock(MYSQL_T
       if (!thd_test_options(thd, (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
       {
         txn->stmt_begin();
-        trans_register_ha(thd, FALSE, ht);
+        trans_register_ha(thd, FALSE, federatedx_hton);
       }
       else
       {
         txn->txn_begin();
-        trans_register_ha(thd, TRUE, ht);
+        trans_register_ha(thd, TRUE, federatedx_hton);
       }
     }
   }

=== modified file 'storage/heap/ha_heap.cc'
--- storage/heap/ha_heap.cc	2013-03-12 16:03:27 +0000
+++ storage/heap/ha_heap.cc	2013-03-12 16:04:31 +0000
@@ -39,10 +39,9 @@ int heap_panic(handlerton *hton, ha_pani
 }
 
 
+handlerton *heap_hton;
 int heap_init(void *p)
 {
-  handlerton *heap_hton;
-
 #ifdef HAVE_PSI_INTERFACE
   init_heap_psi_keys();
 #endif

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- storage/innobase/handler/ha_innodb.cc	2013-03-12 16:03:27 +0000
+++ storage/innobase/handler/ha_innodb.cc	2013-03-12 16:04:31 +0000
@@ -2215,7 +2215,7 @@ ha_innobase::init_table_handle_for_HANDL
 
 	trx_assign_read_view(prebuilt->trx);
 
-	innobase_register_trx(ht, user_thd, prebuilt->trx);
+	innobase_register_trx(innodb_hton_ptr, user_thd, prebuilt->trx);
 
 	/* We did the necessary inits in this function, no need to repeat them
 	in row_search_for_mysql */
@@ -2629,12 +2629,6 @@ innobase_init(
 			 &pending_checkpoint_mutex,
 			 MY_MUTEX_INIT_FAST);
 	innodb_inited= 1;
-#ifdef MYSQL_DYNAMIC_PLUGIN
-	if (innobase_hton != p) {
-		innobase_hton = reinterpret_cast<handlerton*>(p);
-		*innobase_hton = *innodb_hton_ptr;
-	}
-#endif /* MYSQL_DYNAMIC_PLUGIN */
 
 	/* Get the current high water mark format. */
 	innobase_file_format_max = (char*) trx_sys_file_format_max_get();
@@ -4091,7 +4085,7 @@ ha_innobase::open(
 	holding btr_search_latch. This breaks the latching order as
 	we acquire dict_sys->mutex below and leads to a deadlock. */
 	if (thd != NULL) {
-		innobase_release_temporary_latches(ht, thd);
+		innobase_release_temporary_latches(innodb_hton_ptr, thd);
 	}
 
 	normalize_table_name(norm_name, name);
@@ -4450,7 +4444,7 @@ ha_innobase::close(void)
 
 	thd = ha_thd();
 	if (thd != NULL) {
-		innobase_release_temporary_latches(ht, thd);
+		innobase_release_temporary_latches(innodb_hton_ptr, thd);
 	}
 
 	row_prebuilt_free(prebuilt, FALSE);
@@ -5385,7 +5379,7 @@ ha_innobase::write_row(
 			no need to re-acquire locks on it. */
 
 			/* Altering to InnoDB format */
-			innobase_commit(ht, user_thd, 1);
+			innobase_commit(innodb_hton_ptr, user_thd, 1);
 			/* Note that this transaction is still active. */
 			trx_register_for_2pc(prebuilt->trx);
 			/* We will need an IX lock on the destination table. */
@@ -5401,7 +5395,7 @@ ha_innobase::write_row(
 
 			/* Commit the transaction.  This will release the table
 			locks, so they have to be acquired again. */
-			innobase_commit(ht, user_thd, 1);
+			innobase_commit(innodb_hton_ptr, user_thd, 1);
 			/* Note that this transaction is still active. */
 			trx_register_for_2pc(prebuilt->trx);
 			/* Re-acquire the table lock on the source table. */
@@ -9472,7 +9466,7 @@ ha_innobase::start_stmt(
 
 	*trx->detailed_error = 0;
 
-	innobase_register_trx(ht, thd, trx);
+	innobase_register_trx(innodb_hton_ptr, thd, trx);
 
 	return(0);
 }
@@ -9563,7 +9557,7 @@ ha_innobase::external_lock(
 
 		*trx->detailed_error = 0;
 
-		innobase_register_trx(ht, thd, trx);
+		innobase_register_trx(innodb_hton_ptr, thd, trx);
 
 		if (trx->isolation_level == TRX_ISO_SERIALIZABLE
 		    && prebuilt->select_lock_type == LOCK_NONE
@@ -9642,7 +9636,7 @@ ha_innobase::external_lock(
 				thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
 			if (trx_is_started(trx)) {
-				innobase_commit(ht, thd, TRUE);
+				innobase_commit(innodb_hton_ptr, thd, TRUE);
 			}
 
 		} else if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
@@ -9720,7 +9714,7 @@ ha_innobase::transactional_table_lock(
 
 	/* MySQL is setting a new transactional table lock */
 
-	innobase_register_trx(ht, thd, trx);
+	innobase_register_trx(innodb_hton_ptr, thd, trx);
 
 	if (THDVAR(thd, table_locks) && thd_in_lock_tables(thd)) {
 		ulint	error = DB_SUCCESS;

=== modified file 'storage/maria/ha_maria.cc'
--- storage/maria/ha_maria.cc	2013-02-27 11:23:42 +0000
+++ storage/maria/ha_maria.cc	2013-03-12 16:04:31 +0000
@@ -2860,7 +2860,7 @@ int ha_maria::implicit_commit(THD *thd,
   */
   for (table=thd->open_tables; table ; table=table->next)
   {
-    if (table->db_stat && table->file->ht == maria_hton)
+    if (table->db_stat && table->file->hton() == maria_hton)
     {
       MARIA_HA *handler= ((ha_maria*) table->file)->file;
       if (handler->s->base.born_transactional)

=== modified file 'storage/myisam/ha_myisam.cc'
--- storage/myisam/ha_myisam.cc	2013-02-27 11:23:42 +0000
+++ storage/myisam/ha_myisam.cc	2013-03-12 16:04:31 +0000
@@ -2182,10 +2182,9 @@ int myisam_panic(handlerton *hton, ha_pa
   return mi_panic(flag);
 }
 
+handlerton *myisam_hton;
 static int myisam_init(void *p)
 {
-  handlerton *myisam_hton;
-
 #ifdef HAVE_PSI_INTERFACE
   init_myisam_psi_keys();
 #endif

=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- storage/myisammrg/ha_myisammrg.cc	2013-02-27 11:23:42 +0000
+++ storage/myisammrg/ha_myisammrg.cc	2013-03-12 16:04:31 +0000
@@ -673,7 +673,7 @@ extern "C" MI_INFO *myisammrg_attach_chi
   }
 
   /* Extract the MyISAM table structure pointer from the handler object. */
-  if ((child->file->ht->db_type != DB_TYPE_MYISAM) ||
+  if ((child->file->db_type() != DB_TYPE_MYISAM) ||
       !(myisam= ((ha_myisam*) child->file)->file_ptr()))
   {
     DBUG_PRINT("error", ("no MyISAM handle for child table: '%s'.'%s' 0x%lx",

=== modified file 'storage/sphinx/ha_sphinx.cc'
--- storage/sphinx/ha_sphinx.cc	2013-03-10 10:46:20 +0000
+++ storage/sphinx/ha_sphinx.cc	2013-03-12 16:04:31 +0000
@@ -708,6 +708,7 @@ static int sphinx_init_func ( void * p )
 		hton->show_status = sphinx_show_status;
 		hton->panic = sphinx_panic;
 		hton->flags = HTON_CAN_RECREATE;
+                sphinx_hton_ptr= hton;
 		#endif
 	}
 	SPH_RET(0);
@@ -2061,7 +2062,7 @@ int ha_sphinx::open ( const char * name,
 	thr_lock_data_init ( &m_pShare->m_tLock, &m_tLock, NULL );
 
 	#if MYSQL_VERSION_ID>50100
-	void **tmp= thd_ha_data(table->in_use, ht);
+	void **tmp= thd_ha_data(table->in_use, sphinx_hton_ptr);
         if (*tmp)
         {
           CSphSEThreadData* pTls = (CSphSEThreadData*) *tmp;
@@ -2742,7 +2743,7 @@ CSphSEThreadData * ha_sphinx::GetTls()
 	// where do we store that pointer in today's version?
 	CSphSEThreadData ** ppTls;
 #if MYSQL_VERSION_ID>50100
-	ppTls = (CSphSEThreadData**) thd_ha_data ( table->in_use, ht );
+	ppTls = (CSphSEThreadData**) thd_ha_data ( table->in_use, sphinx_hton_ptr);
 #else
 	ppTls = (CSphSEThreadData**) &current_thd->ha_data[sphinx_hton.slot];
 #endif // >50100

=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- storage/xtradb/handler/ha_innodb.cc	2013-03-12 16:03:27 +0000
+++ storage/xtradb/handler/ha_innodb.cc	2013-03-12 16:04:31 +0000
@@ -2457,7 +2457,7 @@ ha_innobase::init_table_handle_for_HANDL
 
 	trx_assign_read_view(prebuilt->trx);
 
-	innobase_register_trx(ht, user_thd, prebuilt->trx);
+	innobase_register_trx(innodb_hton_ptr, user_thd, prebuilt->trx);
 
 	/* We did the necessary inits in this function, no need to repeat them
 	in row_search_for_mysql */
@@ -3186,12 +3186,6 @@ innobase_init(
 			 &pending_checkpoint_mutex,
 			 MY_MUTEX_INIT_FAST);
 	innodb_inited= 1;
-#ifdef MYSQL_DYNAMIC_PLUGIN
-	if (innobase_hton != p) {
-		innobase_hton = reinterpret_cast<handlerton*>(p);
-		*innobase_hton = *innodb_hton_ptr;
-	}
-#endif /* MYSQL_DYNAMIC_PLUGIN */
 
 	/* Get the current high water mark format. */
 	innobase_file_format_max = (char*) trx_sys_file_format_max_get();
@@ -4685,7 +4679,7 @@ ha_innobase::open(
 	holding btr_search_latch. This breaks the latching order as
 	we acquire dict_sys->mutex below and leads to a deadlock. */
 	if (thd != NULL) {
-		innobase_release_temporary_latches(ht, thd);
+		innobase_release_temporary_latches(innodb_hton_ptr, thd);
 	}
 
 	normalize_table_name(norm_name, name);
@@ -5057,7 +5051,7 @@ ha_innobase::close(void)
 
 	thd = ha_thd();
 	if (thd != NULL) {
-		innobase_release_temporary_latches(ht, thd);
+		innobase_release_temporary_latches(innodb_hton_ptr, thd);
 	}
 
 	row_prebuilt_free(prebuilt, FALSE);
@@ -6238,7 +6232,7 @@ ha_innobase::write_row(
 			no need to re-acquire locks on it. */
 
 			/* Altering to InnoDB format */
-			innobase_commit(ht, user_thd, 1);
+			innobase_commit(innodb_hton_ptr, user_thd, 1);
 			/* Note that this transaction is still active. */
 			trx_register_for_2pc(prebuilt->trx);
 			/* We will need an IX lock on the destination table. */
@@ -6254,7 +6248,7 @@ ha_innobase::write_row(
 
 			/* Commit the transaction.  This will release the table
 			locks, so they have to be acquired again. */
-			innobase_commit(ht, user_thd, 1);
+			innobase_commit(innodb_hton_ptr, user_thd, 1);
 			/* Note that this transaction is still active. */
 			trx_register_for_2pc(prebuilt->trx);
 			/* Re-acquire the table lock on the source table. */
@@ -10492,7 +10486,7 @@ ha_innobase::start_stmt(
 
 	*trx->detailed_error = 0;
 
-	innobase_register_trx(ht, thd, trx);
+	innobase_register_trx(innodb_hton_ptr, thd, trx);
 
 	return(0);
 }
@@ -10583,7 +10577,7 @@ ha_innobase::external_lock(
 
 		*trx->detailed_error = 0;
 
-		innobase_register_trx(ht, thd, trx);
+		innobase_register_trx(innodb_hton_ptr, thd, trx);
 
 		if (trx->isolation_level == TRX_ISO_SERIALIZABLE
 		    && prebuilt->select_lock_type == LOCK_NONE
@@ -10681,7 +10675,7 @@ ha_innobase::external_lock(
 				thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
 			if (trx_is_started(trx)) {
-				innobase_commit(ht, thd, TRUE);
+				innobase_commit(innodb_hton_ptr, thd, TRUE);
 			}
 
 		} else if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
@@ -10763,7 +10757,7 @@ ha_innobase::transactional_table_lock(
 
 	/* MySQL is setting a new transactional table lock */
 
-	innobase_register_trx(ht, thd, trx);
+	innobase_register_trx(innodb_hton_ptr, thd, trx);
 
 	if (THDVAR(thd, table_locks) && thd_in_lock_tables(thd)) {
 		ulint	error = DB_SUCCESS;
------------------------------------------------------------
revno: 3585
committer: Sergei Golubchik <sergii@pisem.net>
branch nick: 10.0
timestamp: Tue 2013-03-12 17:03:27 +0100
message:
  cleanup
  
  sql/handler.cc:
    be dbug-friendly
  sql/item_subselect.cc:
    compiler warning
  storage/csv/ha_tina.cc:
    be ctags-friendly
  storage/heap/ha_heap.cc:
    be ctags-friendly
  storage/innobase/handler/ha_innodb.cc:
    be ctags-friendly
  storage/xtradb/handler/ha_innodb.cc:
    be ctags-friendly
modified:
  sql/handler.cc
  sql/item_subselect.cc
  storage/csv/ha_tina.cc
  storage/heap/ha_heap.cc
  storage/innobase/handler/ha_innodb.cc
  storage/xtradb/handler/ha_innodb.cc
diff:
=== modified file 'sql/handler.cc'
--- sql/handler.cc	2013-03-12 09:07:47 +0000
+++ sql/handler.cc	2013-03-12 16:03:27 +0000
@@ -249,12 +249,9 @@ handler *get_new_handler(TABLE_SHARE *sh
       file->init();
     DBUG_RETURN(file);
   }
-  /*
-    Try the default table type
-    Here the call to current_thd() is ok as we call this function a lot of
-    times but we enter this branch very seldom.
-  */
-  DBUG_RETURN(get_new_handler(share, alloc, ha_default_handlerton(current_thd)));
+  /* Try the default table type */
+  file= get_new_handler(share, alloc, ha_default_handlerton(current_thd));
+  DBUG_RETURN(file);
 }
 
 

=== modified file 'sql/item_subselect.cc'
--- sql/item_subselect.cc	2013-02-25 23:20:17 +0000
+++ sql/item_subselect.cc	2013-03-12 16:03:27 +0000
@@ -2918,7 +2918,7 @@ bool Item_exists_subselect::exists2in_pr
         res= TRUE;
         goto out;
       }
-      for (int i= 0; i < eqs.elements(); i++)
+      for (uint i= 0; i < eqs.elements(); i++)
       {
         if (optimizer->arguments()[0]->maybe_null)
         {

=== modified file 'storage/csv/ha_tina.cc'
--- storage/csv/ha_tina.cc	2013-02-27 11:23:42 +0000
+++ storage/csv/ha_tina.cc	2013-03-12 16:03:27 +0000
@@ -81,9 +81,7 @@ extern "C" my_bool tina_check_status(voi
 /* Stuff for shares */
 mysql_mutex_t tina_mutex;
 static HASH tina_open_tables;
-static handler *tina_create_handler(handlerton *hton,
-                                    TABLE_SHARE *table, 
-                                    MEM_ROOT *mem_root);
+static handler *tina_create_handler(handlerton *, TABLE_SHARE *, MEM_ROOT *);
 
 
 /*****************************************************************************

=== modified file 'storage/heap/ha_heap.cc'
--- storage/heap/ha_heap.cc	2013-02-27 11:23:42 +0000
+++ storage/heap/ha_heap.cc	2013-03-12 16:03:27 +0000
@@ -27,9 +27,7 @@
 #include "heapdef.h"
 #include "sql_base.h"                    // enum_tdc_remove_table_type
 
-static handler *heap_create_handler(handlerton *hton,
-                                    TABLE_SHARE *table, 
-                                    MEM_ROOT *mem_root);
+static handler *heap_create_handler(handlerton *, TABLE_SHARE *, MEM_ROOT *);
 static int
 heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
                             HP_CREATE_INFO *hp_create_info);

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- storage/innobase/handler/ha_innodb.cc	2013-02-11 10:46:06 +0000
+++ storage/innobase/handler/ha_innodb.cc	2013-03-12 16:03:27 +0000
@@ -352,9 +352,7 @@ static int innobase_savepoint(handlerton
 static int innobase_release_savepoint(handlerton *hton, THD* thd,
            void *savepoint);
 static void innobase_checkpoint_request(handlerton *hton, void *cookie);
-static handler *innobase_create_handler(handlerton *hton,
-                                        TABLE_SHARE *table,
-                                        MEM_ROOT *mem_root);
+static handler *innobase_create_handler(handlerton *, TABLE_SHARE *, MEM_ROOT *);
 
 /* "GEN_CLUST_INDEX" is the name reserved for Innodb default
 system primary index. */

=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- storage/xtradb/handler/ha_innodb.cc	2013-02-11 10:46:06 +0000
+++ storage/xtradb/handler/ha_innodb.cc	2013-03-12 16:03:27 +0000
@@ -391,9 +391,7 @@ static int innobase_savepoint(handlerton
 static int innobase_release_savepoint(handlerton *hton, THD* thd,
            void *savepoint);
 static void innobase_checkpoint_request(handlerton *hton, void *cookie);
-static handler *innobase_create_handler(handlerton *hton,
-                                        TABLE_SHARE *table,
-                                        MEM_ROOT *mem_root);
+static handler *innobase_create_handler(handlerton *, TABLE_SHARE *, MEM_ROOT *);
 /* "GEN_CLUST_INDEX" is the name reserved for Innodb default
 system primary index. */
 static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
