WL#3567: MERGE engine: a check for underlying table conformance

Affects: Server-4.1   —   Status: Complete

This task is to fix the following, related set of bugs in version 4.1 of
MySQL: BUG#457, BUG#23750, BUG#23751, BUG#23752, BUG#23753.

To make MERGE engine more fool proof and user friendly, it needs to perform a 
check for underlying table conformance when a merge table is being opened. 
Refuse to open merge table if merge table definition differs from underlying 
table definition.
Currently merge engine performs only silly check for underlying table
definition conformance to merge table definition. It checks if record length
of underlying table is equal to record length of merge table.

This is not sufficient, for example if merge table is defined as
(a TEXT, b INT) and underlying table is defined as (a INT, b TEXT). Record
lengths are equal, but definition is different. As a result we can easily
have server crash or memory corruption.

Merge engine does not perform a check for index definition conformance at
all. As a result we can have server crash or memory corruption (see problem
descirbed in BUG#23753).

This worklog was created to solve problems mentioned above. Note that it
will solve merge engine definition _conformance_ issue, not merge engine
_consistency_. That means we will not perform a check for underlying table
conformance and a check for underlying table existance when a merge table
is created. We will check for underlying table conformance when a merge
table is referred (in other words when it is opened).

When a merge table is opened (in ha_myisammrg::open) compare column and key
definition of underlying against column and key definition of merge table.
If any of checks fails, refuse to open merge table.

Column definition
-----------------
Underlying table must have exactly the same amount of columns that merge
table has.

For each column:
a) check if column length of underlying table equals to column length of
   merge table;
b) check if column of underlying table and column of merge table can be
   null;
c) check if column type of underlying table equals to column type of merge
   table;

Key definition
--------------
Underlying table must have at least the same amount of keys that merge table
has. It is not required to have exactly the same amount of keys - it is
allowed to have more keys in underlying table.

For each key:
a) check if key type of underlying table equals to key type of merge table;
b) check if number of key parts in underlying table key definition equals
   to number of key parts in merge table key definition;
c) check key parts conformance;

For each key part:
a) check if key part lengths are equal;
b) check if key part types are equal;
c) check if key part languages are equal;
d) check if key part can be null;
There is a part of code in ha_myisam::create that is resposible for
converting TABLE object into MI_COLUMNDEF and MI_KEYDEF. To reuse this code
for purposes of this worklog, this code should be moved to a spearate
function:
int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
                 MI_COLUMNDEF **recinfo_out, uint *records_out);

Additional function should be created in ha_myisammrg.cc. It will perform a
check for underlying table conformance. First it will convert TABLE object
(merge table definition) to MyISAM column and key definition using
table2myisam. Then compare converted merge table definition against each
underlying table according to HLS.