summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_base.h2
-rw-r--r--mysql-test/suite/archive/archive.result9
-rw-r--r--mysql-test/suite/archive/archive.test2
-rw-r--r--mysql-test/suite/archive/discover.result38
-rw-r--r--mysql-test/suite/archive/discover.test15
-rw-r--r--mysql-test/suite/archive/partition_archive.result4
-rw-r--r--mysys/my_uuid.c2
-rw-r--r--sql/handler.h2
-rw-r--r--sql/table.cc75
-rw-r--r--sql/table.h2
-rw-r--r--sql/unireg.cc80
-rw-r--r--sql/unireg.h16
-rw-r--r--storage/archive/azio.c18
-rw-r--r--storage/archive/azlib.h3
-rw-r--r--storage/archive/ha_archive.cc31
-rw-r--r--storage/test_sql_discovery/mysql-test/archive/discover.rdiff35
16 files changed, 233 insertions, 101 deletions
diff --git a/include/my_base.h b/include/my_base.h
index f1b6825319c..0984ff8dfa9 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -318,7 +318,7 @@ enum ha_base_keytype {
#define HA_OPTION_NULL_FIELDS 1024
#define HA_OPTION_PAGE_CHECKSUM 2048
/* .frm has extra create options in linked-list format */
-#define HA_OPTION_TEXT_CREATE_OPTIONS (1L << 14)
+#define HA_OPTION_TEXT_CREATE_OPTIONS_legacy (1L << 14) /* 5.2 to 5.5, unused since 10.0 */
#define HA_OPTION_TEMP_COMPRESS_RECORD (1L << 15) /* set by isamchk */
#define HA_OPTION_READ_ONLY_DATA (1L << 16) /* Set by isamchk */
#define HA_OPTION_NO_CHECKSUM (1L << 17)
diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result
index 287c2991c1d..a170cdfbd8c 100644
--- a/mysql-test/suite/archive/archive.result
+++ b/mysql-test/suite/archive/archive.result
@@ -12701,12 +12701,12 @@ CREATE TABLE t1(a INT, b BLOB) ENGINE=archive;
SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM
INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
DATA_LENGTH AVG_ROW_LENGTH
-535 15
+550 15
INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2');
SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM
INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
DATA_LENGTH AVG_ROW_LENGTH
-569 284
+584 292
DROP TABLE t1;
SET @save_join_buffer_size= @@join_buffer_size;
SET @@join_buffer_size= 8192;
@@ -12818,10 +12818,11 @@ select * from t1;
a b
flush tables;
select * from t1;
-a b
-1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ERROR HY000: Table 't1' is marked as crashed and should be repaired
show warnings;
Level Code Message
+Warning 127 Got error 127 when reading table `test`.`t1`
+Error 1194 Table 't1' is marked as crashed and should be repaired
drop table t1;
create temporary table t1 (a int) engine=archive;
insert t1 values (1),(2),(3);
diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test
index 2acf8b9e6b5..1114eb4e89a 100644
--- a/mysql-test/suite/archive/archive.test
+++ b/mysql-test/suite/archive/archive.test
@@ -1738,7 +1738,7 @@ select * from t1; # open the table to create the frm
flush tables; # and close the table again
--remove_file $MYSQLD_DATADIR/test/t1.ARZ
copy_file std_data/t917689.ARZ $MYSQLD_DATADIR/test/t1.ARZ;
-#--error ER_CRASHED_ON_USAGE
+--error ER_CRASHED_ON_USAGE
select * from t1;
show warnings;
drop table t1;
diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result
index 8cae289733b..7ffaf30d4d2 100644
--- a/mysql-test/suite/archive/discover.result
+++ b/mysql-test/suite/archive/discover.result
@@ -17,6 +17,8 @@ select * from t1;
a
1
2
+t1.ARZ
+t1.frm
#
# show tables
#
@@ -28,10 +30,9 @@ show tables;
Tables_in_test
t1
t2
-select * from t1;
-a
-1
-2
+t1.ARZ
+t2.ARZ
+t2.frm
#
# show full tables
#
@@ -40,29 +41,27 @@ show full tables;
Tables_in_test Table_type
t1 BASE TABLE
t2 BASE TABLE
-select * from t1;
-a
-1
-2
+t1.ARZ
+t2.ARZ
+t2.frm
#
# discover on truncate
#
flush tables;
truncate table t1;
ERROR HY000: Table storage engine for 't1' doesn't have this option
-show tables;
-Tables_in_test
-t1
-t2
+t1.ARZ
+t1.frm
+t2.ARZ
+t2.frm
#
# discover on rename
#
flush tables;
rename table t2 to t0;
-show tables;
-Tables_in_test
-t0
-t1
+t0.ARZ
+t1.ARZ
+t1.frm
#
# discover on HA_ERR_TABLE_DEF_CHANGED
#
@@ -77,9 +76,7 @@ t1 CREATE TABLE `t1` (
#
flush tables;
drop table t1;
-show tables;
-Tables_in_test
-t0
+t0.ARZ
#
# discover of table non-existance on drop
#
@@ -89,6 +86,9 @@ flush tables;
select * from t1;
ERROR 42S02: Table 'test.t1' doesn't exist
drop table t0;
+show status like 'Handler_discover';
+Variable_name Value
+Handler_discover 7
#
# Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE
#
diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test
index 7a588d4654d..75668baafbf 100644
--- a/mysql-test/suite/archive/discover.test
+++ b/mysql-test/suite/archive/discover.test
@@ -13,6 +13,7 @@ remove_file $mysqld_datadir/test/t1.frm;
flush tables;
insert t1 values (2);
select * from t1;
+--list_files $mysqld_datadir/test
--echo #
--echo # show tables
@@ -22,24 +23,22 @@ select * from t2;
remove_file $mysqld_datadir/test/t1.frm;
flush tables;
show tables;
-select * from t1;
+--list_files $mysqld_datadir/test
--echo #
--echo # show full tables
--echo #
-remove_file $mysqld_datadir/test/t1.frm;
flush tables;
show full tables;
-select * from t1;
+--list_files $mysqld_datadir/test
--echo #
--echo # discover on truncate
--echo #
-remove_file $mysqld_datadir/test/t1.frm;
flush tables;
--error ER_ILLEGAL_HA
truncate table t1;
-show tables;
+--list_files $mysqld_datadir/test
--echo #
--echo # discover on rename
@@ -47,7 +46,7 @@ show tables;
remove_file $mysqld_datadir/test/t2.frm;
flush tables;
rename table t2 to t0;
-show tables;
+--list_files $mysqld_datadir/test
--echo #
--echo # discover on HA_ERR_TABLE_DEF_CHANGED
@@ -63,7 +62,7 @@ show create table t1;
remove_file $mysqld_datadir/test/t1.frm;
flush tables;
drop table t1;
-show tables;
+--list_files $mysqld_datadir/test
--echo #
--echo # discover of table non-existance on drop
@@ -74,6 +73,8 @@ flush tables;
--error ER_NO_SUCH_TABLE
select * from t1;
drop table t0;
+--list_files $mysqld_datadir/test
+show status like 'Handler_discover';
--echo #
--echo # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE
diff --git a/mysql-test/suite/archive/partition_archive.result b/mysql-test/suite/archive/partition_archive.result
index 27ec5edb429..0ba50c38e8d 100644
--- a/mysql-test/suite/archive/partition_archive.result
+++ b/mysql-test/suite/archive/partition_archive.result
@@ -15,10 +15,10 @@ ENGINE = ARCHIVE;
INSERT INTO t1 VALUES(CURRENT_DATE);
SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1';
DATA_LENGTH INDEX_LENGTH
-520 0
+535 0
SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1';
DATA_LENGTH INDEX_LENGTH
-520 0
+535 0
DROP TABLE t1;
drop database if exists db99;
drop table if exists t1;
diff --git a/mysys/my_uuid.c b/mysys/my_uuid.c
index ab1b259ae0f..01c59e42f2e 100644
--- a/mysys/my_uuid.c
+++ b/mysys/my_uuid.c
@@ -123,7 +123,7 @@ void my_uuid_init(ulong seed1, ulong seed2)
Create a global unique identifier (uuid)
@func my_uuid()
- @param to Store uuid here. Must be of size MY_uuid_SIZE (16)
+ @param to Store uuid here. Must be of size MY_UUID_SIZE (16)
*/
void my_uuid(uchar *to)
diff --git a/sql/handler.h b/sql/handler.h
index 8e4d59e7f7f..edbff4b68e1 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1360,6 +1360,7 @@ enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
struct HA_CREATE_INFO
{
CHARSET_INFO *table_charset, *default_table_charset;
+ LEX_CUSTRING tabledef_version;
LEX_STRING connect_string;
const char *password, *tablespace;
LEX_STRING comment;
@@ -1393,6 +1394,7 @@ struct HA_CREATE_INFO
enum ha_storage_media storage_media; ///< DEFAULT, DISK or MEMORY
enum ha_choice page_checksum; ///< If we have page_checksums
engine_option_value *option_list; ///< list of table create options
+
/* the following three are only for ALTER TABLE, check_if_incompatible_data() */
ha_table_option_struct *option_struct; ///< structure with parsed table options
ha_field_option_struct **fields_option_struct; ///< array of field option structures
diff --git a/sql/table.cc b/sql/table.cc
index d6b109a880a..ad1f8893e47 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2008-2011 Monty Program Ab
+ Copyright (c) 2008, 2013, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -706,7 +706,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
uint i,j;
bool use_hash;
char *keynames, *names, *comment_pos;
- const uchar *forminfo;
+ const uchar *forminfo, *extra2;
const uchar *frm_image_end = frm_image + frm_length;
uchar *record, *null_flags, *null_pos;
const uchar *disk_buff, *strpos;
@@ -723,7 +723,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
bool null_bits_are_used;
uint vcol_screen_length, UNINIT_VAR(options_len);
char *vcol_screen_pos;
- const uchar *UNINIT_VAR(options);
+ const uchar *options= 0;
KEY first_keyinfo;
uint len;
KEY_PART_INFO *first_key_part= NULL;
@@ -749,8 +749,60 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
new_frm_ver= (frm_image[2] - FRM_VER);
field_pack_length= new_frm_ver < 2 ? 11 : 17;
- /* Position of the form in the form file. */
+ /* Length of the MariaDB extra2 segment in the form file. */
len = uint2korr(frm_image+4);
+ extra2= frm_image + 64;
+
+ if (*extra2 != '/') // old frm had '/' there
+ {
+ const uchar *e2end= extra2 + len;
+ while (extra2 < e2end)
+ {
+ uchar type= *extra2++;
+ size_t length= *extra2++;
+ if (!length)
+ {
+ length= uint2korr(extra2);
+ extra2+=2;
+ if (length < 256)
+ goto err;
+ }
+ switch (type) {
+ case EXTRA2_TABLEDEF_VERSION:
+ if (tabledef_version.str) // see init_from_sql_statement_string()
+ {
+ if (length != tabledef_version.length ||
+ memcmp(extra2, tabledef_version.str, length))
+ goto err;
+ }
+ else
+ {
+ uchar *buf= (uchar*) alloc_root(&mem_root, length);
+ if (!buf)
+ goto err;
+ memcpy(buf, extra2, length);
+ tabledef_version.str= buf;
+ tabledef_version.length= length;
+ }
+ break;
+ case EXTRA2_ENGINE_TABLEOPTS:
+ if (options)
+ goto err;
+ /* remember but delay parsing until we have read fields and keys */
+ options= extra2;
+ options_len= length;
+ break;
+ default:
+ /* abort frm parsing if it's an unknown but important extra2 value */
+ if (type >= 128)
+ goto err;
+ }
+ extra2+= length;
+ }
+ if (extra2 > e2end)
+ goto err;
+ }
+
if (frm_length < FRM_HEADER_SIZE + len ||
!(pos= uint4korr(frm_image + FRM_HEADER_SIZE + len)))
goto err;
@@ -1169,12 +1221,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
DBUG_ASSERT(next_chunk <= buff_end);
- if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
+ if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS_legacy)
{
- /*
- store options position, but skip till the time we will
- know number of fields
- */
+ if (options)
+ goto err;
options_len= uint4korr(next_chunk);
options= next_chunk + 4;
next_chunk+= options_len + 4;
@@ -1839,7 +1889,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
null_length, 255);
}
- if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
+ if (options)
{
DBUG_ASSERT(options_len);
if (engine_table_options_frm_read(options, options_len, share))
@@ -2028,6 +2078,9 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
thd->lex->create_info.db_type= plugin_data(db_plugin, handlerton *);
+ if (tabledef_version.str)
+ thd->lex->create_info.tabledef_version= tabledef_version;
+
file= mysql_create_frm_image(thd, db.str, table_name.str,
&thd->lex->create_info, &thd->lex->alter_info,
0, 0, &frm);
@@ -3086,7 +3139,7 @@ void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo,
fileinfo[3]= (uchar) ha_legacy_type(
ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
- int2store(fileinfo+4,3);
+
/*
Keep in sync with pack_keys() in unireg.cc
For each key:
diff --git a/sql/table.h b/sql/table.h
index a10617cc938..6d20706cd92 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -616,6 +616,8 @@ struct TABLE_SHARE
I_P_List <TABLE, TABLE_share> used_tables;
I_P_List <TABLE, TABLE_share> free_tables;
+ LEX_CUSTRING tabledef_version;
+
engine_option_value *option_list; /* text options for table */
ha_table_option_struct *option_struct; /* structure with parsed options */
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 588ed622a60..5da9f88132d 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -122,13 +123,6 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
create_fields,
keys, key_info);
DBUG_PRINT("info", ("Options length: %u", options_len));
- if (options_len)
- {
- create_info->table_options|= HA_OPTION_TEXT_CREATE_OPTIONS;
- create_info->extra_size+= (options_len + 4);
- }
- else
- create_info->table_options&= ~HA_OPTION_TEXT_CREATE_OPTIONS;
/*
This gives us the byte-position of the character at
@@ -193,13 +187,31 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
forminfo[46]=(uchar) create_info->comment.length;
}
+ if (!create_info->tabledef_version.str)
+ {
+ uchar *to= (uchar*) thd->alloc(MY_UUID_SIZE);
+ if (unlikely(!to))
+ DBUG_RETURN(frm);
+ my_uuid(to);
+ create_info->tabledef_version.str= to;
+ create_info->tabledef_version.length= MY_UUID_SIZE;
+ }
+ DBUG_ASSERT(create_info->tabledef_version.length > 0);
+ DBUG_ASSERT(create_info->tabledef_version.length <= 255);
+
prepare_frm_header(thd, reclength, fileinfo, create_info, keys, key_info);
+ /* one byte for a type, one or three for a length */
+ uint extra2_size= 1 + 1 + create_info->tabledef_version.length;
+ if (options_len)
+ extra2_size+= 1 + (options_len > 255 ? 3 : 1) + options_len;
+
key_buff_length= uint4korr(fileinfo+47);
frm.length= FRM_HEADER_SIZE; // fileinfo;
- frm.length+= uint2korr(fileinfo+4) + 4; // "form entry"
+ frm.length+= extra2_size + 4; // mariadb extra2 frm segment
+ int2store(fileinfo+4, extra2_size);
int2store(fileinfo+6, frm.length);
frm.length+= key_buff_length;
frm.length+= reclength; // row with default values
@@ -214,11 +226,34 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
if (!frm_ptr)
DBUG_RETURN(frm);
- pos = frm_ptr + uint2korr(fileinfo+6);
- key_info_length= pack_keys(pos, keys, key_info, data_offset);
+ /* write the extra2 segment */
+ pos = frm_ptr + 64;
+ *pos++ = EXTRA2_TABLEDEF_VERSION;
+ *pos++ = create_info->tabledef_version.length;
+ memcpy(pos, create_info->tabledef_version.str,
+ create_info->tabledef_version.length);
+ pos+= create_info->tabledef_version.length;
- memcpy(frm_ptr + FRM_HEADER_SIZE, "//", 3);
- int4store(frm_ptr + 67, filepos);
+ if (options_len)
+ {
+ *pos++= EXTRA2_ENGINE_TABLEOPTS;
+ if (options_len < 255)
+ *pos++= options_len;
+ else
+ {
+ DBUG_ASSERT(options_len <= 65535); // FIXME if necessary
+ int2store(pos + 1, options_len);
+ pos+= 3;
+ }
+ pos= engine_table_options_frm_image(pos, create_info->option_list,
+ create_fields, keys, key_info);
+ }
+
+ int4store(pos, filepos); // end of the extra2 segment
+ pos+= 4;
+
+ DBUG_ASSERT(pos == frm_ptr + uint2korr(fileinfo+6));
+ key_info_length= pack_keys(pos, keys, key_info, data_offset);
maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000));
int2store(forminfo+2,maxlength);
@@ -285,19 +320,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
pos+= create_info->comment.length;
}
- if (options_len)
- {
- int4store(pos, options_len);
- pos+= 4;
- engine_table_options_frm_image(pos,
- create_info->option_list,
- create_fields,
- keys, key_info);
- pos+= options_len;
- }
-
- memcpy(frm_ptr + filepos, forminfo, FRM_FORMINFO_SIZE);
- if (pack_fields(frm_ptr + filepos + FRM_FORMINFO_SIZE, create_fields, data_offset))
+ memcpy(frm_ptr + filepos, forminfo, 288);
+ if (pack_fields(frm_ptr + filepos + 288, create_fields, data_offset))
goto err;
{
@@ -332,14 +356,12 @@ err:
SYNOPSIS
rea_create_table()
thd Thread handler
+ frm binary frm image of the table to create
path Name of file (including database, without .frm)
db Data base name
table_name Table name
create_info create info parameters
- create_fields Fields to create
- keys number of keys to create
- key_info Keys to create
- file Handler to use
+ file Handler to use or NULL if only frm needs to be created
RETURN
0 ok
diff --git a/sql/unireg.h b/sql/unireg.h
index 89dae6b2e97..8fba6e5cfbe 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -167,6 +167,22 @@
#include "sql_list.h" /* List<> */
#include "field.h" /* Create_field */
+/*
+ Types of values in the MariaDB extra2 frm segment.
+ Each value is written as
+ type: 1 byte
+ length: 1 byte (1..255) or \0 and 2 bytes.
+ binary value of the 'length' bytes.
+
+ Older MariaDB servers can ignore values of unknown types if
+ the type code is less than 128. Otherwise older servers are required
+ to report an error.
+*/
+enum extra2_frm_value_type {
+ EXTRA2_TABLEDEF_VERSION=0,
+ EXTRA2_ENGINE_TABLEOPTS=128,
+};
+
int rea_create_table(THD *thd, LEX_CUSTRING *frm,
const char *path, const char *db, const char *table_name,
HA_CREATE_INFO *create_info, handler *file);
diff --git a/storage/archive/azio.c b/storage/archive/azio.c
index c6058af2e3d..4519d15cefc 100644
--- a/storage/archive/azio.c
+++ b/storage/archive/azio.c
@@ -364,6 +364,8 @@ void read_header(azio_stream *s, unsigned char *buffer)
{
if (buffer[0] == az_magic[0] && buffer[1] == az_magic[1])
{
+ uchar tmp[AZ_FRMVER_LEN + 2];
+
s->version= (unsigned int)buffer[AZ_VERSION_POS];
s->minor_version= (unsigned int)buffer[AZ_MINOR_VERSION_POS];
s->block_size= 1024 * buffer[AZ_BLOCK_POS];
@@ -379,6 +381,22 @@ void read_header(azio_stream *s, unsigned char *buffer)
s->comment_start_pos= (unsigned int)uint4korr(buffer + AZ_COMMENT_POS);
s->comment_length= (unsigned int)uint4korr(buffer + AZ_COMMENT_LENGTH_POS);
s->dirty= (unsigned int)buffer[AZ_DIRTY_POS];
+
+ /*
+ we'll hard-code the current frm format for now, to avoid
+ changing archive table versions.
+ */
+ if (s->frm_length == 0 ||
+ my_pread(s->file, tmp, sizeof(tmp), s->frm_start_pos + 64, MYF(MY_NABP)) ||
+ tmp[0] != 0 || tmp[1] != AZ_FRMVER_LEN)
+ {
+ s->frmver_length= 0;
+ }
+ else
+ {
+ s->frmver_length= tmp[1];
+ memcpy(s->frmver, tmp+2, s->frmver_length);
+ }
}
else if (buffer[0] == gz_magic[0] && buffer[1] == gz_magic[1])
{
diff --git a/storage/archive/azlib.h b/storage/archive/azlib.h
index 09f61afcd28..2971705b2f1 100644
--- a/storage/archive/azlib.h
+++ b/storage/archive/azlib.h
@@ -198,6 +198,7 @@ extern "C" {
#define AZ_BUFSIZE_READ 32768
#define AZ_BUFSIZE_WRITE 16384
+#define AZ_FRMVER_LEN 16 /* same as MY_UUID_SIZE in 10.0.2 */
typedef struct azio_stream {
z_stream stream;
@@ -227,6 +228,8 @@ typedef struct azio_stream {
unsigned char dirty; /* State of file */
unsigned int frm_start_pos; /* Position for start of FRM */
unsigned int frm_length; /* Position for start of FRM */
+ unsigned char frmver[AZ_FRMVER_LEN];
+ unsigned int frmver_length;
unsigned int comment_start_pos; /* Position for start of comment */
unsigned int comment_length; /* Position for start of comment */
} azio_stream;
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 515ebf8cf3d..9f164da3359 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -673,33 +673,12 @@ int ha_archive::frm_copy(azio_stream *src, azio_stream *dst)
int ha_archive::frm_compare(azio_stream *s)
{
- int rc= 0;
- const uchar *frm_ptr= 0;
- uchar *azfrm_ptr= 0;
- size_t frm_len;
-
- /* no frm = no discovery. perhaps it's a partitioned table */
- if (table->s->read_frm_image(&frm_ptr, &frm_len))
- goto err;
-
- if (!(azfrm_ptr= (uchar *) my_malloc(s->frm_length,
- MYF(MY_THREAD_SPECIFIC | MY_WME))))
- goto err;
-
- rc= 1;
+ if (!s->frmver_length)
+ return 0; // Old pre-10.0 archive table. Never rediscover.
- if (frm_len != s->frm_length)
- goto err;
-
- if (azread_frm(s, azfrm_ptr))
- goto err;
-
- rc= memcmp(frm_ptr, azfrm_ptr, frm_len);
-
-err:
- my_free(const_cast<uchar*>(frm_ptr));
- my_free(azfrm_ptr);
- return rc;
+ LEX_CUSTRING *ver= &table->s->tabledef_version;
+ return ver->length != s->frmver_length ||
+ memcmp(ver->str, s->frmver, ver->length);
}
diff --git a/storage/test_sql_discovery/mysql-test/archive/discover.rdiff b/storage/test_sql_discovery/mysql-test/archive/discover.rdiff
new file mode 100644
index 00000000000..3148999079f
--- /dev/null
+++ b/storage/test_sql_discovery/mysql-test/archive/discover.rdiff
@@ -0,0 +1,35 @@
+--- suite/archive/discover.result 2013-04-08 00:06:37.000000000 +0200
++++ /usr/home/serg/Abk/mysql/10.0-serg/storage/test_sql_discovery/mysql-test/archive/discover.reject 2013-04-08 00:07:02.000000000 +0200
+@@ -42,6 +42,7 @@
+ t1 BASE TABLE
+ t2 BASE TABLE
+ t1.ARZ
++t1.frm
+ t2.ARZ
+ t2.frm
+ #
+@@ -60,6 +61,7 @@
+ flush tables;
+ rename table t2 to t0;
+ t0.ARZ
++t0.frm
+ t1.ARZ
+ t1.frm
+ #
+@@ -77,6 +79,7 @@
+ flush tables;
+ drop table t1;
+ t0.ARZ
++t0.frm
+ #
+ # discover of table non-existance on drop
+ #
+@@ -86,7 +89,7 @@
+ drop table t0;
+ show status like 'Handler_discover';
+ Variable_name Value
+-Handler_discover 7
++Handler_discover 8
+ #
+ # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE
+ #