List:Commits« Previous MessageNext Message »
From:Georgi Kodinov Date:March 25 2011 2:38pm
Subject:bzr commit into mysql-trunk branch (Georgi.Kodinov:3326)
View as plain text  
#At file:///Users/kgeorge/mysql/work/B11766769-trunk/ based on revid:georgi.kodinov@stripped

 3326 Georgi Kodinov	2011-03-25 [merge]
      merge

    added:
      mysql-test/r/tablespace.result
      mysql-test/std_data/cluster_7022_table.MYD
      mysql-test/std_data/cluster_7022_table.MYI
      mysql-test/std_data/cluster_7022_table.frm
      mysql-test/t/tablespace.test
    modified:
      include/mysql_com.h
      sql/handler.h
      sql/sql_show.cc
      sql/sql_table.cc
      sql/table.cc
      sql/table.h
      sql/unireg.cc
=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h	2010-12-29 00:38:59 +0000
+++ b/include/mysql_com.h	2011-03-25 13:28:19 +0000
@@ -114,6 +114,10 @@ enum enum_server_command
 #define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */
 #define FIELD_IN_ADD_INDEX (1<< 20)	/* Intern: Field used in ADD INDEX */
 #define FIELD_IS_RENAMED (1<< 21)       /* Intern: Field is being renamed */
+#define FIELD_FLAGS_STORAGE_MEDIA 22    /* Field storage media, bit 22-23,
+                                           reserved by MySQL Cluster */
+#define FIELD_FLAGS_COLUMN_FORMAT 24    /* Field column format, bit 24-25,
+                                           reserved by MySQL Cluster */
 
 #define REFRESH_GRANT		1	/* Refresh grant tables */
 #define REFRESH_LOG		2	/* Start on new log file */

=== added file 'mysql-test/r/tablespace.result'
--- a/mysql-test/r/tablespace.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/tablespace.result	2011-03-04 08:41:29 +0000
@@ -0,0 +1,112 @@
+CREATE TABLE t1(a int) TABLESPACE ts ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 TABLESPACE ts */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(a int) TABLESPACE ts STORAGE DISK ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 TABLESPACE ts STORAGE DISK */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(a int) TABLESPACE ts STORAGE MEMORY ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 TABLESPACE ts STORAGE MEMORY */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(a int) STORAGE MEMORY ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 STORAGE MEMORY */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(a int) STORAGE DISK ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 STORAGE DISK */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(a int) TABLESPACE ts ENGINE=MyISAM;
+ALTER TABLE t1 ADD COLUMN b int;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) /*!50100 TABLESPACE ts */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(a int) TABLESPACE ts STORAGE DISK ENGINE=MyISAM;
+ALTER TABLE t1 ADD COLUMN b int;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL
+) /*!50100 TABLESPACE ts STORAGE DISK */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(a int) ENGINE=MyISAM;
+ALTER TABLE t1 TABLESPACE ts;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 TABLESPACE ts */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 TABLESPACE ts2;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 TABLESPACE ts2 */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(a int) ENGINE=MyISAM;
+ALTER TABLE t1 STORAGE MEMORY;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 STORAGE MEMORY */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 STORAGE DISK;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 STORAGE DISK */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1(a int) ENGINE=MyISAM;
+ALTER TABLE t1 STORAGE MEMORY TABLESPACE ts;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 TABLESPACE ts STORAGE MEMORY */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 STORAGE DISK TABLESPACE ts2;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) /*!50100 TABLESPACE ts2 STORAGE DISK */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  `d` int(11) NOT NULL,
+  `e` int(11) DEFAULT NULL,
+  `f` int(11) DEFAULT NULL,
+  `g` int(11) DEFAULT NULL,
+  `h` int(11) NOT NULL,
+  `i` int(11) DEFAULT NULL,
+  `j` int(11) DEFAULT NULL,
+  `k` int(11) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) /*!50100 TABLESPACE the_tablespacename STORAGE DISK */ ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;

