#At file:///export/home/log/Narayanan/mysql_checkouts_bazaar/5.1_main_repository/mysql-5.1-bugteam-37631-2/ based on revid:staale.smedseng@stripped
2837 Narayanan V 2009-03-28
Bug#37631 Incorrect key file for table after upgrading from 5.0 to 5.1
The conformance checker was not taking into
account, and, making concessions for acceptable
incompatibilites in tables created by
versions earlier than 4.1.
The current patch relaxes the conformance
checker to ignore differences in key_alg
and language for tables created by versions
earlier than 4.1.
@ storage/myisam/ha_myisam.cc
Modify check_definition to ignore differences
in key_alg and language for tables created
by versions earlier than 4.1.
@ storage/myisammrg/ha_myisammrg.cc
pass the table object to check_definition.
modified:
storage/myisam/ha_myisam.cc
storage/myisammrg/ha_myisammrg.cc
=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc 2009-03-17 20:29:24 +0000
+++ b/storage/myisam/ha_myisam.cc 2009-03-27 20:45:53 +0000
@@ -315,6 +315,7 @@ int table2myisam(TABLE *table_arg, MI_KE
t2_keys in Number of keys in second table
t2_recs in Number of records in second table
strict in Strict check switch
+ table in handle to the underlying table object
DESCRIPTION
This function compares two MyISAM definitions. By intention it was done
@@ -330,6 +331,11 @@ int table2myisam(TABLE *table_arg, MI_KE
Otherwise 'strict' flag must be set to 1 and it is not required to pass
converted dot-frm definition as t1_*.
+ If the underlying table is created by a mysql server with version
+ earlier than 4.1 the tables differ in key_alg and language. we relax the
+ conformance checker in this case by ignoring the difference in key_alg
+ and language when the table is older than 4.1.
+
RETURN VALUE
0 - Equal definitions.
1 - Different definitions.
@@ -344,7 +350,7 @@ int table2myisam(TABLE *table_arg, MI_KE
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
uint t1_keys, uint t1_recs,
MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
- uint t2_keys, uint t2_recs, bool strict)
+ uint t2_keys, uint t2_recs, bool strict, TABLE *table_arg)
{
uint i, j;
DBUG_ENTER("check_definition");
@@ -386,8 +392,13 @@ int check_definition(MI_KEYDEF *t1_keyin
test(t2_keyinfo[i].flag & HA_SPATIAL)));
DBUG_RETURN(1);
}
- if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
- t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
+ /*
+ check for difference in key_alg only if the table is created by
+ 4.1 or later
+ */
+ if ((table_arg->s->frm_version >= FRM_VER_TRUE_VARCHAR &&
+ t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg) ||
+ t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs)
{
DBUG_PRINT("error", ("Key %d has different definition", i));
DBUG_PRINT("error", ("t1_keysegs=%d, t1_key_alg=%d",
@@ -417,8 +428,13 @@ int check_definition(MI_KEYDEF *t1_keyin
t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1; /* purecov: inspected */
}
- if (t1_keysegs_j__type != t2_keysegs[j].type ||
- t1_keysegs[j].language != t2_keysegs[j].language ||
+ /*
+ check for difference in language only if the table is created by
+ 4.1 or later
+ */
+ if ((table_arg->s->frm_version >= FRM_VER_TRUE_VARCHAR &&
+ t1_keysegs[j].language != t2_keysegs[j].language) ||
+ t1_keysegs_j__type != t2_keysegs[j].type ||
t1_keysegs[j].null_bit != t2_keysegs[j].null_bit ||
t1_keysegs[j].length != t2_keysegs[j].length)
{
@@ -671,7 +687,8 @@ int ha_myisam::open(const char *name, in
}
if (check_definition(keyinfo, recinfo, table->s->keys, recs,
file->s->keyinfo, file->s->rec,
- file->s->base.keys, file->s->base.fields, true))
+ file->s->base.keys, file->s->base.fields,
+ true, table))
{
/* purecov: begin inspected */
my_errno= HA_ERR_CRASHED;
=== modified file 'storage/myisammrg/ha_myisammrg.cc'
--- a/storage/myisammrg/ha_myisammrg.cc 2009-03-17 20:29:24 +0000
+++ b/storage/myisammrg/ha_myisammrg.cc 2009-03-27 20:45:53 +0000
@@ -137,7 +137,8 @@ extern int table2myisam(TABLE *table_arg
extern int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
uint t1_keys, uint t1_recs,
MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
- uint t2_keys, uint t2_recs, bool strict);
+ uint t2_keys, uint t2_recs, bool strict,
+ TABLE *table_arg);
static void split_file_name(const char *file_name,
LEX_STRING *db, LEX_STRING *name);
@@ -595,7 +596,7 @@ int ha_myisammrg::attach_children(void)
if (check_definition(keyinfo, recinfo, keys, recs,
u_table->table->s->keyinfo, u_table->table->s->rec,
u_table->table->s->base.keys,
- u_table->table->s->base.fields, false))
+ u_table->table->s->base.fields, false, NULL))
{
DBUG_PRINT("error", ("table definition mismatch: '%s'",
u_table->table->filename));
Attachment: [text/bzr-bundle] bzr/v.narayanan@sun.com-20090327204553-ozp92f5b0yhqac82.bundle