#At file:///home/msvensson/mysql/5.5-format-section/ based on revid:jorgen.loland@stripped52hiht7i5j
3353 Magnus Blåudd 2011-02-23
Bug#60111 storage type for table not saved in .frm
- Add new "format section" in extra data segment with additional table and
column properties. This was originally introduced in 5.1.20 based MySQL Cluster
- Remove hardcoded STORAGE DISK for table and instead
output the real storage format used. Keep both TABLESPACE
and STORAGE inside same version guard.
- Implement default version of handler::get_tablespace_name() since tablespace
is now available in share and it's unnecessary for each handler to implement.
(the function could actually be removed totally now).
- Add test for combinations of TABLESPACE and STORAGE with CREATE TABLE
and ALTER TABLE
- Add test to show thet 5.5 now can read a .frm file created by MySQL Cluster
7.0.22. Although it does not yet show the column level attributes, they are read.
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:
sql/handler.cc
sql/handler.h
sql/sql_show.cc
sql/table.cc
sql/table.h
sql/unireg.cc
=== 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-02-23 13:15:08 +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 */ 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-02-23 13:15:08 +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-02-23 13:15:08 +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-02-23 13:15:08 +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.cc'
--- a/sql/handler.cc 2011-02-21 15:49:03 +0000
+++ b/sql/handler.cc 2011-02-23 13:15:08 +0000
@@ -3616,6 +3616,22 @@ void handler::get_dynamic_partition_info
}
+char* handler::get_tablespace_name(THD *thd, char *buff, uint buff_len)
+{
+ char* ts= table->s->tablespace;
+ if (!ts)
+ return NULL;
+
+ if (!buff)
+ {
+ buff= my_strdup(ts, MYF(0));
+ return buff;
+ }
+
+ strnmov(buff, ts, buff_len);
+ return buff;
+}
+
/****************************************************************************
** Some general functions that isn't in the handler class
****************************************************************************/
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2011-01-26 13:23:29 +0000
+++ b/sql/handler.h 2011-02-23 13:15:08 +0000
@@ -1646,8 +1646,7 @@ 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 */
+ virtual char* get_tablespace_name(THD *thd, char *name, uint name_len);
/** 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-02-08 15:47:33 +0000
+++ b/sql/sql_show.cc 2011-02-23 13:15:08 +0000
@@ -1379,17 +1379,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(" */"));
}
/*
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2011-01-28 12:28:15 +0000
+++ b/sql/table.cc 2011-02-23 13:15:08 +0000
@@ -750,6 +750,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];
@@ -942,27 +945,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);
@@ -979,7 +982,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;
}
/*
@@ -1009,7 +1011,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);
@@ -1025,7 +1026,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 */
}
@@ -1042,7 +1042,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;
}
}
@@ -1050,7 +1049,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
@@ -1088,7 +1086,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;
@@ -1099,7 +1096,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;
}
}
@@ -1111,19 +1107,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 to 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);
@@ -1438,6 +1483,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)& STORAGE_TYPE_MASK);
+ DBUG_PRINT("debug", ("field flags: %u, storage: %u, column_format: %u",
+ field_flags, field_storage, field_column_format));
+ (void)field_storage; /* Used in MySQL Cluster */
+ (void)field_column_format; /* Used in MySQL Cluster */
+ }
}
*field_ptr=0; // End marker
@@ -1705,6 +1762,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:
@@ -1712,6 +1770,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);
@@ -2687,6 +2746,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 2010-12-29 00:26:31 +0000
+++ b/sql/table.h 2011-02-23 13:15:08 +0000
@@ -609,6 +609,8 @@ struct TABLE_SHARE
}
enum row_type row_type; /* How rows are stored */
enum tmp_table_type tmp_table;
+ enum ha_storage_media default_storage_media;
+ char *tablespace;
uint ref_count; /* How many TABLE objects uses this */
uint blob_ptr_size; /* 4 or 8 */
=== modified file 'sql/unireg.cc'
--- a/sql/unireg.cc 2010-07-08 21:20:08 +0000
+++ b/sql/unireg.cc 2011-02-23 13:15:08 +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) ||
Attachment: [text/bzr-bundle] bzr/magnus.blaudd@oracle.com-20110223131508-wp4i3900m87cge4h.bundle