=== added file 'mysql-test/std_data/cluster_7022_table.MYD'

=== added file 'mysql-test/std_data/cluster_7022_table.MYI'
Binary files a/mysql-test/std_data/cluster_7022_table.MYI	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/cluster_7022_table.MYI	2011-03-04 08:41:29 +0000 differ

=== added file 'mysql-test/std_data/cluster_7022_table.frm'
Binary files a/mysql-test/std_data/cluster_7022_table.frm	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/cluster_7022_table.frm	2011-03-04 08:41:29 +0000 differ

=== added file 'mysql-test/t/tablespace.test'
--- a/mysql-test/t/tablespace.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/tablespace.test	2011-03-04 08:41:29 +0000
@@ -0,0 +1,122 @@
+#
+# BUG#60111 storage type for table not saved in .frm
+#
+
+#
+# Check that the table options for TABLESPACE and STORAGE
+# are printed in SHOW CREATE TABLE
+#
+
+# TABLESPACE only
+CREATE TABLE t1(a int) TABLESPACE ts ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+# TABLESPACE + STORAGE DISK
+CREATE TABLE t1(a int) TABLESPACE ts STORAGE DISK ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+# TABLESPACE + STORAGE MEMORY
+CREATE TABLE t1(a int) TABLESPACE ts STORAGE MEMORY ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+# STORAGE MEMORY only
+CREATE TABLE t1(a int) STORAGE MEMORY ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+# STORAGE DISK only
+CREATE TABLE t1(a int) STORAGE DISK ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+#
+# Check that the table options for TABLESPACE and STORAGE
+# are kept in an ALTER
+#
+
+# TABLESPACE only
+CREATE TABLE t1(a int) TABLESPACE ts ENGINE=MyISAM;
+ALTER TABLE t1 ADD COLUMN b int;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+# TABLESPACE and STORAGE DISK
+CREATE TABLE t1(a int) TABLESPACE ts STORAGE DISK ENGINE=MyISAM;
+ALTER TABLE t1 ADD COLUMN b int;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+#
+# Check that the table options for TABLESPACE and STORAGE
+# can be changed with an ALTER
+#
+
+# TABLESPACE only
+CREATE TABLE t1(a int) ENGINE=MyISAM;
+
+ALTER TABLE t1 TABLESPACE ts;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 TABLESPACE ts2;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
+# STORAGE only
+CREATE TABLE t1(a int) ENGINE=MyISAM;
+
+ALTER TABLE t1 STORAGE MEMORY;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 STORAGE DISK;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
+# TABLESPACE and STORAGE
+CREATE TABLE t1(a int) ENGINE=MyISAM;
+
+ALTER TABLE t1 STORAGE MEMORY TABLESPACE ts;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 STORAGE DISK TABLESPACE ts2;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
+#
+# Check that it's possible to read a .frm fle created
+# by MySQL Cluster 7.0(which introduced the new "format
+# section) with this statement:
+#
+# CREATE TABLE cluster_7022_table
+# (
+#   a int primary key,
+#   b int,
+#   c int STORAGE DISK,
+#   d int STORAGE MEMORY NOT NULL,
+#   e int COLUMN_FORMAT DYNAMIC,
+#   f int COLUMN_FORMAT FIXED,
+#   g int COLUMN_FORMAT DEFAULT,
+#   h int STORAGE DISK COLUMN_FORMAT DYNAMIC NOT NULL,
+#   i int STORAGE MEMORY COLUMN_FORMAT DYNAMIC,
+#   j int STORAGE DISK COLUMN_FORMAT FIXED,
+#   k int STORAGE MEMORY COLUMN_FORMAT FIXED
+# ) STORAGE DISK TABLESPACE the_tablespacename ENGINE=MyISAM;
+#
+# NOTE! The column level properties will not yet show up
+# in SHOW CREATE TABLE of MySQL Server(although they are
+# visible in .trace file)
+#
+
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+copy_file std_data/cluster_7022_table.frm $MYSQLD_DATADIR/test/t1.frm;
+copy_file std_data/cluster_7022_table.MYD $MYSQLD_DATADIR/test/t1.MYD;
+copy_file std_data/cluster_7022_table.MYI $MYSQLD_DATADIR/test/t1.MYI;
+
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2011-03-22 11:44:40 +0000
+++ b/sql/handler.h	2011-03-25 13:48:39 +0000
@@ -1973,8 +1973,6 @@ public:
   { return FALSE; }
   virtual char* get_foreign_key_create_info()
   { return(NULL);}  /* gets foreign key create string from InnoDB */
-  virtual char* get_tablespace_name(THD *thd, char *name, uint name_len)
-  { return(NULL);}  /* gets tablespace name from handler */
   /** used in ALTER TABLE; 1 if changing storage engine is allowed */
   virtual bool can_switch_engines() { return 1; }
   /**

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2011-03-11 18:53:12 +0000
+++ b/sql/sql_show.cc	2011-03-25 13:28:19 +0000
@@ -1383,17 +1383,24 @@ int store_create_info(THD *thd, TABLE_LI
   if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
   {
     show_table_options= TRUE;
-    /*
-      Get possible table space definitions and append them
-      to the CREATE TABLE statement
-    */
 
-    if ((for_str= file->get_tablespace_name(thd,0,0)))
+    /* TABLESPACE and STORAGE */
+    if (share->tablespace ||
+        share->default_storage_media != HA_SM_DEFAULT)
     {
-      packet->append(STRING_WITH_LEN(" /*!50100 TABLESPACE "));
-      packet->append(for_str, strlen(for_str));
-      packet->append(STRING_WITH_LEN(" STORAGE DISK */"));
-      my_free(for_str);
+      packet->append(STRING_WITH_LEN(" /*!50100"));
+      if (share->tablespace)
+      {
+        packet->append(STRING_WITH_LEN(" TABLESPACE "));
+        packet->append(share->tablespace, strlen(share->tablespace));
+      }
+
+      if (share->default_storage_media == HA_SM_DISK)
+        packet->append(STRING_WITH_LEN(" STORAGE DISK"));
+      if (share->default_storage_media == HA_SM_MEMORY)
+        packet->append(STRING_WITH_LEN(" STORAGE MEMORY"));
+
+      packet->append(STRING_WITH_LEN(" */"));
     }
 
     /*
@@ -5495,12 +5502,9 @@ static void store_schema_partitions_reco
                               strlen(part_elem->tablespace_name), cs);
     else
     {
-      char *ts= showing_table->file->get_tablespace_name(thd,0,0);
+      char *ts= showing_table->s->tablespace;
       if(ts)
-      {
         table->field[24]->store(ts, strlen(ts), cs);
-        my_free(ts);
-      }
       else
         table->field[24]->set_null();
     }

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-03-17 17:39:31 +0000
+++ b/sql/sql_table.cc	2011-03-25 13:28:19 +0000
@@ -5484,17 +5484,12 @@ mysql_prepare_alter_table(THD *thd, TABL
   if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
     create_info->key_block_size= table->s->key_block_size;
 
-  if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY)
-  {
-    char *tablespace= static_cast<char *>(thd->alloc(FN_LEN + 1));
-    /*
-       Regular alter table of disk stored table (no tablespace/storage change)
-       Copy tablespace name
-    */
-    if (tablespace &&
-        (table->file->get_tablespace_name(thd, tablespace, FN_LEN)))
-      create_info->tablespace= tablespace;
-  }
+  if (!create_info->tablespace)
+    create_info->tablespace= table->s->tablespace;
+
+  if (create_info->storage_media == HA_SM_DEFAULT)
+    create_info->storage_media= table->s->default_storage_media;
+
   restore_record(table, s->default_values);     // Empty record for DEFAULT
   Create_field *def;
 

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2011-03-17 09:47:50 +0000
+++ b/sql/table.cc	2011-03-25 13:28:19 +0000
@@ -791,6 +791,9 @@ static int open_binary_frm(THD *thd, TAB
   const char **interval_array;
   enum legacy_db_type legacy_db_type;
   my_bitmap_map *bitmaps;
+  uchar *extra_segment_buff= 0;
+  const uint format_section_header_size= 8;
+  uchar *format_section_fields= 0;
   DBUG_ENTER("open_binary_frm");
 
   new_field_pack_flag= head[27];
@@ -983,27 +986,27 @@ static int open_binary_frm(THD *thd, TAB
   if ((n_length= uint4korr(head+55)))
   {
     /* Read extra data segment */
-    uchar *buff, *next_chunk, *buff_end;
+    uchar *next_chunk, *buff_end;
     DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
-    if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
+    if (!(extra_segment_buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
       goto err;
-    if (mysql_file_pread(file, buff, n_length, record_offset + share->reclength,
+    next_chunk= extra_segment_buff;
+    if (mysql_file_pread(file, extra_segment_buff,
+                         n_length, record_offset + share->reclength,
                          MYF(MY_NABP)))
     {
-      my_free(buff);
       goto err;
     }
-    share->connect_string.length= uint2korr(buff);
+    share->connect_string.length= uint2korr(next_chunk);
     if (!(share->connect_string.str= strmake_root(&share->mem_root,
                                                   (char*) next_chunk + 2,
                                                   share->connect_string.
                                                   length)))
     {
-      my_free(buff);
       goto err;
     }
     next_chunk+= share->connect_string.length + 2;
-    buff_end= buff + n_length;
+    buff_end= extra_segment_buff + n_length;
     if (next_chunk + 2 < buff_end)
     {
       uint str_db_type_length= uint2korr(next_chunk);
@@ -1020,7 +1023,6 @@ static int open_binary_frm(THD *thd, TAB
                 plugin_data(tmp_plugin, handlerton *)))
         {
           /* bad file, legacy_db_type did not match the name */
-          my_free(buff);
           goto err;
         }
         /*
@@ -1050,7 +1052,6 @@ static int open_binary_frm(THD *thd, TAB
           error= 8;
           my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
                    "--skip-partition");
-          my_free(buff);
           goto err;
         }
         plugin_unlock(NULL, share->db_plugin);
@@ -1066,7 +1067,6 @@ static int open_binary_frm(THD *thd, TAB
         error= 8;
         name.str[name.length]=0;
         my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
-        my_free(buff);
         goto err;
         /* purecov: end */
       }
@@ -1083,7 +1083,6 @@ static int open_binary_frm(THD *thd, TAB
               memdup_root(&share->mem_root, next_chunk + 4,
                           partition_info_str_len + 1)))
         {
-          my_free(buff);
           goto err;
         }
       }
@@ -1091,7 +1090,6 @@ static int open_binary_frm(THD *thd, TAB
       if (partition_info_str_len)
       {
         DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined"));
-        my_free(buff);
         goto err;
       }
 #endif
@@ -1129,7 +1127,6 @@ static int open_binary_frm(THD *thd, TAB
         {
           DBUG_PRINT("error",
                      ("fulltext key uses parser that is not defined in .frm"));
-          my_free(buff);
           goto err;
         }
         parser_name.str= (char*) next_chunk;
@@ -1140,7 +1137,6 @@ static int open_binary_frm(THD *thd, TAB
         if (! keyinfo->parser)
         {
           my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str);
-          my_free(buff);
           goto err;
         }
       }
@@ -1152,19 +1148,68 @@ static int open_binary_frm(THD *thd, TAB
       {
           DBUG_PRINT("error",
                      ("long table comment is not defined in .frm"));
-          my_free(buff);
           goto err;
       }
       share->comment.length = uint2korr(next_chunk);
       if (! (share->comment.str= strmake_root(&share->mem_root,
              (char*)next_chunk + 2, share->comment.length)))
       {
-          my_free(buff);
           goto err;
       }
       next_chunk+= 2 + share->comment.length;
     }
-    my_free(buff);
+
+    if (next_chunk + format_section_header_size < buff_end)
+    {
+      /*
+        New extra data segment called "format section" with additional
+        table and column properties introduced by MySQL Cluster
+        based on 5.1.20
+
+        Table properties:
+        TABLESPACE <ts> and STORAGE [DISK|MEMORY]
+
+        Column properties:
+        COLUMN_FORMAT [DYNAMIC|FIXED] and STORAGE [DISK|MEMORY]
+      */
+      DBUG_PRINT("info", ("Found format section"));
+
+      /* header */
+      const uint format_section_length= uint2korr(next_chunk);
+      const uint format_section_flags= uint4korr(next_chunk+2);
+      /* 2 bytes unused */
+
+      if (next_chunk + format_section_length > buff_end)
+      {
+        DBUG_PRINT("error", ("format section length too long: %u",
+                             format_section_length));
+        goto err;
+      }
+      DBUG_PRINT("info", ("format_section_length: %u, format_section_flags: %u",
+                          format_section_length, format_section_flags));
+
+      share->default_storage_media=
+        (enum ha_storage_media) (format_section_flags & 0x7);
+
+      /* tablespace */
+      const char *tablespace=
+        (const char*)next_chunk + format_section_header_size;
+      const uint tablespace_length= strlen(tablespace);
+      if (tablespace_length &&
+          !(share->tablespace= strmake_root(&share->mem_root,
+                                            tablespace, tablespace_length+1)))
+      {
+        goto err;
+      }
+      DBUG_PRINT("info", ("tablespace: '%s'",
+                          share->tablespace ? share->tablespace : "<null>"));
+
+      /* pointer to format section for fields */
+      format_section_fields=
+        next_chunk + format_section_header_size + tablespace_length + 1;
+
+      next_chunk+= format_section_length;
+    }
   }
   share->key_block_size= uint2korr(head+62);
 
@@ -1479,6 +1524,18 @@ static int open_binary_frm(THD *thd, TAB
         error= 8; 
         goto err;
       }
+
+    if (format_section_fields)
+    {
+      const uchar field_flags= format_section_fields[i];
+      const uchar field_storage= (field_flags & STORAGE_TYPE_MASK);
+      const uchar field_column_format=
+        ((field_flags >> COLUMN_FORMAT_SHIFT)& COLUMN_FORMAT_MASK);
+      DBUG_PRINT("debug", ("field flags: %u, storage: %u, column_format: %u",
+                           field_flags, field_storage, field_column_format));
+      (void)field_storage; /* Reserved by and used in MySQL Cluster */
+      (void)field_column_format; /* Reserved by and used in MySQL Cluster */
+    }
   }
   *field_ptr=0;					// End marker
 
@@ -1734,6 +1791,7 @@ static int open_binary_frm(THD *thd, TAB
   if (use_hash)
     (void) my_hash_check(&share->name_hash);
 #endif
+  my_free(extra_segment_buff);
   DBUG_RETURN (0);
 
  err:
@@ -1741,6 +1799,7 @@ static int open_binary_frm(THD *thd, TAB
   share->open_errno= my_errno;
   share->errarg= errarg;
   my_free(disk_buff);
+  my_free(extra_segment_buff);
   delete crypted;
   delete handler_file;
   my_hash_free(&share->name_hash);
@@ -2723,6 +2782,8 @@ void update_create_info_from_table(HA_CR
   create_info->default_table_charset= share->table_charset;
   create_info->table_charset= 0;
   create_info->comment= share->comment;
+  create_info->storage_media= share->default_storage_media;
+  create_info->tablespace= share->tablespace;
 
   DBUG_VOID_RETURN;
 }

=== modified file 'sql/table.h'
--- a/sql/table.h	2011-03-09 20:54:55 +0000
+++ b/sql/table.h	2011-03-25 13:28:19 +0000
@@ -687,6 +687,16 @@ struct TABLE_SHARE
   */
   int cached_row_logging_check;
 
+  /*
+    Storage media to use for this table (unless another storage
+    media has been specified on an individual column - in versions
+    where that is supported)
+  */
+  enum ha_storage_media default_storage_media;
+
+  /* Name of the tablespace used for this table */
+  char *tablespace;
+
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   /* filled in when reading from frm */
   bool auto_partitioned;

=== modified file 'sql/unireg.cc'
--- a/sql/unireg.cc	2010-07-08 21:42:23 +0000
+++ b/sql/unireg.cc	2011-03-25 13:28:19 +0000
@@ -124,6 +124,9 @@ bool mysql_create_frm(THD *thd, const ch
 #endif
   Pack_header_error_handler pack_header_error_handler;
   int error;
+  const uint format_section_header_size= 8;
+  uint format_section_length;
+  uint tablespace_length= 0;
   DBUG_ENTER("mysql_create_frm");
 
   DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension
@@ -256,6 +259,18 @@ bool mysql_create_frm(THD *thd, const ch
     forminfo[46]=(uchar) create_info->comment.length;
   }
 
+  /*
+    Add room in extra segment for "format section" with additional
+    table and column properties
+  */
+  if (create_info->tablespace)
+    tablespace_length= strlen(create_info->tablespace);
+  format_section_length=
+    format_section_header_size +
+    tablespace_length + 1 +
+    create_fields.elements;
+  create_info->extra_size+= format_section_length;
+
   if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo,
 		       create_info, keys, key_info)) < 0)
   {
@@ -353,6 +368,55 @@ bool mysql_create_frm(THD *thd, const ch
       goto err;
   }
 
+  /* "Format section" with additional table and column properties */
+  {
+    uchar *ptr, *format_section_buff;
+    if (!(format_section_buff=(uchar*) my_malloc(format_section_length,
+                                                 MYF(MY_WME))))
+      goto err;
+    ptr= format_section_buff;
+
+    /* header */
+    const uint format_section_flags=
+      create_info->storage_media; // 3 bits
+    const uint format_section_unused= 0;
+    int2store(ptr+0, format_section_length);
+    int4store(ptr+2, format_section_flags);
+    int2store(ptr+6, format_section_unused);
+    ptr+= format_section_header_size;
+
+    /* tablespace name */
+    if (tablespace_length > 0)
+      memcpy(ptr, create_info->tablespace, tablespace_length);
+    ptr+= tablespace_length;
+    *ptr= 0; /* tablespace string terminating zero */
+    ptr++;
+
+    /* column properties  */
+    Create_field *field;
+    List_iterator<Create_field> it(create_fields);
+    while ((field=it++))
+    {
+      const uchar field_storage= 0; /* Used in MySQL Cluster */
+      const uchar field_column_format= 0; /* Used in MySQL Cluster */
+      const uchar field_flags=
+        field_storage + (field_column_format << COLUMN_FORMAT_SHIFT);
+      *ptr= field_flags;
+      ptr++;
+    }
+    DBUG_ASSERT(format_section_buff + format_section_length == ptr);
+
+    if (mysql_file_write(file, format_section_buff,
+                         format_section_length, MYF_RW))
+    {
+      my_free(format_section_buff);
+      goto err;
+    }
+    DBUG_PRINT("info", ("wrote format section, length: %u",
+                        format_section_length));
+    my_free(format_section_buff);
+  }
+
   mysql_file_seek(file, filepos, MY_SEEK_SET, MYF(0));
   if (mysql_file_write(file, forminfo, 288, MYF_RW) ||
       mysql_file_write(file, screen_buff, info_length, MYF_RW) ||

No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).
Thread
bzr commit into mysql-trunk branch (Georgi.Kodinov:3326) Georgi Kodinov25 Mar